]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
hw/block/xen_block: backend type support xen-shim-rfc
authorJoao Martins <joao.m.martins@oracle.com>
Tue, 12 Feb 2019 02:31:03 +0000 (21:31 -0500)
committerJoao Martins <joao.m.martins@oracle.com>
Tue, 19 Feb 2019 14:00:57 +0000 (09:00 -0500)
This series allows configuring xen-block as a vbd backend,
and thus qemu just sets it up and blkback is the backend
driving block IO.

Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
hw/block/xen-block.c
hw/xen/xen-bus.c
include/hw/xen/xen-bus.h

index 5012af9cb6fe71389d006321bc0b01b5101bd478..e6bc5c6bce95a12378ffdd6a49c9b8473c6ac0f8 100644 (file)
@@ -176,6 +176,45 @@ static const BlockDevOps xen_block_dev_ops = {
     .resize_cb = xen_block_resize_cb,
 };
 
+static int xen_block_device_configure(XenDevice *xendev, Error **errp)
+{
+    XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
+    XenBlockVdev *vdev = &blockdev->props.vdev;
+    BlockConf *conf = &blockdev->props.conf;
+    BlockDriverState *bs = blk_bs(conf->blk);
+    Error *local_err = NULL;
+    const char *filename;
+    char *dev;
+
+    if (xen_device_needs_backend(xendev)) {
+        return 0;
+    }
+
+    filename = qdict_get_try_str(bs->options, "filename");
+    if (!filename) {
+        error_setg(errp, "'%s' backend with no filename", xendev->backend);
+        return -1;
+    }
+
+    xen_device_frontend_printf(xendev, "virtual-device", "%lu",
+                               vdev->number);
+    xen_device_frontend_printf(xendev, "device-type", "%s",
+                               blockdev->device_type);
+
+    dev = object_property_get_str(OBJECT(xendev), "vdev", &local_err);
+    if (local_err) {
+        error_propagate_prepend(errp, local_err, "failed to get 'vdev': ");
+        return -1;
+    }
+
+    xen_device_backend_printf(xendev, "dev", "%s", dev);
+    xen_device_backend_printf(xendev, "type", "%s", "file");
+    xen_device_backend_printf(xendev, "params", "%s", filename);
+    xen_device_backend_printf(xendev, "mode", "%s",
+                              blockdev->info & VDISK_CDROM ? "r" : "w");
+    return 1;
+}
+
 static void xen_block_realize(XenDevice *xendev, Error **errp)
 {
     XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
@@ -211,6 +250,9 @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
         return;
     }
 
+    if (xen_block_device_configure(xendev, errp))
+        return;
+
     if (!blkconf_apply_backend_options(conf, blockdev->info & VDISK_READONLY,
                                        true, errp)) {
         return;
index f6b131a2f9587c281756fecf9231108a0b2c66bc..94b791ebe120ee4af3fdfddc77b2e0080356f2f0 100644 (file)
 
 XenDeviceHandler *xen_dev_handler;
 
+bool xen_device_needs_backend(XenDevice *xendev)
+{
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+
+    return !xendev->backend || !strcmp(xendev_class->backend, xendev->backend);
+}
+
 static char *xen_device_get_backend_path(XenDevice *xendev)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
     XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
     const char *type = object_get_typename(OBJECT(xendev));
-    const char *backend = xendev_class->backend;
+    const char *backend = xendev->backend ?:xendev_class->backend;
 
     if (!backend) {
         backend = type;
@@ -593,6 +600,9 @@ static void xen_device_backend_create(XenDevice *xendev, Error **errp)
         return;
     }
 
+    if (!xen_device_needs_backend(xendev))
+        return;
+
     xendev->backend_state_watch =
         xen_bus_add_watch(xenbus, xendev->backend_path,
                           "state", xen_device_backend_changed,
@@ -757,6 +767,10 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
         return;
     }
 
+    if (!xen_device_needs_backend(xendev)) {
+        return;
+    }
+
     xendev->frontend_state_watch =
         xen_bus_add_watch(xenbus, xendev->frontend_path, "state",
                           xen_device_frontend_changed, xendev, &local_err);
@@ -1177,10 +1191,15 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
                               xendev->frontend_path);
     xen_device_backend_printf(xendev, "frontend-id", "%u",
                               xendev->frontend_id);
-    xen_device_backend_printf(xendev, "hotplug-status", "connected");
 
     xen_device_backend_set_online(xendev, true);
-    xen_device_backend_set_state(xendev, XenbusStateInitWait);
+    if (xen_device_needs_backend(xendev)) {
+        xen_device_backend_printf(xendev, "hotplug-status", "connected");
+
+        xen_device_backend_set_state(xendev, XenbusStateInitWait);
+    } else {
+        xen_device_backend_set_state(xendev, XenbusStateInitialising);
+    }
 
     xen_device_frontend_printf(xendev, "backend", "%s",
                                xendev->backend_path);
@@ -1198,6 +1217,7 @@ unrealize:
 }
 
 static Property xen_device_props[] = {
+    DEFINE_PROP_STRING("backendtype", XenDevice, backend),
     DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
                        DOMID_INVALID),
     DEFINE_PROP_END_OF_LIST()
index 11d22fb2584889a018635d34c6730d7bdba005c1..f099991d9fcd26833c06aa15987d4fd055353751 100644 (file)
@@ -19,6 +19,7 @@ typedef struct XenWatch XenWatch;
 typedef struct XenDevice {
     DeviceState qdev;
     domid_t frontend_id;
+    char *backend;
     char *name;
     char *backend_path, *frontend_path;
     enum xenbus_state backend_state, frontend_state;
@@ -82,6 +83,8 @@ typedef struct XenBusClass {
 
 void xen_bus_init(void);
 
+bool xen_device_needs_backend(XenDevice *xendev);
+
 void xen_device_backend_set_state(XenDevice *xendev,
                                   enum xenbus_state state);
 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev);