Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
xen.787
xend-set-migration-constraints-from-cmdline.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xend-set-migration-constraints-from-cmdline.patch of Package xen.787
From aa0cecb067ca6077c67cfc13f0ce31af7a3b72bb Mon Sep 17 00:00:00 2001 From: Olaf Hering <olaf@aepfle.de> Date: Mon, 10 Feb 2014 09:43:40 +0100 Subject: xend: set migration constraints from cmdline xend part of required libxl change to tweak parameters of xc_domain_save Add xm migrate --log_progress option. xc_domain_save does print progress messages. These verbose messages are disabled per default to avoid flood in xend.log. Sometimes it is helpful to see progress when migrating large and busy guests. So add a new option to xm migrate to actually enable the printing of progress messsages. Print messages from xc_save with xc_report. Make use of xc_report in xc_save to log also pid if some error occoured. Signed-off-by: Olaf Hering <olaf@aepfle.de> --- tools/libxc/xc_private.h | 1 + tools/libxc/xenguest.h | 1 + tools/python/xen/xend/XendCheckpoint.py | 22 +++++++++- tools/python/xen/xend/XendDomain.py | 14 ++++++ tools/python/xen/xend/XendDomainInfo.py | 16 +++++++ tools/python/xen/xm/migrate.py | 26 +++++++++++ tools/xcutils/xc_save.c | 76 +++++++++++++++++++++------------ 7 files changed, 127 insertions(+), 29 deletions(-) Index: xen-4.4.1-testing/tools/libxc/xc_private.h =================================================================== --- xen-4.4.1-testing.orig/tools/libxc/xc_private.h +++ xen-4.4.1-testing/tools/libxc/xc_private.h @@ -119,6 +119,7 @@ void xc_report_progress_step(xc_interfac /* anamorphic macros: struct xc_interface *xch must be in scope */ +#define WPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_WARN,0, _f , ## _a) #define IPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_INFO,0, _f , ## _a) #define DPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_DETAIL,0, _f , ## _a) #define DBGPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_DEBUG,0, _f , ## _a) Index: xen-4.4.1-testing/tools/libxc/xenguest.h =================================================================== --- xen-4.4.1-testing.orig/tools/libxc/xenguest.h +++ xen-4.4.1-testing/tools/libxc/xenguest.h @@ -29,6 +29,7 @@ #define XCFLAGS_STDVGA (1 << 3) #define XCFLAGS_CHECKPOINT_COMPRESS (1 << 4) #define XCFLAGS_DOMSAVE_ABORT_IF_BUSY (1 << 5) +#define XCFLAGS_PROGRESS (1 << 6) #define X86_64_B_SIZE 64 #define X86_32_B_SIZE 32 Index: xen-4.4.1-testing/tools/python/xen/xend/XendCheckpoint.py =================================================================== --- xen-4.4.1-testing.orig/tools/python/xen/xend/XendCheckpoint.py +++ xen-4.4.1-testing/tools/python/xen/xend/XendCheckpoint.py @@ -118,9 +118,27 @@ 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") + min_remaining = dominfo.info.get('min_remaining', "0") + abort_if_busy = dominfo.info.get('abort_if_busy', "0") + log_save_progress = dominfo.info.get('log_save_progress', "0") + if max_iters == "None": + max_iters = "0" + if max_factor == "None": + max_factor = "0" + if min_remaining == "None": + min_remaining = "0" + if abort_if_busy == "None": + abort_if_busy = "0" + if log_save_progress == "None": + log_save_progress = "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(abort_if_busy) << 5) | (int(log_save_progress) << 6) ), + min_remaining + ] log.debug("[xc_save]: %s", string.join(cmd)) def saveInputHandler(line, tochild): Index: xen-4.4.1-testing/tools/python/xen/xend/XendDomain.py =================================================================== --- xen-4.4.1-testing.orig/tools/python/xen/xend/XendDomain.py +++ xen-4.4.1-testing/tools/python/xen/xend/XendDomain.py @@ -1832,6 +1832,20 @@ class XendDomain: log.exception(ex) raise XendError(str(ex)) + def domain_migrate_constraints_set(self, domid, max_iters, max_factor, min_remaining, abort_if_busy, log_save_progress): + """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 min_remaining: Number of dirty pages before final suspend + @param abort_if_busy: Abort migration instead of doing final suspend + @param log_save_progress: Log progress of migrate to xend.log + """ + dominfo = self.domain_lookup_nr(domid) + if not dominfo: + raise XendInvalidDomain(str(domid)) + dominfo.setMigrateConstraints(max_iters, max_factor, min_remaining, abort_if_busy, log_save_progress) + def domain_maxmem_set(self, domid, mem): """Set the memory limit for a domain. Index: xen-4.4.1-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-4.4.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-4.4.1-testing/tools/python/xen/xend/XendDomainInfo.py @@ -1461,6 +1461,22 @@ 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, min_remaining, abort_if_busy, log_save_progress): + """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 min_remaining: Number of dirty pages before final suspend + @param abort_if_busy: Abort migration instead of doing final suspend + @param log_save_progress: Log progress of migrate to xend.log + """ + log.debug("Setting migration constraints of domain %s (%s) to '%s' '%s' '%s' '%s'.", + self.info['name_label'], str(self.domid), max_iters, max_factor, min_remaining, abort_if_busy) + self.info['max_iters'] = str(max_iters) + self.info['max_factor'] = str(max_factor) + self.info['min_remaining'] = str(min_remaining) + self.info['abort_if_busy'] = str(abort_if_busy) + self.info['log_save_progress'] = str(log_save_progress) + def setMemoryTarget(self, target): """Set the memory target of this domain. @param target: In MiB. Index: xen-4.4.1-testing/tools/python/xen/xm/migrate.py =================================================================== --- xen-4.4.1-testing.orig/tools/python/xen/xm/migrate.py +++ xen-4.4.1-testing/tools/python/xen/xm/migrate.py @@ -55,6 +55,26 @@ gopts.opt('change_home_server', short='c fn=set_true, default=0, use="Change home server for managed domains.") +gopts.opt('max_iters', val='max_iters', + fn=set_int, default=0, + use="Number of iterations before final suspend (default: 30).") + +gopts.opt('max_factor', val='max_factor', + fn=set_int, default=0, + use="Max amount of memory to transfer before final suspend (default: 3*RAM).") + +gopts.opt('min_remaining', val='min_remaining', + fn=set_int, default=0, + use="Number of dirty pages before final suspend (default: 50).") + +gopts.opt('abort_if_busy', + fn=set_true, default=0, + use="Abort migration instead of doing final suspend.") + +gopts.opt('log_progress', + fn=set_true, default=0, + use="Log progress of migration to xend.log") + def help(): return str(gopts) @@ -80,6 +100,12 @@ 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.min_remaining, + opts.vals.abort_if_busy, + opts.vals.log_progress) server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.port, opts.vals.node, Index: xen-4.4.1-testing/tools/xcutils/xc_save.c =================================================================== --- xen-4.4.1-testing.orig/tools/xcutils/xc_save.c +++ xen-4.4.1-testing/tools/xcutils/xc_save.c @@ -7,6 +7,7 @@ * */ +#include <unistd.h> #include <err.h> #include <stdlib.h> #include <stdint.h> @@ -19,6 +20,7 @@ #include <fcntl.h> #include <err.h> +#include <xc_private.h> #include <xenstore.h> #include <xenctrl.h> #include <xenguest.h> @@ -51,16 +53,17 @@ static int compat_suspend(void) * receive the acknowledgement from the subscribe event channel. */ static int evtchn_suspend(void) { + xc_interface *xch = si.xch; int rc; rc = xc_evtchn_notify(si.xce, si.suspend_evtchn); if (rc < 0) { - warnx("failed to notify suspend request channel: %d", rc); + WPRINTF("failed to notify suspend request channel: %d", rc); return 0; } - if (xc_await_suspend(si.xch, si.xce, si.suspend_evtchn) < 0) { - warnx("suspend failed"); + if (xc_await_suspend(xch, si.xce, si.suspend_evtchn) < 0) { + WPRINTF("suspend failed"); return 0; } @@ -104,20 +107,27 @@ static int suspend(void* data) static int switch_qemu_logdirty(int domid, unsigned int enable, void *data) { + xc_interface *xch = si.xch; struct xs_handle *xs; char *path, *p, *ret_str, *cmd_str, **watch; unsigned int len; struct timeval tv; fd_set fdset; - if ((xs = xs_daemon_open()) == NULL) - errx(1, "Couldn't contact xenstore"); - if (!(path = strdup("/local/domain/0/device-model/"))) - errx(1, "can't get domain path in store"); + if ((xs = xs_daemon_open()) == NULL) { + PERROR("Couldn't contact xenstore"); + exit(1); + } + if (!(path = strdup("/local/domain/0/device-model/"))) { + PERROR("can't get domain path in store"); + exit(1); + } if (!(path = realloc(path, strlen(path) + 10 - + strlen("/logdirty/cmd") + 1))) - errx(1, "no memory for constructing xenstore path"); + + strlen("/logdirty/cmd") + 1))) { + PERROR("no memory for constructing xenstore path"); + exit(1); + } snprintf(path + strlen(path), 11, "%i", domid); strcat(path, "/logdirty/"); p = path + strlen(path); @@ -126,16 +136,22 @@ static int switch_qemu_logdirty(int domi /* Watch for qemu's return value */ strcpy(p, "ret"); if (!xs_watch(xs, path, "qemu-logdirty-ret")) - errx(1, "can't set watch in store (%s)\n", path); + { + ERROR("can't set watch in store (%s)\n", path); + exit(1); + } - if (!(cmd_str = strdup( enable == 0 ? "disable" : "enable"))) - errx(1, "can't get logdirty cmd path in store"); + if (!(cmd_str = strdup( enable == 0 ? "disable" : "enable"))) { + PERROR("can't get logdirty cmd path in store"); + exit(1); + } /* Tell qemu that we want it to start logging dirty page to Xen */ strcpy(p, "cmd"); - if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str))) - errx(1, "can't write to store path (%s)\n", - path); + if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str))) { + PERROR("can't write to store path (%s)\n", path); + exit(1); + } /* Wait a while for qemu to signal that it has service logdirty command */ read_again: @@ -144,8 +160,10 @@ static int switch_qemu_logdirty(int domi FD_ZERO(&fdset); FD_SET(xs_fileno(xs), &fdset); - if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1) - errx(1, "timed out waiting for qemu logdirty response.\n"); + if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1) { + PERROR("timed out waiting for qemu logdirty response.\n"); + exit(1); + } watch = xs_read_watch(xs, &len); free(watch); @@ -166,53 +184,57 @@ static int switch_qemu_logdirty(int domi int main(int argc, char **argv) { - unsigned int maxit, max_f, lflags; + xc_interface *xch; + unsigned int maxit, max_f, lflags, min_r; int io_fd, ret, port; struct save_callbacks callbacks; xentoollog_level lvl; xentoollog_logger *l; - if (argc != 6) - errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]); + if (argc != 7) + errx(1, "usage: %s iofd domid maxit maxf flags minr", argv[0]); io_fd = atoi(argv[1]); si.domid = atoi(argv[2]); maxit = atoi(argv[3]); max_f = atoi(argv[4]); si.flags = atoi(argv[5]); + min_r = atoi(argv[6]); si.suspend_evtchn = -1; lvl = si.flags & XCFLAGS_DEBUG ? XTL_DEBUG: XTL_DETAIL; - lflags = XTL_STDIOSTREAM_SHOW_PID | XTL_STDIOSTREAM_HIDE_PROGRESS; + lflags = XTL_STDIOSTREAM_SHOW_PID; + if (si.flags & XCFLAGS_PROGRESS) + lflags |= XTL_STDIOSTREAM_HIDE_PROGRESS; l = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, lvl, lflags); - si.xch = xc_interface_open(l, 0, 0); + xch = si.xch = xc_interface_open(l, 0, 0); if (!si.xch) - errx(1, "failed to open control interface"); + errx(1, "[%lu] failed to open control interface", (unsigned long)getpid()); si.xce = xc_evtchn_open(NULL, 0); if (si.xce == NULL) - warnx("failed to open event channel handle"); + WPRINTF("failed to open event channel handle"); else { port = xs_suspend_evtchn_port(si.domid); if (port < 0) - warnx("failed to get the suspend evtchn port\n"); + WPRINTF("failed to get the suspend evtchn port\n"); else { si.suspend_evtchn = xc_suspend_evtchn_init(si.xch, si.xce, si.domid, port); if (si.suspend_evtchn < 0) - warnx("suspend event channel initialization failed, " + WPRINTF("suspend event channel initialization failed, " "using slow path"); } } memset(&callbacks, 0, sizeof(callbacks)); callbacks.suspend = suspend; callbacks.switch_qemu_logdirty = switch_qemu_logdirty; - ret = xc_domain_save(si.xch, io_fd, si.domid, maxit, max_f, si.flags, + ret = xc_domain_save_suse(si.xch, io_fd, si.domid, maxit, max_f, min_r, si.flags, &callbacks, !!(si.flags & XCFLAGS_HVM), 0); if (si.suspend_evtchn > 0) Index: xen-4.4.1-testing/tools/python/xen/xend/server/SrvDomain.py =================================================================== --- xen-4.4.1-testing.orig/tools/python/xen/xend/server/SrvDomain.py +++ xen-4.4.1-testing/tools/python/xen/xend/server/SrvDomain.py @@ -108,6 +108,17 @@ class SrvDomain(SrvDir): ['reset', 'int']]) return fn(req.args, {'dom': self.dom.domid}) + def op_migrate_constraints_set(self, _, req): + self.acceptCommand(req) + fn = FormFn(self.xd.domain_migrate_constraints_set, + [['dom', 'int'], + ['max_iters', 'int'], + ['max_factor', 'int'], + ['min_remaining', 'int'], + ['abort_if_busy', 'int'], + ['log_progress', 'int']]) + return fn(req.args, {'dom': self.dom.domid}) + def op_migrate(self, op, req): return req.threadRequest(self.do_migrate, op, req)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor