@@ -7478,6 +7478,14 @@ static void libxl_device_disk_merge(libxl_ctx *ctx, void *d1, void *d2)
}
}
+static int libxl_device_disk_dm_needed(void *e, unsigned domid)
+{
+ libxl_device_disk *elem = e;
+
+ return elem->backend == LIBXL_DISK_BACKEND_QDISK &&
+ elem->backend_domid == domid;
+}
+
static int libxl_device_nic_compare(libxl_device_nic *d1,
libxl_device_nic *d2)
{
@@ -7490,7 +7498,11 @@ static int libxl_device_vtpm_compare(libxl_device_vtpm *d1,
return COMPARE_DEVID(d1, d2);
}
-DEFINE_DEVICE_TYPE_STRUCT(disk, .merge = libxl_device_disk_merge);
+DEFINE_DEVICE_TYPE_STRUCT(disk,
+ .merge = libxl_device_disk_merge,
+ .dm_needed = libxl_device_disk_dm_needed,
+ .skip_attach = 1
+);
DEFINE_DEVICE_TYPE_STRUCT(nic);
DEFINE_DEVICE_TYPE_STRUCT(vtpm);
@@ -1454,7 +1454,7 @@ static void domcreate_attach_devices(libxl__egc *egc,
dcs->device_type_idx++;
dt = device_type_tbl[dcs->device_type_idx];
if (dt) {
- if (*libxl__device_type_get_num(dt, d_config) > 0) {
+ if (*libxl__device_type_get_num(dt, d_config) > 0 && !dt->skip_attach) {
/* Attach devices */
libxl__multidev_begin(ao, &dcs->multidev);
dcs->multidev.callback = domcreate_attach_devices;
@@ -1501,11 +1501,7 @@ static void domcreate_devmodel_started(libxl__egc *egc,
}
}
- /*
- * Setting dcs->device_type_idx to 0 will skip disks, those have been
- * already added.
- */
- dcs->device_type_idx = 0;
+ dcs->device_type_idx = -1;
domcreate_attach_devices(egc, &dcs->multidev, 0);
return;
@@ -2348,8 +2348,9 @@ int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid)
/* Return 0 if no dm needed, 1 if needed and <0 if error. */
int libxl__need_xenpv_qemu(libxl__gc *gc, libxl_domain_config *d_config)
{
- int i, ret;
+ int idx, i, ret, num;
uint32_t domid;
+ const struct libxl_device_type *dt;
ret = libxl__get_domid(gc, &domid);
if (ret) {
@@ -2362,11 +2363,21 @@ int libxl__need_xenpv_qemu(libxl__gc *gc, libxl_domain_config *d_config)
goto out;
}
- for (i = 0; i < d_config->num_disks; i++) {
- if (d_config->disks[i].backend == LIBXL_DISK_BACKEND_QDISK &&
- d_config->disks[i].backend_domid == domid) {
- ret = 1;
- goto out;
+ for (idx = 0;; idx++) {
+ dt = device_type_tbl[idx];
+ if (!dt)
+ break;
+
+ num = *libxl__device_type_get_num(dt, d_config);
+ if (!dt->dm_needed || !num)
+ continue;
+
+ for (i = 0; i < num; i++) {
+ if (dt->dm_needed(libxl__device_type_get_elem(dt, d_config, i),
+ domid)) {
+ ret = 1;
+ goto out;
+ }
}
}
@@ -2380,14 +2391,6 @@ int libxl__need_xenpv_qemu(libxl__gc *gc, libxl_domain_config *d_config)
}
}
- for (i = 0; i < d_config->num_usbctrls; i++) {
- if (d_config->usbctrls[i].type == LIBXL_USBCTRL_TYPE_QUSB &&
- d_config->usbctrls[i].backend_domid == domid) {
- ret = 1;
- goto out;
- }
- }
-
out:
return ret;
}
@@ -3441,6 +3441,7 @@ _hidden void libxl__bootloader_run(libxl__egc*, libxl__bootloader_state *st);
struct libxl_device_type {
char *type;
+ int skip_attach; /* Skip entry in domcreate_attach_devices() if 1 */
int ptr_offset; /* Offset of device array ptr in libxl_domain_config */
int num_offset; /* Offset of # of devices in libxl_domain_config */
int dev_elem_size; /* Size of one device element in array */
@@ -3450,6 +3451,7 @@ struct libxl_device_type {
void (*dispose)(void *);
int (*compare)(void *, void *);
void (*merge)(libxl_ctx *, void *, void *);
+ int (*dm_needed)(void *, unsigned);
};
#define DEFINE_DEVICE_TYPE_STRUCT_X(name, sname, ...) \
@@ -1681,13 +1681,23 @@ static int libxl_device_usbctrl_compare(libxl_device_usbctrl *d1,
return COMPARE_USBCTRL(d1, d2);
}
+static int libxl_device_usbctrl_dm_needed(void *e, unsigned domid)
+{
+ libxl_device_usbctrl *elem = e;
+
+ return elem->type == LIBXL_USBCTRL_TYPE_QUSB &&
+ elem->backend_domid == domid;
+}
+
static int libxl_device_usbdev_compare(libxl_device_usbdev *d1,
libxl_device_usbdev *d2)
{
return COMPARE_USB(d1, d2);
}
-DEFINE_DEVICE_TYPE_STRUCT(usbctrl);
+DEFINE_DEVICE_TYPE_STRUCT(usbctrl,
+ .dm_needed = libxl_device_usbctrl_dm_needed
+);
DEFINE_DEVICE_TYPE_STRUCT(usbdev);
/*
Add another callback to the device type framework in order to aid decision whether a pv domain needs a device model. Signed-off-by: Juergen Gross <jgross@suse.com> --- tools/libxl/libxl.c | 14 +++++++++++++- tools/libxl/libxl_create.c | 8 ++------ tools/libxl/libxl_dm.c | 31 +++++++++++++++++-------------- tools/libxl/libxl_internal.h | 2 ++ tools/libxl/libxl_pvusb.c | 12 +++++++++++- 5 files changed, 45 insertions(+), 22 deletions(-)