- Update to c/s 28372 to include libxl fork and event fixes for

libvirt
  xen-4.4.0-testing-src.tar.bz2

- bnc#863297: xend/pvscsi: recognize also SCSI CDROM devices
  xend-pvscsi-recognize-also-SCSI-CDROM-devices.patch

- fate#316614: set migration constraints from cmdline
  fix xl migrate to print the actual error string
  libxc-pass-errno-to-callers-of-xc_domain_save.patch

- Include additional help docs for xl in xen-tools
- Apply all patches including those for unpackaged xend
  xen.spec

- fate#316614: set migration constraints from cmdline
  split existing changes into libxl and xend part
  added libxl.set-migration-constraints-from-cmdline.patch
  added xend-set-migration-constraints-from-cmdline.patch
  removed xen.migrate.tools_add_xm_migrate_--log_progress_option.patch
  removed xen.migrate.tools_set_number_of_dirty_pages_during_migration.patch
  removed xen.migrate.tools_set_migration_constraints_from_cmdline.patch

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=299
This commit is contained in:
Charles Arnold 2014-02-11 20:53:28 +00:00 committed by Git OBS Bridge
parent c0303bd7d9
commit f43e68d196
22 changed files with 1685 additions and 749 deletions

View File

@ -2,71 +2,23 @@ Add support of change-vnc-password while vm is running.
Signed-off-by: Chunyan Liu <cyliu@novell.com>
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/vl.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vl.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/vl.c
@@ -200,7 +200,7 @@ DriveInfo drives_table[MAX_DRIVES+1];
int nb_drives;
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
int vga_ram_size;
-static DisplayState *display_state;
+DisplayState *display_state;
int nographic;
static int curses;
static int sdl;
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
@@ -2600,6 +2600,7 @@ int vnc_display_password(DisplayState *d
if (password && password[0]) {
if (!(vs->password = qemu_strdup(password)))
return -1;
+ vs->auth = VNC_AUTH_VNC;
}
return 0;
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
@@ -25,6 +25,7 @@
#include "qemu-xen.h"
#include "xen_backend.h"
+extern DisplayState *display_state;
struct xs_handle *xsh = NULL;
static char *media_filename[MAX_DRIVES+1];
static QEMUTimer *insert_timer = NULL;
@@ -897,6 +898,19 @@ static void xenstore_process_dm_command_
} else if (!strncmp(command, "continue", len)) {
fprintf(logfile, "dm-command: continue after state save\n");
xen_pause_requested = 0;
+ } else if (!strncmp(command, "chgvncpasswd", len)) {
+ fprintf(logfile, "dm-command: change vnc passwd\n");
+ if (pasprintf(&path,
+ "/local/domain/0/backend/vfb/%u/0/vncpasswd", domid) == -1) {
+ fprintf(logfile, "out of memory reading dm command parameter\n");
+ goto out;
+ }
+ par = xs_read(xsh, XBT_NULL, path, &len);
+ if (!par)
+ goto out;
+ if (vnc_display_password(display_state, par) == 0)
+ xenstore_record_dm_state("vncpasswdchged");
+ free(par);
} else if (!strncmp(command, "usb-add", len)) {
fprintf(logfile, "dm-command: usb-add a usb device\n");
if (pasprintf(&path,
---
tools/python/xen/xend/XendDomainInfo.py | 14 ++++++++++++++
tools/python/xen/xend/server/XMLRPCServer.py | 2 +-
tools/python/xen/xm/main.py | 12 ++++++++++++
tools/qemu-xen-traditional-dir-remote/vl.c | 2 +-
tools/qemu-xen-traditional-dir-remote/vnc.c | 1 +
tools/qemu-xen-traditional-dir-remote/xenstore.c | 14 ++++++++++++++
6 files changed, 43 insertions(+), 2 deletions(-)
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1461,6 +1461,20 @@ class XendDomainInfo:
pci_conf = self.info['devices'][dev_uuid][1]
return map(pci_dict_to_bdf_str, pci_conf['devs'])
@@ -1665,6 +1665,20 @@ class XendDomainInfo:
vfb_ctrl.reconfigureDevice(0, dev_info)
break
+ def chgvncpasswd(self, passwd):
+ if self._stateGet() != DOM_STATE_HALTED:
+ path = '/local/domain/0/backend/vfb/%u/0/' % self.getDomid()
@ -81,9 +33,9 @@ Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
+ break
+ xen.xend.XendDomain.instance().managed_config_save(self)
+
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@param target: In MiB.
#
# Function to update xenstore /vm/*
#
Index: xen-4.4.0-testing/tools/python/xen/xend/server/XMLRPCServer.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/server/XMLRPCServer.py
@ -155,3 +107,60 @@ Index: xen-4.4.0-testing/tools/python/xen/xm/main.py
}
## The commands supported by a separate argument parser in xend.xm.
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/vl.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vl.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/vl.c
@@ -200,7 +200,7 @@ DriveInfo drives_table[MAX_DRIVES+1];
int nb_drives;
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
int vga_ram_size;
-static DisplayState *display_state;
+DisplayState *display_state;
int nographic;
static int curses;
static int sdl;
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
@@ -2600,6 +2600,7 @@ int vnc_display_password(DisplayState *d
if (password && password[0]) {
if (!(vs->password = qemu_strdup(password)))
return -1;
+ vs->auth = VNC_AUTH_VNC;
}
return 0;
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
@@ -25,6 +25,7 @@
#include "qemu-xen.h"
#include "xen_backend.h"
+extern DisplayState *display_state;
struct xs_handle *xsh = NULL;
static char *media_filename[MAX_DRIVES+1];
static QEMUTimer *insert_timer = NULL;
@@ -897,6 +898,19 @@ static void xenstore_process_dm_command_
} else if (!strncmp(command, "continue", len)) {
fprintf(logfile, "dm-command: continue after state save\n");
xen_pause_requested = 0;
+ } else if (!strncmp(command, "chgvncpasswd", len)) {
+ fprintf(logfile, "dm-command: change vnc passwd\n");
+ if (pasprintf(&path,
+ "/local/domain/0/backend/vfb/%u/0/vncpasswd", domid) == -1) {
+ fprintf(logfile, "out of memory reading dm command parameter\n");
+ goto out;
+ }
+ par = xs_read(xsh, XBT_NULL, path, &len);
+ if (!par)
+ goto out;
+ if (vnc_display_password(display_state, par) == 0)
+ xenstore_record_dm_state("vncpasswdchged");
+ free(par);
} else if (!strncmp(command, "usb-add", len)) {
fprintf(logfile, "dm-command: usb-add a usb device\n");
if (pasprintf(&path,

View File

@ -0,0 +1,647 @@
From b7fc90f3d4f0d61281312c5d05859ee2de8fc8be Mon Sep 17 00:00:00 2001
From: Olaf Hering <olaf@aepfle.de>
Date: Mon, 10 Feb 2014 12:47:26 +0100
Subject: libxc: pass errno to callers of xc_domain_save
Callers of xc_domain_save use errno to print diagnostics if the call
fails. But xc_domain_save does not preserve the actual errno in case of
a failure.
This change preserves errno in all cases where code jumps to the label
"out". In addition a new label "exit" is added to catch also code which
used to do just "return 1".
Now libxl_save_helper:complete can print the actual error string.
Note: some of the functions used in xc_domain_save do not use errno to
indicate a reason. In these cases the errno remains undefined as it used
to be without this change.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/libxc/xc_domain_save.c | 88 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 82 insertions(+), 6 deletions(-)
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 42c4752..f32ac81 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -806,6 +806,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
xc_dominfo_t info;
DECLARE_DOMCTL;
+ int errnoval = 0;
int rc = 1, frc, i, j, last_iter = 0, iter = 0;
int live = (flags & XCFLAGS_LIVE);
int debug = (flags & XCFLAGS_DEBUG);
@@ -898,8 +899,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( hvm && !callbacks->switch_qemu_logdirty )
{
ERROR("No switch_qemu_logdirty callback provided.");
- errno = EINVAL;
- return 1;
+ errnoval = EINVAL;
+ goto exit;
}
outbuf_init(xch, &ob_pagebuf, OUTBUF_SIZE);
@@ -913,14 +914,16 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( !get_platform_info(xch, dom,
&ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, &dinfo->guest_width) )
{
+ errnoval = errno;
ERROR("Unable to get platform info.");
- return 1;
+ goto exit;
}
if ( xc_domain_getinfo(xch, dom, 1, &info) != 1 )
{
+ errnoval = errno;
PERROR("Could not get domain info");
- return 1;
+ goto exit;
}
shared_info_frame = info.shared_info_frame;
@@ -932,6 +935,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
PROT_READ, shared_info_frame);
if ( !live_shinfo )
{
+ errnoval = errno;
PERROR("Couldn't map live_shinfo");
goto out;
}
@@ -942,6 +946,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( dinfo->p2m_size > ~XEN_DOMCTL_PFINFO_LTAB_MASK )
{
+ errnoval = E2BIG;
ERROR("Cannot save this big a guest");
goto out;
}
@@ -967,6 +972,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( frc < 0 )
{
+ errnoval = errno;
PERROR("Couldn't enable shadow mode (rc %d) (errno %d)", frc, errno );
goto out;
}
@@ -975,6 +981,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
/* Enable qemu-dm logging dirty pages to xen */
if ( hvm && callbacks->switch_qemu_logdirty(dom, 1, callbacks->data) )
{
+ errnoval = errno;
PERROR("Couldn't enable qemu log-dirty mode (errno %d)", errno);
goto out;
}
@@ -985,6 +992,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( suspend_and_state(callbacks->suspend, callbacks->data, xch,
io_fd, dom, &info) )
{
+ errnoval = errno;
ERROR("Domain appears not to have suspended");
goto out;
}
@@ -994,6 +1002,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
{
if (!(compress_ctx = xc_compression_create_context(xch, dinfo->p2m_size)))
{
+ errnoval = errno;
ERROR("Failed to create compression context");
goto out;
}
@@ -1012,6 +1021,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( !to_send || !to_fix || !to_skip )
{
+ errnoval = ENOMEM;
ERROR("Couldn't allocate to_send array");
goto out;
}
@@ -1024,12 +1034,14 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
hvm_buf_size = xc_domain_hvm_getcontext(xch, dom, 0, 0);
if ( hvm_buf_size == -1 )
{
+ errnoval = errno;
PERROR("Couldn't get HVM context size from Xen");
goto out;
}
hvm_buf = malloc(hvm_buf_size);
if ( !hvm_buf )
{
+ errnoval = ENOMEM;
ERROR("Couldn't allocate memory");
goto out;
}
@@ -1043,7 +1055,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (pfn_type == NULL) || (pfn_batch == NULL) || (pfn_err == NULL) )
{
ERROR("failed to alloc memory for pfn_type and/or pfn_batch arrays");
- errno = ENOMEM;
+ errnoval = ENOMEM;
goto out;
}
memset(pfn_type, 0,
@@ -1052,6 +1064,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
/* Setup the mfn_to_pfn table mapping */
if ( !(ctx->live_m2p = xc_map_m2p(xch, ctx->max_mfn, PROT_READ, &ctx->m2p_mfn0)) )
{
+ errnoval = errno;
PERROR("Failed to map live M2P table");
goto out;
}
@@ -1059,6 +1072,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
/* Start writing out the saved-domain record. */
if ( write_exact(io_fd, &dinfo->p2m_size, sizeof(unsigned long)) )
{
+ errnoval = errno;
PERROR("write: p2m_size");
goto out;
}
@@ -1071,6 +1085,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
ctx->live_p2m = map_and_save_p2m_table(xch, io_fd, dom, ctx, live_shinfo);
if ( ctx->live_p2m == NULL )
{
+ errnoval = errno;
PERROR("Failed to map/save the p2m frame list");
goto out;
}
@@ -1097,12 +1112,14 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
tmem_saved = xc_tmem_save(xch, dom, io_fd, live, XC_SAVE_ID_TMEM);
if ( tmem_saved == -1 )
{
+ errnoval = errno;
PERROR("Error when writing to state file (tmem)");
goto out;
}
if ( !live && save_tsc_info(xch, dom, io_fd) < 0 )
{
+ errnoval = errno;
PERROR("Error when writing to state file (tsc)");
goto out;
}
@@ -1143,6 +1160,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
dinfo->p2m_size, NULL, 0, NULL);
if ( frc != dinfo->p2m_size )
{
+ errnoval = errno;
ERROR("Error peeking shadow bitmap");
goto out;
}
@@ -1257,6 +1275,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
xch, dom, PROT_READ, pfn_type, pfn_err, batch);
if ( region_base == NULL )
{
+ errnoval = errno;
PERROR("map batch failed");
goto out;
}
@@ -1264,6 +1283,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
/* Get page types */
if ( xc_get_pfn_type_batch(xch, dom, batch, pfn_type) )
{
+ errnoval = errno;
PERROR("get_pfn_type_batch failed");
goto out;
}
@@ -1332,6 +1352,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( wrexact(io_fd, &batch, sizeof(unsigned int)) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (2)");
goto out;
}
@@ -1341,6 +1362,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
((unsigned long *)pfn_type)[j] = pfn_type[j];
if ( wrexact(io_fd, pfn_type, sizeof(unsigned long)*batch) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (3)");
goto out;
}
@@ -1368,6 +1390,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
(char*)region_base+(PAGE_SIZE*(j-run)),
PAGE_SIZE*run) != PAGE_SIZE*run )
{
+ errnoval = errno;
PERROR("Error when writing to state file (4a)"
" (errno %d)", errno);
goto out;
@@ -1396,6 +1419,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( race && !live )
{
+ errnoval = errno;
ERROR("Fatal PT race (pfn %lx, type %08lx)", pfn,
pagetype);
goto out;
@@ -1409,6 +1433,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
pfn, 1 /* raw page */);
if (c_err == -2) /* OOB PFN */
{
+ errnoval = errno;
ERROR("Could not add pagetable page "
"(pfn:%" PRIpfn "to page buffer\n", pfn);
goto out;
@@ -1428,6 +1453,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
*/
if (wrcompressed(io_fd) < 0)
{
+ errnoval = errno;
ERROR("Error when writing compressed"
" data (4b)\n");
goto out;
@@ -1437,6 +1463,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
else if ( wruncached(io_fd, live, page,
PAGE_SIZE) != PAGE_SIZE )
{
+ errnoval = errno;
PERROR("Error when writing to state file (4b)"
" (errno %d)", errno);
goto out;
@@ -1456,6 +1483,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if (c_err == -2) /* OOB PFN */
{
+ errnoval = errno;
ERROR("Could not add page "
"(pfn:%" PRIpfn "to page buffer\n", pfn);
goto out;
@@ -1465,6 +1493,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
{
if (wrcompressed(io_fd) < 0)
{
+ errnoval = errno;
ERROR("Error when writing compressed"
" data (4c)\n");
goto out;
@@ -1483,6 +1512,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
(char*)region_base+(PAGE_SIZE*(j-run)),
PAGE_SIZE*run) != PAGE_SIZE*run )
{
+ errnoval = errno;
PERROR("Error when writing to state file (4c)"
" (errno %d)", errno);
goto out;
@@ -1520,6 +1550,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
/* send "-1" to put receiver into debug mode */
if ( wrexact(io_fd, &id, sizeof(int)) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (6)");
goto out;
}
@@ -1542,6 +1573,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( suspend_and_state(callbacks->suspend, callbacks->data,
xch, io_fd, dom, &info) )
{
+ errnoval = errno;
ERROR("Domain appears not to have suspended");
goto out;
}
@@ -1550,12 +1582,14 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (tmem_saved > 0) &&
(xc_tmem_save_extra(xch,dom,io_fd,XC_SAVE_ID_TMEM_EXTRA) == -1) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (tmem)");
goto out;
}
if ( save_tsc_info(xch, dom, io_fd) < 0 )
{
+ errnoval = errno;
PERROR("Error when writing to state file (tsc)");
goto out;
}
@@ -1567,6 +1601,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
XEN_DOMCTL_SHADOW_OP_CLEAN, HYPERCALL_BUFFER(to_send),
dinfo->p2m_size, NULL, 0, &shadow_stats) != dinfo->p2m_size )
{
+ errnoval = errno;
PERROR("Error flushing shadow PT");
goto out;
}
@@ -1598,6 +1633,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( info.max_vcpu_id >= XC_SR_MAX_VCPUS )
{
+ errnoval = E2BIG;
ERROR("Too many VCPUS in guest!");
goto out;
}
@@ -1614,6 +1650,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( wrexact(io_fd, &chunk, offsetof(struct chunk, vcpumap)
+ vcpumap_sz(info.max_vcpu_id)) )
{
+ errnoval = errno;
PERROR("Error when writing to state file");
goto out;
}
@@ -1633,6 +1670,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (chunk.data != 0) &&
wrexact(io_fd, &chunk, sizeof(chunk)) )
{
+ errnoval = errno;
PERROR("Error when writing the generation id buffer location for guest");
goto out;
}
@@ -1645,6 +1683,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (chunk.data != 0) &&
wrexact(io_fd, &chunk, sizeof(chunk)) )
{
+ errnoval = errno;
PERROR("Error when writing the ident_pt for EPT guest");
goto out;
}
@@ -1657,6 +1696,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (chunk.data != 0) &&
wrexact(io_fd, &chunk, sizeof(chunk)) )
{
+ errnoval = errno;
PERROR("Error when writing the paging ring pfn for guest");
goto out;
}
@@ -1669,6 +1709,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (chunk.data != 0) &&
wrexact(io_fd, &chunk, sizeof(chunk)) )
{
+ errnoval = errno;
PERROR("Error when writing the access ring pfn for guest");
goto out;
}
@@ -1681,6 +1722,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (chunk.data != 0) &&
wrexact(io_fd, &chunk, sizeof(chunk)) )
{
+ errnoval = errno;
PERROR("Error when writing the sharing ring pfn for guest");
goto out;
}
@@ -1693,6 +1735,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (chunk.data != 0) &&
wrexact(io_fd, &chunk, sizeof(chunk)) )
{
+ errnoval = errno;
PERROR("Error when writing the vm86 TSS for guest");
goto out;
}
@@ -1705,6 +1748,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (chunk.data != 0) &&
wrexact(io_fd, &chunk, sizeof(chunk)) )
{
+ errnoval = errno;
PERROR("Error when writing the console pfn for guest");
goto out;
}
@@ -1716,6 +1760,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ((chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)))
{
+ errnoval = errno;
PERROR("Error when writing the firmware ioport version");
goto out;
}
@@ -1728,6 +1773,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (chunk.data != 0) &&
wrexact(io_fd, &chunk, sizeof(chunk)) )
{
+ errnoval = errno;
PERROR("Error when writing the viridian flag");
goto out;
}
@@ -1741,6 +1787,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( callbacks->toolstack_save(dom, &buf, &len, callbacks->data) < 0 )
{
+ errnoval = errno;
PERROR("Error calling toolstack_save");
goto out;
}
@@ -1759,6 +1806,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
i = XC_SAVE_ID_LAST_CHECKPOINT;
if ( wrexact(io_fd, &i, sizeof(int)) )
{
+ errnoval = errno;
PERROR("Error when writing last checkpoint chunk");
goto out;
}
@@ -1778,6 +1826,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
i = XC_SAVE_ID_ENABLE_COMPRESSION;
if ( wrexact(io_fd, &i, sizeof(int)) )
{
+ errnoval = errno;
PERROR("Error when writing enable_compression marker");
goto out;
}
@@ -1787,6 +1836,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
i = 0;
if ( wrexact(io_fd, &i, sizeof(int)) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (6')");
goto out;
}
@@ -1805,6 +1855,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
(unsigned long *)&magic_pfns[2]);
if ( wrexact(io_fd, magic_pfns, sizeof(magic_pfns)) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (7)");
goto out;
}
@@ -1813,18 +1864,21 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (rec_size = xc_domain_hvm_getcontext(xch, dom, hvm_buf,
hvm_buf_size)) == -1 )
{
+ errnoval = errno;
PERROR("HVM:Could not get hvm buffer");
goto out;
}
if ( wrexact(io_fd, &rec_size, sizeof(uint32_t)) )
{
+ errnoval = errno;
PERROR("error write hvm buffer size");
goto out;
}
if ( wrexact(io_fd, hvm_buf, rec_size) )
{
+ errnoval = errno;
PERROR("write HVM info failed!");
goto out;
}
@@ -1849,6 +1903,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( wrexact(io_fd, &j, sizeof(unsigned int)) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (6a)");
goto out;
}
@@ -1863,6 +1918,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
{
if ( wrexact(io_fd, &pfntab, sizeof(unsigned long)*j) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (6b)");
goto out;
}
@@ -1873,6 +1929,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( xc_vcpu_getcontext(xch, dom, 0, &ctxt) )
{
+ errnoval = errno;
PERROR("Could not get vcpu context");
goto out;
}
@@ -1888,6 +1945,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
mfn = GET_FIELD(&ctxt, user_regs.edx);
if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
{
+ errnoval = ERANGE;
ERROR("Suspend record is not in range of pseudophys map");
goto out;
}
@@ -1900,6 +1958,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( (i != 0) && xc_vcpu_getcontext(xch, dom, i, &ctxt) )
{
+ errnoval = errno;
PERROR("No context for VCPU%d", i);
goto out;
}
@@ -1910,6 +1969,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
mfn = GET_FIELD(&ctxt, gdt_frames[j]);
if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
{
+ errnoval = ERANGE;
ERROR("GDT frame is not in range of pseudophys map");
goto out;
}
@@ -1920,6 +1980,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( !MFN_IS_IN_PSEUDOPHYS_MAP(UNFOLD_CR3(
GET_FIELD(&ctxt, ctrlreg[3]))) )
{
+ errnoval = ERANGE;
ERROR("PT base is not in range of pseudophys map");
goto out;
}
@@ -1931,6 +1992,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
{
if ( !MFN_IS_IN_PSEUDOPHYS_MAP(UNFOLD_CR3(ctxt.x64.ctrlreg[1])) )
{
+ errnoval = ERANGE;
ERROR("PT base is not in range of pseudophys map");
goto out;
}
@@ -1943,6 +2005,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
? sizeof(ctxt.x64)
: sizeof(ctxt.x32))) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (1)");
goto out;
}
@@ -1953,11 +2016,13 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
domctl.u.ext_vcpucontext.vcpu = i;
if ( xc_domctl(xch, &domctl) < 0 )
{
+ errnoval = errno;
PERROR("No extended context for VCPU%d", i);
goto out;
}
if ( wrexact(io_fd, &domctl.u.ext_vcpucontext, 128) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (2)");
goto out;
}
@@ -1971,6 +2036,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
domctl.u.vcpuextstate.size = 0;
if ( xc_domctl(xch, &domctl) < 0 )
{
+ errnoval = errno;
PERROR("No eXtended states (XSAVE) for VCPU%d", i);
goto out;
}
@@ -1982,6 +2048,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
buffer = xc_hypercall_buffer_alloc(xch, buffer, domctl.u.vcpuextstate.size);
if ( !buffer )
{
+ errnoval = errno;
PERROR("Insufficient memory for getting eXtended states for"
"VCPU%d", i);
goto out;
@@ -1989,6 +2056,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
set_xen_guest_handle(domctl.u.vcpuextstate.buffer, buffer);
if ( xc_domctl(xch, &domctl) < 0 )
{
+ errnoval = errno;
PERROR("No eXtended states (XSAVE) for VCPU%d", i);
xc_hypercall_buffer_free(xch, buffer);
goto out;
@@ -2000,6 +2068,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
sizeof(domctl.u.vcpuextstate.size)) ||
wrexact(io_fd, buffer, domctl.u.vcpuextstate.size) )
{
+ errnoval = errno;
PERROR("Error when writing to state file VCPU extended state");
xc_hypercall_buffer_free(xch, buffer);
goto out;
@@ -2015,6 +2084,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
arch.pfn_to_mfn_frame_list_list, 0);
if ( wrexact(io_fd, page, PAGE_SIZE) )
{
+ errnoval = errno;
PERROR("Error when writing to state file (1)");
goto out;
}
@@ -2022,6 +2092,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
/* Flush last write and check for errors. */
if ( fsync(io_fd) && errno != EINVAL )
{
+ errnoval = errno;
PERROR("Error when flushing state file");
goto out;
}
@@ -2043,6 +2114,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
ob = &ob_pagebuf;
if (wrcompressed(io_fd) < 0)
{
+ errnoval = errno;
ERROR("Error when writing compressed data, after postcopy\n");
rc = 1;
goto out;
@@ -2051,6 +2123,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( wrexact(io_fd, ob_tailbuf.buf, ob_tailbuf.pos) )
{
rc = 1;
+ errnoval = errno;
PERROR("Error when copying tailbuf into outbuf");
goto out;
}
@@ -2079,6 +2152,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( suspend_and_state(callbacks->suspend, callbacks->data, xch,
io_fd, dom, &info) )
{
+ errnoval = errno;
ERROR("Domain appears not to have suspended");
goto out;
}
@@ -2130,7 +2204,9 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
free(hvm_buf);
outbuf_free(&ob_pagebuf);
- DPRINTF("Save exit of domid %u with rc=%d\n", dom, rc);
+exit:
+ DPRINTF("Save exit of domid %u with rc=%d, errno=%d\n", dom, rc, errnoval);
+ errno = errnoval;
return !!rc;
}

