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