[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 |