[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |