- 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:
parent
c0303bd7d9
commit
f43e68d196
@ -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,
|
||||
|
647
libxc-pass-errno-to-callers-of-xc_domain_save.patch
Normal file
647
libxc-pass-errno-to-callers-of-xc_domain_save.patch
Normal 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;
|
||||
}
|
@ -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");
|
||||
|
493
libxl.set-migration-constraints-from-cmdline.patch
Normal file
493
libxl.set-migration-constraints-from-cmdline.patch
Normal 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© (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,
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:59ff093f019bef266d60fdf799321b322d98664a4cb410fc064706d165e103d5
|
||||
size 7572593
|
||||
oid sha256:27825df0797b7e7da48974205534f73cfb54c21270f6cf1fdad4a09efe77ed3d
|
||||
size 7570627
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:554f1d2575ee8650425dcceec67de6cabcab54c185648a4a606713c680eaf492
|
||||
size 3212156
|
||||
oid sha256:850f3fa6cef695d4df38ce848dc92eabc202d4da4a2199335f4851538c27ee2f
|
||||
size 3212885
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:84121ad5559806fc92fb032a94929a2c9c47719369a913cca677e2e2b9a70e7b
|
||||
size 366155
|
||||
oid sha256:0a6cbb7ee06faa1c2f922b96a9883a56461db169ea13a22f46d4c56d174c3923
|
||||
size 366315
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:782788ab7f071adc277781f0478681fc267d576cff682c0343d7663e987cc29c
|
||||
size 4351908
|
||||
oid sha256:d349ab905290a20cea87fe5012cfeacd00663d25a1cb9f6dcbc6aee30f9eacab
|
||||
size 4356190
|
||||
|
38
xen.changes
38
xen.changes
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
@ -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,
|
@ -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)
|
25
xen.spec
25
xen.spec
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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:
|
||||
|
27
xend-pvscsi-recognize-also-SCSI-CDROM-devices.patch
Normal file
27
xend-pvscsi-recognize-also-SCSI-CDROM-devices.patch
Normal 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)
|
366
xend-set-migration-constraints-from-cmdline.patch
Normal file
366
xend-set-migration-constraints-from-cmdline.patch
Normal 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)
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user