From 97bc91ac28e5553503d1c63be8401825e3cac8ef Mon Sep 17 00:00:00 2001 From: Paul Durrant Date: Mon, 30 Apr 2018 09:18:14 +0100 Subject: [PATCH] Add compat layer to instantiate backend Signed-off-by: Paul Durrant --- hw/block/xen_qdisk.c | 186 ++++++++++++++++++++++++++++----------- hw/xen/xen_bus.c | 54 ++++++------ include/hw/xen/xen_bus.h | 12 ++- 3 files changed, 174 insertions(+), 78 deletions(-) diff --git a/hw/block/xen_qdisk.c b/hw/block/xen_qdisk.c index c18ad8e1a8..742f4ff6d3 100644 --- a/hw/block/xen_qdisk.c +++ b/hw/block/xen_qdisk.c @@ -1,4 +1,5 @@ #include "qemu/osdep.h" +#include "qemu/option.h" #include "qapi/error.h" #include "qapi/visitor.h" #include "hw/hw.h" @@ -22,6 +23,7 @@ typedef struct XenQdiskVdev { XenQdiskVdevType type; unsigned int disk; unsigned int partition; + unsigned int number; bool valid; } XenQdiskVdev; @@ -565,53 +567,8 @@ static void blk_handle_requests(XenQdiskBackend *d) static char *xen_qdisk_get_name(XenBackend *dev, Error **errp) { XenQdiskBackend *d = XEN_QDISK_BACKEND(dev); - XenQdiskVdev *vdev = &d->vdev; - unsigned int number; - - switch (vdev->type) { - case XEN_QDISK_VDEV_TYPE_DP: - case XEN_QDISK_VDEV_TYPE_XVD: - if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) { - number = (202 << 8) | (vdev->disk << 4) | vdev->partition; - } else if (vdev->disk < (1 << 20) && vdev->partition < (1 << 8)) { - number = (1 << 28) | (vdev ->disk << 8) | vdev->partition; - } else { - error_setg(errp, "cannot use xvd encoding for d%up%u", - vdev->disk, vdev->partition); - return NULL; - } - break; - case XEN_QDISK_VDEV_TYPE_HD: - if ((vdev->disk == 0 || vdev->disk == 1) && - vdev->partition < (1 << 4)) { - number = (3 << 8) | (vdev->disk << 6) | vdev->partition; - } else if ((vdev->disk == 2 || vdev->disk == 3) && - vdev->partition < (1 << 4)) { - number = (22 << 8) | ((vdev->disk - 2) << 6) | vdev->partition; - } else { - error_setg(errp, "cannot use hd encoding for d%up%u", - vdev->disk, vdev->partition); - return NULL; - } - break; - - case XEN_QDISK_VDEV_TYPE_SD: - if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) { - number = (8 << 8) | (vdev->disk << 4) | vdev->partition; - } else { - error_setg(errp, "cannot use sd encoding for d%up%u", - vdev->disk, vdev->partition); - return NULL; - } - break; - - default: - error_setg(errp, "invalid type"); - return NULL; - } - - return g_strdup_printf("%u", number); + return g_strdup_printf("%u", d->vdev.number); } static void xen_qdisk_bh(void *opaque) @@ -684,7 +641,8 @@ static void xen_qdisk_realize(XenBackend *dev, Error **errp) info |= is_cdrom ? VDISK_CDROM : 0; xenstore_backend_printf(dev, "info", "%u", info); - + + xenstore_frontend_printf(dev, "virtual-device", "%u", d->vdev.number); xenstore_frontend_printf(dev, "device-type", "%s", is_cdrom ? "cdrom" : "disk"); @@ -978,7 +936,7 @@ static unsigned int vbd_name_to_disk(char *name, char **endp) return disk; } - + static void xen_qdisk_set_vdev(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { @@ -1040,12 +998,51 @@ static void xen_qdisk_set_vdev(Object *obj, Visitor *v, const char *name, vdev->partition = 0; } + switch (vdev->type) { + case XEN_QDISK_VDEV_TYPE_DP: + case XEN_QDISK_VDEV_TYPE_XVD: + if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) { + vdev->number = (202 << 8) | (vdev->disk << 4) | + vdev->partition; + } else if (vdev->disk < (1 << 20) && vdev->partition < (1 << 8)) { + vdev->number = (1 << 28) | (vdev ->disk << 8) | + vdev->partition; + } else { + goto invalid; + } + break; + + case XEN_QDISK_VDEV_TYPE_HD: + if ((vdev->disk == 0 || vdev->disk == 1) && + vdev->partition < (1 << 4)) { + vdev->number = (3 << 8) | (vdev->disk << 6) | vdev->partition; + } else if ((vdev->disk == 2 || vdev->disk == 3) && + vdev->partition < (1 << 4)) { + vdev->number = (22 << 8) | ((vdev->disk - 2) << 6) | + vdev->partition; + } else { + goto invalid; + } + break; + + case XEN_QDISK_VDEV_TYPE_SD: + if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) { + vdev->number = (8 << 8) | (vdev->disk << 4) | vdev->partition; + } else { + goto invalid; + } + break; + + default: + goto invalid; + } + g_free(str); vdev->valid = true; return; invalid: - error_setg(errp, "invalid vbd name"); + error_setg(errp, "invalid virtual disk specifier"); g_free(str); } @@ -1096,7 +1093,96 @@ static void xen_qdisk_register_types(void) type_init(xen_qdisk_register_types) -void xen_qdisk_backend_create(char *path) +void xen_qdisk_backend_create(BusState *bus, struct xs_handle *xsh, + char *path) { + char *params, *dev, *device_type, mode; + unsigned int discard_enable; + char *format = NULL; + char *file = NULL; + char *vdev = NULL; + char *media = NULL; + bool readonly = false; + char *optstr; + QemuOpts *opts; + DeviceState *qdisk; + BlockBackend *blk; + fprintf(stderr, "%s: %s\n", __func__, path); + + if (xenstore_scanf(xsh, path, "params", "%ms", ¶ms) == 1) { + char **v = g_strsplit(params, ":", 2); + + if (v[1] == NULL) { + file = g_strdup(v[0]); + } else { + if (strcmp(v[0], "aio") == 0) { + format = g_strdup("raw"); + } else if (strcmp(v[0], "vhd") == 0) { + format = g_strdup("vpc"); + } else { + format = g_strdup(v[0]); + } + file = g_strdup(v[1]); + } + + g_strfreev(v); + free(params); + } + + if (xenstore_scanf(xsh, path, "dev", "%ms", &dev) == 1) { + vdev = g_strdup(dev); + free(dev); + } + + if (xenstore_scanf(xsh, path, "device-type", "%ms", + &device_type) == 1) { + media = g_strdup(device_type); + free(device_type); + } + + if (xenstore_scanf(xsh, path, "mode", "%c", &mode) == 1 && + mode != 'w') { + readonly = true; + } + + if (xenstore_scanf(xsh, path, "discard-enable", "%u", + &discard_enable) != 1) { + discard_enable = 0; + } + + if (!file || !vdev) + goto out; + + optstr = g_strdup_printf("id=%s", vdev); + opts = drive_def(optstr); + + qemu_opt_set(opts, "file", file, &error_abort); + + if (media) { + qemu_opt_set(opts, "media", media, &error_abort); + } + + if (format) { + qemu_opt_set(opts, "format", format, &error_abort); + } + + qemu_opt_set_bool(opts, BDRV_OPT_CACHE_WB, true, &error_abort); + qemu_opt_set_bool(opts, BDRV_OPT_READ_ONLY, readonly, &error_abort); + + drive_new(opts, IF_NONE); + + qdisk = qdev_create(bus, TYPE_XEN_QDISK_BACKEND); + blk = blk_by_name(vdev); + qdev_prop_set_drive(qdisk, "drive", blk, &error_abort); + qdev_prop_set_string(qdisk, "vdev", vdev); + qdev_prop_set_bit(qdisk, "discard-enable", !!discard_enable); + qdev_init_nofail(qdisk); + +out: + g_free(format); + g_free(file); + g_free(media); + g_free(vdev); + g_free(optstr); } diff --git a/hw/xen/xen_bus.c b/hw/xen/xen_bus.c index 2f5958d93f..ff114a30bb 100644 --- a/hw/xen/xen_bus.c +++ b/hw/xen/xen_bus.c @@ -114,6 +114,32 @@ static int xenstore_vscanf(struct xs_handle *xsh, char *node, return rc; } +int xenstore_printf(struct xs_handle *xsh, char *node, const char *key, + const char *fmt, ...) +{ + va_list ap; + int rc; + + va_start(ap, fmt); + rc = xenstore_vprintf(xsh, node, key, fmt, ap); + va_end(ap); + + return rc; +} + +int xenstore_scanf(struct xs_handle *xsh, char *node, const char *key, + const char *fmt, ...) +{ + va_list ap; + int rc; + + va_start(ap, fmt); + rc = xenstore_vscanf(xsh, node, key, fmt, ap); + va_end(ap); + + return rc; +} + int xenstore_backend_printf(XenBackend *d, const char *key, const char *fmt, ...) { @@ -520,7 +546,7 @@ static void xen_backend_class_init(ObjectClass *klass, void *data) k->bus_type = TYPE_XEN_BUS; } -static void xen_backend_compat_scan(const char *type, +static void xen_backend_compat_scan(BusState *bus, const char *type, XenBackendCreate create) { struct xs_handle *xsh; @@ -546,7 +572,7 @@ static void xen_backend_compat_scan(const char *type, path = g_strdup_printf("backend/%s/%u/%s", type, xen_domid, backend[i]); - create(path); + create(bus, xsh, path); g_free(path); } @@ -558,11 +584,6 @@ static void xen_backend_compat_scan(const char *type, void xen_bus_init(void) { DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE); -#if 0 - DeviceState *qdisk; - QemuOpts *opts; - BlockBackend *blk; -#endif XenBus *b; qdev_init_nofail(dev); @@ -573,24 +594,7 @@ void xen_bus_init(void) /* Need a 'proper' way of getting current domid */ xen_backend_id = 0; - xen_backend_compat_scan("qdisk", xen_qdisk_backend_create); - -#if 0 - opts = drive_def("id=extra"); - qemu_opt_set(opts, "file", "/root/disk.qcow2", &error_abort); - qemu_opt_set(opts, "media", "disk", &error_abort); - qemu_opt_set(opts, "format", "qcow2", &error_abort); - qemu_opt_set_bool(opts, BDRV_OPT_CACHE_WB, true, &error_abort); - qemu_opt_set_bool(opts, BDRV_OPT_READ_ONLY, false, &error_abort); - - drive_new(opts, IF_NONE); - - qdisk = qdev_create(BUS(b), "xen-qdisk"); - blk = blk_by_name("extra"); - qdev_prop_set_drive(qdisk, "drive", blk, &error_abort); - qdev_prop_set_int32(qdisk, "disk", 1); - qdev_init_nofail(qdisk); -#endif + xen_backend_compat_scan(BUS(b), "qdisk", xen_qdisk_backend_create); } static const TypeInfo xen_bridge_type_info = { diff --git a/include/hw/xen/xen_bus.h b/include/hw/xen/xen_bus.h index 15613a5823..d426d862b1 100644 --- a/include/hw/xen/xen_bus.h +++ b/include/hw/xen/xen_bus.h @@ -77,13 +77,19 @@ typedef struct XenBackendClass { #define TYPE_XEN_BRIDGE "xen-bridge" -typedef void (*XenBackendCreate)(char *path); - -void xen_qdisk_backend_create(char *path); +typedef void (*XenBackendCreate)(BusState *bus, struct xs_handle *xsh, + char *path); +void xen_qdisk_backend_create(BusState *bus, struct xs_handle *xsh, + char *path); void xen_bus_init(void); +int xenstore_printf(struct xs_handle *xsh, char *node, const char *key, + const char *fmt, ...); +int xenstore_scanf(struct xs_handle *xsh, char *node, const char *key, + const char *fmt, ...); + int xenstore_backend_printf(XenBackend *d, const char *key, const char *fmt, ...); int xenstore_frontend_printf(XenBackend *d, const char *key, -- 2.39.5