|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 10/19] libxl: prepare for asynchronous writing of qemu save file
On Fri, 2012-06-08 at 18:34 +0100, Ian Jackson wrote:
> * Combine the various calls to libxl__device_model_savefile into one
> at the start of libxl__domain_suspend, storing the result in the
> dss. Consequently a few functions take a dss instead of some or all
> of their other arguments.
>
> * Make libxl__domain_save_device_model's API into an asynchronous
> style which takes a callback. The function is, however, still
> synchronous; it will be made actually async in the next patch.
>
> * Consequently make libxl__remus_domain_checkpoint_callback into an
> asynchronous callback.
>
> Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
> ---
> tools/libxl/libxl_dom.c | 54
> ++++++++++++++++++++++++++----------
> tools/libxl/libxl_internal.h | 18 ++++++++++--
> tools/libxl/libxl_save_msgs_gen.pl | 2 +-
> 3 files changed, 55 insertions(+), 19 deletions(-)
>
> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> index d5ac79f..3a53f97 100644
> --- a/tools/libxl/libxl_dom.c
> +++ b/tools/libxl/libxl_dom.c
> @@ -702,11 +702,13 @@ static void switch_logdirty_done(libxl__egc *egc,
>
> /*----- callbacks, called by xc_domain_save -----*/
>
> -int libxl__domain_suspend_device_model(libxl__gc *gc, uint32_t domid)
> +int libxl__domain_suspend_device_model(libxl__gc *gc,
> + libxl__domain_suspend_state *dss)
> {
> libxl_ctx *ctx = libxl__gc_owner(gc);
> int ret = 0;
> - const char *filename = libxl__device_model_savefile(gc, domid);
> + uint32_t const domid = dss->domid;
> + const char *const filename = dss->dm_savefile;
>
> switch (libxl__device_model_version_running(gc, domid)) {
> case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: {
> @@ -875,7 +877,7 @@ int libxl__domain_suspend_common_callback(void *user)
>
> guest_suspended:
> if (dss->hvm) {
> - ret = libxl__domain_suspend_device_model(gc, dss->domid);
> + ret = libxl__domain_suspend_device_model(gc, dss);
> if (ret) {
> LOG(ERROR, "libxl__domain_suspend_device_model failed ret=%d",
> ret);
> return 0;
> @@ -990,19 +992,32 @@ static int libxl__remus_domain_resume_callback(void
> *data)
> return 1;
> }
>
> -static int libxl__remus_domain_checkpoint_callback(void *data)
> +/*----- remus asynchronous checkpoint callback -----*/
> +
> +static void remus_checkpoint_dm_saved(libxl__egc *egc,
> + libxl__domain_suspend_state *dss, int
> rc);
> +
> +static void libxl__remus_domain_checkpoint_callback(void *data)
> {
> libxl__domain_suspend_state *dss = data;
> + libxl__egc *egc = dss->shs.egc;
> STATE_AO_GC(dss->ao);
>
> /* This would go into tailbuf. */
> - if (dss->hvm &&
> - libxl__domain_save_device_model(gc, dss->domid, dss->fd))
> - return 0;
> + if (dss->hvm) {
> + libxl__domain_save_device_model(egc, dss, remus_checkpoint_dm_saved);
> + } else {
> + remus_checkpoint_dm_saved(egc, dss, 0);
> + }
> +}
>
> +static void remus_checkpoint_dm_saved(libxl__egc *egc,
> + libxl__domain_suspend_state *dss, int
> rc)
> +{
> /* TODO: Wait for disk and memory ack, release network buffer */
> + /* TODO: make this asynchronous */
> usleep(dss->interval * 1000);
> - return 1;
> + libxl__xc_domain_saverestore_async_callback_done(egc, &dss->shs, 1);
> }
>
> /*----- main code for suspending, in order of execution -----*/
> @@ -1052,6 +1067,7 @@ void libxl__domain_suspend(libxl__egc *egc,
> libxl__domain_suspend_state *dss)
>
> dss->suspend_eventchn = -1;
> dss->guest_responded = 0;
> + dss->dm_savefile = libxl__device_model_savefile(gc, domid);
>
> if (r_info != NULL) {
> dss->interval = r_info->interval;
> @@ -1101,7 +1117,6 @@ void libxl__xc_domain_save_done(libxl__egc *egc, void
> *dss_void,
>
> /* Convenience aliases */
> const libxl_domain_type type = dss->type;
> - const uint32_t domid = dss->domid;
>
> if (rc)
> goto out;
> @@ -1119,11 +1134,11 @@ void libxl__xc_domain_save_done(libxl__egc *egc, void
> *dss_void,
> }
>
> if (type == LIBXL_DOMAIN_TYPE_HVM) {
> - rc = libxl__domain_suspend_device_model(gc, domid);
> + rc = libxl__domain_suspend_device_model(gc, dss);
> if (rc) goto out;
>
> - rc = libxl__domain_save_device_model(gc, domid, dss->fd);
> - if (rc) goto out;
> + libxl__domain_save_device_model(egc, dss, domain_suspend_done);
> + return;
> }
>
> rc = 0;
> @@ -1132,14 +1147,22 @@ out:
> domain_suspend_done(egc, dss, rc);
> }
>
> -int libxl__domain_save_device_model(libxl__gc *gc, uint32_t domid, int fd)
> +void libxl__domain_save_device_model(libxl__egc *egc,
> + libxl__domain_suspend_state *dss,
> + libxl__save_device_model_cb *callback)
> {
> + STATE_AO_GC(dss->ao);
> int rc, fd2 = -1, c;
> char buf[1024];
> - const char *filename = libxl__device_model_savefile(gc, domid);
> struct stat st;
> uint32_t qemu_state_len;
>
> + dss->save_dm_callback = callback;
> +
> + /* Convenience aliases */
> + const char *const filename = dss->dm_savefile;
> + const int fd = dss->fd;
> +
> if (stat(filename, &st) < 0)
> {
> LOG(ERROR, "Unable to stat qemu save file\n");
> @@ -1181,7 +1204,8 @@ int libxl__domain_save_device_model(libxl__gc *gc,
> uint32_t domid, int fd)
> out:
> if (fd2 >= 0) close(fd2);
> unlink(filename);
> - return rc;
> +
> + dss->save_dm_callback(egc, dss, rc);
> }
>
> static void domain_suspend_done(libxl__egc *egc,
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index 7e0ab11..c7fe9e9 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -824,10 +824,8 @@ _hidden int libxl__domain_rename(libxl__gc *gc, uint32_t
> domid,
>
> _hidden int libxl__toolstack_restore(uint32_t domid, const uint8_t *buf,
> uint32_t size, void *data);
> -_hidden const char *libxl__device_model_savefile(libxl__gc *gc, uint32_t
> domid);
> -_hidden int libxl__domain_suspend_device_model(libxl__gc *gc, uint32_t
> domid);
> _hidden int libxl__domain_resume_device_model(libxl__gc *gc, uint32_t domid);
> -_hidden int libxl__domain_save_device_model(libxl__gc *gc, uint32_t domid,
> int fd);
> +
> _hidden void libxl__userdata_destroyall(libxl__gc *gc, uint32_t domid);
>
> _hidden int libxl__domain_pvcontrol_available(libxl__gc *gc, uint32_t domid);
> @@ -1869,6 +1867,8 @@ typedef struct libxl__domain_suspend_state
> libxl__domain_suspend_state;
>
> typedef void libxl__domain_suspend_cb(libxl__egc*,
> libxl__domain_suspend_state*, int rc);
> +typedef void libxl__save_device_model_cb(libxl__egc*,
> + libxl__domain_suspend_state*, int
> rc);
>
> typedef struct libxl__logdirty_switch {
> const char *cmd;
> @@ -1895,9 +1895,12 @@ struct libxl__domain_suspend_state {
> int hvm;
> int xcflags;
> int guest_responded;
> + const char *dm_savefile;
> int interval; /* checkpoint interval (for Remus) */
> libxl__save_helper_state shs;
> libxl__logdirty_switch logdirty;
> + /* private for libxl__domain_save_device_model */
> + libxl__save_device_model_cb *save_dm_callback;
> };
>
>
> @@ -2053,6 +2056,15 @@ _hidden void libxl__xc_domain_restore(libxl__egc *egc,
> _hidden void libxl__xc_domain_restore_done(libxl__egc *egc, void *dcs_void,
> int rc, int retval, int errnoval);
>
> +/* 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);
> +_hidden void libxl__domain_save_device_model(libxl__egc *egc,
> + libxl__domain_suspend_state *dss,
> + libxl__save_device_model_cb *callback);
> +
> +_hidden const char *libxl__device_model_savefile(libxl__gc *gc, uint32_t
> domid);
> +
>
> /*
> * Convenience macros.
> diff --git a/tools/libxl/libxl_save_msgs_gen.pl
> b/tools/libxl/libxl_save_msgs_gen.pl
> index 8832c46..3ac6f80 100755
> --- a/tools/libxl/libxl_save_msgs_gen.pl
> +++ b/tools/libxl/libxl_save_msgs_gen.pl
> @@ -25,7 +25,7 @@ our @msgs = (
> 'unsigned long', 'total'] ],
> [ 3, 'scxW', "suspend", [] ],
> [ 4, 'scxW', "postcopy", [] ],
> - [ 5, 'scxW', "checkpoint", [] ],
> + [ 5, 'scxA', "checkpoint", [] ],
> [ 6, 'scxA', "switch_qemu_logdirty", [qw(int domid
> unsigned enable)] ],
> # toolstack_save done entirely `by hand'
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |