@@ -719,6 +719,8 @@ static void remus_checkpoint_stream_done(
*/
/* Event callbacks, in this order: */
+static void domcreate_dm_support_checked(libxl__egc *egc,
+ libxl__dm_support_check_state *checking, int rc);
static void domcreate_devmodel_started(libxl__egc *egc,
libxl__dm_spawn_state *dmss,
int rc);
@@ -774,7 +776,7 @@ static void initiate_domain_create(libxl__egc *egc,
/* convenience aliases */
libxl_domain_config *const d_config = dcs->guest_config;
libxl__domain_build_state *const state = &dcs->build_state;
- const int restore_fd = dcs->restore_fd;
+ const libxl_domain_build_info *b_info = &d_config->b_info;
domid = dcs->domid_soft_reset;
@@ -911,10 +913,6 @@ static void initiate_domain_create(libxl__egc *egc,
}
}
- dcs->bl.ao = ao;
- libxl_device_disk *bootdisk =
- d_config->num_disks > 0 ? &d_config->disks[0] : NULL;
-
/*
* The devid has to be set before launching the device model. For the
* hotplug case this is done in libxl_device_nic_add but on domain
@@ -942,6 +940,41 @@ static void initiate_domain_create(libxl__egc *egc,
d_config->nics[i].devid = ++last_devid;
}
+ if (b_info->type != LIBXL_DOMAIN_TYPE_HVM ||
+ libxl_defbool_val(b_info->device_model_stubdomain)) {
+ domcreate_dm_support_checked(egc, &dcs->dm_support_check, 0);
+ } else {
+ dcs->dm_support_check.ao = ao;
+ dcs->dm_support_check.dm = libxl__domain_device_model(gc, b_info);
+ dcs->dm_support_check.callback = domcreate_dm_support_checked;
+ libxl__dm_support_check_start(&dcs->dm_support_check);
+ }
+
+error_out:
+ assert(ret);
+ domcreate_complete(egc, dcs, ret);
+}
+
+static void domcreate_dm_support_checked(libxl__egc *egc,
+ libxl__dm_support_check_state *checking, int rc)
+{
+ libxl__domain_create_state *dcs =
+ CONTAINER_OF(checking, *dcs, dm_support_check);
+ STATE_AO_GC(dcs->ao);
+
+ /* convenience aliases */
+ libxl_domain_config *const d_config = dcs->guest_config;
+ const int restore_fd = dcs->restore_fd;
+
+ if (rc) {
+ domcreate_complete(egc, dcs, rc);
+ return;
+ }
+
+ dcs->bl.ao = ao;
+ libxl_device_disk *bootdisk =
+ d_config->num_disks > 0 ? &d_config->disks[0] : NULL;
+
if (restore_fd >= 0 || dcs->domid_soft_reset != INVALID_DOMID) {
LOG(DEBUG, "restoring, not running bootloader");
domcreate_bootloader_done(egc, &dcs->bl, 0);
@@ -959,10 +992,6 @@ static void initiate_domain_create(libxl__egc *egc,
libxl__bootloader_run(egc, &dcs->bl);
}
return;
-
-error_out:
- assert(ret);
- domcreate_complete(egc, dcs, ret);
}
static void domcreate_bootloader_console_available(libxl__egc *egc,
@@ -3510,6 +3510,7 @@ struct libxl__domain_create_state {
/* private to domain_create */
int guest_domid;
libxl__domain_build_state build_state;
+ libxl__dm_support_check_state dm_support_check;
libxl__bootloader_state bl;
libxl__stub_dm_spawn_state dmss;
/* If we're not doing stubdom, we use only dmss.dm,
When creating a domain (including when restoring), invoke the dm_support_check machinery on the principal qemu dm (if applicable). This involves another introducing function callback boundary in the domcreate control flow; but this is a straightforward one. Now, libxl__dm_supported is available (for the principal qemu dm) in the rest of the creation path. No callers of libxl__dm_supported yet. So in this patch we just pointlessly run qemu, collect and scan its usage message, and cache what we understand from the results. Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com> --- v6: New patch. --- tools/libxl/libxl_create.c | 47 ++++++++++++++++++++++++++++++++++-------- tools/libxl/libxl_internal.h | 1 + 2 files changed, 39 insertions(+), 9 deletions(-)