[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] tools: set migration constraints from cmdline
On Mon, 2013-01-28 at 17:32 +0000, Olaf Hering wrote: > # HG changeset patch > # User Olaf Hering <olaf@xxxxxxxxx> > # Date 1359394320 -3600 > # Node ID 577b051fca174be9f7b3d6590c62735cdf214021 > # Parent 6727070b4129cf852199b66b6a81042ee6966a98 > tools: set migration constraints from cmdline > > Add new options to xm/xl migrate to control the process of migration. > The intention is to optionally abort the migration if it takes too long > to migrate a busy guest due to the high number of dirty pages. Currently > the guest is suspended to transfer the remaining dirty pages. This > transfer can take too long, which can confuse the guest if its suspended > for too long. > > -M <number> Number of iterations before final suspend (default: 30) > --max_iters <number> > > -m <factor> Max amount of memory to transfer before final suspend (default: > 3*RAM) > --max_factor <factor> > > -N Abort migration instead of doing final suspend. > --no_suspend > > > A variant of this change has been tested with xend, the patch below is > only compile tested. The changes to libxl change the API, is that > approach acceptable? I'm afraid not, the compatibility requirements are covered in the comment near the top of libxl.h. So you either need a new function or to leverage the LIBXL_API_VERSION define (which the user must supply) such that people providing 0x040200 see the current interface and people providing 0x040300 (or nothing) see the new one. > > Signed-off-by: Olaf Hering <olaf@xxxxxxxxx> > > diff -r 6727070b4129 -r 577b051fca17 tools/libxc/xc_domain_save.c > --- a/tools/libxc/xc_domain_save.c > +++ b/tools/libxc/xc_domain_save.c > @@ -43,6 +43,8 @@ > */ > #define DEF_MAX_ITERS 29 /* limit us to 30 times round loop */ > #define DEF_MAX_FACTOR 3 /* never send more than 3x p2m_size */ > +/* Suspend guest for final transit once number of dirty pages is that low */ > +#define DEF_MIN_REMAINING 50 > > struct save_ctx { > unsigned long hvirt_start; /* virtual starting address of the hypervisor > */ > @@ -804,9 +806,11 @@ int xc_domain_save(xc_interface *xch, in > int rc = 1, frc, i, j, last_iter = 0, iter = 0; > int live = (flags & XCFLAGS_LIVE); > int debug = (flags & XCFLAGS_DEBUG); > + int nosuspend = (flags & XCFLAGS_DOMSAVE_NOSUSPEND); > int superpages = !!hvm; > int race = 0, sent_last_iter, skip_this_iter = 0; > unsigned int sent_this_iter = 0; > + int min_reached; > int tmem_saved = 0; > > /* The new domain's shared-info frame number. */ > @@ -1525,10 +1529,20 @@ int xc_domain_save(xc_interface *xch, in > > if ( live ) > { > + min_reached = sent_this_iter + skip_this_iter < > DEF_MIN_REMAINING; > if ( (iter >= max_iters) || > - (sent_this_iter+skip_this_iter < 50) || > + min_reached || > (total_sent > dinfo->p2m_size*max_factor) ) > { > + if ( min_reached && nosuspend ) > + { > + ERROR("Live migration aborted, as requested. (guest too > busy?)" > + " total_sent %lu iter %d, max_iters %u max_factor %u", > + total_sent, iter, max_iters, max_factor); > + rc = 1; > + goto out; > + } > + > DPRINTF("Start last iteration\n"); > last_iter = 1; > > diff -r 6727070b4129 -r 577b051fca17 tools/libxc/xenguest.h > --- a/tools/libxc/xenguest.h > +++ b/tools/libxc/xenguest.h > @@ -28,6 +28,8 @@ > #define XCFLAGS_HVM 4 > #define XCFLAGS_STDVGA 8 > #define XCFLAGS_CHECKPOINT_COMPRESS 16 > +#define XCFLAGS_DOMSAVE_NOSUSPEND 32 > + > #define X86_64_B_SIZE 64 > #define X86_32_B_SIZE 32 > > diff -r 6727070b4129 -r 577b051fca17 tools/libxl/libxl.c > --- a/tools/libxl/libxl.c > +++ b/tools/libxl/libxl.c > @@ -757,6 +757,7 @@ static void domain_suspend_cb(libxl__egc > } > > int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags, > + int max_iters, int max_factor, > const libxl_asyncop_how *ao_how) > { > AO_CREATE(ctx, domid, ao_how); > @@ -779,6 +780,9 @@ int libxl_domain_suspend(libxl_ctx *ctx, > dss->type = type; > dss->live = flags & LIBXL_SUSPEND_LIVE; > dss->debug = flags & LIBXL_SUSPEND_DEBUG; > + dss->max_iters = max_iters; > + dss->max_factor = max_factor; > + dss->xlflags = flags; > > libxl__domain_suspend(egc, dss); > return AO_INPROGRESS; > diff -r 6727070b4129 -r 577b051fca17 tools/libxl/libxl.h > --- a/tools/libxl/libxl.h > +++ b/tools/libxl/libxl.h > @@ -502,10 +502,12 @@ void libxl_domain_config_dispose(libxl_d > > int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, > int flags, /* LIBXL_SUSPEND_* */ > + int max_iters, int max_factor, > const libxl_asyncop_how *ao_how) > LIBXL_EXTERNAL_CALLERS_ONLY; > #define LIBXL_SUSPEND_DEBUG 1 > #define LIBXL_SUSPEND_LIVE 2 > +#define LIBXL_SUSPEND_NO_FINAL_SUSPEND 4 > > /* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )] > * If this parameter is true, use co-operative resume. The guest > diff -r 6727070b4129 -r 577b051fca17 tools/libxl/libxl_dom.c > --- a/tools/libxl/libxl_dom.c > +++ b/tools/libxl/libxl_dom.c > @@ -1240,6 +1240,7 @@ void libxl__domain_suspend(libxl__egc *e > > dss->xcflags = (live) ? XCFLAGS_LIVE : 0 > | (debug) ? XCFLAGS_DEBUG : 0 > + | (dss->xlflags & LIBXL_SUSPEND_NO_FINAL_SUSPEND) ? > XCFLAGS_DOMSAVE_NOSUSPEND : 0 > | (dss->hvm) ? XCFLAGS_HVM : 0; > > dss->suspend_eventchn = -1; > diff -r 6727070b4129 -r 577b051fca17 tools/libxl/libxl_internal.h > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h > @@ -2253,6 +2253,9 @@ struct libxl__domain_suspend_state { > xc_evtchn *xce; /* event channel handle */ > int suspend_eventchn; > int hvm; > + int max_iters; > + int max_factor; > + int xlflags; > int xcflags; > int guest_responded; > const char *dm_savefile; > diff -r 6727070b4129 -r 577b051fca17 tools/libxl/xl_cmdimpl.c > --- a/tools/libxl/xl_cmdimpl.c > +++ b/tools/libxl/xl_cmdimpl.c > @@ -3172,7 +3172,7 @@ static int save_domain(uint32_t domid, c > > save_domain_core_writeconfig(fd, filename, config_data, config_len); > > - int rc = libxl_domain_suspend(ctx, domid, fd, 0, NULL); > + int rc = libxl_domain_suspend(ctx, domid, fd, 0, 0, 0, NULL); > close(fd); > > if (rc < 0) > @@ -3332,6 +3332,8 @@ static void migrate_do_preamble(int send > } > > static void migrate_domain(uint32_t domid, const char *rune, > + int max_iters, int max_factor, > + int no_suspend, > const char *override_config_file) > { > pid_t child = -1; > @@ -3341,6 +3343,7 @@ static void migrate_domain(uint32_t domi > char rc_buf; > uint8_t *config_data; > int config_len; > + int flags = LIBXL_SUSPEND_LIVE; > > save_domain_core_begin(domid, override_config_file, > &config_data, &config_len); > @@ -3358,7 +3361,10 @@ static void migrate_domain(uint32_t domi > > xtl_stdiostream_adjust_flags(logger, XTL_STDIOSTREAM_HIDE_PROGRESS, 0); > > - rc = libxl_domain_suspend(ctx, domid, send_fd, LIBXL_SUSPEND_LIVE, NULL); > + if (no_suspend) > + flags |= LIBXL_SUSPEND_NO_FINAL_SUSPEND; > + > + rc = libxl_domain_suspend(ctx, domid, send_fd, flags, max_iters, > max_factor, NULL); > if (rc) { > fprintf(stderr, "migration sender: libxl_domain_suspend failed" > " (rc=%d)\n", rc); > @@ -3751,8 +3757,9 @@ int main_migrate(int argc, char **argv) > char *rune = NULL; > char *host; > int opt, daemonize = 1, monitor = 1, debug = 0; > - > - SWITCH_FOREACH_OPT(opt, "FC:s:ed", NULL, "migrate", 2) { > + int max_iters = 0, max_factor = 0, no_suspend = 0; > + > + SWITCH_FOREACH_OPT(opt, "FC:s:edM:m:N", NULL, "migrate", 2) { > case 'C': > config_filename = optarg; > break; > @@ -3769,6 +3776,15 @@ int main_migrate(int argc, char **argv) > case 'd': > debug = 1; > break; > + case 'M': > + max_iters = atoi(optarg); > + break; > + case 'm': > + max_factor = atoi(optarg); > + break; > + case 'N': > + no_suspend = 1; > + break; > } > > domid = find_domain(argv[optind]); > @@ -3784,7 +3800,7 @@ int main_migrate(int argc, char **argv) > return 1; > } > > - migrate_domain(domid, rune, config_filename); > + migrate_domain(domid, rune, max_iters, max_factor, no_suspend, > config_filename); > return 0; > } > > diff -r 6727070b4129 -r 577b051fca17 tools/libxl/xl_cmdtable.c > --- a/tools/libxl/xl_cmdtable.c > +++ b/tools/libxl/xl_cmdtable.c > @@ -152,6 +152,9 @@ struct cmd_spec cmd_table[] = { > "-s <sshcommand> Use <sshcommand> instead of ssh. String will be > passed\n" > " to sh. If empty, run <host> instead of ssh <host> > xl\n" > " migrate-receive [-d -e]\n" > + "-M --max_iters <number> Number of iterations before final suspend > (default: 30)\n" > + "-m --max_factor <factor> Max amount of memory to transfer before > final suspend (default: 3*RAM).\n" > + "-N --no_suspend Abort migration instead of doing final suspend.\n" > "-e Do not wait in the background (on <host>) for the > death\n" > " of the domain." > }, > diff -r 6727070b4129 -r 577b051fca17 tools/python/xen/xend/XendCheckpoint.py > --- a/tools/python/xen/xend/XendCheckpoint.py > +++ b/tools/python/xen/xend/XendCheckpoint.py > @@ -118,9 +118,19 @@ def save(fd, dominfo, network, live, dst > # enabled. Passing "0" simply uses the defaults compiled into > # libxenguest; see the comments and/or code in xc_linux_save() for > # more information. > + max_iters = dominfo.info.get('max_iters', "0") > + max_factor = dominfo.info.get('max_factor', "0") > + no_suspend = dominfo.info.get('no_suspend', None) > + if max_iters == "None": > + max_iters = "0" > + if max_factor == "None": > + max_factor = "0" > + if no_suspend == "None": > + no_suspend = "0" > cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd), > - str(dominfo.getDomid()), "0", "0", > - str(int(live) | (int(hvm) << 2)) ] > + str(dominfo.getDomid()), > + max_iters, max_factor, > + str(int(live) | (int(hvm) << 2) | (int(no_suspend) << 5) ] > log.debug("[xc_save]: %s", string.join(cmd)) > > def saveInputHandler(line, tochild): > diff -r 6727070b4129 -r 577b051fca17 tools/python/xen/xend/XendDomain.py > --- a/tools/python/xen/xend/XendDomain.py > +++ b/tools/python/xen/xend/XendDomain.py > @@ -1832,6 +1832,18 @@ class XendDomain: > log.exception(ex) > raise XendError(str(ex)) > > + def domain_migrate_constraints_set((self, domid, max_iters, max_factor, > no_suspend): > + """Set the Migrate Constraints of this domain. > + @param domid: Domain ID or Name > + @param max_iters: Number of iterations before final suspend > + @param max_factor: Max amount of memory to transfer before final > suspend > + @param no_suspend: Abort migration instead of doing final suspend > + """ > + dominfo = self.domain_lookup_nr(domid) > + if not dominfo: > + raise XendInvalidDomain(str(domid)) > + dominfo.setMigrateConstraints(max_iters, max_factor, no_suspend) > + > def domain_maxmem_set(self, domid, mem): > """Set the memory limit for a domain. > > diff -r 6727070b4129 -r 577b051fca17 tools/python/xen/xend/XendDomainInfo.py > --- a/tools/python/xen/xend/XendDomainInfo.py > +++ b/tools/python/xen/xend/XendDomainInfo.py > @@ -1459,6 +1459,18 @@ class XendDomainInfo: > pci_conf = self.info['devices'][dev_uuid][1] > return map(pci_dict_to_bdf_str, pci_conf['devs']) > > + def setMigrateConstraints(self, max_iters, max_factor, no_suspend): > + """Set the Migrate Constraints of this domain. > + @param max_iters: Number of iterations before final suspend > + @param max_factor: Max amount of memory to transfer before final > suspend > + @param no_suspend: Abort migration instead of doing final suspend > + """ > + log.debug("Setting setMigrateConstraints of domain %s (%s) to '%s' > '%s' '%s'.", > + self.info['name_label'], str(self.domid), max_iters, > max_factor, no_suspend) > + self.info['max_iters'] = str(max_iters) > + self.info['max_factor'] = str(max_factor) > + self.info['no_suspend'] = str(no_suspend) > + > def setMemoryTarget(self, target): > """Set the memory target of this domain. > @param target: In MiB. > diff -r 6727070b4129 -r 577b051fca17 tools/python/xen/xm/migrate.py > --- a/tools/python/xen/xm/migrate.py > +++ b/tools/python/xen/xm/migrate.py > @@ -55,6 +55,18 @@ gopts.opt('change_home_server', short='c > fn=set_true, default=0, > use="Change home server for managed domains.") > > +gopts.opt('max_iters', short='M', val='max_iters', > + fn=set_int, default=None, > + use="Number of iterations before final suspend (default: 30).") > + > +gopts.opt('max_factor', short='m', val='max_factor', > + fn=set_int, default=None, > + use="Max amount of memory to transfer before final suspend > (default: 3*RAM).") > + > +gopts.opt('no_suspend', short='S', > + fn=set_true, default=None, > + use="Abort migration instead of doing final suspend.") > + > def help(): > return str(gopts) > > @@ -80,6 +92,10 @@ def main(argv): > server.xenapi.VM.migrate(vm_ref, dst, bool(opts.vals.live), > other_config) > else: > + server.xend.domain.migrate_constraints_set(dom, > + opts.vals.max_iters, > + opts.vals.max_factor, > + opts.vals.no_suspend) > server.xend.domain.migrate(dom, dst, opts.vals.live, > opts.vals.port, > opts.vals.node, > > _______________________________________________ > 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 |