[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 05/21] libxl: domain save: API changes for asynchrony
> @@ -648,32 +648,51 @@ libxl_vminfo * libxl_list_vm(libxl_ctx *ctx, int *nb_vm) > return ptr; > } > > +static void remus_crashed_cb(libxl__egc *egc, > + libxl__domain_suspend_state *dss, int rc); I think you were going to rename this remus_failover_cb but nevertheless: Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Were you going to ping Shriram to test remus with this series applied? > + > /* TODO: Explicit Checkpoint acknowledgements via recv_fd. */ > int libxl_domain_remus_start(libxl_ctx *ctx, libxl_domain_remus_info *info, > - uint32_t domid, int send_fd, int recv_fd) > + uint32_t domid, int send_fd, int recv_fd, > + const libxl_asyncop_how *ao_how) > { > - GC_INIT(ctx); > - libxl_domain_type type = libxl__domain_type(gc, domid); > - int rc = 0; > + AO_CREATE(ctx, domid, ao_how); > + libxl__domain_suspend_state *dss; > + int rc; > > + libxl_domain_type type = libxl__domain_type(gc, domid); > if (type == LIBXL_DOMAIN_TYPE_INVALID) { > rc = ERROR_FAIL; > - goto remus_fail; > + goto out; > } > > - if (info == NULL) { > - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, > - "No remus_info structure supplied for domain %d", domid); > - rc = ERROR_INVAL; > - goto remus_fail; > - } > + GCNEW(dss); > + dss->ao = ao; > + dss->callback = remus_crashed_cb; > + dss->domid = domid; > + dss->fd = send_fd; > + /* TODO do something with recv_fd */ > + dss->type = type; > + dss->live = 1; > + dss->debug = 0; > + dss->remus = info; > + > + assert(info); > > /* TBD: Remus setup - i.e. attach qdisc, enable disk buffering, etc */ > > /* Point of no return */ > - rc = libxl__domain_suspend_common(gc, domid, send_fd, type, /* live */ 1, > - /* debug */ 0, info); > + libxl__domain_suspend(egc, dss); > + return AO_INPROGRESS; > + > + out: > + return AO_ABORT(rc); > +} > > +static void remus_crashed_cb(libxl__egc *egc, > + libxl__domain_suspend_state *dss, int rc) > +{ > + STATE_AO_GC(dss->ao); > /* > * With Remus, if we reach this point, it means either > * backup died or some network error occurred preventing us > @@ -683,27 +702,46 @@ int libxl_domain_remus_start(libxl_ctx *ctx, > libxl_domain_remus_info *info, > /* TBD: Remus cleanup - i.e. detach qdisc, release other > * resources. > */ > - remus_fail: > - GC_FREE; > - return rc; > + libxl__ao_complete(egc, ao, rc); > } > > -int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info, > - uint32_t domid, int fd) > +static void domain_suspend_cb(libxl__egc *egc, > + libxl__domain_suspend_state *dss, int rc) > { > - GC_INIT(ctx); > + STATE_AO_GC(dss->ao); > + libxl__ao_complete(egc,ao,rc); > + > +} > + > +int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags, > + const libxl_asyncop_how *ao_how) > +{ > + AO_CREATE(ctx, domid, ao_how); > + int rc; > + > libxl_domain_type type = libxl__domain_type(gc, domid); > - int live = info != NULL && info->flags & XL_SUSPEND_LIVE; > - int debug = info != NULL && info->flags & XL_SUSPEND_DEBUG; > - int rc = 0; > + if (type == LIBXL_DOMAIN_TYPE_INVALID) { > + rc = ERROR_FAIL; > + goto out_err; > + } > > - rc = libxl__domain_suspend_common(gc, domid, fd, type, live, debug, > - /* No Remus */ NULL); > + libxl__domain_suspend_state *dss; > + GCNEW(dss); > > - if (!rc && type == LIBXL_DOMAIN_TYPE_HVM) > - rc = libxl__domain_save_device_model(gc, domid, fd); > - GC_FREE; > - return rc; > + dss->ao = ao; > + dss->callback = domain_suspend_cb; > + > + dss->domid = domid; > + dss->fd = fd; > + dss->type = type; > + dss->live = flags & LIBXL_SUSPEND_LIVE; > + dss->debug = flags & LIBXL_SUSPEND_DEBUG; > + > + libxl__domain_suspend(egc, dss); > + return AO_INPROGRESS; > + > + out_err: > + return AO_ABORT(rc); > } > > int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid) > diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h > index 05f0e01..10d7115 100644 > --- a/tools/libxl/libxl.h > +++ b/tools/libxl/libxl.h > @@ -347,13 +347,6 @@ typedef struct libxl__ctx libxl_ctx; > > const libxl_version_info* libxl_get_version_info(libxl_ctx *ctx); > > -typedef struct { > -#define XL_SUSPEND_DEBUG 1 > -#define XL_SUSPEND_LIVE 2 > - int flags; > - int (*suspend_callback)(void *, int); > -} libxl_domain_suspend_info; > - > enum { > ERROR_NONSPECIFIC = -1, > ERROR_VERSION = -2, > @@ -514,16 +507,23 @@ int libxl_domain_create_restore(libxl_ctx *ctx, > libxl_domain_config *d_config, > > void libxl_domain_config_init(libxl_domain_config *d_config); > void libxl_domain_config_dispose(libxl_domain_config *d_config); > -int libxl_domain_remus_start(libxl_ctx *ctx, libxl_domain_remus_info *info, > - uint32_t domid, int send_fd, int recv_fd); > -int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info, > - uint32_t domid, int fd); > + > +int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, > + int flags, /* LIBXL_SUSPEND_* */ > + const libxl_asyncop_how *ao_how); > +#define LIBXL_SUSPEND_DEBUG 1 > +#define LIBXL_SUSPEND_LIVE 2 > > /* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )] > * If this parameter is true, use co-operative resume. The guest > * must support this. > */ > int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid, int suspend_cancel); > + > +int libxl_domain_remus_start(libxl_ctx *ctx, libxl_domain_remus_info *info, > + uint32_t domid, int send_fd, int recv_fd, > + const libxl_asyncop_how *ao_how); > + > int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid); > int libxl_domain_reboot(libxl_ctx *ctx, uint32_t domid); > int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid); > diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c > index 1d4e809..b48452c 100644 > --- a/tools/libxl/libxl_dom.c > +++ b/tools/libxl/libxl_dom.c > @@ -17,13 +17,11 @@ > > #include <glob.h> > > -#include <xenctrl.h> > -#include <xc_dom.h> > +#include "libxl_internal.h" > > +#include <xc_dom.h> > #include <xen/hvm/hvm_info_table.h> > > -#include "libxl_internal.h" > - > libxl_domain_type libxl__domain_type(libxl__gc *gc, uint32_t domid) > { > libxl_ctx *ctx = libxl__gc_owner(gc); > @@ -521,11 +519,18 @@ int libxl__toolstack_restore(uint32_t domid, const > uint8_t *buf, > return 0; > } > > -static int libxl__domain_suspend_common_switch_qemu_logdirty > +/*==================== Domain suspend (save) ====================*/ > + > +static void domain_suspend_done(libxl__egc *egc, > + libxl__domain_suspend_state *dss, int rc); > + > +/*----- callbacks, called by xc_domain_save -----*/ > + > +int libxl__domain_suspend_common_switch_qemu_logdirty > (int domid, unsigned int enable, void *data) > { > libxl__domain_suspend_state *dss = data; > - libxl__gc *gc = dss->gc; > + STATE_AO_GC(dss->ao); > char *path; > bool rc; > > @@ -590,10 +595,10 @@ int libxl__domain_resume_device_model(libxl__gc *gc, > uint32_t domid) > return 0; > } > > -static int libxl__domain_suspend_common_callback(void *data) > +int libxl__domain_suspend_common_callback(void *data) > { > libxl__domain_suspend_state *dss = data; > - libxl__gc *gc = dss->gc; > + STATE_AO_GC(dss->ao); > unsigned long hvm_s_state = 0, hvm_pvdrv = 0; > int ret; > char *state = "suspend"; > @@ -714,7 +719,7 @@ static int libxl__domain_suspend_common_callback(void > *data) > > guest_suspended: > if (dss->hvm) { > - ret = libxl__domain_suspend_device_model(dss->gc, dss->domid); > + ret = libxl__domain_suspend_device_model(gc, dss->domid); > if (ret) { > LOG(ERROR, "libxl__domain_suspend_device_model failed ret=%d", > ret); > return 0; > @@ -731,11 +736,11 @@ static inline char *save_helper(libxl__gc *gc, uint32_t > domid, > domid, phys_offset, node); > } > > -static int libxl__toolstack_save(uint32_t domid, uint8_t **buf, > +int libxl__toolstack_save(uint32_t domid, uint8_t **buf, > uint32_t *len, void *data) > { > libxl__domain_suspend_state *dss = data; > - libxl__gc *gc = dss->gc; > + STATE_AO_GC(dss->ao); > int i = 0; > char *start_addr = NULL, *size = NULL, *phys_offset = NULL, *name = NULL; > unsigned int num = 0; > @@ -806,6 +811,8 @@ static int libxl__toolstack_save(uint32_t domid, uint8_t > **buf, > return 0; > } > > +/*----- remus callbacks -----*/ > + > static int libxl__remus_domain_suspend_callback(void *data) > { > /* TODO: Issue disk and network checkpoint reqs. */ > @@ -815,7 +822,7 @@ static int libxl__remus_domain_suspend_callback(void > *data) > static int libxl__remus_domain_resume_callback(void *data) > { > libxl__domain_suspend_state *dss = data; > - libxl__gc *gc = dss->gc; > + STATE_AO_GC(dss->ao); > > /* Resumes the domain and the device model */ > if (libxl_domain_resume(CTX, dss->domid, /* Fast Suspend */1)) > @@ -828,10 +835,11 @@ static int libxl__remus_domain_resume_callback(void > *data) > static int libxl__remus_domain_checkpoint_callback(void *data) > { > libxl__domain_suspend_state *dss = data; > + STATE_AO_GC(dss->ao); > > /* This would go into tailbuf. */ > if (dss->hvm && > - libxl__domain_save_device_model(dss->gc, dss->domid, dss->save_fd)) > + libxl__domain_save_device_model(gc, dss->domid, dss->fd)) > return 0; > > /* TODO: Wait for disk and memory ack, release network buffer */ > @@ -839,17 +847,23 @@ static int libxl__remus_domain_checkpoint_callback(void > *data) > return 1; > } > > -int libxl__domain_suspend_common(libxl__gc *gc, uint32_t domid, int fd, > - libxl_domain_type type, > - int live, int debug, > - const libxl_domain_remus_info *r_info) > +/*----- main code for suspending, in order of execution -----*/ > + > +void libxl__domain_suspend(libxl__egc *egc, libxl__domain_suspend_state *dss) > { > + STATE_AO_GC(dss->ao); > int port; > - struct save_callbacks callbacks[1]; > - libxl__domain_suspend_state dss[1]; > int rc = ERROR_FAIL; > unsigned long vm_generationid_addr; > > + /* Convenience aliases */ > + const uint32_t domid = dss->domid; > + const libxl_domain_type type = dss->type; > + const int live = dss->live; > + const int debug = dss->debug; > + const libxl_domain_remus_info *const r_info = dss->remus; > + struct save_callbacks *const callbacks = &dss->callbacks; > + > switch (type) { > case LIBXL_DOMAIN_TYPE_HVM: { > char *path; > @@ -868,15 +882,13 @@ int libxl__domain_suspend_common(libxl__gc *gc, > uint32_t domid, int fd, > dss->hvm = 0; > break; > default: > - return ERROR_INVAL; > + abort(); > } > > dss->xcflags = (live) ? XCFLAGS_LIVE : 0 > | (debug) ? XCFLAGS_DEBUG : 0 > | (dss->hvm) ? XCFLAGS_HVM : 0; > > - dss->domid = domid; > - dss->gc = gc; > dss->suspend_eventchn = -1; > dss->guest_responded = 0; > > @@ -884,10 +896,7 @@ int libxl__domain_suspend_common(libxl__gc *gc, uint32_t > domid, int fd, > dss->interval = r_info->interval; > if (r_info->compression) > dss->xcflags |= XCFLAGS_CHECKPOINT_COMPRESS; > - dss->save_fd = fd; > } > - else > - dss->save_fd = -1; > > dss->xce = xc_evtchn_open(NULL, 0); > if (dss->xce == NULL) > @@ -917,10 +926,28 @@ int libxl__domain_suspend_common(libxl__gc *gc, > uint32_t domid, int fd, > callbacks->toolstack_save = libxl__toolstack_save; > callbacks->data = dss; > > - rc = xc_domain_save(CTX->xch, fd, domid, 0, 0, dss->xcflags, callbacks, > - dss->hvm, vm_generationid_addr); > - if ( rc ) { > - LOGE(ERROR, "saving domain: %s", > + libxl__xc_domain_save(egc, dss, vm_generationid_addr); > + return; > + > + out: > + domain_suspend_done(egc, dss, rc); > +} > + > +void libxl__xc_domain_save_done(libxl__egc *egc, > + libxl__domain_suspend_state *dss, > + int rc, int retval, int errnoval) > +{ > + STATE_AO_GC(dss->ao); > + > + /* Convenience aliases */ > + const libxl_domain_type type = dss->type; > + const uint32_t domid = dss->domid; > + > + if (rc) > + goto out; > + > + if (retval) { > + LOGEV(ERROR, errnoval, "saving domain: %s", > dss->guest_responded ? > "domain responded to suspend request" : > "domain did not respond to suspend request"); > @@ -928,16 +955,21 @@ int libxl__domain_suspend_common(libxl__gc *gc, > uint32_t domid, int fd, > rc = ERROR_GUEST_TIMEDOUT; > else > rc = ERROR_FAIL; > + goto out; > } > > - if (dss->suspend_eventchn > 0) > - xc_suspend_evtchn_release(CTX->xch, dss->xce, domid, > - dss->suspend_eventchn); > - if (dss->xce != NULL) > - xc_evtchn_close(dss->xce); > + if (type == LIBXL_DOMAIN_TYPE_HVM) { > + rc = libxl__domain_suspend_device_model(gc, domid); > + if (rc) goto out; > + > + rc = libxl__domain_save_device_model(gc, domid, dss->fd); > + if (rc) goto out; > + } > + > + rc = 0; > > out: > - return rc; > + domain_suspend_done(egc, dss, rc); > } > > int libxl__domain_save_device_model(libxl__gc *gc, uint32_t domid, int fd) > @@ -992,6 +1024,25 @@ out: > return rc; > } > > +static void domain_suspend_done(libxl__egc *egc, > + libxl__domain_suspend_state *dss, int rc) > +{ > + STATE_AO_GC(dss->ao); > + > + /* Convenience aliases */ > + const uint32_t domid = dss->domid; > + > + if (dss->suspend_eventchn > 0) > + xc_suspend_evtchn_release(CTX->xch, dss->xce, domid, > + dss->suspend_eventchn); > + if (dss->xce != NULL) > + xc_evtchn_close(dss->xce); > + > + dss->callback(egc, dss, rc); > +} > + > +/*==================== Miscellaneous ====================*/ > + > char *libxl__uuid2string(libxl__gc *gc, const libxl_uuid uuid) > { > char *s = libxl__sprintf(gc, LIBXL_UUID_FMT, LIBXL_UUID_BYTES(uuid)); > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > index 28478ea..7cf1b04 100644 > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h > @@ -1777,16 +1777,28 @@ _hidden int > libxl__datacopier_start(libxl__datacopier_state *dc); > > typedef struct libxl__domain_suspend_state libxl__domain_suspend_state; > > +typedef void libxl__domain_suspend_cb(libxl__egc*, > + libxl__domain_suspend_state*, int rc); > + > struct libxl__domain_suspend_state { > - libxl__gc *gc; > + /* set by caller of libxl__domain_suspend */ > + libxl__ao *ao; > + libxl__domain_suspend_cb *callback; > + > + uint32_t domid; > + int fd; > + libxl_domain_type type; > + int live; > + int debug; > + const libxl_domain_remus_info *remus; > + /* private */ > xc_evtchn *xce; /* event channel handle */ > int suspend_eventchn; > - int domid; > int hvm; > - unsigned int xcflags; > + int xcflags; > int guest_responded; > - int save_fd; /* Migration stream fd (for Remus) */ > int interval; /* checkpoint interval (for Remus) */ > + struct save_callbacks callbacks; > }; > > > @@ -1903,10 +1915,27 @@ struct libxl__domain_create_state { > > /*----- Domain suspend (save) functions -----*/ > > -_hidden int libxl__domain_suspend_common(libxl__gc *gc, uint32_t domid, int > fd, > - libxl_domain_type type, > - int live, int debug, > - const libxl_domain_remus_info > *r_info); > +/* calls dss->callback when done */ > +_hidden void libxl__domain_suspend(libxl__egc *egc, > + libxl__domain_suspend_state *dss); > + > + > +/* calls libxl__xc_domain_suspend_done when done */ > +_hidden void libxl__xc_domain_save(libxl__egc*, libxl__domain_suspend_state*, > + unsigned long vm_generationid_addr); > +/* 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. */ > +_hidden void libxl__xc_domain_save_done(libxl__egc*, > + libxl__domain_suspend_state*, > + int rc, int retval, int errnoval); > + > +_hidden int libxl__domain_suspend_common_callback(void *data); > +_hidden int libxl__domain_suspend_common_switch_qemu_logdirty > + (int domid, unsigned int enable, void *data); > +_hidden int libxl__toolstack_save(uint32_t domid, uint8_t **buf, > + uint32_t *len, void *data); > + > > /* calls libxl__xc_domain_restore_done when done */ > _hidden void libxl__xc_domain_restore(libxl__egc *egc, > diff --git a/tools/libxl/libxl_save_callout.c > b/tools/libxl/libxl_save_callout.c > index 2f8db9f..1b481ab 100644 > --- a/tools/libxl/libxl_save_callout.c > +++ b/tools/libxl/libxl_save_callout.c > @@ -35,3 +35,14 @@ void libxl__xc_domain_restore(libxl__egc *egc, > libxl__domain_create_state *dcs, > &state->vm_generationid_addr, &dcs->callbacks); > libxl__xc_domain_restore_done(egc, dcs, 0, r, errno); > } > + > +void libxl__xc_domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss, > + unsigned long vm_generationid_addr) > +{ > + STATE_AO_GC(dss->ao); > + int r; > + > + r = xc_domain_save(CTX->xch, dss->fd, dss->domid, 0, 0, dss->xcflags, > + &dss->callbacks, dss->hvm, vm_generationid_addr); > + libxl__xc_domain_save_done(egc, dss, 0, r, errno); > +} > diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c > index 3ea95ef..19daa1c 100644 > --- a/tools/libxl/xl_cmdimpl.c > +++ b/tools/libxl/xl_cmdimpl.c > @@ -2846,7 +2846,7 @@ static int save_domain(const char *p, const char > *filename, int checkpoint, > > save_domain_core_writeconfig(fd, filename, config_data, config_len); > > - CHK_ERRNO(libxl_domain_suspend(ctx, NULL, domid, fd)); > + CHK_ERRNO(libxl_domain_suspend(ctx, domid, fd, 0, NULL)); > close(fd); > > if (checkpoint) > @@ -3008,7 +3008,6 @@ static void migrate_domain(const char *domain_spec, > const char *rune, > pid_t child = -1; > int rc; > int send_fd = -1, recv_fd = -1; > - libxl_domain_suspend_info suspinfo; > char *away_domname; > char rc_buf; > uint8_t *config_data; > @@ -3030,9 +3029,7 @@ static void migrate_domain(const char *domain_spec, > const char *rune, > > xtl_stdiostream_adjust_flags(logger, XTL_STDIOSTREAM_HIDE_PROGRESS, 0); > > - memset(&suspinfo, 0, sizeof(suspinfo)); > - suspinfo.flags |= XL_SUSPEND_LIVE; > - rc = libxl_domain_suspend(ctx, &suspinfo, domid, send_fd); > + rc = libxl_domain_suspend(ctx, domid, send_fd, LIBXL_SUSPEND_LIVE, NULL); > if (rc) { > fprintf(stderr, "migration sender: libxl_domain_suspend failed" > " (rc=%d)\n", rc); > @@ -6604,7 +6601,7 @@ int main_remus(int argc, char **argv) > } > > /* Point of no return */ > - rc = libxl_domain_remus_start(ctx, &r_info, domid, send_fd, recv_fd); > + rc = libxl_domain_remus_start(ctx, &r_info, domid, send_fd, recv_fd, 0); > > /* If we are here, it means backup has failed/domain suspend failed. > * Try to resume the domain and exit gracefully. > -- > 1.7.2.5 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |