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

Re: [Xen-devel] [PATCH v2 5/5] libxl: spawns two QEMUs for HVM guests



On Tue, 9 Jun 2015, Ian Jackson wrote:
> Ian Jackson writes ("Re: [PATCH v2 5/5] libxl: spawns two QEMUs for HVM 
> guests"):
> > The spawn_outcome function does something like this:
> > 
> >        int worst_rc = 0;
> > 
> >        libxl_report_child_exitstatus(...)
> >        dcs->qemus[myself]->rc = status ? ERROR_QEMU_DIED : 0;
> > 
> >        for (i=0; i<n_qemus; i++) {
> >           if (libxl__ev_child_inuse(&dcs->qemus[i].childw))
> >               return;
> >           if (dcs->qemus[i].rc IS WORSE THAN worst_rc)
> >               worst_rc = dcs->qemus[i].rc;
> >        }
> >        /* all qemus have completed */
> >        if (worst_rc)
> >            domcreate_complete(egc, dcs, worst_rc)
> >        else
> >           domain_create_do_next_thing(egc, dcs, ...);
> 
> ... except you're using libxl__spawn, not libxl__ev_child, so you
> don't get status but rather rc and you don't need to call
> libxl_report_child_exitstatus, and instead of a childw you probably
> have a dmss.  But the principles are the same.

That is of great help, but this code is quite complex and I don't
understand it. I tried to complete the missing bits but I think I ended
up with something quite far from what you had in mind. At least it
compiles but it segfaults. See below:



diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index a74b340..ad5191d 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -981,6 +981,25 @@ static void domcreate_console_available(libxl__egc *egc,
                                         dcs->aop_console_how.for_event));
 }
 
+static void qdisk_spawn_outcome(libxl__egc *egc, libxl__dm_spawn_state *dmss,
+                                int rc)
+{
+    STATE_AO_GC(dmss->spawn.ao);
+    int worst_rc = 0, i;
+
+    dmss->qemus[dmss->emulator_id].rc = rc;
+
+    for (i=0; i<dmss->num_qemus; i++) {
+       if (libxl__spawn_inuse(&dmss->qemus[i].dmss->spawn))
+           return;
+       if (dmss->qemus[i].rc < worst_rc)
+           worst_rc = dmss->qemus[i].rc;
+    }
+    /* all qemus have completed */
+    if (worst_rc)
+        domcreate_complete(egc, dmss->dcs, worst_rc);
+}
+
 static void domcreate_bootloader_done(libxl__egc *egc,
                                       libxl__bootloader_state *bl,
                                       int rc)
@@ -1014,8 +1033,27 @@ static void domcreate_bootloader_done(libxl__egc *egc,
     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.dm.emulator_id = QEMU_XEN_DEVICE_MODEL_ID;
+    dcs->dmss.dm.qemus = libxl__malloc(gc, sizeof(struct qemu_spawn_state));
+    dcs->dmss.dm.qemus[QEMU_XEN_DEVICE_MODEL_ID].dmss = &dcs->dmss.dm;
+    dcs->dmss.dm.dcs = dcs;
+    dcs->dmss.dm.num_qemus = 2;
     dcs->dmss.callback = domcreate_devmodel_started;
 
+    if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
+        libxl__dm_spawn_state *dmss2;
+        GCNEW(dmss2);
+        dmss2->guest_domid = domid;
+        dmss2->spawn.ao = ao;
+        dmss2->emulator_id = QEMU_XEN_PV_ID;
+        dmss2->qemus = dcs->dmss.dm.qemus;
+        dmss2->qemus[QEMU_XEN_PV_ID].dmss = dmss2;
+        dmss2->callback = qdisk_spawn_outcome;
+        dmss2->num_qemus = 2;
+        dmss2->dcs = dcs;
+        libxl__spawn_qdisk_backend(egc, dmss2);
+    }
+
     if ( restore_fd < 0 ) {
         rc = libxl__domain_build(gc, d_config, domid, state);
         domcreate_rebuild_done(egc, dcs, rc);
@@ -1348,6 +1386,7 @@ static void domcreate_devmodel_started(libxl__egc *egc,
     STATE_AO_GC(dmss->spawn.ao);
     libxl_ctx *ctx = CTX;
     int domid = dcs->guest_domid;
+    int i;
 
     /* convenience aliases */
     libxl_domain_config *const d_config = dcs->guest_config;
@@ -1380,6 +1419,10 @@ static void domcreate_devmodel_started(libxl__egc *egc,
 
 error_out:
     assert(ret);
+    for (i=0; i<dcs->dmss.dm.num_qemus; i++) {
+        if (libxl__spawn_inuse(&dmss->qemus[i].dmss->spawn))
+            return;
+    }
     domcreate_complete(egc, dcs, ret);
 }
 
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 3a9819b..bf02280 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1848,13 +1848,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("libxl/%u/qdisk-backend-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..b0350bc 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3062,9 +3062,18 @@ 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 qemu_spawn_state {
+    int rc;
+    struct libxl__dm_spawn_state *dmss;
+};
 struct libxl__dm_spawn_state {
     /* mixed - spawn.ao must be initialised by user; rest is private: */
     libxl__spawn_state spawn;
+    uint32_t emulator_id;
+    struct qemu_spawn_state *qemus;
+    libxl__domain_create_state *dcs;
+    int num_qemus;
     /* filled in by user, must remain valid: */
     uint32_t guest_domid; /* domain being served */
     libxl_domain_config *guest_config;

_______________________________________________
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®.