|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 6/6] libxl: spawns two QEMUs for HVM guests
Starts a second QEMU to provide PV backends in userspace to HVM guests.
Use both dcs->dmss.pvqemu and dcs->dmss.dm to keep track of the starting
QEMUs. Introduce two new fields to struct libxl__dm_spawn_state: dcs to
store the pointer to libxl__domain_create_state, and rc to store the
return code.
Only proceed when both QEMUs have started.
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
Changes in v3:
- use dcs->dmss.pvqemu to spawn the second QEMU
- keep track of the rc of both QEMUs before proceeding
---
tools/libxl/libxl_create.c | 50 ++++++++++++++++++++++++++++++------------
tools/libxl/libxl_dm.c | 9 +++++++-
tools/libxl/libxl_internal.h | 3 +++
3 files changed, 47 insertions(+), 15 deletions(-)
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index df946e2..94dd52c 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -751,6 +751,9 @@ static int store_libxl_entry(libxl__gc *gc, uint32_t domid,
static void domcreate_devmodel_started(libxl__egc *egc,
libxl__dm_spawn_state *dmss,
int rc);
+static void domcreate_devmodel_callback(libxl__egc *egc,
+ libxl__dm_spawn_state *dmss,
+ int ret);
static void domcreate_bootloader_console_available(libxl__egc *egc,
libxl__bootloader_state
*bl);
static void domcreate_bootloader_done(libxl__egc *egc,
@@ -1016,8 +1019,17 @@ static void domcreate_bootloader_done(libxl__egc *egc,
dcs->dmss.dm.spawn.ao = ao;
dcs->dmss.dm.guest_config = dcs->guest_config;
dcs->dmss.dm.build_state = &dcs->build_state;
- dcs->dmss.dm.callback = domcreate_devmodel_started;
- dcs->dmss.callback = domcreate_devmodel_started;
+ dcs->dmss.dm.callback = domcreate_devmodel_callback;
+ dcs->dmss.dm.dcs = dcs;
+ dcs->dmss.callback = domcreate_devmodel_callback;
+
+ if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
+ dcs->dmss.pvqemu.guest_domid = domid;
+ dcs->dmss.pvqemu.spawn.ao = ao;
+ dcs->dmss.pvqemu.callback = domcreate_devmodel_callback;
+ dcs->dmss.pvqemu.dcs = dcs;
+ libxl__spawn_qdisk_backend(egc, &dcs->dmss.pvqemu);
+ }
if ( restore_fd < 0 ) {
rc = libxl__domain_build(gc, d_config, domid, state);
@@ -1347,20 +1359,13 @@ static void domcreate_devmodel_started(libxl__egc *egc,
libxl__dm_spawn_state *dmss,
int ret)
{
- libxl__domain_create_state *dcs = CONTAINER_OF(dmss, *dcs, dmss.dm);
+ libxl__domain_create_state *dcs = dmss->dcs;
STATE_AO_GC(dmss->spawn.ao);
- libxl_ctx *ctx = CTX;
int domid = dcs->guest_domid;
/* convenience aliases */
libxl_domain_config *const d_config = dcs->guest_config;
- if (ret) {
- LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
- "device model did not start: %d", ret);
- goto error_out;
- }
-
if (dcs->dmss.dm.guest_domid) {
if (d_config->b_info.device_model_version
== LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
@@ -1379,11 +1384,28 @@ static void domcreate_devmodel_started(libxl__egc *egc,
}
domcreate_attach_vtpms(egc, &dcs->multidev, 0);
- return;
+}
-error_out:
- assert(ret);
- domcreate_complete(egc, dcs, ret);
+static void domcreate_devmodel_callback(libxl__egc *egc,
+ libxl__dm_spawn_state *dmss,
+ int ret)
+{
+ libxl__domain_create_state *dcs = dmss->dcs;
+ STATE_AO_GC(dmss->spawn.ao);
+ int worst_rc = 0;
+
+ dmss->rc = ret;
+
+ if (libxl__spawn_inuse(&dcs->dmss.dm.spawn) ||
+ libxl__spawn_inuse(&dcs->dmss.pvqemu.spawn))
+ return;
+ worst_rc = (dcs->dmss.dm.rc < dcs->dmss.pvqemu.rc) ? dcs->dmss.dm.rc :
dcs->dmss.pvqemu.rc;
+
+ /* all qemus have completed */
+ if (worst_rc)
+ domcreate_complete(egc, dcs, worst_rc);
+ else
+ domcreate_devmodel_started(egc, dmss, 0);
}
static void domcreate_attach_vtpms(libxl__egc *egc,
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index fdd4d93..7423ef9 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1846,13 +1846,20 @@ out:
int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid)
{
+ int rc;
char *path = libxl__device_model_xs_path(gc, false, LIBXL_TOOLSTACK_DOMID,
domid, "");
if (!xs_rm(CTX->xsh, XBT_NULL, path))
LOG(ERROR, "xs_rm failed for %s", path);
+
+ kill_device_model(gc,
+ GCSPRINTF("/local/domain/%d/image/pvqemu-pid", domid));
+
/* We should try to destroy the device model anyway. */
- return kill_device_model(gc,
+ rc = kill_device_model(gc,
GCSPRINTF("/local/domain/%d/image/device-model-pid", domid));
+
+ return rc;
}
int libxl__need_xenpv_qemu(libxl__gc *gc,
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index e15cdc7..977ccca 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3062,9 +3062,12 @@ typedef struct libxl__dm_spawn_state
libxl__dm_spawn_state;
typedef void libxl__dm_spawn_cb(libxl__egc *egc, libxl__dm_spawn_state*,
int rc /* if !0, error was logged */);
+typedef struct libxl__domain_create_state libxl__domain_create_state;
struct libxl__dm_spawn_state {
/* mixed - spawn.ao must be initialised by user; rest is private: */
libxl__spawn_state spawn;
+ int rc;
+ libxl__domain_create_state *dcs;
/* filled in by user, must remain valid: */
uint32_t guest_domid; /* domain being served */
libxl_domain_config *guest_config;
--
1.7.10.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |