[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 COLOPre 06/26] libxl/save: Refactor libxl__domain_suspend_state
Currently struct libxl__domain_suspend_state contains 2 type of states, one is save state, another is suspend state. This patch separates those two out. The motivation of this is that COLO will need to do suspend/resume continuously, we need a more common suspend state. After this change, dss stands for libxl__domain_save_state, dsps stands for libxl__domain_suspend_state. Signed-off-by: Yang Hongyang <yanghy@xxxxxxxxxxxxxx> CC: Ian Campbell <Ian.Campbell@xxxxxxxxxx> CC: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> CC: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- tools/libxl/libxl.c | 10 +-- tools/libxl/libxl_dom_save.c | 74 +++++++++-------- tools/libxl/libxl_dom_suspend.c | 167 ++++++++++++++++++++------------------- tools/libxl/libxl_internal.h | 55 +++++++------ tools/libxl/libxl_netbuffer.c | 2 +- tools/libxl/libxl_remus.c | 39 ++++----- tools/libxl/libxl_save_callout.c | 2 +- tools/libxl/libxl_stream_write.c | 26 +++--- 8 files changed, 199 insertions(+), 176 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index b939f2f..8b63eff 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -793,7 +793,7 @@ out: } static void remus_failover_cb(libxl__egc *egc, - libxl__domain_suspend_state *dss, int rc); + libxl__domain_save_state *dss, int rc); /* TODO: Explicit Checkpoint acknowledgements via recv_fd. */ int libxl_domain_remus_start(libxl_ctx *ctx, libxl_domain_remus_info *info, @@ -801,7 +801,7 @@ int libxl_domain_remus_start(libxl_ctx *ctx, libxl_domain_remus_info *info, const libxl_asyncop_how *ao_how) { AO_CREATE(ctx, domid, ao_how); - libxl__domain_suspend_state *dss; + libxl__domain_save_state *dss; int rc; libxl_domain_type type = libxl__domain_type(gc, domid); @@ -849,7 +849,7 @@ int libxl_domain_remus_start(libxl_ctx *ctx, libxl_domain_remus_info *info, } static void remus_failover_cb(libxl__egc *egc, - libxl__domain_suspend_state *dss, int rc) + libxl__domain_save_state *dss, int rc) { STATE_AO_GC(dss->ao); /* @@ -861,7 +861,7 @@ static void remus_failover_cb(libxl__egc *egc, } static void domain_suspend_cb(libxl__egc *egc, - libxl__domain_suspend_state *dss, int rc) + libxl__domain_save_state *dss, int rc) { STATE_AO_GC(dss->ao); libxl__ao_complete(egc,ao,rc); @@ -880,7 +880,7 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags, goto out_err; } - libxl__domain_suspend_state *dss; + libxl__domain_save_state *dss; GCNEW(dss); dss->ao = ao; diff --git a/tools/libxl/libxl_dom_save.c b/tools/libxl/libxl_dom_save.c index 9ee74ba..93061c7 100644 --- a/tools/libxl/libxl_dom_save.c +++ b/tools/libxl/libxl_dom_save.c @@ -30,9 +30,10 @@ struct libxl__physmap_info { /*========================= Domain save ============================*/ static void stream_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, int rc); + libxl__domain_save_state *dss, int rc); static void domain_save_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, int rc); + libxl__domain_save_state *dss, int rc); + /*----- complicated callback, called by xc_domain_save -----*/ @@ -49,7 +50,7 @@ static void switch_logdirty_timeout(libxl__egc *egc, libxl__ev_time *ev, static void switch_logdirty_xswatch(libxl__egc *egc, libxl__ev_xswatch*, const char *watch_path, const char *event_path); static void switch_logdirty_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, int ok); + libxl__domain_save_state *dss, int ok); static void logdirty_init(libxl__logdirty_switch *lds) { @@ -63,7 +64,7 @@ static void domain_suspend_switch_qemu_xen_traditional_logdirty libxl__save_helper_state *shs) { libxl__egc *egc = shs->egc; - libxl__domain_suspend_state *dss = CONTAINER_OF(shs, *dss, shs); + libxl__domain_save_state *dss = CONTAINER_OF(shs, *dss, shs); libxl__logdirty_switch *lds = &dss->logdirty; STATE_AO_GC(dss->ao); int rc; @@ -135,7 +136,7 @@ static void domain_suspend_switch_qemu_xen_logdirty libxl__save_helper_state *shs) { libxl__egc *egc = shs->egc; - libxl__domain_suspend_state *dss = CONTAINER_OF(shs, *dss, shs); + libxl__domain_save_state *dss = CONTAINER_OF(shs, *dss, shs); STATE_AO_GC(dss->ao); int rc; @@ -153,7 +154,7 @@ void libxl__domain_suspend_common_switch_qemu_logdirty { libxl__save_helper_state *shs = user; libxl__egc *egc = shs->egc; - libxl__domain_suspend_state *dss = CONTAINER_OF(shs, *dss, shs); + libxl__domain_save_state *dss = CONTAINER_OF(shs, *dss, shs); STATE_AO_GC(dss->ao); switch (libxl__device_model_version_running(gc, domid)) { @@ -172,7 +173,7 @@ void libxl__domain_suspend_common_switch_qemu_logdirty static void switch_logdirty_timeout(libxl__egc *egc, libxl__ev_time *ev, const struct timeval *requested_abs) { - libxl__domain_suspend_state *dss = CONTAINER_OF(ev, *dss, logdirty.timeout); + libxl__domain_save_state *dss = CONTAINER_OF(ev, *dss, logdirty.timeout); STATE_AO_GC(dss->ao); LOG(ERROR,"logdirty switch: wait for device model timed out"); switch_logdirty_done(egc,dss,-1); @@ -181,7 +182,7 @@ static void switch_logdirty_timeout(libxl__egc *egc, libxl__ev_time *ev, static void switch_logdirty_xswatch(libxl__egc *egc, libxl__ev_xswatch *watch, const char *watch_path, const char *event_path) { - libxl__domain_suspend_state *dss = + libxl__domain_save_state *dss = CONTAINER_OF(watch, *dss, logdirty.watch); libxl__logdirty_switch *lds = &dss->logdirty; STATE_AO_GC(dss->ao); @@ -236,7 +237,7 @@ static void switch_logdirty_xswatch(libxl__egc *egc, libxl__ev_xswatch *watch, } static void switch_logdirty_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_save_state *dss, int broke) { STATE_AO_GC(dss->ao); @@ -260,7 +261,7 @@ static inline char *physmap_path(libxl__gc *gc, uint32_t dm_domid, int libxl__toolstack_save(uint32_t domid, uint8_t **buf, uint32_t *len, void *dss_void) { - libxl__domain_suspend_state *dss = dss_void; + libxl__domain_save_state *dss = dss_void; STATE_AO_GC(dss->ao); int i = 0; char *start_addr = NULL, *size = NULL, *phys_offset = NULL, *name = NULL; @@ -338,9 +339,9 @@ int libxl__toolstack_save(uint32_t domid, uint8_t **buf, return 0; } -/*----- main code for suspending, in order of execution -----*/ +/*----- main code for saving, in order of execution -----*/ -void libxl__domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss) +void libxl__domain_save(libxl__egc *egc, libxl__domain_save_state *dss) { STATE_AO_GC(dss->ao); int port; @@ -354,20 +355,23 @@ void libxl__domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss) const libxl_domain_remus_info *const r_info = dss->remus; libxl__srm_save_autogen_callbacks *const callbacks = &dss->shs.callbacks.save.a; + libxl__domain_suspend_state *dsps = &dss->dsps; logdirty_init(&dss->logdirty); - libxl__xswait_init(&dss->pvcontrol); - libxl__ev_evtchn_init(&dss->guest_evtchn); - libxl__ev_xswatch_init(&dss->guest_watch); - libxl__ev_time_init(&dss->guest_timeout); + libxl__xswait_init(&dsps->pvcontrol); + libxl__ev_evtchn_init(&dsps->guest_evtchn); + libxl__ev_xswatch_init(&dsps->guest_watch); + libxl__ev_time_init(&dsps->guest_timeout); switch (type) { case LIBXL_DOMAIN_TYPE_HVM: { dss->hvm = 1; + dsps->hvm = 1; break; } case LIBXL_DOMAIN_TYPE_PV: dss->hvm = 0; + dsps->hvm = 0; break; default: abort(); @@ -377,10 +381,12 @@ void libxl__domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss) | (debug ? XCFLAGS_DEBUG : 0) | (dss->hvm ? XCFLAGS_HVM : 0); - dss->guest_evtchn.port = -1; - dss->guest_evtchn_lockfd = -1; - dss->guest_responded = 0; - dss->dm_savefile = libxl__device_model_savefile(gc, domid); + dsps->ao = ao; + dsps->domid = domid; + dsps->guest_evtchn.port = -1; + dsps->guest_evtchn_lockfd = -1; + dsps->guest_responded = 0; + dsps->dm_savefile = libxl__device_model_savefile(gc, domid); if (r_info != NULL) { dss->interval = r_info->interval; @@ -389,17 +395,18 @@ void libxl__domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss) dss->xcflags |= XCFLAGS_CHECKPOINT_COMPRESS; } - port = xs_suspend_evtchn_port(dss->domid); + port = xs_suspend_evtchn_port(dsps->domid); if (port >= 0) { rc = libxl__ctx_evtchn_init(gc); if (rc) goto out; - dss->guest_evtchn.port = + dsps->guest_evtchn.port = xc_suspend_evtchn_init_exclusive(CTX->xch, CTX->xce, - dss->domid, port, &dss->guest_evtchn_lockfd); + dsps->domid, port, + &dsps->guest_evtchn_lockfd); - if (dss->guest_evtchn.port < 0) { + if (dsps->guest_evtchn.port < 0) { LOG(WARN, "Suspend event channel initialization failed"); rc = ERROR_FAIL; goto out; @@ -428,7 +435,7 @@ void libxl__domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss) } static void stream_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, int rc) + libxl__domain_save_state *dss, int rc) { domain_save_done(egc, dss, rc); } @@ -437,7 +444,7 @@ static void save_device_model_datacopier_done(libxl__egc *egc, libxl__datacopier_state *dc, int onwrite, int errnoval); void libxl__domain_save_device_model(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_save_state *dss, libxl__save_device_model_cb *callback) { STATE_AO_GC(dss->ao); @@ -448,7 +455,7 @@ void libxl__domain_save_device_model(libxl__egc *egc, dss->save_dm_callback = callback; /* Convenience aliases */ - const char *const filename = dss->dm_savefile; + const char *const filename = dss->dsps.dm_savefile; const int fd = dss->fd; libxl__datacopier_state *dc = &dss->save_dm_datacopier; @@ -500,12 +507,12 @@ void libxl__domain_save_device_model(libxl__egc *egc, static void save_device_model_datacopier_done(libxl__egc *egc, libxl__datacopier_state *dc, int onwrite, int errnoval) { - libxl__domain_suspend_state *dss = + libxl__domain_save_state *dss = CONTAINER_OF(dc, *dss, save_dm_datacopier); STATE_AO_GC(dss->ao); /* Convenience aliases */ - const char *const filename = dss->dm_savefile; + const char *const filename = dss->dsps.dm_savefile; int our_rc = 0; int rc; @@ -526,18 +533,19 @@ static void save_device_model_datacopier_done(libxl__egc *egc, } static void domain_save_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, int rc) + libxl__domain_save_state *dss, int rc) { STATE_AO_GC(dss->ao); /* Convenience aliases */ const uint32_t domid = dss->domid; + libxl__domain_suspend_state *dsps = &dss->dsps; - libxl__ev_evtchn_cancel(gc, &dss->guest_evtchn); + libxl__ev_evtchn_cancel(gc, &dsps->guest_evtchn); - if (dss->guest_evtchn.port > 0) + if (dsps->guest_evtchn.port > 0) xc_suspend_evtchn_release(CTX->xch, CTX->xce, domid, - dss->guest_evtchn.port, &dss->guest_evtchn_lockfd); + dsps->guest_evtchn.port, &dsps->guest_evtchn_lockfd); if (!dss->remus) { dss->callback(egc, dss, rc); diff --git a/tools/libxl/libxl_dom_suspend.c b/tools/libxl/libxl_dom_suspend.c index 5f1f4fd..1c486c4 100644 --- a/tools/libxl/libxl_dom_suspend.c +++ b/tools/libxl/libxl_dom_suspend.c @@ -22,11 +22,11 @@ /*----- callbacks, called by xc_domain_save -----*/ int libxl__domain_suspend_device_model(libxl__gc *gc, - libxl__domain_suspend_state *dss) + libxl__domain_suspend_state *dsps) { int ret = 0; - uint32_t const domid = dss->domid; - const char *const filename = dss->dm_savefile; + uint32_t const domid = dsps->domid; + const char *const filename = dsps->dm_savefile; switch (libxl__device_model_version_running(gc, domid)) { case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: { @@ -51,9 +51,9 @@ int libxl__domain_suspend_device_model(libxl__gc *gc, } static void domain_suspend_common_wait_guest(libxl__egc *egc, - libxl__domain_suspend_state *dss); + libxl__domain_suspend_state *dsps); static void domain_suspend_common_guest_suspended(libxl__egc *egc, - libxl__domain_suspend_state *dss); + libxl__domain_suspend_state *dsps); static void domain_suspend_common_pvcontrol_suspending(libxl__egc *egc, libxl__xswait_state *xswa, int rc, const char *state); @@ -62,64 +62,63 @@ static void domain_suspend_common_wait_guest_evtchn(libxl__egc *egc, static void suspend_common_wait_guest_watch(libxl__egc *egc, libxl__ev_xswatch *xsw, const char *watch_path, const char *event_path); static void suspend_common_wait_guest_check(libxl__egc *egc, - libxl__domain_suspend_state *dss); + libxl__domain_suspend_state *dsps); static void suspend_common_wait_guest_timeout(libxl__egc *egc, libxl__ev_time *ev, const struct timeval *requested_abs); static void domain_suspend_common_failed(libxl__egc *egc, - libxl__domain_suspend_state *dss); + libxl__domain_suspend_state *dsps); static void domain_suspend_common_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_suspend_state *dsps, bool ok); static void domain_suspend_callback_common(libxl__egc *egc, - libxl__domain_suspend_state *dss); + libxl__domain_suspend_state *dsps); static void domain_suspend_callback_common_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, int ok); + libxl__domain_suspend_state *dsps, int ok); -/* calls dss->callback_common_done when done */ +/* calls dsps->callback_common_done when done */ void libxl__domain_suspend(libxl__egc *egc, - libxl__domain_suspend_state *dss) + libxl__domain_suspend_state *dsps) { - domain_suspend_callback_common(egc, dss); + domain_suspend_callback_common(egc, dsps); } - static bool domain_suspend_pvcontrol_acked(const char *state) { /* any value other than "suspend", including ENOENT (i.e. !state), is OK */ if (!state) return 1; return strcmp(state,"suspend"); } -/* calls dss->callback_common_done when done */ +/* calls dsps->callback_common_done when done */ static void domain_suspend_callback_common(libxl__egc *egc, - libxl__domain_suspend_state *dss) + libxl__domain_suspend_state *dsps) { - STATE_AO_GC(dss->ao); + STATE_AO_GC(dsps->ao); uint64_t hvm_s_state = 0, hvm_pvdrv = 0; int ret, rc; /* Convenience aliases */ - const uint32_t domid = dss->domid; + const uint32_t domid = dsps->domid; - if (dss->hvm) { + if (dsps->hvm) { xc_hvm_param_get(CTX->xch, domid, HVM_PARAM_CALLBACK_IRQ, &hvm_pvdrv); xc_hvm_param_get(CTX->xch, domid, HVM_PARAM_ACPI_S_STATE, &hvm_s_state); } - if ((hvm_s_state == 0) && (dss->guest_evtchn.port >= 0)) { + if ((hvm_s_state == 0) && (dsps->guest_evtchn.port >= 0)) { LOG(DEBUG, "issuing %s suspend request via event channel", - dss->hvm ? "PVHVM" : "PV"); - ret = xc_evtchn_notify(CTX->xce, dss->guest_evtchn.port); + dsps->hvm ? "PVHVM" : "PV"); + ret = xc_evtchn_notify(CTX->xce, dsps->guest_evtchn.port); if (ret < 0) { LOG(ERROR, "xc_evtchn_notify failed ret=%d", ret); goto err; } - dss->guest_evtchn.callback = domain_suspend_common_wait_guest_evtchn; - rc = libxl__ev_evtchn_wait(gc, &dss->guest_evtchn); + dsps->guest_evtchn.callback = domain_suspend_common_wait_guest_evtchn; + rc = libxl__ev_evtchn_wait(gc, &dsps->guest_evtchn); if (rc) goto err; - rc = libxl__ev_time_register_rel(gc, &dss->guest_timeout, + rc = libxl__ev_time_register_rel(gc, &dsps->guest_timeout, suspend_common_wait_guest_timeout, 60*1000); if (rc) goto err; @@ -127,7 +126,7 @@ static void domain_suspend_callback_common(libxl__egc *egc, return; } - if (dss->hvm && (!hvm_pvdrv || hvm_s_state)) { + if (dsps->hvm && (!hvm_pvdrv || hvm_s_state)) { LOG(DEBUG, "Calling xc_domain_shutdown on HVM domain"); ret = xc_domain_shutdown(CTX->xch, domid, SHUTDOWN_suspend); if (ret < 0) { @@ -135,55 +134,55 @@ static void domain_suspend_callback_common(libxl__egc *egc, goto err; } /* The guest does not (need to) respond to this sort of request. */ - dss->guest_responded = 1; - domain_suspend_common_wait_guest(egc, dss); + dsps->guest_responded = 1; + domain_suspend_common_wait_guest(egc, dsps); return; } LOG(DEBUG, "issuing %s suspend request via XenBus control node", - dss->hvm ? "PVHVM" : "PV"); + dsps->hvm ? "PVHVM" : "PV"); libxl__domain_pvcontrol_write(gc, XBT_NULL, domid, "suspend"); - dss->pvcontrol.path = libxl__domain_pvcontrol_xspath(gc, domid); - if (!dss->pvcontrol.path) goto err; + dsps->pvcontrol.path = libxl__domain_pvcontrol_xspath(gc, domid); + if (!dsps->pvcontrol.path) goto err; - dss->pvcontrol.ao = ao; - dss->pvcontrol.what = "guest acknowledgement of suspend request"; - dss->pvcontrol.timeout_ms = 60 * 1000; - dss->pvcontrol.callback = domain_suspend_common_pvcontrol_suspending; - libxl__xswait_start(gc, &dss->pvcontrol); + dsps->pvcontrol.ao = ao; + dsps->pvcontrol.what = "guest acknowledgement of suspend request"; + dsps->pvcontrol.timeout_ms = 60 * 1000; + dsps->pvcontrol.callback = domain_suspend_common_pvcontrol_suspending; + libxl__xswait_start(gc, &dsps->pvcontrol); return; err: - domain_suspend_common_failed(egc, dss); + domain_suspend_common_failed(egc, dsps); } static void domain_suspend_common_wait_guest_evtchn(libxl__egc *egc, libxl__ev_evtchn *evev) { - libxl__domain_suspend_state *dss = CONTAINER_OF(evev, *dss, guest_evtchn); - STATE_AO_GC(dss->ao); + libxl__domain_suspend_state *dsps = CONTAINER_OF(evev, *dsps, guest_evtchn); + STATE_AO_GC(dsps->ao); /* If we should be done waiting, suspend_common_wait_guest_check * will end up calling domain_suspend_common_guest_suspended or * domain_suspend_common_failed, both of which cancel the evtchn * wait. So re-enable it now. */ - libxl__ev_evtchn_wait(gc, &dss->guest_evtchn); - suspend_common_wait_guest_check(egc, dss); + libxl__ev_evtchn_wait(gc, &dsps->guest_evtchn); + suspend_common_wait_guest_check(egc, dsps); } static void domain_suspend_common_pvcontrol_suspending(libxl__egc *egc, libxl__xswait_state *xswa, int rc, const char *state) { - libxl__domain_suspend_state *dss = CONTAINER_OF(xswa, *dss, pvcontrol); - STATE_AO_GC(dss->ao); + libxl__domain_suspend_state *dsps = CONTAINER_OF(xswa, *dsps, pvcontrol); + STATE_AO_GC(dsps->ao); xs_transaction_t t = 0; if (!rc && !domain_suspend_pvcontrol_acked(state)) /* keep waiting */ return; - libxl__xswait_stop(gc, &dss->pvcontrol); + libxl__xswait_stop(gc, &dsps->pvcontrol); if (rc == ERROR_TIMEDOUT) { /* @@ -226,56 +225,56 @@ static void domain_suspend_common_pvcontrol_suspending(libxl__egc *egc, LOG(DEBUG, "guest acknowledged suspend request"); libxl__xs_transaction_abort(gc, &t); - dss->guest_responded = 1; - domain_suspend_common_wait_guest(egc,dss); + dsps->guest_responded = 1; + domain_suspend_common_wait_guest(egc,dsps); return; err: libxl__xs_transaction_abort(gc, &t); - domain_suspend_common_failed(egc, dss); + domain_suspend_common_failed(egc, dsps); return; } static void domain_suspend_common_wait_guest(libxl__egc *egc, - libxl__domain_suspend_state *dss) + libxl__domain_suspend_state *dsps) { - STATE_AO_GC(dss->ao); + STATE_AO_GC(dsps->ao); int rc; LOG(DEBUG, "wait for the guest to suspend"); - rc = libxl__ev_xswatch_register(gc, &dss->guest_watch, + rc = libxl__ev_xswatch_register(gc, &dsps->guest_watch, suspend_common_wait_guest_watch, "@releaseDomain"); if (rc) goto err; - rc = libxl__ev_time_register_rel(gc, &dss->guest_timeout, + rc = libxl__ev_time_register_rel(gc, &dsps->guest_timeout, suspend_common_wait_guest_timeout, 60*1000); if (rc) goto err; return; err: - domain_suspend_common_failed(egc, dss); + domain_suspend_common_failed(egc, dsps); } static void suspend_common_wait_guest_watch(libxl__egc *egc, libxl__ev_xswatch *xsw, const char *watch_path, const char *event_path) { - libxl__domain_suspend_state *dss = CONTAINER_OF(xsw, *dss, guest_watch); - suspend_common_wait_guest_check(egc, dss); + libxl__domain_suspend_state *dsps = CONTAINER_OF(xsw, *dsps, guest_watch); + suspend_common_wait_guest_check(egc, dsps); } static void suspend_common_wait_guest_check(libxl__egc *egc, - libxl__domain_suspend_state *dss) + libxl__domain_suspend_state *dsps) { - STATE_AO_GC(dss->ao); + STATE_AO_GC(dsps->ao); xc_domaininfo_t info; int ret; int shutdown_reason; /* Convenience aliases */ - const uint32_t domid = dss->domid; + const uint32_t domid = dsps->domid; ret = xc_domain_getinfolist(CTX->xch, domid, 1, &info); if (ret < 0) { @@ -302,74 +301,76 @@ static void suspend_common_wait_guest_check(libxl__egc *egc, } LOG(DEBUG, "guest has suspended"); - domain_suspend_common_guest_suspended(egc, dss); + domain_suspend_common_guest_suspended(egc, dsps); return; err: - domain_suspend_common_failed(egc, dss); + domain_suspend_common_failed(egc, dsps); } static void suspend_common_wait_guest_timeout(libxl__egc *egc, libxl__ev_time *ev, const struct timeval *requested_abs) { - libxl__domain_suspend_state *dss = CONTAINER_OF(ev, *dss, guest_timeout); - STATE_AO_GC(dss->ao); + libxl__domain_suspend_state *dsps = CONTAINER_OF(ev, *dsps, guest_timeout); + STATE_AO_GC(dsps->ao); LOG(ERROR, "guest did not suspend, timed out"); - domain_suspend_common_failed(egc, dss); + domain_suspend_common_failed(egc, dsps); } static void domain_suspend_common_guest_suspended(libxl__egc *egc, - libxl__domain_suspend_state *dss) + libxl__domain_suspend_state *dsps) { - STATE_AO_GC(dss->ao); + STATE_AO_GC(dsps->ao); int ret; - libxl__ev_evtchn_cancel(gc, &dss->guest_evtchn); - libxl__ev_xswatch_deregister(gc, &dss->guest_watch); - libxl__ev_time_deregister(gc, &dss->guest_timeout); + libxl__ev_evtchn_cancel(gc, &dsps->guest_evtchn); + libxl__ev_xswatch_deregister(gc, &dsps->guest_watch); + libxl__ev_time_deregister(gc, &dsps->guest_timeout); - if (dss->hvm) { - ret = libxl__domain_suspend_device_model(gc, dss); + if (dsps->hvm) { + ret = libxl__domain_suspend_device_model(gc, dsps); if (ret) { LOG(ERROR, "libxl__domain_suspend_device_model failed ret=%d", ret); - domain_suspend_common_failed(egc, dss); + domain_suspend_common_failed(egc, dsps); return; } } - domain_suspend_common_done(egc, dss, 1); + domain_suspend_common_done(egc, dsps, 1); } static void domain_suspend_common_failed(libxl__egc *egc, - libxl__domain_suspend_state *dss) + libxl__domain_suspend_state *dsps) { - domain_suspend_common_done(egc, dss, 0); + domain_suspend_common_done(egc, dsps, 0); } static void domain_suspend_common_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_suspend_state *dsps, bool ok) { EGC_GC; - assert(!libxl__xswait_inuse(&dss->pvcontrol)); - libxl__ev_evtchn_cancel(gc, &dss->guest_evtchn); - libxl__ev_xswatch_deregister(gc, &dss->guest_watch); - libxl__ev_time_deregister(gc, &dss->guest_timeout); - dss->callback_common_done(egc, dss, ok); + assert(!libxl__xswait_inuse(&dsps->pvcontrol)); + libxl__ev_evtchn_cancel(gc, &dsps->guest_evtchn); + libxl__ev_xswatch_deregister(gc, &dsps->guest_watch); + libxl__ev_time_deregister(gc, &dsps->guest_timeout); + dsps->callback_common_done(egc, dsps, ok); } void libxl__domain_suspend_callback(void *data) { libxl__save_helper_state *shs = data; libxl__egc *egc = shs->egc; - libxl__domain_suspend_state *dss = CONTAINER_OF(shs, *dss, shs); + libxl__domain_save_state *dss = CONTAINER_OF(shs, *dss, shs); + libxl__domain_suspend_state *dsps = &dss->dsps; - dss->callback_common_done = domain_suspend_callback_common_done; - domain_suspend_callback_common(egc, dss); + dsps->callback_common_done = domain_suspend_callback_common_done; + domain_suspend_callback_common(egc, dsps); } static void domain_suspend_callback_common_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, int ok) + libxl__domain_suspend_state *dsps, int ok) { + libxl__domain_save_state *dss = CONTAINER_OF(dsps, *dss, dsps); libxl__xc_domain_saverestore_async_callback_done(egc, &dss->shs, ok); } diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index b342988..4fdf9d8 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2859,11 +2859,12 @@ static inline bool libxl__convert_legacy_stream_inuse( /*----- Domain suspend (save) state structure -----*/ typedef struct libxl__domain_suspend_state libxl__domain_suspend_state; +typedef struct libxl__domain_save_state libxl__domain_save_state; -typedef void libxl__domain_suspend_cb(libxl__egc*, - libxl__domain_suspend_state*, int rc); +typedef void libxl__domain_save_cb(libxl__egc*, + libxl__domain_save_state*, int rc); typedef void libxl__save_device_model_cb(libxl__egc*, - libxl__domain_suspend_state*, int rc); + libxl__domain_save_state*, int rc); /* State for writing a libxl migration v2 stream */ typedef struct libxl__stream_write_state libxl__stream_write_state; @@ -2874,10 +2875,10 @@ struct libxl__stream_write_state { int fd; uint32_t domid; void (*completion_callback)(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_save_state *dss, int rc); void (*checkpoint_callback)(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_save_state *dss, int rc); /* Private */ int rc; @@ -2913,9 +2914,27 @@ typedef struct libxl__logdirty_switch { } libxl__logdirty_switch; struct libxl__domain_suspend_state { + /* set by caller of domain_suspend_callback_common */ + libxl__ao *ao; + + uint32_t domid; + int hvm; + /* private */ + libxl__ev_evtchn guest_evtchn; + int guest_evtchn_lockfd; + int guest_responded; + libxl__xswait_state pvcontrol; + libxl__ev_xswatch guest_watch; + libxl__ev_time guest_timeout; + const char *dm_savefile; + void (*callback_common_done)(libxl__egc*, + struct libxl__domain_suspend_state*, int ok); +}; + +struct libxl__domain_save_state { /* set by caller of libxl__domain_suspend */ libxl__ao *ao; - libxl__domain_suspend_cb *callback; + libxl__domain_save_cb *callback; uint32_t domid; int fd; @@ -2924,22 +2943,14 @@ struct libxl__domain_suspend_state { int debug; const libxl_domain_remus_info *remus; /* private */ - libxl__ev_evtchn guest_evtchn; - int guest_evtchn_lockfd; + libxl__domain_suspend_state dsps; int hvm; int xcflags; - int guest_responded; - libxl__xswait_state pvcontrol; - libxl__ev_xswatch guest_watch; - libxl__ev_time guest_timeout; - const char *dm_savefile; libxl__remus_devices_state rds; libxl__ev_time checkpoint_timeout; /* used for Remus checkpoint */ int interval; /* checkpoint interval (for Remus) */ libxl__save_helper_state shs; libxl__logdirty_switch logdirty; - void (*callback_common_done)(libxl__egc*, - struct libxl__domain_suspend_state*, int ok); /* private for libxl__domain_save_device_model */ libxl__save_device_model_cb *save_dm_callback; libxl__datacopier_state save_dm_datacopier; @@ -3264,11 +3275,11 @@ struct libxl__domain_create_state { /* calls dss->callback when done */ _hidden void libxl__domain_save(libxl__egc *egc, - libxl__domain_suspend_state *dss); + libxl__domain_save_state *dss); /* calls libxl__xc_domain_suspend_done when done */ -_hidden void libxl__xc_domain_save(libxl__egc*, libxl__domain_suspend_state*); +_hidden void libxl__xc_domain_save(libxl__egc*, libxl__domain_save_state*); /* If rc==0 then retval is the return value from xc_domain_save * and errnoval is the errno value it provided. * If rc!=0, retval and errnoval are undefined. */ @@ -3310,16 +3321,16 @@ static inline bool libxl__save_helper_inuse(const libxl__save_helper_state *shs) /* 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, - libxl__domain_suspend_state *dss); + libxl__domain_suspend_state *dsps); _hidden void libxl__domain_save_device_model(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_save_state *dss, libxl__save_device_model_cb *callback); _hidden const char *libxl__device_model_savefile(libxl__gc *gc, uint32_t domid); /* calls dss->callback_common_done when done */ _hidden void libxl__domain_suspend(libxl__egc *egc, - libxl__domain_suspend_state *dss); + libxl__domain_suspend_state *dsps); /* used by libxc to suspend the guest during migration */ _hidden void libxl__domain_suspend_callback(void *data); @@ -3331,9 +3342,9 @@ _hidden void libxl__remus_domain_save_checkpoint_callback(void *data); _hidden void libxl__remus_domain_restore_checkpoint_callback(void *data); /* Remus setup and teardown*/ _hidden void libxl__remus_setup(libxl__egc *egc, - libxl__domain_suspend_state *dss); + libxl__domain_save_state *dss); _hidden void libxl__remus_teardown(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_save_state *dss, int rc); /* diff --git a/tools/libxl/libxl_netbuffer.c b/tools/libxl/libxl_netbuffer.c index edc6843..71c6531 100644 --- a/tools/libxl/libxl_netbuffer.c +++ b/tools/libxl/libxl_netbuffer.c @@ -41,7 +41,7 @@ int libxl__netbuffer_enabled(libxl__gc *gc) int init_subkind_nic(libxl__remus_devices_state *rds) { int rc, ret; - libxl__domain_suspend_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); STATE_AO_GC(rds->ao); diff --git a/tools/libxl/libxl_remus.c b/tools/libxl/libxl_remus.c index 504cd44..01cc9e7 100644 --- a/tools/libxl/libxl_remus.c +++ b/tools/libxl/libxl_remus.c @@ -24,7 +24,7 @@ static void remus_setup_done(libxl__egc *egc, static void remus_setup_failed(libxl__egc *egc, libxl__remus_devices_state *rds, int rc); -void libxl__remus_setup(libxl__egc *egc, libxl__domain_suspend_state *dss) +void libxl__remus_setup(libxl__egc *egc, libxl__domain_save_state *dss) { /* Convenience aliases */ libxl__remus_devices_state *const rds = &dss->rds; @@ -57,7 +57,7 @@ out: static void remus_setup_done(libxl__egc *egc, libxl__remus_devices_state *rds, int rc) { - libxl__domain_suspend_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); STATE_AO_GC(dss->ao); if (!rc) { @@ -74,7 +74,7 @@ static void remus_setup_done(libxl__egc *egc, static void remus_setup_failed(libxl__egc *egc, libxl__remus_devices_state *rds, int rc) { - libxl__domain_suspend_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); STATE_AO_GC(dss->ao); if (rc) @@ -88,7 +88,7 @@ static void remus_teardown_done(libxl__egc *egc, libxl__remus_devices_state *rds, int rc); void libxl__remus_teardown(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_save_state *dss, int rc) { EGC_GC; @@ -103,7 +103,7 @@ static void remus_teardown_done(libxl__egc *egc, libxl__remus_devices_state *rds, int rc) { - libxl__domain_suspend_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); STATE_AO_GC(dss->ao); if (rc) @@ -116,7 +116,7 @@ static void remus_teardown_done(libxl__egc *egc, /*---------------------- remus callbacks (save) -----------------------*/ static void remus_domain_suspend_callback_common_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, int ok); + libxl__domain_suspend_state *dsps, int ok); static void remus_devices_postsuspend_cb(libxl__egc *egc, libxl__remus_devices_state *rds, int rc); @@ -128,15 +128,18 @@ void libxl__remus_domain_suspend_callback(void *data) { libxl__save_helper_state *shs = data; libxl__egc *egc = shs->egc; - libxl__domain_suspend_state *dss = CONTAINER_OF(shs, *dss, shs); + libxl__domain_save_state *dss = CONTAINER_OF(shs, *dss, shs); + libxl__domain_suspend_state *dsps = &dss->dsps; - dss->callback_common_done = remus_domain_suspend_callback_common_done; - libxl__domain_suspend(egc, dss); + dsps->callback_common_done = remus_domain_suspend_callback_common_done; + libxl__domain_suspend(egc, dsps); } static void remus_domain_suspend_callback_common_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, int ok) + libxl__domain_suspend_state *dsps, int ok) { + libxl__domain_save_state *dss = CONTAINER_OF(dsps, *dss, dsps); + if (!ok) goto out; @@ -154,7 +157,7 @@ static void remus_devices_postsuspend_cb(libxl__egc *egc, int rc) { int ok = 0; - libxl__domain_suspend_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); if (rc) goto out; @@ -169,7 +172,7 @@ void libxl__remus_domain_resume_callback(void *data) { libxl__save_helper_state *shs = data; libxl__egc *egc = shs->egc; - libxl__domain_suspend_state *dss = CONTAINER_OF(shs, *dss, shs); + libxl__domain_save_state *dss = CONTAINER_OF(shs, *dss, shs); STATE_AO_GC(dss->ao); libxl__remus_devices_state *const rds = &dss->rds; @@ -182,7 +185,7 @@ static void remus_devices_preresume_cb(libxl__egc *egc, int rc) { int ok = 0; - libxl__domain_suspend_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); STATE_AO_GC(dss->ao); if (rc) @@ -202,7 +205,7 @@ out: /*----- remus asynchronous checkpoint callback -----*/ static void remus_checkpoint_stream_written( - libxl__egc *egc, libxl__domain_suspend_state *dss, int rc); + libxl__egc *egc, libxl__domain_save_state *dss, int rc); static void remus_devices_commit_cb(libxl__egc *egc, libxl__remus_devices_state *rds, int rc); @@ -212,7 +215,7 @@ static void remus_next_checkpoint(libxl__egc *egc, libxl__ev_time *ev, void libxl__remus_domain_save_checkpoint_callback(void *data) { libxl__save_helper_state *shs = data; - libxl__domain_suspend_state *dss = CONTAINER_OF(shs, *dss, shs); + libxl__domain_save_state *dss = CONTAINER_OF(shs, *dss, shs); libxl__egc *egc = dss->shs.egc; STATE_AO_GC(dss->ao); @@ -221,7 +224,7 @@ void libxl__remus_domain_save_checkpoint_callback(void *data) } static void remus_checkpoint_stream_written( - libxl__egc *egc, libxl__domain_suspend_state *dss, int rc) + libxl__egc *egc, libxl__domain_save_state *dss, int rc) { /* Convenience aliases */ libxl__remus_devices_state *const rds = &dss->rds; @@ -246,7 +249,7 @@ static void remus_devices_commit_cb(libxl__egc *egc, libxl__remus_devices_state *rds, int rc) { - libxl__domain_suspend_state *dss = CONTAINER_OF(rds, *dss, rds); + libxl__domain_save_state *dss = CONTAINER_OF(rds, *dss, rds); STATE_AO_GC(dss->ao); @@ -280,7 +283,7 @@ out: static void remus_next_checkpoint(libxl__egc *egc, libxl__ev_time *ev, const struct timeval *requested_abs) { - libxl__domain_suspend_state *dss = + libxl__domain_save_state *dss = CONTAINER_OF(ev, *dss, checkpoint_timeout); STATE_AO_GC(dss->ao); diff --git a/tools/libxl/libxl_save_callout.c b/tools/libxl/libxl_save_callout.c index 02e0190..a5039e6 100644 --- a/tools/libxl/libxl_save_callout.c +++ b/tools/libxl/libxl_save_callout.c @@ -74,7 +74,7 @@ void libxl__xc_domain_restore(libxl__egc *egc, libxl__domain_create_state *dcs, argnums, ARRAY_SIZE(argnums)); } -void libxl__xc_domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss) +void libxl__xc_domain_save(libxl__egc *egc, libxl__domain_save_state *dss) { STATE_AO_GC(dss->ao); diff --git a/tools/libxl/libxl_stream_write.c b/tools/libxl/libxl_stream_write.c index 40f2cb7..1ebe306 100644 --- a/tools/libxl/libxl_stream_write.c +++ b/tools/libxl/libxl_stream_write.c @@ -60,7 +60,7 @@ static void stream_done(libxl__egc *egc, libxl__stream_write_state *stream); static void check_stream_finished(libxl__egc *egc, - libxl__domain_suspend_state *dcs, + libxl__domain_save_state *dcs, int rc, const char *what); /* Event callbacks for plain VM. */ @@ -187,7 +187,7 @@ static void stream_failed(libxl__egc *egc, static void stream_done(libxl__egc *egc, libxl__stream_write_state *stream) { - libxl__domain_suspend_state *dss = CONTAINER_OF(stream, *dss, sws); + libxl__domain_save_state *dss = CONTAINER_OF(stream, *dss, sws); assert(!stream->running); assert(!stream->in_checkpoint); @@ -196,7 +196,7 @@ static void stream_done(libxl__egc *egc, } static void check_stream_finished(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_save_state *dss, int rc, const char *what) { libxl__stream_write_state *stream = &dss->sws; @@ -270,7 +270,7 @@ static void libxc_header_done(libxl__egc *egc, int onwrite, int errnoval) { libxl__stream_write_state *stream = CONTAINER_OF(dc, *stream, dc); - libxl__domain_suspend_state *dss = CONTAINER_OF(stream, *dss, sws); + libxl__domain_save_state *dss = CONTAINER_OF(stream, *dss, sws); STATE_AO_GC(stream->ao); int ret = 0; @@ -290,7 +290,7 @@ static void libxc_header_done(libxl__egc *egc, void libxl__xc_domain_save_done(libxl__egc *egc, void *dss_void, int rc, int retval, int errnoval) { - libxl__domain_suspend_state *dss = dss_void; + libxl__domain_save_state *dss = dss_void; libxl__stream_write_state *stream = &dss->sws; STATE_AO_GC(dss->ao); @@ -299,10 +299,10 @@ void libxl__xc_domain_save_done(libxl__egc *egc, void *dss_void, if (retval) { LOGEV(ERROR, errnoval, "saving domain: %s", - dss->guest_responded ? + dss->dsps.guest_responded ? "domain responded to suspend request" : "domain did not respond to suspend request"); - if ( !dss->guest_responded ) + if ( !dss->dsps.guest_responded ) rc = ERROR_GUEST_TIMEDOUT; else rc = ERROR_FAIL; @@ -320,7 +320,7 @@ void libxl__xc_domain_save_done(libxl__egc *egc, void *dss_void, static void write_toolstack_record(libxl__egc *egc, libxl__stream_write_state *stream) { - libxl__domain_suspend_state *dss = CONTAINER_OF(stream, *dss, sws); + libxl__domain_save_state *dss = CONTAINER_OF(stream, *dss, sws); libxl__datacopier_state *dc = &stream->dc; STATE_AO_GC(stream->ao); struct libxl_sr_rec_hdr rec = { REC_TYPE_XENSTORE_DATA, 0 }; @@ -364,7 +364,7 @@ static void toolstack_record_done(libxl__egc *egc, int onwrite, int errnoval) { libxl__stream_write_state *stream = CONTAINER_OF(dc, *stream, dc); - libxl__domain_suspend_state *dss = CONTAINER_OF(stream, *dss, sws); + libxl__domain_save_state *dss = CONTAINER_OF(stream, *dss, sws); STATE_AO_GC(stream->ao); int ret = 0; @@ -392,7 +392,7 @@ static void toolstack_record_done(libxl__egc *egc, static void write_emulator_record(libxl__egc *egc, libxl__stream_write_state *stream) { - libxl__domain_suspend_state *dss = CONTAINER_OF(stream, *dss, sws); + libxl__domain_save_state *dss = CONTAINER_OF(stream, *dss, sws); libxl__datacopier_state *dc = &stream->dc; STATE_AO_GC(stream->ao); struct libxl_sr_rec_hdr rec = { REC_TYPE_EMULATOR_CONTEXT, 0 }; @@ -404,7 +404,7 @@ static void write_emulator_record(libxl__egc *egc, assert(dss->type == LIBXL_DOMAIN_TYPE_HVM); /* Convenience aliases */ - const char *const filename = dss->dm_savefile; + const char *const filename = dss->dsps.dm_savefile; const uint32_t domid = dss->domid; switch(libxl__device_model_version_running(gc, domid)) { @@ -421,7 +421,7 @@ static void write_emulator_record(libxl__egc *egc, goto err; } - ret = libxl__domain_suspend_device_model(gc, dss); + ret = libxl__domain_suspend_device_model(gc, &dss->dsps); if (ret) goto err; @@ -577,7 +577,7 @@ static void checkpoint_done(libxl__egc *egc, libxl__stream_write_state *stream, int rc) { - libxl__domain_suspend_state *dss = CONTAINER_OF(stream, *dss, sws); + libxl__domain_save_state *dss = CONTAINER_OF(stream, *dss, sws); assert(stream->in_checkpoint); stream->in_checkpoint = false; -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |