]> xenbits.xensource.com Git - people/pauldu/qemu.git/commitdiff
Add compat layer to instantiate backend qom3
authorPaul Durrant <paul.durrant@citrix.com>
Mon, 30 Apr 2018 08:18:14 +0000 (09:18 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Mon, 30 Apr 2018 08:18:14 +0000 (09:18 +0100)
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
hw/block/xen_qdisk.c
hw/xen/xen_bus.c
include/hw/xen/xen_bus.h

index c18ad8e1a8df6213675ebe11142378a3e81222d9..742f4ff6d370b70d406e2334cc7f0f05c80dd2e9 100644 (file)
@@ -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", &params) == 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);
 }
index 2f5958d93fd470beab158a6fd228e3afea63d321..ff114a30bb9ae4495e26297c7b5345db33e58ecb 100644 (file)
@@ -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 = {
index 15613a5823f07b8be3435099f0819f93f436a039..d426d862b134f593bd66a4485b648118b92ff658 100644 (file)
@@ -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,