[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.