[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC/WIPv2 6/6] libxl: soft reset support
Perform soft reset when a domain did SHUTDOWN_soft_reset. Migrate the content with xc_domain_soft_reset(), reload dm and toolstack. Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> --- tools/libxl/libxl.h | 6 +++ tools/libxl/libxl_create.c | 100 +++++++++++++++++++++++++++++++++++++++---- tools/libxl/libxl_internal.h | 5 +++ tools/libxl/xl_cmdimpl.c | 29 ++++++++++++- 4 files changed, 129 insertions(+), 11 deletions(-) diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index bc68cac..24b43c5 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -877,6 +877,12 @@ int static inline libxl_domain_create_restore_0x040200( #endif +int libxl_domain_soft_reset(libxl_ctx *ctx, libxl_domain_config *d_config, + uint32_t *domid, uint32_t domid_old, + const libxl_asyncop_how *ao_how, + const libxl_asyncprogress_how *aop_console_how) + LIBXL_EXTERNAL_CALLERS_ONLY; + /* A progress report will be made via ao_console_how, of type * domain_create_console_available, when the domain's primary * console is available and can be connected to. diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index 8b82584..b63fc1c 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -24,6 +24,8 @@ #include <xenguest.h> #include <xen/hvm/hvm_info_table.h> +#define INVALID_DOMID ~0 + int libxl__domain_create_info_setdefault(libxl__gc *gc, libxl_domain_create_info *c_info) { @@ -885,6 +887,9 @@ static void initiate_domain_create(libxl__egc *egc, if (restore_fd >= 0) { LOG(DEBUG, "restoring, not running bootloader"); domcreate_bootloader_done(egc, &dcs->bl, 0); + } else if (dcs->domid_soft_reset != INVALID_DOMID) { + LOG(DEBUG, "soft reset, not running bootloader\n"); + domcreate_bootloader_done(egc, &dcs->bl, 0); } else { LOG(DEBUG, "running bootloader"); dcs->bl.callback = domcreate_bootloader_done; @@ -933,6 +938,7 @@ static void domcreate_bootloader_done(libxl__egc *egc, libxl_domain_config *const d_config = dcs->guest_config; libxl_domain_build_info *const info = &d_config->b_info; const int restore_fd = dcs->restore_fd; + const uint32_t domid_soft_reset = dcs->domid_soft_reset; libxl__domain_build_state *const state = &dcs->build_state; libxl__srm_restore_autogen_callbacks *const callbacks = &dcs->shs.callbacks.restore.a; @@ -956,7 +962,7 @@ static void domcreate_bootloader_done(libxl__egc *egc, dcs->dmss.dm.callback = domcreate_devmodel_started; dcs->dmss.callback = domcreate_devmodel_started; - if ( restore_fd < 0 ) { + if ( (restore_fd < 0) && (domid_soft_reset == INVALID_DOMID) ) { rc = libxl__domain_build(gc, d_config, domid, state); domcreate_rebuild_done(egc, dcs, rc); return; @@ -986,14 +992,71 @@ static void domcreate_bootloader_done(libxl__egc *egc, rc = ERROR_INVAL; goto out; } - libxl__xc_domain_restore(egc, dcs, - hvm, pae, superpages); + if ( restore_fd >= 0 ) { + libxl__xc_domain_restore(egc, dcs, + hvm, pae, superpages); + } else { + libxl__xc_domain_soft_reset(egc, dcs, hvm); + } + return; out: libxl__xc_domain_restore_done(egc, dcs, rc, 0, 0); } +void libxl__xc_domain_soft_reset(libxl__egc *egc, + libxl__domain_create_state *dcs, int hvm) +{ + STATE_AO_GC(dcs->ao); + libxl_ctx *ctx = libxl__gc_owner(gc); + const uint32_t domid_soft_reset = dcs->domid_soft_reset; + const uint32_t domid = dcs->guest_domid; + libxl_domain_config *const d_config = dcs->guest_config; + libxl_domain_build_info *const info = &d_config->b_info; + uint8_t *buf; + uint32_t len; + uint32_t console_domid, store_domid, console_evtchn, store_evtchn; + unsigned long store_mfn, console_mfn; + int rc; + struct libxl__domain_suspend_state *dss; + + GCNEW(dss); + + dss->ao = ao; + dss->domid = domid_soft_reset; + dss->dm_savefile = GCSPRINTF("/var/lib/xen/qemu-save.%d", domid_soft_reset); + + if (info->type == LIBXL_DOMAIN_TYPE_HVM) { + rc = libxl__domain_suspend_device_model(gc, dss); + if (rc) goto out; + } + console_domid = dcs->build_state.console_domid; + console_evtchn = dcs->build_state.console_port; + store_domid = dcs->build_state.store_domid; + store_evtchn = dcs->build_state.store_port; + + rc = xc_domain_soft_reset(ctx->xch, domid_soft_reset, domid, hvm, + console_domid, console_evtchn, &console_mfn, + store_domid, store_evtchn, &store_mfn); + if (rc) goto out; + + dcs->build_state.store_mfn = store_mfn; + dcs->build_state.console_mfn = console_mfn; + + rc = libxl__toolstack_save(domid_soft_reset, &buf, &len, dss); + if (rc) goto out; + + rc = libxl__toolstack_restore(domid, buf, len, &dcs->shs); + if (rc) goto out; +out: + /* + * Now pretend we did normal restore and simply call + * libxl__xc_domain_restore_done(). + */ + libxl__xc_domain_restore_done(egc, dcs, rc, 0, 0); +} + void libxl__srm_callout_callback_restore_results(unsigned long store_mfn, unsigned long console_mfn, void *user) { @@ -1019,6 +1082,7 @@ void libxl__xc_domain_restore_done(libxl__egc *egc, void *dcs_void, /* convenience aliases */ const uint32_t domid = dcs->guest_domid; + const uint32_t domid_soft_reset = dcs->domid_soft_reset; libxl_domain_config *const d_config = dcs->guest_config; libxl_domain_build_info *const info = &d_config->b_info; libxl__domain_build_state *const state = &dcs->build_state; @@ -1071,9 +1135,12 @@ void libxl__xc_domain_restore_done(libxl__egc *egc, void *dcs_void, if (ret) goto out; - if (info->type == LIBXL_DOMAIN_TYPE_HVM) { + if (info->type == LIBXL_DOMAIN_TYPE_HVM && fd != -1) { state->saved_state = GCSPRINTF( XC_DEVICE_MODEL_RESTORE_FILE".%d", domid); + } else if (domid_soft_reset != INVALID_DOMID) { + state->saved_state = GCSPRINTF( + "/var/lib/xen/qemu-save.%d", domid_soft_reset); } out: @@ -1082,9 +1149,12 @@ out: libxl__file_reference_unmap(&state->pv_ramdisk); } - esave = errno; - libxl_fd_set_nonblock(ctx, fd, 0); - errno = esave; + if ( fd != -1 ) { + esave = errno; + libxl_fd_set_nonblock(ctx, fd, 0); + errno = esave; + } + domcreate_rebuild_done(egc, dcs, ret); } @@ -1463,6 +1533,7 @@ static void domain_create_cb(libxl__egc *egc, static int do_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config, uint32_t *domid, int restore_fd, int checkpointed_stream, + uint32_t domid_old, const libxl_asyncop_how *ao_how, const libxl_asyncprogress_how *aop_console_how) { @@ -1475,6 +1546,7 @@ static int do_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_domain_config_init(&cdcs->dcs.guest_config_saved); libxl_domain_config_copy(ctx, &cdcs->dcs.guest_config_saved, d_config); cdcs->dcs.restore_fd = restore_fd; + cdcs->dcs.domid_soft_reset = domid_old; cdcs->dcs.callback = domain_create_cb; cdcs->dcs.checkpointed_stream = checkpointed_stream; libxl__ao_progress_gethow(&cdcs->dcs.aop_console_how, aop_console_how); @@ -1503,7 +1575,7 @@ int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, const libxl_asyncop_how *ao_how, const libxl_asyncprogress_how *aop_console_how) { - return do_domain_create(ctx, d_config, domid, -1, 0, + return do_domain_create(ctx, d_config, domid, -1, 0, INVALID_DOMID, ao_how, aop_console_how); } @@ -1514,7 +1586,17 @@ int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config, const libxl_asyncprogress_how *aop_console_how) { return do_domain_create(ctx, d_config, domid, restore_fd, - params->checkpointed_stream, ao_how, aop_console_how); + params->checkpointed_stream, INVALID_DOMID, + ao_how, aop_console_how); +} + +int libxl_domain_soft_reset(libxl_ctx *ctx, libxl_domain_config *d_config, + uint32_t *domid, uint32_t domid_old, + const libxl_asyncop_how *ao_how, + const libxl_asyncprogress_how *aop_console_how) +{ + return do_domain_create(ctx, d_config, domid, -1, 0, domid_old, + ao_how, aop_console_how); } /* diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index f61673c..03f490b 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2861,6 +2861,7 @@ struct libxl__domain_create_state { libxl_domain_config *guest_config; libxl_domain_config guest_config_saved; /* vanilla config */ int restore_fd; + uint32_t domid_soft_reset; libxl__domain_create_cb *callback; libxl_asyncprogress_how aop_console_how; /* private to domain_create */ @@ -2915,6 +2916,10 @@ _hidden void libxl__xc_domain_restore(libxl__egc *egc, * If rc!=0, retval and errnoval are undefined. */ _hidden void libxl__xc_domain_restore_done(libxl__egc *egc, void *dcs_void, int rc, int retval, int errnoval); +/* calls libxl__xc_domain_restore_done when done */ +_hidden void libxl__xc_domain_soft_reset(libxl__egc *egc, + libxl__domain_create_state *dcs, + int hvm); /* Each time the dm needs to be saved, we must call suspend and then save */ _hidden int libxl__domain_suspend_device_model(libxl__gc *gc, diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index b40ad50..9183be4 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -1818,7 +1818,8 @@ static void reload_domain_config(uint32_t domid, } /* Returns 1 if domain should be restarted, - * 2 if domain should be renamed then restarted, or 0 + * 2 if domain should be renamed then restarted, + * 3 if domain performed soft reset, or 0 * Can update r_domid if domain is destroyed etc */ static int handle_domain_death(uint32_t *r_domid, libxl_event *event, @@ -1844,6 +1845,9 @@ static int handle_domain_death(uint32_t *r_domid, case LIBXL_SHUTDOWN_REASON_WATCHDOG: action = d_config->on_watchdog; break; + case LIBXL_SHUTDOWN_REASON_SOFT_RESET: + LOG("Domain performed soft reset."); + return 3; default: LOG("Unknown shutdown reason code %d. Destroying domain.", event->u.domain_shutdown.shutdown_reason); @@ -2067,6 +2071,7 @@ static void evdisable_disk_ejects(libxl_evgen_disk_eject **diskws, static uint32_t create_domain(struct domain_create *dom_info) { uint32_t domid = INVALID_DOMID; + uint32_t domid_old = INVALID_DOMID; libxl_domain_config d_config; @@ -2292,7 +2297,25 @@ start: * restore/migrate-receive it again. */ restoring = 0; - }else{ + } else if ( domid_old != INVALID_DOMID ) { + /* Do soft reset */ + d_config.b_info.nodemap.size = 0; + ret = libxl_domain_soft_reset(ctx, &d_config, + &domid, domid_old, + 0, 0); + + if ( libxl_domain_destroy(ctx, domid_old, 0) ) + fprintf(stderr, "failed to destroy old domain, ret %d\n", ret); + + if ( ret ) { + /* + * Soft reset failed for some reason. It's probbably best to kill + * the new domain as well. + */ + goto error_out; + } + domid_old = INVALID_DOMID; + } else { ret = libxl_domain_create_new(ctx, &d_config, &domid, 0, autoconnect_console_how); } @@ -2356,6 +2379,8 @@ start: event->u.domain_shutdown.shutdown_reason, event->u.domain_shutdown.shutdown_reason); switch (handle_domain_death(&domid, event, &d_config)) { + case 3: + domid_old = domid; case 2: if (!preserve_domain(&domid, event, &d_config)) { /* If we fail then exit leaving the old domain in place. */ -- 1.9.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |