[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v4 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 3a4625a..71e7fe2 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1850,13 +1850,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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.