View File

@ -54,7 +54,7 @@ Index: xen-4.4.0-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.0-testing/tools/libxl/libxl.c
@@ -2196,6 +2196,8 @@ static void device_disk_add(libxl__egc *
@@ -2213,6 +2213,8 @@ static void device_disk_add(libxl__egc *
flexarray_append(back, disk->readwrite ? "w" : "r");
flexarray_append(back, "device-type");
flexarray_append(back, disk->is_cdrom ? "cdrom" : "disk");

View File

@ -0,0 +1,493 @@
From 77deb80879859ed279e24a790ec08e9c5d37dd0e Mon Sep 17 00:00:00 2001
From: Olaf Hering <olaf@aepfle.de>
Date: Wed, 5 Feb 2014 14:37:53 +0100
Subject: libxl: set migration constraints from cmdline
Add new options to 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 new dirty pages.
Currently the guest is suspended to transfer the remaining dirty pages.
The suspend/resume cycle will cause a time jump. This transfer can take
a long time, which can confuse the guest if the time jump is too far.
The new options allow to override the built-in default values, which are
not changed by this patch.
--max_iters <number> Number of iterations before final suspend (default: 30)
--max_factor <factor> Max amount of memory to transfer before final suspend (default: 3*RAM)
--min_remaing <pages> Number of dirty pages before stop&copy (default: 50)
--abort_if_busy Abort migration instead of doing final suspend.
The changes to libxl change the API, handle LIBXL_API_VERSION == 0x040200.
v8:
- merge --min_remaing changes
- tools/libxc: print stats if migration is aborted
- use special _suse version of lib calls to preserve ABI
v7:
- remove short options
- update description of --abort_if_busy in xl.1
- extend description of --abort_if_busy in xl help
- add comment to libxl_domain_suspend declaration, props is optional
v6:
- update the LIBXL_API_VERSION handling for libxl_domain_suspend
change it to an inline function if LIBXL_API_VERSION is defined to 4.2.0
- rename libxl_save_properties to libxl_domain_suspend_properties
- rename ->xlflags to ->flags within that struct
v5:
- adjust libxl_domain_suspend prototype, move flags, max_iters,
max_factor into a new, optional struct libxl_save_properties
- rename XCFLAGS_DOMSAVE_NOSUSPEND to XCFLAGS_DOMSAVE_ABORT_IF_BUSY
- rename LIBXL_SUSPEND_NO_FINAL_SUSPEND to LIBXL_SUSPEND_ABORT_IF_BUSY
- rename variables no_suspend to abort_if_busy
- rename option -N/--no_suspend to -A/--abort_if_busy
- update xl.1, extend description of -A option
v4:
- update default for no_suspend from None to 0 in XendCheckpoint.py:save
- update logoutput in setMigrateConstraints
- change xm migrate defaults from None to 0
- add new options to xl.1
- fix syntax error in XendDomain.py:domain_migrate_constraints_set
- fix xm migrate -N option name to match xl migrate
v3:
- move logic errors in libxl__domain_suspend and fixed help text in
cmd_table to separate patches
- fix syntax error in XendCheckpoint.py
- really pass max_iters and max_factor in libxl__xc_domain_save
- make libxl_domain_suspend_0x040200 declaration globally visible
- bump libxenlight.so SONAME from 2.0 to 2.1 due to changed
libxl_domain_suspend
v2:
- use LIBXL_API_VERSION and define libxl_domain_suspend_0x040200
- fix logic error in min_reached check in xc_domain_save
- add longopts
- update --help text
- correct description of migrate --help text
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
docs/man/xl.pod.1 | 20 ++++++++++++++++++++
tools/libxc/xc_domain_save.c | 27 ++++++++++++++++++++++++--
tools/libxc/xenguest.h | 7 +++++++
tools/libxl/libxl.c | 27 +++++++++++++++++++++++---
tools/libxl/libxl.h | 14 ++++++++++++++
tools/libxl/libxl_dom.c | 1 +
tools/libxl/libxl_internal.h | 4 ++++
tools/libxl/libxl_save_callout.c | 4 +++-
tools/libxl/libxl_save_helper.c | 4 +++-
tools/libxl/xl_cmdimpl.c | 41 ++++++++++++++++++++++++++++++++++------
tools/libxl/xl_cmdtable.c | 23 ++++++++++++++--------
11 files changed, 151 insertions(+), 21 deletions(-)
Index: xen-4.4.0-testing/docs/man/xl.pod.1
===================================================================
--- xen-4.4.0-testing.orig/docs/man/xl.pod.1
+++ xen-4.4.0-testing/docs/man/xl.pod.1
@@ -392,6 +392,26 @@ Send <config> instead of config file fro
Print huge (!) amount of debug during the migration process.
+=item B<--max_iters> I<number>
+
+Number of iterations before final suspend (default: 30)
+
+=item B<--max_factor> I<factor>
+
+Max amount of memory to transfer before final suspend (default: 3*RAM)
+
+=item B<--min_remaining>
+
+Number of remaining dirty pages. If the number of dirty pages drops that
+low the guest is suspended and the remaing pages are transfered to <host>.
+
+=item B<--abort_if_busy>
+
+Abort migration instead of doing final suspend/transfer/resume if the
+guest has still dirty pages after the number of iterations and/or the
+amount of RAM transferred. This avoids long periods of time where the
+guest is suspended.
+
=back
=item B<remus> [I<OPTIONS>] I<domain-id> I<host>
Index: xen-4.4.0-testing/tools/libxc/xc_domain_save.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxc/xc_domain_save.c
+++ xen-4.4.0-testing/tools/libxc/xc_domain_save.c
@@ -43,6 +43,7 @@
*/
#define DEF_MAX_ITERS 29 /* limit us to 30 times round loop */
#define DEF_MAX_FACTOR 3 /* never send more than 3x p2m_size */
+#define DEF_MIN_REMAINING 50 /* low water mark of dirty pages */
struct save_ctx {
unsigned long hvirt_start; /* virtual starting address of the hypervisor */
@@ -798,8 +799,9 @@ static int save_tsc_info(xc_interface *x
return 0;
}
-int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
+int xc_domain_save_suse(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
uint32_t max_factor, uint32_t flags,
+ uint32_t min_remaining,
struct save_callbacks* callbacks, int hvm,
unsigned long vm_generationid_addr)
{
@@ -810,6 +812,7 @@ 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 abort_if_busy = (flags & XCFLAGS_DOMSAVE_ABORT_IF_BUSY);
int superpages = !!hvm;
int race = 0, sent_last_iter, skip_this_iter = 0;
unsigned int sent_this_iter = 0;
@@ -910,6 +913,7 @@ int xc_domain_save(xc_interface *xch, in
/* If no explicit control parameters given, use defaults */
max_iters = max_iters ? : DEF_MAX_ITERS;
max_factor = max_factor ? : DEF_MAX_FACTOR;
+ min_remaining = min_remaining ? : DEF_MIN_REMAINING;
if ( !get_platform_info(xch, dom,
&ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, &dinfo->guest_width) )
@@ -1563,10 +1567,22 @@ int xc_domain_save(xc_interface *xch, in
if ( live )
{
+ int min_reached = sent_this_iter + skip_this_iter < 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 && abort_if_busy )
+ {
+ errnoval = EBUSY;
+ DPRINTF("Live migration aborted, as requested. (guest too busy?)");
+ DPRINTF(" total_sent %lu iter %d, max_iters %u max_factor %u",
+ total_sent, iter, max_iters, max_factor);
+ print_stats(xch, dom, sent_this_iter, &time_stats, &shadow_stats, 1);
+ rc = 1;
+ goto out;
+ }
+
DPRINTF("Start last iteration\n");
last_iter = 1;
@@ -2210,6 +2226,13 @@ exit:
return !!rc;
}
+int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
+ uint32_t max_factor, uint32_t flags,
+ struct save_callbacks* callbacks, int hvm,
+ unsigned long vm_generationid_addr)
+{
+ return xc_domain_save_suse(xch, io_fd, dom, max_iters, max_factor, flags, 0, callbacks, hvm, vm_generationid_addr);
+}
/*
* Local variables:
Index: xen-4.4.0-testing/tools/libxc/xenguest.h
===================================================================
--- xen-4.4.0-testing.orig/tools/libxc/xenguest.h
+++ xen-4.4.0-testing/tools/libxc/xenguest.h
@@ -28,6 +28,7 @@
#define XCFLAGS_HVM (1 << 2)
#define XCFLAGS_STDVGA (1 << 3)
#define XCFLAGS_CHECKPOINT_COMPRESS (1 << 4)
+#define XCFLAGS_DOMSAVE_ABORT_IF_BUSY (1 << 5)
#define X86_64_B_SIZE 64
#define X86_32_B_SIZE 32
@@ -89,6 +90,12 @@ int xc_domain_save(xc_interface *xch, in
struct save_callbacks* callbacks, int hvm,
unsigned long vm_generationid_addr);
+int xc_domain_save_suse(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
+ uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
+ uint32_t min_remaining,
+ struct save_callbacks* callbacks, int hvm,
+ unsigned long vm_generationid_addr);
+
/* callbacks provided by xc_domain_restore */
struct restore_callbacks {
Index: xen-4.4.0-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.0-testing/tools/libxl/libxl.c
@@ -763,7 +763,8 @@ static void domain_suspend_cb(libxl__egc
}
-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
+static int do_libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
+ const libxl_domain_suspend_suse_properties *props,
const libxl_asyncop_how *ao_how)
{
AO_CREATE(ctx, domid, ao_how);
@@ -784,8 +785,14 @@ int libxl_domain_suspend(libxl_ctx *ctx,
dss->domid = domid;
dss->fd = fd;
dss->type = type;
- dss->live = flags & LIBXL_SUSPEND_LIVE;
- dss->debug = flags & LIBXL_SUSPEND_DEBUG;
+ if (props) {
+ dss->live = props->flags & LIBXL_SUSPEND_LIVE;
+ dss->debug = props->flags & LIBXL_SUSPEND_DEBUG;
+ dss->max_iters = props->max_iters;
+ dss->max_factor = props->max_factor;
+ dss->min_remaining = props->min_remaining;
+ dss->xlflags = props->flags;
+ }
libxl__domain_suspend(egc, dss);
return AO_INPROGRESS;
@@ -794,6 +801,20 @@ int libxl_domain_suspend(libxl_ctx *ctx,
return AO_ABORT(rc);
}
+int libxl_domain_suspend_suse(libxl_ctx *ctx, uint32_t domid, int fd,
+ const libxl_domain_suspend_suse_properties *props,
+ const libxl_asyncop_how *ao_how)
+{
+ return do_libxl_domain_suspend(ctx, domid, fd, props, ao_how);
+}
+
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
+ const libxl_asyncop_how *ao_how)
+{
+ libxl_domain_suspend_suse_properties props = { .flags = flags };
+ return do_libxl_domain_suspend(ctx, domid, fd, &props, ao_how);
+}
+
int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid)
{
int ret;
Index: xen-4.4.0-testing/tools/libxl/libxl.h
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/libxl.h
+++ xen-4.4.0-testing/tools/libxl/libxl.h
@@ -673,8 +673,22 @@ int libxl_domain_suspend(libxl_ctx *ctx,
int flags, /* LIBXL_SUSPEND_* */
const libxl_asyncop_how *ao_how)
LIBXL_EXTERNAL_CALLERS_ONLY;
+
+typedef struct {
+ int flags; /* LIBXL_SUSPEND_* */
+ int max_iters;
+ int max_factor;
+ int min_remaining;
+} libxl_domain_suspend_suse_properties;
+
+int libxl_domain_suspend_suse(libxl_ctx *ctx, uint32_t domid, int fd,
+ const libxl_domain_suspend_suse_properties *props, /* optional */
+ const libxl_asyncop_how *ao_how)
+ LIBXL_EXTERNAL_CALLERS_ONLY;
+
#define LIBXL_SUSPEND_DEBUG 1
#define LIBXL_SUSPEND_LIVE 2
+#define LIBXL_SUSPEND_ABORT_IF_BUSY 4
/* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )]
* If this parameter is true, use co-operative resume. The guest
Index: xen-4.4.0-testing/tools/libxl/libxl_dom.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/libxl_dom.c
+++ xen-4.4.0-testing/tools/libxl/libxl_dom.c
@@ -1337,6 +1337,7 @@ void libxl__domain_suspend(libxl__egc *e
dss->xcflags = (live ? XCFLAGS_LIVE : 0)
| (debug ? XCFLAGS_DEBUG : 0)
+ | (dss->xlflags & LIBXL_SUSPEND_ABORT_IF_BUSY ? XCFLAGS_DOMSAVE_ABORT_IF_BUSY : 0)
| (dss->hvm ? XCFLAGS_HVM : 0);
dss->suspend_eventchn = -1;
Index: xen-4.4.0-testing/tools/libxl/libxl_internal.h
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/libxl_internal.h
+++ xen-4.4.0-testing/tools/libxl/libxl_internal.h
@@ -2319,6 +2319,10 @@ struct libxl__domain_suspend_state {
xc_evtchn *xce; /* event channel handle */
int suspend_eventchn;
int hvm;
+ int max_iters;
+ int max_factor;
+ int min_remaining;
+ int xlflags;
int xcflags;
int guest_responded;
const char *dm_savefile;
Index: xen-4.4.0-testing/tools/libxl/libxl_save_callout.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/libxl_save_callout.c
+++ xen-4.4.0-testing/tools/libxl/libxl_save_callout.c
@@ -108,7 +108,9 @@ void libxl__xc_domain_save(libxl__egc *e
}
const unsigned long argnums[] = {
- dss->domid, 0, 0, dss->xcflags, dss->hvm, vm_generationid_addr,
+ dss->domid,
+ dss->max_iters, dss->max_factor, dss->min_remaining,
+ dss->xcflags, dss->hvm, vm_generationid_addr,
toolstack_data_fd, toolstack_data_len,
cbflags,
};
Index: xen-4.4.0-testing/tools/libxl/libxl_save_helper.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/libxl_save_helper.c
+++ xen-4.4.0-testing/tools/libxl/libxl_save_helper.c
@@ -221,6 +221,7 @@ int main(int argc, char **argv)
uint32_t dom = strtoul(NEXTARG,0,10);
uint32_t max_iters = strtoul(NEXTARG,0,10);
uint32_t max_factor = strtoul(NEXTARG,0,10);
+ uint32_t min_remaining = strtoul(NEXTARG,0,10);
uint32_t flags = strtoul(NEXTARG,0,10);
int hvm = atoi(NEXTARG);
unsigned long genidad = strtoul(NEXTARG,0,10);
@@ -235,7 +236,8 @@ int main(int argc, char **argv)
helper_setcallbacks_save(&helper_save_callbacks, cbflags);
startup("save");
- r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, flags,
+ r = xc_domain_save_suse(xch, io_fd, dom, max_iters, max_factor, flags,
+ min_remaining,
&helper_save_callbacks, hvm, genidad);
complete(r);
Index: xen-4.4.0-testing/tools/libxl/xl_cmdimpl.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/xl_cmdimpl.c
+++ xen-4.4.0-testing/tools/libxl/xl_cmdimpl.c
@@ -3636,6 +3636,8 @@ static void migrate_do_preamble(int send
}
static void migrate_domain(uint32_t domid, const char *rune, int debug,
+ int max_iters, int max_factor,
+ int min_remaining, int abort_if_busy,
const char *override_config_file)
{
pid_t child = -1;
@@ -3644,7 +3646,13 @@ static void migrate_domain(uint32_t domi
char *away_domname;
char rc_buf;
uint8_t *config_data;
- int config_len, flags = LIBXL_SUSPEND_LIVE;
+ int config_len;
+ libxl_domain_suspend_suse_properties props = {
+ .flags = LIBXL_SUSPEND_LIVE,
+ .max_iters = max_iters,
+ .max_factor = max_factor,
+ .min_remaining = min_remaining,
+ };
save_domain_core_begin(domid, override_config_file,
&config_data, &config_len);
@@ -3663,10 +3671,13 @@ static void migrate_domain(uint32_t domi
xtl_stdiostream_adjust_flags(logger, XTL_STDIOSTREAM_HIDE_PROGRESS, 0);
if (debug)
- flags |= LIBXL_SUSPEND_DEBUG;
- rc = libxl_domain_suspend(ctx, domid, send_fd, flags, NULL);
+ props.flags |= LIBXL_SUSPEND_DEBUG;
+ if (abort_if_busy)
+ props.flags |= LIBXL_SUSPEND_ABORT_IF_BUSY;
+
+ rc = libxl_domain_suspend_suse(ctx, domid, send_fd, &props, NULL);
if (rc) {
- fprintf(stderr, "migration sender: libxl_domain_suspend failed"
+ fprintf(stderr, "migration sender: libxl_domain_suspend_suse failed"
" (rc=%d)\n", rc);
if (rc == ERROR_GUEST_TIMEDOUT)
goto failed_suspend;
@@ -4061,13 +4072,18 @@ int main_migrate(int argc, char **argv)
char *rune = NULL;
char *host;
int opt, daemonize = 1, monitor = 1, debug = 0;
+ int max_iters = 0, max_factor = 0, min_remaining = 0, abort_if_busy = 0;
static struct option opts[] = {
{"debug", 0, 0, 0x100},
+ {"max_iters", 1, 0, 0x101},
+ {"max_factor", 1, 0, 0x102},
+ {"min_remaining", 1, 0, 0x103},
+ {"abort_if_busy", 0, 0, 0x104},
COMMON_LONG_OPTS,
{0, 0, 0, 0}
};
- SWITCH_FOREACH_OPT(opt, "FC:s:e", opts, "migrate", 2) {
+ SWITCH_FOREACH_OPT(opt, "FC:s:eM:m:A", opts, "migrate", 2) {
case 'C':
config_filename = optarg;
break;
@@ -4084,6 +4100,18 @@ int main_migrate(int argc, char **argv)
case 0x100:
debug = 1;
break;
+ case 0x101:
+ max_iters = atoi(optarg);
+ break;
+ case 0x102:
+ max_factor = atoi(optarg);
+ break;
+ case 0x103:
+ min_remaining = atoi(optarg);
+ break;
+ case 0x104:
+ abort_if_busy = 1;
+ break;
}
domid = find_domain(argv[optind]);
@@ -4099,7 +4127,8 @@ int main_migrate(int argc, char **argv)
return 1;
}
- migrate_domain(domid, rune, debug, config_filename);
+ migrate_domain(domid, rune, debug, max_iters, max_factor, min_remaining,
+ abort_if_busy, config_filename);
return 0;
}
Index: xen-4.4.0-testing/tools/libxl/xl_cmdtable.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/xl_cmdtable.c
+++ xen-4.4.0-testing/tools/libxl/xl_cmdtable.c
@@ -149,14 +149,21 @@ struct cmd_spec cmd_table[] = {
&main_migrate, 0, 1,
"Migrate a domain to another host",
"[options] <Domain> <host>",
- "-h Print this help.\n"
- "-C <config> Send <config> instead of config file from creation.\n"
- "-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"
- "-e Do not wait in the background (on <host>) for the death\n"
- " of the domain.\n"
- "--debug Print huge (!) amount of debug during the migration process."
+ "-h Print this help.\n"
+ "-C <config> Send <config> instead of config file from creation.\n"
+ "-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"
+ "-e Do not wait in the background (on <host>) for the death\n"
+ " of the domain.\n"
+ "--debug Print huge (!) amount of debug during the migration process.\n"
+ "\n"
+ "SUSE Linux specific options:\n"
+ "--max_iters <number> Number of iterations before final suspend (default: 30)\n"
+ "--max_factor <factor> Max amount of memory to transfer before final suspend (default: 3*RAM).\n"
+ "--min_remaining <pages> Number of remaining dirty pages before final suspend (default: 50).\n"
+ "--abort_if_busy Abort migration instead of doing final suspend, if number\n"
+ " of iterations or amount of transfered memory is exceeded."
},
{ "dump-core",
&main_dump_core, 0, 1,

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:59ff093f019bef266d60fdf799321b322d98664a4cb410fc064706d165e103d5
size 7572593
oid sha256:27825df0797b7e7da48974205534f73cfb54c21270f6cf1fdad4a09efe77ed3d
size 7570627

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:554f1d2575ee8650425dcceec67de6cabcab54c185648a4a606713c680eaf492
size 3212156
oid sha256:850f3fa6cef695d4df38ce848dc92eabc202d4da4a2199335f4851538c27ee2f
size 3212885

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:84121ad5559806fc92fb032a94929a2c9c47719369a913cca677e2e2b9a70e7b
size 366155
oid sha256:0a6cbb7ee06faa1c2f922b96a9883a56461db169ea13a22f46d4c56d174c3923
size 366315

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:782788ab7f071adc277781f0478681fc267d576cff682c0343d7663e987cc29c
size 4351908
oid sha256:d349ab905290a20cea87fe5012cfeacd00663d25a1cb9f6dcbc6aee30f9eacab
size 4356190

View File

@ -1,3 +1,41 @@
-------------------------------------------------------------------
Tue Feb 11 13:27:42 MST 2014 - carnold@suse.com
- Update to c/s 28372 to include libxl fork and event fixes for
libvirt
xen-4.4.0-testing-src.tar.bz2
-------------------------------------------------------------------
Tue Feb 11 16:14:08 CET 2014 - ohering@suse.de
- bnc#863297: xend/pvscsi: recognize also SCSI CDROM devices
xend-pvscsi-recognize-also-SCSI-CDROM-devices.patch
-------------------------------------------------------------------
Tue Feb 11 09:24:23 CET 2014 - ohering@suse.de
- fate#316614: set migration constraints from cmdline
fix xl migrate to print the actual error string
libxc-pass-errno-to-callers-of-xc_domain_save.patch
-------------------------------------------------------------------
Mon Feb 10 10:01:54 MST 2014 - carnold@suse.com
- Include additional help docs for xl in xen-tools
- Apply all patches including those for unpackaged xend
xen.spec
-------------------------------------------------------------------
Mon Feb 10 10:28:18 CET 2014 - ohering@suse.de
- fate#316614: set migration constraints from cmdline
split existing changes into libxl and xend part
added libxl.set-migration-constraints-from-cmdline.patch
added xend-set-migration-constraints-from-cmdline.patch
removed xen.migrate.tools_add_xm_migrate_--log_progress_option.patch
removed xen.migrate.tools_set_number_of_dirty_pages_during_migration.patch
removed xen.migrate.tools_set_migration_constraints_from_cmdline.patch
-------------------------------------------------------------------
Tue Feb 4 11:20:12 MST 2014 - carnold@suse.com

View File

@ -17,11 +17,11 @@ Signed-off-by: Olaf Hering <olaf@aepfle.de>
tools/python/xen/xend/XendCheckpoint.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Index: xen-4.2.1-testing/tools/python/xen/xend/XendCheckpoint.py
Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.2.1-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.2.1-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -262,9 +262,6 @@ def restore(xd, fd, dominfo = None, paus
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -267,9 +267,6 @@ def restore(xd, fd, dominfo = None, paus
store_port = dominfo.getStorePort()
console_port = dominfo.getConsolePort()
@ -31,7 +31,7 @@ Index: xen-4.2.1-testing/tools/python/xen/xend/XendCheckpoint.py
# if hvm, pass mem size to calculate the store_mfn
if is_hvm:
apic = int(dominfo.info['platform'].get('apic', 0))
@@ -276,6 +273,9 @@ def restore(xd, fd, dominfo = None, paus
@@ -281,6 +278,9 @@ def restore(xd, fd, dominfo = None, paus
pae = 0
try:

View File

@ -1,144 +0,0 @@
user: Olaf Hering <olaf@aepfle.de>
date: Wed Mar 06 17:05:15 2013 +0100
files: tools/libxc/xenguest.h tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xm/migrate.py tools/xcutils/xc_save.c
description:
tools: 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.
xl migrate is not modified with this change because it does not use the
stdio logger.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Index: xen-4.4.0-testing/tools/libxc/xenguest.h
===================================================================
--- xen-4.4.0-testing.orig/tools/libxc/xenguest.h
+++ xen-4.4.0-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.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -121,16 +121,19 @@ def save(fd, dominfo, network, live, dst
max_iters = dominfo.info.get('max_iters', "0")
max_factor = dominfo.info.get('max_factor', "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 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()),
max_iters, max_factor,
- str( int(live) | (int(hvm) << 2) | (int(abort_if_busy) << 5) ) ]
+ str( int(live) | (int(hvm) << 2) | (int(abort_if_busy) << 5) | (int(log_save_progress) << 6) ) ]
log.debug("[xc_save]: %s", string.join(cmd))
def saveInputHandler(line, tochild):
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomain.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomain.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomain.py
@@ -1832,17 +1832,18 @@ class XendDomain:
log.exception(ex)
raise XendError(str(ex))
- def domain_migrate_constraints_set(self, domid, max_iters, max_factor, abort_if_busy):
+ def domain_migrate_constraints_set(self, domid, max_iters, max_factor, 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 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, abort_if_busy)
+ dominfo.setMigrateConstraints(max_iters, max_factor, abort_if_busy, log_save_progress)
def domain_maxmem_set(self, domid, mem):
"""Set the memory limit for a domain.
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1475,17 +1475,19 @@ class XendDomainInfo:
break
xen.xend.XendDomain.instance().managed_config_save(self)
- def setMigrateConstraints(self, max_iters, max_factor, abort_if_busy):
+ def setMigrateConstraints(self, max_iters, max_factor, 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 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'.",
self.info['name_label'], str(self.domid), max_iters, max_factor, abort_if_busy)
self.info['max_iters'] = str(max_iters)
self.info['max_factor'] = str(max_factor)
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.
Index: xen-4.4.0-testing/tools/python/xen/xm/migrate.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/migrate.py
+++ xen-4.4.0-testing/tools/python/xen/xm/migrate.py
@@ -67,6 +67,10 @@ 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)
@@ -95,7 +99,8 @@ def main(argv):
server.xend.domain.migrate_constraints_set(dom,
opts.vals.max_iters,
opts.vals.max_factor,
- opts.vals.abort_if_busy)
+ 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.0-testing/tools/xcutils/xc_save.c
===================================================================
--- xen-4.4.0-testing.orig/tools/xcutils/xc_save.c
+++ xen-4.4.0-testing/tools/xcutils/xc_save.c
@@ -184,7 +184,8 @@ main(int argc, char **argv)
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;
+ lflags |= si.flags & XCFLAGS_PROGRESS ? 0 : XTL_STDIOSTREAM_HIDE_PROGRESS;
l = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, lvl, lflags);
si.xch = xc_interface_open(l, 0, 0);
if (!si.xch)

View File

@ -1,232 +0,0 @@
user: Olaf Hering <olaf@aepfle.de>
date: Wed Mar 06 17:05:14 2013 +0100
files: docs/man/xl.pod.1 tools/libxc/xc_domain_save.c tools/libxc/xenguest.h tools/libxl/Makefile tools/libxl/libxl.c tools/libxl/libxl.h tools/libxl/libxl_dom.c tools/libxl/libxl_internal.h tools/libxl/libxl_save_callout.c tools/libxl/xl_cmdimpl.c tools/libxl/xl_cmdtable.c tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xm/migrate.py
description:
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>
-A Abort migration instead of doing final suspend.
--abort_if_busy
The changes to libxl change the API, handle LIBXL_API_VERSION == 0x040200.
TODO:
eventually add also --min_remaining (default value 50) in a seperate patch
v6:
- update the LIBXL_API_VERSION handling for libxl_domain_suspend
change it to an inline function if LIBXL_API_VERSION is defined to 4.2.0
- rename libxl_save_properties to libxl_domain_suspend_properties
- rename ->xlflags to ->flags within that struct
v5:
- adjust libxl_domain_suspend prototype, move flags, max_iters,
max_factor into a new, optional struct libxl_save_properties
- rename XCFLAGS_DOMSAVE_NOSUSPEND to XCFLAGS_DOMSAVE_ABORT_IF_BUSY
- rename LIBXL_SUSPEND_NO_FINAL_SUSPEND to LIBXL_SUSPEND_ABORT_IF_BUSY
- rename variables no_suspend to abort_if_busy
- rename option -N/--no_suspend to -A/--abort_if_busy
- update xl.1, extend description of -A option
v4:
- update default for no_suspend from None to 0 in XendCheckpoint.py:save
- update logoutput in setMigrateConstraints
- change xm migrate defaults from None to 0
- add new options to xl.1
- fix syntax error in XendDomain.py:domain_migrate_constraints_set
- fix xm migrate -N option name to match xl migrate
v3:
- move logic errors in libxl__domain_suspend and fixed help text in
cmd_table to separate patches
- fix syntax error in XendCheckpoint.py
- really pass max_iters and max_factor in libxl__xc_domain_save
- make libxl_domain_suspend_0x040200 declaration globally visible
- bump libxenlight.so SONAME from 2.0 to 2.1 due to changed
libxl_domain_suspend
v2:
- use LIBXL_API_VERSION and define libxl_domain_suspend_0x040200
- fix logic error in min_reached check in xc_domain_save
- add longopts
- update --help text
- correct description of migrate --help text
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/libxc/xc_domain_save.c | 13 ++++++++++++-
tools/libxc/xenguest.h | 1 +
tools/python/xen/xend/XendCheckpoint.py | 14 ++++++++++++--
tools/python/xen/xend/XendDomain.py | 12 ++++++++++++
tools/python/xen/xend/XendDomainInfo.py | 12 ++++++++++++
tools/python/xen/xm/migrate.py | 16 ++++++++++++++++
6 files changed, 65 insertions(+), 3 deletions(-)
Index: xen-4.4.0-testing/tools/libxc/xc_domain_save.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxc/xc_domain_save.c
+++ xen-4.4.0-testing/tools/libxc/xc_domain_save.c
@@ -809,6 +809,7 @@ 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 abort_if_busy = (flags & XCFLAGS_DOMSAVE_ABORT_IF_BUSY);
int superpages = !!hvm;
int race = 0, sent_last_iter, skip_this_iter = 0;
unsigned int sent_this_iter = 0;
@@ -1532,10 +1533,20 @@ int xc_domain_save(xc_interface *xch, in
if ( live )
{
+ int min_reached = sent_this_iter + skip_this_iter < 50;
if ( (iter >= max_iters) ||
- (sent_this_iter+skip_this_iter < 50) ||
+ min_reached ||
(total_sent > dinfo->p2m_size*max_factor) )
{
+ if ( !min_reached && abort_if_busy )
+ {
+ 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;
Index: xen-4.4.0-testing/tools/libxc/xenguest.h
===================================================================
--- xen-4.4.0-testing.orig/tools/libxc/xenguest.h
+++ xen-4.4.0-testing/tools/libxc/xenguest.h
@@ -28,6 +28,7 @@
#define XCFLAGS_HVM (1 << 2)
#define XCFLAGS_STDVGA (1 << 3)
#define XCFLAGS_CHECKPOINT_COMPRESS (1 << 4)
+#define XCFLAGS_DOMSAVE_ABORT_IF_BUSY (1 << 5)
#define X86_64_B_SIZE 64
#define X86_32_B_SIZE 32
Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/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")
+ abort_if_busy = dominfo.info.get('abort_if_busy', "0")
+ if max_iters == "None":
+ max_iters = "0"
+ if max_factor == "None":
+ max_factor = "0"
+ if abort_if_busy == "None":
+ abort_if_busy = "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) ) ]
log.debug("[xc_save]: %s", string.join(cmd))
def saveInputHandler(line, tochild):
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomain.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomain.py
+++ xen-4.4.0-testing/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, abort_if_busy):
+ """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 abort_if_busy: 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, abort_if_busy)
+
def domain_maxmem_set(self, domid, mem):
"""Set the memory limit for a domain.
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1475,6 +1475,18 @@ class XendDomainInfo:
break
xen.xend.XendDomain.instance().managed_config_save(self)
+ def setMigrateConstraints(self, max_iters, max_factor, abort_if_busy):
+ """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 abort_if_busy: Abort migration instead of doing final suspend
+ """
+ log.debug("Setting migration constraints of domain %s (%s) to '%s' '%s' '%s'.",
+ self.info['name_label'], str(self.domid), max_iters, max_factor, abort_if_busy)
+ self.info['max_iters'] = str(max_iters)
+ self.info['max_factor'] = str(max_factor)
+ self.info['abort_if_busy'] = str(abort_if_busy)
+
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@param target: In MiB.
Index: xen-4.4.0-testing/tools/python/xen/xm/migrate.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/migrate.py
+++ xen-4.4.0-testing/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', 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('abort_if_busy',
+ fn=set_true, default=0,
+ 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.abort_if_busy)
server.xend.domain.migrate(dom, dst, opts.vals.live,
opts.vals.port,
opts.vals.node,

View File

@ -1,269 +0,0 @@
user: Olaf Hering <olaf@aepfle.de>
date: Thu Mar 28 15:42:14 2013 +0100
files: docs/man/xl.pod.1 tools/libxc/Makefile tools/libxc/xc_domain_save.c tools/libxc/xc_nomigrate.c tools/libxc/xenguest.h tools/libxl/libxl.c tools/libxl/libxl.h tools/libxl/libxl_internal.h tools/libxl/libxl_save_callout.c tools/libxl/libxl_save_helper.c tools/libxl/xl_cmdimpl.c tools/libxl/xl_cmdtable.c tools/python/xen/lowlevel/checkpoint/libcheckpoint.c tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xm/migrate.py tools/xcutils/xc_save.c
description:
tools: set number of dirty pages during migration
If a guest is really busy it will not reach the low number of remaining
50 dirty pages for the final suspend. As a result the guest is either
suspendend for a long time during the final transfer, or if the number
of iterations is increased the migration will take a long time.
Add a new option xm/xl migrate --min_remaing <pages> to increase the
default from command line. The default of 50 is 200kb, which is
appearently an arbitrary number. With todays network speeds a larger
block of memory can be transfered quickly without causing too much
suspension time. This knob gives the admin the chance to adapt the
suspension time to the given workload.
The existing default of 50 pages is not altered by this change.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/libxc/xc_domain_save.c | 6 ++++--
tools/libxc/xc_nomigrate.c | 2 +-
tools/libxc/xenguest.h | 2 +-
tools/libxl/libxl_save_helper.c | 2 +-
tools/python/xen/lowlevel/checkpoint/libcheckpoint.c | 2 +-
tools/python/xen/xend/XendCheckpoint.py | 5 ++++-
tools/python/xen/xend/XendDomain.py | 5 +++--
tools/python/xen/xend/XendDomainInfo.py | 8 +++++---
tools/python/xen/xm/migrate.py | 5 +++++
tools/xcutils/xc_save.c | 11 ++++++-----
11 files changed, 32 insertions(+), 18 deletions(-)
Index: xen-4.4.0-testing/tools/libxc/xc_domain_save.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxc/xc_domain_save.c
+++ xen-4.4.0-testing/tools/libxc/xc_domain_save.c
@@ -43,6 +43,7 @@
*/
#define DEF_MAX_ITERS 29 /* limit us to 30 times round loop */
#define DEF_MAX_FACTOR 3 /* never send more than 3x p2m_size */
+#define DEF_MIN_REMAINING 50 /* low water mark of dirty pages */
struct save_ctx {
unsigned long hvirt_start; /* virtual starting address of the hypervisor */
@@ -799,7 +800,7 @@ static int save_tsc_info(xc_interface *x
}
int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
- uint32_t max_factor, uint32_t flags,
+ uint32_t max_factor, uint32_t min_remaining, uint32_t flags,
struct save_callbacks* callbacks, int hvm,
unsigned long vm_generationid_addr)
{
@@ -910,6 +911,7 @@ int xc_domain_save(xc_interface *xch, in
/* If no explicit control parameters given, use defaults */
max_iters = max_iters ? : DEF_MAX_ITERS;
max_factor = max_factor ? : DEF_MAX_FACTOR;
+ min_remaining = min_remaining ? : DEF_MIN_REMAINING;
if ( !get_platform_info(xch, dom,
&ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, &dinfo->guest_width) )
@@ -1533,7 +1535,7 @@ int xc_domain_save(xc_interface *xch, in
if ( live )
{
- int min_reached = sent_this_iter + skip_this_iter < 50;
+ int min_reached = sent_this_iter + skip_this_iter < min_remaining;
if ( (iter >= max_iters) ||
min_reached ||
(total_sent > dinfo->p2m_size*max_factor) )
Index: xen-4.4.0-testing/tools/libxc/xc_nomigrate.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxc/xc_nomigrate.c
+++ xen-4.4.0-testing/tools/libxc/xc_nomigrate.c
@@ -22,7 +22,7 @@
#include <xenguest.h>
int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
- uint32_t max_factor, uint32_t flags,
+ uint32_t max_factor, uint32_t min_remaining, uint32_t flags,
struct save_callbacks* callbacks, int hvm,
unsigned long vm_generationid_addr)
{
Index: xen-4.4.0-testing/tools/libxc/xenguest.h
===================================================================
--- xen-4.4.0-testing.orig/tools/libxc/xenguest.h
+++ xen-4.4.0-testing/tools/libxc/xenguest.h
@@ -87,7 +87,7 @@ struct save_callbacks {
* @return 0 on success, -1 on failure
*/
int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
- uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
+ uint32_t max_factor, uint32_t min_remaining, uint32_t flags /* XCFLAGS_xxx */,
struct save_callbacks* callbacks, int hvm,
unsigned long vm_generationid_addr);
Index: xen-4.4.0-testing/tools/libxl/libxl_save_helper.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/libxl_save_helper.c
+++ xen-4.4.0-testing/tools/libxl/libxl_save_helper.c
@@ -235,7 +235,7 @@ int main(int argc, char **argv)
helper_setcallbacks_save(&helper_save_callbacks, cbflags);
startup("save");
- r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, flags,
+ r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, 0, flags,
&helper_save_callbacks, hvm, genidad);
complete(r);
Index: xen-4.4.0-testing/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
+++ xen-4.4.0-testing/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
@@ -206,7 +206,7 @@ int checkpoint_start(checkpoint_state* s
callbacks->switch_qemu_logdirty = noop_switch_logdirty;
- rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, flags, callbacks, hvm,
+ rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, 0, flags, callbacks, hvm,
vm_generationid_addr);
if (hvm)
Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -120,19 +120,22 @@ def save(fd, dominfo, network, live, dst
# 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()),
- max_iters, max_factor,
+ max_iters, max_factor, min_remaining,
str( int(live) | (int(hvm) << 2) | (int(abort_if_busy) << 5) | (int(log_save_progress) << 6) ) ]
log.debug("[xc_save]: %s", string.join(cmd))
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomain.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomain.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomain.py
@@ -1832,18 +1832,19 @@ class XendDomain:
log.exception(ex)
raise XendError(str(ex))
- def domain_migrate_constraints_set(self, domid, max_iters, max_factor, abort_if_busy, log_save_progress):
+ 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, abort_if_busy, log_save_progress)
+ 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.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1475,17 +1475,19 @@ class XendDomainInfo:
break
xen.xend.XendDomain.instance().managed_config_save(self)
- def setMigrateConstraints(self, max_iters, max_factor, abort_if_busy, log_save_progress):
+ 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'.",
- self.info['name_label'], str(self.domid), max_iters, max_factor, abort_if_busy)
+ 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)
Index: xen-4.4.0-testing/tools/python/xen/xm/migrate.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/migrate.py
+++ xen-4.4.0-testing/tools/python/xen/xm/migrate.py
@@ -63,6 +63,10 @@ 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.")
@@ -99,6 +103,7 @@ def main(argv):
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,
Index: xen-4.4.0-testing/tools/xcutils/xc_save.c
===================================================================
--- xen-4.4.0-testing.orig/tools/xcutils/xc_save.c
+++ xen-4.4.0-testing/tools/xcutils/xc_save.c
@@ -166,20 +166,21 @@ static int switch_qemu_logdirty(int domi
int
main(int argc, char **argv)
{
- unsigned int maxit, max_f, lflags;
+ unsigned int maxit, max_f, min_r, lflags;
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 minr flags", 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[5]);
+ si.flags = atoi(argv[6]);
si.suspend_evtchn = -1;
@@ -213,7 +214,7 @@ main(int argc, char **argv)
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(si.xch, io_fd, si.domid, maxit, max_f, min_r, si.flags,
&callbacks, !!(si.flags & XCFLAGS_HVM), 0);
if (si.suspend_evtchn > 0)

View File

@ -15,11 +15,12 @@
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
Name: xen
ExclusiveArch: %ix86 x86_64 %arm aarch64
%define xvers 4.4
%define xvermaj 4
%define changeset 28321
%define changeset 28372
%define xen_build_dir xen-4.4.0-testing
#
%define with_kmp 0
@ -95,7 +96,7 @@ BuildRequires: libyajl-devel
BuildRequires: libpixman-1-0-devel
%if %{?with_qemu_traditional}0
BuildRequires: pciutils-devel
BuildRequires: libSDL-devel
BuildRequires: SDL-devel
%endif
%if %{?with_stubdom}0
%if 0%{?suse_version} < 1230
@ -138,7 +139,7 @@ BuildRequires: xorg-x11-util-devel
%endif
%endif
Version: 4.4.0_03
Version: 4.4.0_04
Release: 0
PreReq: %insserv_prereq %fillup_prereq
Summary: Xen Virtualization: Hypervisor (aka VMM aka Microkernel)
@ -258,11 +259,12 @@ Patch382: ioemu-disable-emulated-ide-if-pv.patch
Patch383: xenpaging.qemu.flush-cache.patch
Patch384: qemu-xen-upstream-blkif-discard.patch
Patch385: xen_pvonhvm.xen_emul_unplug.patch
Patch386: libxc-pass-errno-to-callers-of-xc_domain_save.patch
Patch387: libxl.set-migration-constraints-from-cmdline.patch
# Xend
Patch400: xen.migrate.tools_set_migration_constraints_from_cmdline.patch
Patch401: xen.migrate.tools_add_xm_migrate_--log_progress_option.patch
Patch400: xend-set-migration-constraints-from-cmdline.patch
Patch402: xen.migrate.tools-xend_move_assert_to_exception_block.patch
Patch403: xen.migrate.tools_set_number_of_dirty_pages_during_migration.patch
Patch403: xend-pvscsi-recognize-also-SCSI-CDROM-devices.patch
Patch404: xend-config.patch
Patch405: xend-max-free-mem.patch
Patch406: xend-hvm-default-pae.patch
@ -607,10 +609,10 @@ Authors:
%patch383 -p1
%patch384 -p1
%patch385 -p1
%patch386 -p1
%patch387 -p1
# Xend
%if %{?with_xend}0
%patch400 -p1
%patch401 -p1
%patch402 -p1
%patch403 -p1
%patch404 -p1
@ -647,10 +649,7 @@ Authors:
%patch435 -p1
%patch436 -p1
%patch437 -p1
%if %suse_version <= 1230
%patch438 -p1
%endif
%endif
# Other bug fixes or features
%patch450 -p1
%patch451 -p1
@ -846,7 +845,9 @@ for name in COPYING %SOURCE10 %SOURCE11 %SOURCE12; do
install -m 644 $name $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/
done
mkdir -p $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/misc
for name in vtpm.txt crashdb.txt sedf_scheduler_mini-HOWTO.txt xenpaging.txt; do
for name in vtpm.txt crashdb.txt sedf_scheduler_mini-HOWTO.txt \
xenpaging.txt xl-disk-configuration.txt xl-network-configuration.markdown \
xl-numa-placement.markdown; do
install -m 644 docs/misc/$name $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/misc/
done

View File

@ -1,8 +1,8 @@
Index: xen-4.2.1-testing/tools/python/xen/xend/XendCheckpoint.py
Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.2.1-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.2.1-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -188,7 +188,7 @@ def save(fd, dominfo, network, live, dst
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -190,7 +190,7 @@ def save(fd, dominfo, network, live, dst
dominfo.destroy()
dominfo.testDeviceComplete()
try:

View File

@ -7,7 +7,7 @@ Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -345,8 +345,7 @@ def restore(xd, fd, dominfo = None, paus
@@ -347,8 +347,7 @@ def restore(xd, fd, dominfo = None, paus
restore_image.setCpuid()
# xc_restore will wait for source to close connection

View File

@ -3,10 +3,10 @@
tools/hotplug/Linux/Makefile | 1
tools/hotplug/Linux/domain-lock | 83 ++++++++++++++++++++++++++++++++
tools/hotplug/Linux/vm-monitor | 41 +++++++++++++++
tools/python/xen/xend/XendCheckpoint.py | 3 +
tools/python/xen/xend/XendCheckpoint.py | 9 +++
tools/python/xen/xend/XendDomainInfo.py | 74 ++++++++++++++++++++++++++++
tools/python/xen/xend/XendOptions.py | 29 +++++++++++
7 files changed, 290 insertions(+)
7 files changed, 296 insertions(+)
Index: xen-4.4.0-testing/tools/examples/xend-config.sxp
===================================================================
@ -228,8 +228,8 @@ Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -139,6 +139,11 @@ def save(fd, dominfo, network, live, dst
str( int(live) | (int(hvm) << 2) | (int(abort_if_busy) << 5) | (int(log_save_progress) << 6) ) ]
@@ -141,6 +141,11 @@ def save(fd, dominfo, network, live, dst
]
log.debug("[xc_save]: %s", string.join(cmd))
+ # It is safe to release the domain lock at this point if not
@ -240,7 +240,7 @@ Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
def saveInputHandler(line, tochild):
log.debug("In saveInputHandler %s", line)
if line == "suspend":
@@ -203,6 +208,9 @@ def save(fd, dominfo, network, live, dst
@@ -205,6 +210,9 @@ def save(fd, dominfo, network, live, dst
log.exception("Save failed on domain %s (%s) - resuming.", domain_name,
dominfo.getDomid())
dominfo.resumeDomain()
@ -250,7 +250,7 @@ Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
try:
dominfo.setName(domain_name)
@@ -369,6 +377,7 @@ def restore(xd, fd, dominfo = None, paus
@@ -371,6 +379,7 @@ def restore(xd, fd, dominfo = None, paus
if not paused:
dominfo.unpause()

View File

@ -92,7 +92,7 @@ Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1491,6 +1491,27 @@ class XendDomainInfo:
@@ -1477,6 +1477,27 @@ class XendDomainInfo:
self.info['abort_if_busy'] = str(abort_if_busy)
self.info['log_save_progress'] = str(log_save_progress)

View File

@ -21,7 +21,7 @@ Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -188,7 +188,10 @@ def save(fd, dominfo, network, live, dst
@@ -190,7 +190,10 @@ def save(fd, dominfo, network, live, dst
dominfo.destroy()
dominfo.testDeviceComplete()
try:

View File

@ -0,0 +1,27 @@
From: Olaf Hering <olaf@aepfle.de>
Date: Tue, 11 Feb 2014 15:21:01 +0100
Subject: xend/pvscsi: recognize also SCSI CDROM devices
Attaching a CDROM device with 'xm scsi-attach domU /dev/sr0 0:0:0:0'
fails because for some reason the sr driver was not handled at all in
the match list. With the change the above command succeeds and the
device is attached.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/python/xen/util/vscsi_util.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/python/xen/util/vscsi_util.py b/tools/python/xen/util/vscsi_util.py
--- a/tools/python/xen/util/vscsi_util.py
+++ b/tools/python/xen/util/vscsi_util.py
@@ -66,6 +66,9 @@ def _vscsi_get_hctl_by(phyname, scsi_devices):
if re.match('/dev/sd[a-z]+([1-9]|1[0-5])?$', phyname):
# sd driver
name = re.sub('(^/dev/)|([1-9]|1[0-5])?$', '', phyname)
+ elif re.match('/dev/sr[0-9]+$', phyname):
+ # sr driver
+ name = re.sub('^/dev/', '', phyname)
elif re.match('/dev/sg[0-9]+$', phyname):
# sg driver
name = re.sub('^/dev/', '', phyname)

View File

@ -0,0 +1,366 @@
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(-)
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index 92271c9..947991a 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -119,6 +119,7 @@ void xc_report_progress_step(xc_interface *xch,
/* 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)
diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h
index fc255c7..172d98a 100644
--- a/tools/libxc/xenguest.h
+++ b/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
diff --git a/tools/python/xen/xend/XendCheckpoint.py b/tools/python/xen/xend/XendCheckpoint.py
index b8caf02..4233e49 100644
--- a/tools/python/xen/xend/XendCheckpoint.py
+++ b/tools/python/xen/xend/XendCheckpoint.py
@@ -118,9 +118,27 @@ def save(fd, dominfo, network, live, dst, checkpoint=False, node=-1,sock=None):
# 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):
diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py
index 1d4da8f..6d873d6 100644
--- a/tools/python/xen/xend/XendDomain.py
+++ b/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.
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index 8d4ff5c..f77b270 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/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.
diff --git a/tools/python/xen/xm/migrate.py b/tools/python/xen/xm/migrate.py
index c1ea19d..c5c9500 100644
--- a/tools/python/xen/xm/migrate.py
+++ b/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,
diff --git a/tools/xcutils/xc_save.c b/tools/xcutils/xc_save.c
index e34bd2c..08ad224 100644
--- a/tools/xcutils/xc_save.c
+++ b/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 domid, unsigned int enable, void *data)
/* 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 domid, unsigned int enable, void *data)
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 domid, unsigned int enable, void *data)
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)

View File

@ -150,7 +150,7 @@ Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1563,6 +1563,17 @@ class XendDomainInfo:
@@ -1549,6 +1549,17 @@ class XendDomainInfo:
target = max_target
self.setMemoryTarget(target)