Commit 637c53ff authored by Juergen Gross's avatar Juergen Gross Committed by Gerd Hoffmann
Browse files

xen: write information about supported backends



Add a Xenstore directory for each supported pv backend. This will allow
Xen tools to decide which backend type to use in case there are
multiple possibilities.

The information is added under
/local/domain/<backend-domid>/device-model/<domid>/backends
before the "running" state is written to Xenstore. Using a directory
for each backend enables us to add parameters for specific backends
in the future.

This interface is documented in the Xen source repository in the file
docs/misc/qemu-backends.txt

In order to reuse the Xenstore directory creation already present in
hw/xen/xen_devconfig.c move the related functions to
hw/xen/xen_backend.c where they fit better.

Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
Acked-by: default avatarAnthony PERARD <anthony.perard@citrix.com>
Reviewed-by: default avatarWei Liu <wei.liu2@citrix.com>
Message-id: 1463062421-613-3-git-send-email-jgross@suse.com
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 9432e53a
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -42,11 +42,36 @@ struct xs_handle *xenstore = NULL;
const char *xen_protocol;

/* private */
struct xs_dirs {
    char *xs_dir;
    QTAILQ_ENTRY(xs_dirs) list;
};
static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
    QTAILQ_HEAD_INITIALIZER(xs_cleanup);

static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs);
static int debug = 0;

/* ------------------------------------------------------------- */

static void xenstore_cleanup_dir(char *dir)
{
    struct xs_dirs *d;

    d = g_malloc(sizeof(*d));
    d->xs_dir = dir;
    QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
}

void xen_config_cleanup(void)
{
    struct xs_dirs *d;

    QTAILQ_FOREACH(d, &xs_cleanup, list) {
        xs_rm(xenstore, 0, d->xs_dir);
    }
}

int xenstore_write_str(const char *base, const char *node, const char *val)
{
    char abspath[XEN_BUFSIZE];
@@ -75,6 +100,30 @@ char *xenstore_read_str(const char *base, const char *node)
    return ret;
}

int xenstore_mkdir(char *path, int p)
{
    struct xs_permissions perms[2] = {
        {
            .id    = 0, /* set owner: dom0 */
        }, {
            .id    = xen_domid,
            .perms = p,
        }
    };

    if (!xs_mkdir(xenstore, 0, path)) {
        xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", path);
        return -1;
    }
    xenstore_cleanup_dir(g_strdup(path));

    if (!xs_set_permissions(xenstore, 0, path, perms, 2)) {
        xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", path);
        return -1;
    }
    return 0;
}

int xenstore_write_int(const char *base, const char *node, int ival)
{
    char val[12];
@@ -726,6 +775,20 @@ err:

int xen_be_register(const char *type, struct XenDevOps *ops)
{
    char path[50];
    int rc;

    if (ops->backend_register) {
        rc = ops->backend_register();
        if (rc) {
            return rc;
        }
    }

    snprintf(path, sizeof(path), "device-model/%u/backends/%s", xen_domid,
             type);
    xenstore_mkdir(path, XS_PERM_NONE);

    return xenstore_scan(type, xen_domid, ops);
}

+2 −50
Original line number Diff line number Diff line
@@ -5,54 +5,6 @@

/* ------------------------------------------------------------- */

struct xs_dirs {
    char *xs_dir;
    QTAILQ_ENTRY(xs_dirs) list;
};
static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = QTAILQ_HEAD_INITIALIZER(xs_cleanup);

static void xen_config_cleanup_dir(char *dir)
{
    struct xs_dirs *d;

    d = g_malloc(sizeof(*d));
    d->xs_dir = dir;
    QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
}

void xen_config_cleanup(void)
{
    struct xs_dirs *d;

    QTAILQ_FOREACH(d, &xs_cleanup, list) {
	xs_rm(xenstore, 0, d->xs_dir);
    }
}

/* ------------------------------------------------------------- */

static int xen_config_dev_mkdir(char *dev, int p)
{
    struct xs_permissions perms[2] = {{
            .id    = 0, /* set owner: dom0 */
        },{
            .id    = xen_domid,
            .perms = p,
        }};

    if (!xs_mkdir(xenstore, 0, dev)) {
	xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev);
	return -1;
    }
    xen_config_cleanup_dir(g_strdup(dev));

    if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) {
	xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev);
	return -1;
    }
    return 0;
}

static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev,
			       char *fe, char *be, int len)
{
@@ -66,8 +18,8 @@ static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev,
    snprintf(be, len, "%s/backend/%s/%d/%d", dom, btype, xen_domid, vdev);
    free(dom);

    xen_config_dev_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE);
    xen_config_dev_mkdir(be, XS_PERM_READ);
    xenstore_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE);
    xenstore_mkdir(be, XS_PERM_READ);
    return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ struct XenDevOps {
    int       (*free)(struct XenDevice *xendev);
    void      (*backend_changed)(struct XenDevice *xendev, const char *node);
    void      (*frontend_changed)(struct XenDevice *xendev, const char *node);
    int       (*backend_register)(void);
};

struct XenDevice {
@@ -63,6 +64,7 @@ extern const char *xen_protocol;
extern DeviceState *xen_sysdev;

/* xenstore helper functions */
int xenstore_mkdir(char *path, int p);
int xenstore_write_str(const char *base, const char *node, const char *val);
int xenstore_write_int(const char *base, const char *node, int ival);
int xenstore_write_int64(const char *base, const char *node, int64_t ival);