.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);
return;
}
+ if (xen_block_device_configure(xendev, errp))
+ return;
+
if (!blkconf_apply_backend_options(conf, blockdev->info & VDISK_READONLY,
true, errp)) {
return;
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;
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,
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);
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);
}
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()
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;
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);