From: Olaf Hering <olaf@aepfle.de>
To: xen-devel@lists.xensource.com
Subject: [PATCH 7 of 7] xenpaging: start xenpaging via config option
Date: Thu, 31 Mar 2011 19:36:24 +0200 [thread overview]
Message-ID: <93889c2c6aad3d8ab9c0.1301592984@localhost> (raw)
In-Reply-To: <patchbomb.1301592977@localhost>
# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1301591717 -7200
# Node ID 93889c2c6aad3d8ab9c02da4197e9645a9a1aae2
# Parent 1d040925ea0dc5c01f7cf2c188ab01da48028f92
xenpaging: start xenpaging via config option
Start xenpaging via config option.
TODO: add libxl support
TODO: parse config values like 42K, 42M, 42G, 42%
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
v4:
add config option for pagefile directory
add config option to enable debug
add config option to set polic mru_size
fail if chdir fails
force self.xenpaging* variables to be strings because a xm new may turn some
of them into type int and later os.execve fails with a TypeError
v3:
decouple create/destroycreateXenPaging from _create/_removeDevices
init xenpaging variable to 0 if xenpaging is not in config file to
avoid string None coming from sxp file
v2:
unlink logfile instead of truncating it.
allows hardlinking for further inspection
diff -r 1d040925ea0d -r 93889c2c6aad tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm Thu Mar 31 19:14:01 2011 +0200
+++ b/tools/examples/xmexample.hvm Thu Mar 31 19:15:17 2011 +0200
@@ -127,6 +127,18 @@
# Device Model to be used
device_model = 'qemu-dm'
+# number of guest pages to page-out, or -1 for entire guest memory range
+xenpaging=42
+
+# directory to store guest page file
+#xenpaging_workdir="/var/lib/xen/xenpaging"
+
+# enable debug output in pager
+#xenpaging_debug=0
+
+# number of paged-in pages to keep in memory
+#xenpaging_policy_mru_size=1024
+
#-----------------------------------------------------------------------------
# boot on floppy (a), hard disk (c), Network (n) or CD-ROM (d)
# default: hard disk, cd-rom, floppy
diff -r 1d040925ea0d -r 93889c2c6aad tools/python/README.XendConfig
--- a/tools/python/README.XendConfig Thu Mar 31 19:14:01 2011 +0200
+++ b/tools/python/README.XendConfig Thu Mar 31 19:15:17 2011 +0200
@@ -120,6 +120,10 @@
image.vncdisplay
image.vncunused
image.hvm.device_model
+ image.hvm.xenpaging
+ image.hvm.xenpaging_workdir
+ image.hvm.xenpaging_debug
+ image.hvm.xenpaging_policy_mru_size
image.hvm.display
image.hvm.xauthority
image.hvm.vncconsole
diff -r 1d040925ea0d -r 93889c2c6aad tools/python/README.sxpcfg
--- a/tools/python/README.sxpcfg Thu Mar 31 19:14:01 2011 +0200
+++ b/tools/python/README.sxpcfg Thu Mar 31 19:15:17 2011 +0200
@@ -51,6 +51,10 @@
- vncunused
(HVM)
- device_model
+ - xenpaging
+ - xenpaging_workdir
+ - xenpaging_debug
+ - xenpaging_policy_mru_size
- display
- xauthority
- vncconsole
diff -r 1d040925ea0d -r 93889c2c6aad tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Thu Mar 31 19:14:01 2011 +0200
+++ b/tools/python/xen/xend/XendConfig.py Thu Mar 31 19:15:17 2011 +0200
@@ -147,6 +147,10 @@
'apic': int,
'boot': str,
'device_model': str,
+ 'xenpaging': str,
+ 'xenpaging_workdir': str,
+ 'xenpaging_debug': str,
+ 'xenpaging_policy_mru_size': str,
'loader': str,
'display' : str,
'fda': str,
@@ -512,6 +516,14 @@
self['platform']['nomigrate'] = 0
if self.is_hvm():
+ if 'xenpaging' not in self['platform']:
+ self['platform']['xenpaging'] = "0"
+ if 'xenpaging_workdir' not in self['platform']:
+ self['platform']['xenpaging_workdir'] = "/var/lib/xen/xenpaging"
+ if 'xenpaging_debug' not in self['platform']:
+ self['platform']['xenpaging_debug'] = "0"
+ if 'xenpaging_policy_mru_size' not in self['platform']:
+ self['platform']['xenpaging_policy_mru_size'] = "0"
if 'timer_mode' not in self['platform']:
self['platform']['timer_mode'] = 1
if 'viridian' not in self['platform']:
diff -r 1d040925ea0d -r 93889c2c6aad tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Thu Mar 31 19:14:01 2011 +0200
+++ b/tools/python/xen/xend/XendDomainInfo.py Thu Mar 31 19:15:17 2011 +0200
@@ -2246,6 +2246,8 @@
self.info['name_label'], self.domid, self.info['uuid'],
new_name, new_uuid)
self._unwatchVm()
+ if self.image:
+ self.image.destroyXenPaging()
self._releaseDevices()
# Remove existing vm node in xenstore
self._removeVm()
@@ -2913,6 +2915,9 @@
self._createDevices()
+ if self.image:
+ self.image.createXenPaging()
+
self.image.cleanupTmpImages()
self.info['start_time'] = time.time()
@@ -2937,6 +2942,8 @@
self.refresh_shutdown_lock.acquire()
try:
self.unwatchShutdown()
+ if self.image:
+ self.image.destroyXenPaging()
self._releaseDevices()
bootloader_tidy(self)
@@ -3016,6 +3023,7 @@
self.image = image.create(self, self.info)
if self.image:
self.image.createDeviceModel(True)
+ self.image.createXenPaging()
self._storeDomDetails()
self._registerWatches()
self.refreshShutdown()
@@ -3151,6 +3159,8 @@
# could also fetch a parsed note from xenstore
fast = self.info.get_notes().get('SUSPEND_CANCEL') and 1 or 0
if not fast:
+ if self.image:
+ self.image.destroyXenPaging()
self._releaseDevices()
self.testDeviceComplete()
self.testvifsComplete()
@@ -3166,6 +3176,8 @@
self._storeDomDetails()
self._createDevices()
+ if self.image:
+ self.image.createXenPaging()
log.debug("XendDomainInfo.resumeDomain: devices created")
xc.domain_resume(self.domid, fast)
diff -r 1d040925ea0d -r 93889c2c6aad tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Thu Mar 31 19:14:01 2011 +0200
+++ b/tools/python/xen/xend/image.py Thu Mar 31 19:15:17 2011 +0200
@@ -122,6 +122,11 @@
self.vm.permissionsVm("image/cmdline", { 'dom': self.vm.getDomid(), 'read': True } )
self.device_model = vmConfig['platform'].get('device_model')
+ self.xenpaging = str(vmConfig['platform'].get('xenpaging'))
+ self.xenpaging_workdir = str(vmConfig['platform'].get('xenpaging_workdir'))
+ self.xenpaging_debug = str(vmConfig['platform'].get('xenpaging_debug'))
+ self.xenpaging_policy_mru_size = str(vmConfig['platform'].get('xenpaging_policy_mru_size'))
+ self.xenpaging_pid = None
self.display = vmConfig['platform'].get('display')
self.xauthority = vmConfig['platform'].get('xauthority')
@@ -392,6 +397,88 @@
sentinel_fifos_inuse[sentinel_path_fifo] = 1
self.sentinel_path_fifo = sentinel_path_fifo
+ def createXenPaging(self):
+ if not self.vm.info.is_hvm():
+ return
+ if self.xenpaging == "0":
+ return
+ if self.xenpaging_pid:
+ return
+ xenpaging_bin = auxbin.pathTo("xenpaging")
+ args = [xenpaging_bin]
+ args = args + ([ "%d" % self.vm.getDomid()])
+ args = args + ([ "%s" % self.xenpaging])
+ env = dict(os.environ)
+ if not self.xenpaging_debug == "0":
+ env['XENPAGING_DEBUG'] = self.xenpaging_debug
+ if not self.xenpaging_policy_mru_size == "0":
+ env['XENPAGING_POLICY_MRU_SIZE'] = self.xenpaging_policy_mru_size
+ self.xenpaging_logfile = "/var/log/xen/xenpaging-%s.log" % str(self.vm.info['name_label'])
+ logfile_mode = os.O_WRONLY|os.O_CREAT|os.O_APPEND|os.O_TRUNC
+ null = os.open("/dev/null", os.O_RDONLY)
+ try:
+ os.unlink(self.xenpaging_logfile)
+ except:
+ pass
+ logfd = os.open(self.xenpaging_logfile, logfile_mode, 0644)
+ sys.stderr.flush()
+ contract = osdep.prefork("%s:%d" % (self.vm.getName(), self.vm.getDomid()))
+ xenpaging_pid = os.fork()
+ if xenpaging_pid == 0: #child
+ try:
+ osdep.postfork(contract)
+ os.dup2(null, 0)
+ os.dup2(logfd, 1)
+ os.dup2(logfd, 2)
+ os.chdir(self.xenpaging_workdir)
+ try:
+ log.info("starting %s" % args)
+ os.execve(xenpaging_bin, args, env)
+ except Exception, e:
+ log.warn('failed to execute xenpaging: %s' % utils.exception_string(e))
+ os._exit(126)
+ except:
+ log.warn("starting xenpaging in %s failed" % self.xenpaging_workdir)
+ os._exit(127)
+ else:
+ osdep.postfork(contract, abandon=True)
+ self.xenpaging_pid = xenpaging_pid
+ os.close(null)
+ os.close(logfd)
+
+ def destroyXenPaging(self):
+ if self.xenpaging == "0":
+ return
+ if self.xenpaging_pid:
+ try:
+ os.kill(self.xenpaging_pid, signal.SIGHUP)
+ except OSError, exn:
+ log.exception(exn)
+ for i in xrange(100):
+ try:
+ (p, rv) = os.waitpid(self.xenpaging_pid, os.WNOHANG)
+ if p == self.xenpaging_pid:
+ break
+ except OSError:
+ # This is expected if Xend has been restarted within
+ # the life of this domain. In this case, we can kill
+ # the process, but we can't wait for it because it's
+ # not our child. We continue this loop, and after it is
+ # terminated make really sure the process is going away
+ # (SIGKILL).
+ pass
+ time.sleep(0.1)
+ else:
+ log.warning("xenpaging %d took more than 10s "
+ "to terminate: sending SIGKILL" % self.xenpaging_pid)
+ try:
+ os.kill(self.xenpaging_pid, signal.SIGKILL)
+ os.waitpid(self.xenpaging_pid, 0)
+ except OSError:
+ # This happens if the process doesn't exist.
+ pass
+ self.xenpaging_pid = None
+
def createDeviceModel(self, restore = False):
if self.device_model is None:
return
diff -r 1d040925ea0d -r 93889c2c6aad tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Thu Mar 31 19:14:01 2011 +0200
+++ b/tools/python/xen/xm/create.py Thu Mar 31 19:15:17 2011 +0200
@@ -491,6 +491,22 @@
fn=set_value, default=None,
use="Set the path of the root NFS directory.")
+gopts.var('xenpaging', val='NUM',
+ fn=set_value, default='0',
+ use="Number of pages to swap.")
+
+gopts.var('xenpaging_workdir', val='PATH',
+ fn=set_value, default='/var/lib/xen/xenpaging',
+ use="Number of pages to swap.")
+
+gopts.var('xenpaging_debug', val='NUM',
+ fn=set_value, default='0',
+ use="Number of pages to swap.")
+
+gopts.var('xenpaging_policy_mru_size', val='NUM',
+ fn=set_value, default='0',
+ use="Number of pages to swap.")
+
gopts.var('device_model', val='FILE',
fn=set_value, default=None,
use="Path to device model program.")
@@ -1076,6 +1092,10 @@
args = [ 'acpi', 'apic',
'boot',
'cpuid', 'cpuid_check',
+ 'xenpaging',
+ 'xenpaging_workdir',
+ 'xenpaging_debug',
+ 'xenpaging_policy_mru_size',
'device_model', 'display',
'fda', 'fdb',
'gfx_passthru', 'guest_os_type',
diff -r 1d040925ea0d -r 93889c2c6aad tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py Thu Mar 31 19:14:01 2011 +0200
+++ b/tools/python/xen/xm/xenapi_create.py Thu Mar 31 19:15:17 2011 +0200
@@ -1085,6 +1085,10 @@
'acpi',
'apic',
'boot',
+ 'xenpaging',
+ 'xenpaging_workdir',
+ 'xenpaging_debug',
+ 'xenpaging_policy_mru_size',
'device_model',
'loader',
'fda',
next prev parent reply other threads:[~2011-03-31 17:36 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-31 17:36 [PATCH 0 of 7] xenpaging updates Olaf Hering
2011-03-31 17:36 ` [PATCH 1 of 7] xenpaging: correct dropping pages to avoid full ring buffer Olaf Hering
2011-03-31 17:36 ` [PATCH 2 of 7] xenpaging: do not bounce p2mt to xenpaging Olaf Hering
2011-03-31 17:36 ` [PATCH 3 of 7] xenpaging: remove srand call Olaf Hering
2011-03-31 17:48 ` Patrick Colp
2011-03-31 18:17 ` Olaf Hering
2011-03-31 18:37 ` Patrick Colp
2011-04-01 8:20 ` Olaf Hering
2011-04-02 19:29 ` Patrick Colp
2011-03-31 17:36 ` [PATCH 4 of 7] xenpaging: remove return values from functions that can not fail Olaf Hering
2011-03-31 17:36 ` [PATCH 5 of 7] xenpaging: catch xc_mem_paging_resume errors Olaf Hering
2011-03-31 17:36 ` [PATCH 6 of 7] xenpaging: pass integer to xenpaging_populate_page Olaf Hering
2011-03-31 17:36 ` Olaf Hering [this message]
2011-04-01 10:24 ` [PATCH 0 of 7] xenpaging updates Keir Fraser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=93889c2c6aad3d8ab9c0.1301592984@localhost \
--to=olaf@aepfle.de \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.