From: Joao Martins Date: Tue, 12 Feb 2019 02:31:03 +0000 (-0500) Subject: hw/block/xen_block: backend type support X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fxen-shim-rfc;p=users%2Fdwmw2%2Fqemu.git hw/block/xen_block: backend type support 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 --- diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index 5012af9cb6..e6bc5c6bce 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -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; diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index f6b131a2f9..94b791ebe1 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -22,12 +22,19 @@ 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() diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index 11d22fb258..f099991d9f 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -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);