From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefano Stabellini Subject: [PATCH v5 6/6] libxl: spawns two QEMUs for HVM guests Date: Thu, 23 Jul 2015 18:27:44 +0100 Message-ID: <1437672464-29909-6-git-send-email-stefano.stabellini@eu.citrix.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xensource.com Cc: wei.liu2@citrix.com, Ian.Jackson@eu.citrix.com, Ian.Campbell@citrix.com, Stefano Stabellini List-Id: xen-devel@lists.xenproject.org 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 --- 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 e4d3b1c..986fc84 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("/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