From patchwork Fri Jan 29 05:27:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Congyang X-Patchwork-Id: 8159301 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 02C7ABEEE5 for ; Fri, 29 Jan 2016 05:30:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7131C20351 for ; Fri, 29 Jan 2016 05:30:18 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C3EA62024F for ; Fri, 29 Jan 2016 05:30:15 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aP1ak-0007bu-68; Fri, 29 Jan 2016 05:27:30 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aP1ai-0007ac-0a for xen-devel@lists.xen.org; Fri, 29 Jan 2016 05:27:28 +0000 Received: from [85.158.143.35] by server-2.bemta-4.messagelabs.com id 10/09-08977-F38FAA65; Fri, 29 Jan 2016 05:27:27 +0000 X-Env-Sender: wency@cn.fujitsu.com X-Msg-Ref: server-15.tower-21.messagelabs.com!1454045241!12756590!1 X-Originating-IP: [59.151.112.132] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 42500 invoked from network); 29 Jan 2016 05:27:23 -0000 Received: from cn.fujitsu.com (HELO heian.cn.fujitsu.com) (59.151.112.132) by server-15.tower-21.messagelabs.com with SMTP; 29 Jan 2016 05:27:23 -0000 X-IronPort-AV: E=Sophos;i="5.20,346,1444665600"; d="scan'208";a="3106334" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 29 Jan 2016 13:27:19 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id 31E09418AD47; Fri, 29 Jan 2016 13:26:26 +0800 (CST) Received: from G08FNSTD140052.g08.fujitsu.local (10.167.226.52) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.181.6; Fri, 29 Jan 2016 13:27:01 +0800 From: Wen Congyang To: xen devel , Konrad Rzeszutek Wilk , Andrew Cooper , Ian Campbell , Ian Jackson , Wei Liu Date: Fri, 29 Jan 2016 13:27:20 +0800 Message-ID: <1454045254-3711-5-git-send-email-wency@cn.fujitsu.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1454045254-3711-1-git-send-email-wency@cn.fujitsu.com> References: <1454045254-3711-1-git-send-email-wency@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.226.52] X-yoursite-MailScanner-ID: 31E09418AD47.A8C7A X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: wency@cn.fujitsu.com X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Cc: Lars Kurth , Changlong Xie , Ian Campbell , Wen Congyang , Gui Jianfeng , Jiang Yunhong , Dong Eddie , Shriram Rajagopalan , Ian Jackson , Yang Hongyang Subject: [Xen-devel] [PATCH v7 04/18] libxl/save: Refactor libxl__domain_suspend_state X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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. Also introduce libxl__domain_suspend_init to initialise the libxl__domain_suspend_state. Signed-off-by: Yang Hongyang Signed-off-by: Wen Congyang CC: Ian Campbell CC: Ian Jackson CC: Wei Liu CC: Andrew Cooper Acked-by:Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk Acked-by: Wei Liu --- tools/libxl/libxl.c | 10 +- tools/libxl/libxl_create.c | 10 +- tools/libxl/libxl_dom_save.c | 61 ++++-------- tools/libxl/libxl_dom_suspend.c | 207 ++++++++++++++++++++++++--------------- tools/libxl/libxl_internal.h | 61 +++++++----- tools/libxl/libxl_netbuffer.c | 2 +- tools/libxl/libxl_remus.c | 37 +++---- tools/libxl/libxl_save_callout.c | 2 +- tools/libxl/libxl_stream_write.c | 16 +-- 9 files changed, 227 insertions(+), 179 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 6347097..8707b08 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -832,7 +832,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, @@ -840,7 +840,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); @@ -888,7 +888,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); /* @@ -900,7 +900,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); int flrc; @@ -925,7 +925,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_create.c b/tools/libxl/libxl_create.c index 6f1cf93..91c78e5 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -1549,7 +1549,7 @@ typedef struct { typedef struct { libxl__app_domain_create_state cdcs; libxl__domain_destroy_state dds; - libxl__domain_suspend_state dss; + libxl__domain_save_state dss; char *toolstack_buf; uint32_t toolstack_len; } libxl__domain_soft_reset_state; @@ -1644,7 +1644,7 @@ static int do_domain_soft_reset(libxl_ctx *ctx, libxl__app_domain_create_state *cdcs; libxl__domain_create_state *dcs; libxl__domain_build_state *state; - libxl__domain_suspend_state *dss; + libxl__domain_save_state *dss; char *dom_path, *xs_store_mfn, *xs_console_mfn; uint32_t domid_out; int rc; @@ -1688,8 +1688,8 @@ static int do_domain_soft_reset(libxl_ctx *ctx, dss->ao = ao; dss->domid = domid_soft_reset; - dss->dm_savefile = GCSPRINTF(LIBXL_DEVICE_MODEL_SAVE_FILE".%d", - domid_soft_reset); + dss->dsps.dm_savefile = GCSPRINTF(LIBXL_DEVICE_MODEL_SAVE_FILE".%d", + domid_soft_reset); rc = libxl__save_emulator_xenstore_data(dss, &srs->toolstack_buf, &srs->toolstack_len); @@ -1698,7 +1698,7 @@ static int do_domain_soft_reset(libxl_ctx *ctx, goto out; } - rc = libxl__domain_suspend_device_model(gc, dss); + rc = libxl__domain_suspend_device_model(gc, &dss->dsps); if (rc) { LOG(ERROR, "failed to suspend device model."); goto out; diff --git a/tools/libxl/libxl_dom_save.c b/tools/libxl/libxl_dom_save.c index 27fd58b..02cc143 100644 --- a/tools/libxl/libxl_dom_save.c +++ b/tools/libxl/libxl_dom_save.c @@ -24,7 +24,7 @@ static void stream_done(libxl__egc *egc, libxl__stream_write_state *sws, 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 -----*/ @@ -42,7 +42,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 rc); + libxl__domain_save_state *dss, int rc); static void logdirty_init(libxl__logdirty_switch *lds) { @@ -56,7 +56,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 = shs->caller_state; + libxl__domain_save_state *dss = shs->caller_state; libxl__logdirty_switch *lds = &dss->logdirty; STATE_AO_GC(dss->ao); int rc; @@ -128,7 +128,7 @@ static void domain_suspend_switch_qemu_xen_logdirty libxl__save_helper_state *shs) { libxl__egc *egc = shs->egc; - libxl__domain_suspend_state *dss = shs->caller_state; + libxl__domain_save_state *dss = shs->caller_state; STATE_AO_GC(dss->ao); int rc; @@ -147,7 +147,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 = shs->caller_state; + libxl__domain_save_state *dss = shs->caller_state; STATE_AO_GC(dss->ao); switch (libxl__device_model_version_running(gc, domid)) { @@ -171,7 +171,7 @@ static void switch_logdirty_timeout(libxl__egc *egc, libxl__ev_time *ev, const struct timeval *requested_abs, int rc) { - 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,ERROR_FAIL); @@ -180,7 +180,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); @@ -234,7 +234,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 rc) { STATE_AO_GC(dss->ao); @@ -270,7 +270,7 @@ static void append_string(libxl__gc *gc, char **buf, uint32_t *len, *len += extralen; } -int libxl__save_emulator_xenstore_data(libxl__domain_suspend_state *dss, +int libxl__save_emulator_xenstore_data(libxl__domain_save_state *dss, char **callee_buf, uint32_t *callee_len) { @@ -322,10 +322,9 @@ int libxl__save_emulator_xenstore_data(libxl__domain_suspend_state *dss, /*----- 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; int rc, ret; /* Convenience aliases */ @@ -337,13 +336,14 @@ void libxl__domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss) libxl__srm_save_autogen_callbacks *const callbacks = &dss->sws.shs.callbacks.save.a; unsigned int nr_vnodes = 0, nr_vmemranges = 0, nr_vcpus = 0; + libxl__domain_suspend_state *dsps = &dss->dsps; dss->rc = 0; 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); + dsps->ao = ao; + dsps->domid = domid; + rc = libxl__domain_suspend_init(egc, dsps, type); + if (rc) goto out; switch (type) { case LIBXL_DOMAIN_TYPE_HVM: { @@ -376,11 +376,6 @@ void libxl__domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss) goto out; } - dss->guest_evtchn.port = -1; - dss->guest_evtchn_lockfd = -1; - dss->guest_responded = 0; - dss->dm_savefile = libxl__device_model_savefile(gc, domid); - if (r_info != NULL) { dss->interval = r_info->interval; dss->xcflags |= XCFLAGS_CHECKPOINTED; @@ -388,23 +383,6 @@ void libxl__domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss) dss->xcflags |= XCFLAGS_CHECKPOINT_COMPRESS; } - port = xs_suspend_evtchn_port(dss->domid); - - if (port >= 0) { - rc = libxl__ctx_evtchn_init(gc); - if (rc) goto out; - - dss->guest_evtchn.port = - xc_suspend_evtchn_init_exclusive(CTX->xch, CTX->xce, - dss->domid, port, &dss->guest_evtchn_lockfd); - - if (dss->guest_evtchn.port < 0) { - LOG(WARN, "Suspend event channel initialization failed"); - rc = ERROR_FAIL; - goto out; - } - } - memset(callbacks, 0, sizeof(*callbacks)); if (r_info != NULL) { callbacks->suspend = libxl__remus_domain_suspend_callback; @@ -434,18 +412,19 @@ static void stream_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) { /* diff --git a/tools/libxl/libxl_dom_suspend.c b/tools/libxl/libxl_dom_suspend.c index 16f603f..cc0b217 100644 --- a/tools/libxl/libxl_dom_suspend.c +++ b/tools/libxl/libxl_dom_suspend.c @@ -19,14 +19,61 @@ /*====================== Domain suspend =======================*/ +int libxl__domain_suspend_init(libxl__egc *egc, + libxl__domain_suspend_state *dsps, + libxl_domain_type type) +{ + STATE_AO_GC(dsps->ao); + int rc = ERROR_FAIL; + int port; + + /* Convenience aliases */ + const uint32_t domid = dsps->domid; + + 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); + + if (type == LIBXL_DOMAIN_TYPE_INVALID) goto out; + dsps->type = type; + + dsps->guest_evtchn.port = -1; + dsps->guest_evtchn_lockfd = -1; + dsps->guest_responded = 0; + dsps->dm_savefile = libxl__device_model_savefile(gc, domid); + + port = xs_suspend_evtchn_port(domid); + + if (port >= 0) { + rc = libxl__ctx_evtchn_init(gc); + if (rc) goto out; + + dsps->guest_evtchn.port = + xc_suspend_evtchn_init_exclusive(CTX->xch, CTX->xce, + domid, port, &dsps->guest_evtchn_lockfd); + + if (dsps->guest_evtchn.port < 0) { + LOG(WARN, "Suspend event channel initialization failed"); + rc = ERROR_FAIL; + goto out; + } + } + + rc = 0; + +out: + return rc; +} + /*----- 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: { @@ -53,9 +100,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); @@ -64,24 +111,24 @@ 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, int rc); static void domain_suspend_common_done(libxl__egc *egc, - libxl__domain_suspend_state *dss, + libxl__domain_suspend_state *dsps, int rc); 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 rc); + libxl__domain_suspend_state *dsps, int rc); -/* 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) { @@ -90,37 +137,37 @@ static bool domain_suspend_pvcontrol_acked(const char *state) { 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->type == LIBXL_DOMAIN_TYPE_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 = xenevtchn_notify(CTX->xce, dss->guest_evtchn.port); + dsps->type == LIBXL_DOMAIN_TYPE_HVM ? "PVHVM" : "PV"); + ret = xenevtchn_notify(CTX->xce, dsps->guest_evtchn.port); if (ret < 0) { LOG(ERROR, "xenevtchn_notify failed ret=%d", ret); rc = ERROR_FAIL; 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(ao, &dss->guest_timeout, + rc = libxl__ev_time_register_rel(ao, &dsps->guest_timeout, suspend_common_wait_guest_timeout, 60*1000); if (rc) goto err; @@ -128,7 +175,7 @@ static void domain_suspend_callback_common(libxl__egc *egc, return; } - if (dss->hvm && (!hvm_pvdrv || hvm_s_state)) { + if (dsps->type == LIBXL_DOMAIN_TYPE_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) { @@ -137,55 +184,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->type == LIBXL_DOMAIN_TYPE_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) { rc = ERROR_FAIL; goto err; } + dsps->pvcontrol.path = libxl__domain_pvcontrol_xspath(gc, domid); + if (!dsps->pvcontrol.path) { rc = ERROR_FAIL; 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_done(egc, dss, rc); + domain_suspend_common_done(egc, dsps, rc); } 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_done, both of which cancel the evtchn * wait as needed. 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) { /* @@ -228,56 +275,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_done(egc, dss, rc); + domain_suspend_common_done(egc, dsps, rc); 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(ao, &dss->guest_timeout, + rc = libxl__ev_time_register_rel(ao, &dsps->guest_timeout, suspend_common_wait_guest_timeout, 60*1000); if (rc) goto err; return; err: - domain_suspend_common_done(egc, dss, rc); + domain_suspend_common_done(egc, dsps, rc); } 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) { @@ -304,71 +351,73 @@ 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_done(egc, dss, ERROR_FAIL); + domain_suspend_common_done(egc, dsps, ERROR_FAIL); } static void suspend_common_wait_guest_timeout(libxl__egc *egc, libxl__ev_time *ev, const struct timeval *requested_abs, int rc) { - 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); if (rc == ERROR_TIMEDOUT) { LOG(ERROR, "guest did not suspend, timed out"); rc = ERROR_GUEST_TIMEDOUT; } - domain_suspend_common_done(egc, dss, rc); + domain_suspend_common_done(egc, dsps, rc); } 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 rc; - 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) { - rc = libxl__domain_suspend_device_model(gc, dss); + if (dsps->type == LIBXL_DOMAIN_TYPE_HVM) { + rc = libxl__domain_suspend_device_model(gc, dsps); if (rc) { LOG(ERROR, "libxl__domain_suspend_device_model failed ret=%d", rc); - domain_suspend_common_done(egc, dss, rc); + domain_suspend_common_done(egc, dsps, rc); return; } } - 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, int rc) { 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, rc); + 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, rc); } void libxl__domain_suspend_callback(void *data) { libxl__save_helper_state *shs = data; libxl__egc *egc = shs->egc; - libxl__domain_suspend_state *dss = shs->caller_state; + libxl__domain_save_state *dss = shs->caller_state; + 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 rc) + libxl__domain_suspend_state *dsps, int rc) { + libxl__domain_save_state *dss = CONTAINER_OF(dsps, *dss, dsps); dss->rc = rc; libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, !rc); } diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 7005d6b..bc48bec 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -3009,11 +3009,12 @@ static inline bool libxl__conversion_helper_inuse */ 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; @@ -3022,7 +3023,7 @@ typedef void (*sws_record_done_cb)(libxl__egc *egc, struct libxl__stream_write_state { /* filled by the user */ libxl__ao *ao; - libxl__domain_suspend_state *dss; + libxl__domain_save_state *dss; int fd; void (*completion_callback)(libxl__egc *egc, libxl__stream_write_state *sws, @@ -3076,9 +3077,33 @@ typedef struct libxl__logdirty_switch { } libxl__logdirty_switch; struct libxl__domain_suspend_state { + /* set by caller of libxl__domain_suspend_init */ + libxl__ao *ao; + uint32_t domid; + + /* private */ + libxl_domain_type type; + + 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); +}; +int libxl__domain_suspend_init(libxl__egc *egc, + libxl__domain_suspend_state *dsps, + libxl_domain_type type); + +struct libxl__domain_save_state { /* set by caller of libxl__domain_save */ libxl__ao *ao; - libxl__domain_suspend_cb *callback; + libxl__domain_save_cb *callback; uint32_t domid; int fd; @@ -3089,22 +3114,14 @@ struct libxl__domain_suspend_state { const libxl_domain_remus_info *remus; /* private */ int rc; - libxl__ev_evtchn guest_evtchn; - int guest_evtchn_lockfd; 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__domain_suspend_state dsps; libxl__remus_devices_state rds; libxl__ev_time checkpoint_timeout; /* used for Remus checkpoint */ int interval; /* checkpoint interval (for Remus) */ libxl__stream_write_state sws; libxl__logdirty_switch logdirty; - void (*callback_common_done)(libxl__egc*, - struct libxl__domain_suspend_state*, int ok); }; @@ -3445,12 +3462,12 @@ 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 *egc, - libxl__domain_suspend_state *dss, + libxl__domain_save_state *dss, libxl__save_helper_state *shs); /* If rc==0 then retval is the return value from xc_domain_save * and errnoval is the errno value it provided. @@ -3468,7 +3485,7 @@ void libxl__xc_domain_saverestore_async_callback_done(libxl__egc *egc, _hidden void libxl__domain_suspend_common_switch_qemu_logdirty (int domid, unsigned int enable, void *data); -_hidden int libxl__save_emulator_xenstore_data(libxl__domain_suspend_state *dss, +_hidden int libxl__save_emulator_xenstore_data(libxl__domain_save_state *dss, char **buf, uint32_t *len); _hidden int libxl__restore_emulator_xenstore_data (libxl__domain_create_state *dcs, const char *ptr, uint32_t size); @@ -3496,13 +3513,13 @@ 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 const char *libxl__device_model_savefile(libxl__gc *gc, uint32_t domid); -/* calls dss->callback_common_done when done */ +/* calls dsps->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); @@ -3512,9 +3529,9 @@ _hidden void libxl__remus_domain_resume_callback(void *data); _hidden void libxl__remus_domain_save_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); /* Remus callbacks for restore */ _hidden void libxl__remus_domain_restore_checkpoint_callback(void *data); diff --git a/tools/libxl/libxl_netbuffer.c b/tools/libxl/libxl_netbuffer.c index 107e867..c245a4e 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 e3caf7d..fae2120 100644 --- a/tools/libxl/libxl_remus.c +++ b/tools/libxl/libxl_remus.c @@ -28,7 +28,7 @@ static void remus_checkpoint_stream_written( libxl__egc *egc, libxl__stream_write_state *sws, int rc); void libxl__remus_setup(libxl__egc *egc, - libxl__domain_suspend_state *dss) + libxl__domain_save_state *dss) { /* Convenience aliases */ libxl__remus_devices_state *const rds = &dss->rds; @@ -63,7 +63,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) { @@ -80,7 +80,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) @@ -94,7 +94,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; @@ -109,7 +109,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) @@ -122,7 +122,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); @@ -134,15 +134,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 = shs->caller_state; + libxl__domain_save_state *dss = shs->caller_state; + 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 rc) + libxl__domain_suspend_state *dsps, int rc) { + libxl__domain_save_state *dss = CONTAINER_OF(dsps, *dss, dsps); + if (rc) goto out; @@ -160,7 +163,7 @@ static void remus_devices_postsuspend_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); if (rc) goto out; @@ -177,7 +180,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 = shs->caller_state; + libxl__domain_save_state *dss = shs->caller_state; STATE_AO_GC(dss->ao); libxl__remus_devices_state *const rds = &dss->rds; @@ -189,7 +192,7 @@ static void remus_devices_preresume_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); if (rc) @@ -220,7 +223,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 = shs->caller_state; + libxl__domain_save_state *dss = shs->caller_state; libxl__egc *egc = shs->egc; STATE_AO_GC(dss->ao); @@ -230,7 +233,7 @@ void libxl__remus_domain_save_checkpoint_callback(void *data) static void remus_checkpoint_stream_written( libxl__egc *egc, libxl__stream_write_state *sws, int rc) { - libxl__domain_suspend_state *dss = CONTAINER_OF(sws, *dss, sws); + libxl__domain_save_state *dss = CONTAINER_OF(sws, *dss, sws); /* Convenience aliases */ libxl__remus_devices_state *const rds = &dss->rds; @@ -255,7 +258,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); @@ -290,7 +293,7 @@ static void remus_next_checkpoint(libxl__egc *egc, libxl__ev_time *ev, const struct timeval *requested_abs, int rc) { - 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 3af99af..2d06b42 100644 --- a/tools/libxl/libxl_save_callout.c +++ b/tools/libxl/libxl_save_callout.c @@ -75,7 +75,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, libxl__save_helper_state *shs) { STATE_AO_GC(dss->ao); diff --git a/tools/libxl/libxl_stream_write.c b/tools/libxl/libxl_stream_write.c index 21b4b51..9053146 100644 --- a/tools/libxl/libxl_stream_write.c +++ b/tools/libxl/libxl_stream_write.c @@ -216,7 +216,7 @@ void libxl__stream_write_start(libxl__egc *egc, libxl__stream_write_state *stream) { libxl__datacopier_state *dc = &stream->dc; - libxl__domain_suspend_state *dss = stream->dss; + libxl__domain_save_state *dss = stream->dss; STATE_AO_GC(stream->ao); struct libxl__sr_hdr hdr; int rc = 0; @@ -324,7 +324,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); @@ -333,10 +333,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 if (dss->rc) rc = dss->rc; @@ -371,7 +371,7 @@ void libxl__xc_domain_save_done(libxl__egc *egc, void *dss_void, static void write_emulator_xenstore_record(libxl__egc *egc, libxl__stream_write_state *stream) { - libxl__domain_suspend_state *dss = stream->dss; + libxl__domain_save_state *dss = stream->dss; STATE_AO_GC(stream->ao); struct libxl__sr_rec_hdr rec; int rc; @@ -410,7 +410,7 @@ static void write_emulator_xenstore_record(libxl__egc *egc, static void emulator_xenstore_record_done(libxl__egc *egc, libxl__stream_write_state *stream) { - libxl__domain_suspend_state *dss = stream->dss; + libxl__domain_save_state *dss = stream->dss; if (dss->type == LIBXL_DOMAIN_TYPE_HVM) write_emulator_context_record(egc, stream); @@ -425,7 +425,7 @@ static void emulator_xenstore_record_done(libxl__egc *egc, static void write_emulator_context_record(libxl__egc *egc, libxl__stream_write_state *stream) { - libxl__domain_suspend_state *dss = stream->dss; + libxl__domain_save_state *dss = stream->dss; libxl__datacopier_state *dc = &stream->emu_dc; STATE_AO_GC(stream->ao); struct libxl__sr_rec_hdr *rec = &stream->emu_rec_hdr; @@ -440,7 +440,7 @@ static void write_emulator_context_record(libxl__egc *egc, } /* Convenience aliases */ - const char *const filename = dss->dm_savefile; + const char *const filename = dss->dsps.dm_savefile; libxl__carefd_begin(); int readfd = open(filename, O_RDONLY);