mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
Transcendent memory ("tmem") for Xen.
Tmem, when called from a tmem-capable (paravirtualized) guest, makes
use of otherwise unutilized ("fallow") memory to create and manage
pools of pages that can be accessed from the guest either as
"ephemeral" pages or as "persistent" pages. In either case, the pages
are not directly addressible by the guest, only copied to and fro via
the tmem interface. Ephemeral pages are a nice place for a guest to
put recently evicted clean pages that it might need again; these pages
can be reclaimed synchronously by Xen for other guests or other uses.
Persistent pages are a nice place for a guest to put "swap" pages to
avoid sending them to disk. These pages retain data as long as the
guest lives, but count against the guest memory allocation.
Tmem pages may optionally be compressed and, in certain cases, can be
shared between guests. Tmem also handles concurrency nicely and
provides limited QoS settings to combat malicious DoS attempts.
Save/restore and live migration support is not yet provided.
Tmem is primarily targeted for an x86 64-bit hypervisor. On a 32-bit
x86 hypervisor, it has limited functionality and testing due to
limitations of the xen heap. Nearly all of tmem is
architecture-independent; three routines remain to be ported to ia64
and it should work on that architecture too. It is also structured to
be portable to non-Xen environments.
Tmem defaults off (for now) and must be enabled with a "tmem" xen boot
option (and does nothing unless a tmem-capable guest is running). The
"tmem_compress" boot option enables compression which takes about 10x
more CPU but approximately doubles the number of pages that can be
stored.
Tmem can be controlled via several "xm" commands and many interesting
tmem statistics can be obtained. A README and internal specification
will follow, but lots of useful prose about tmem, as well as Linux
patches, can be found at http://oss.oracle.com/projects/tmem .
Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>
This commit is contained in:
1 parent
ff811c2bc4
commit
6009f4ddb2
49 files changed
+5638
-39
No files matched your search
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "xenctrl.h"
|
||||
#include <xen/elfnote.h>
|
||||
#include <xen/tmem.h>
|
||||
#include "xc_dom.h"
|
||||
#include <xen/hvm/hvm_info_table.h>
|
||||
#include <xen/hvm/params.h>
|
||||
@@ -1506,6 +1507,50 @@ static PyObject *dom_op(XcObject *self, PyObject *args,
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyObject *pyxc_tmem_control(XcObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
int32_t pool_id;
|
||||
uint32_t subop;
|
||||
uint32_t cli_id;
|
||||
uint32_t arg1;
|
||||
uint32_t arg2;
|
||||
char *buf;
|
||||
char _buffer[32768], *buffer = _buffer;
|
||||
int rc;
|
||||
|
||||
static char *kwd_list[] = { "pool_id", "subop", "cli_id", "arg1", "arg2", "buf", NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiiis", kwd_list,
|
||||
&pool_id, &subop, &cli_id, &arg1, &arg2, &buf) )
|
||||
return NULL;
|
||||
|
||||
if ( (subop == TMEMC_LIST) && (arg1 > 32768) )
|
||||
arg1 = 32768;
|
||||
|
||||
if ( (rc = xc_tmem_control(self->xc_handle, pool_id, subop, cli_id, arg1, arg2, buffer)) < 0 )
|
||||
return Py_BuildValue("i", rc);
|
||||
|
||||
switch (subop) {
|
||||
case TMEMC_LIST:
|
||||
return Py_BuildValue("s", buffer);
|
||||
case TMEMC_FLUSH:
|
||||
return Py_BuildValue("i", rc);
|
||||
case TMEMC_THAW:
|
||||
case TMEMC_FREEZE:
|
||||
case TMEMC_DESTROY:
|
||||
case TMEMC_SET_WEIGHT:
|
||||
case TMEMC_SET_CAP:
|
||||
case TMEMC_SET_COMPRESS:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyMethodDef pyxc_methods[] = {
|
||||
{ "handle",
|
||||
(PyCFunction)pyxc_handle,
|
||||
@@ -1965,6 +2010,18 @@ static PyMethodDef pyxc_methods[] = {
|
||||
" dom [int]: Identifier of domain.\n" },
|
||||
#endif
|
||||
|
||||
{ "tmem_control",
|
||||
(PyCFunction)pyxc_tmem_control,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Do various control on a tmem pool.\n"
|
||||
" pool_id [int]: Identifier of the tmem pool (-1 == all).\n"
|
||||
" subop [int]: Supplementary Operation.\n"
|
||||
" cli_id [int]: Client identifier (-1 == all).\n"
|
||||
" arg1 [int]: Argument.\n"
|
||||
" arg2 [int]: Argument.\n"
|
||||
" buf [str]: Buffer.\n\n"
|
||||
"Returns: [int] 0 or [str] tmem info on success; exception on error.\n" },
|
||||
|
||||
{ NULL, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
@@ -925,7 +925,15 @@ class XendAPI(object):
|
||||
('dmesg', 'String'),
|
||||
('dmesg_clear', 'String'),
|
||||
('get_log', 'String'),
|
||||
('send_debug_keys', None)]
|
||||
('send_debug_keys', None),
|
||||
('tmem_thaw', None),
|
||||
('tmem_freeze', None),
|
||||
('tmem_flush', None),
|
||||
('tmem_destroy', None),
|
||||
('tmem_list', None),
|
||||
('tmem_set_weight', None),
|
||||
('tmem_set_cap', None),
|
||||
('tmem_set_compress', None)]
|
||||
|
||||
host_funcs = [('get_by_name_label', None),
|
||||
('list_methods', None)]
|
||||
@@ -1061,6 +1069,70 @@ class XendAPI(object):
|
||||
'PSCSIs': XendPSCSI.get_all()}
|
||||
return xen_api_success(record)
|
||||
|
||||
def host_tmem_thaw(self, _, host_ref, cli_id):
|
||||
node = XendNode.instance()
|
||||
try:
|
||||
node.tmem_thaw(cli_id)
|
||||
except Exception, e:
|
||||
return xen_api_error(e)
|
||||
return xen_api_success_void()
|
||||
|
||||
def host_tmem_freeze(self, _, host_ref, cli_id):
|
||||
node = XendNode.instance()
|
||||
try:
|
||||
node.tmem_freeze(cli_id)
|
||||
except Exception, e:
|
||||
return xen_api_error(e)
|
||||
return xen_api_success_void()
|
||||
|
||||
def host_tmem_flush(self, _, host_ref, cli_id, pages):
|
||||
node = XendNode.instance()
|
||||
try:
|
||||
node.tmem_flush(cli_id, pages)
|
||||
except Exception, e:
|
||||
return xen_api_error(e)
|
||||
return xen_api_success_void()
|
||||
|
||||
def host_tmem_destroy(self, _, host_ref, cli_id):
|
||||
node = XendNode.instance()
|
||||
try:
|
||||
node.tmem_destroy(cli_id)
|
||||
except Exception, e:
|
||||
return xen_api_error(e)
|
||||
return xen_api_success_void()
|
||||
|
||||
def host_tmem_list(self, _, host_ref, cli_id, use_long):
|
||||
node = XendNode.instance()
|
||||
try:
|
||||
info = node.tmem_list(cli_id, use_long)
|
||||
except Exception, e:
|
||||
return xen_api_error(e)
|
||||
return xen_api_success(info)
|
||||
|
||||
def host_tmem_set_weight(self, _, host_ref, cli_id, value):
|
||||
node = XendNode.instance()
|
||||
try:
|
||||
node.tmem_set_weight(cli_id, value)
|
||||
except Exception, e:
|
||||
return xen_api_error(e)
|
||||
return xen_api_success_void()
|
||||
|
||||
def host_tmem_set_cap(self, _, host_ref, cli_id, value):
|
||||
node = XendNode.instance()
|
||||
try:
|
||||
node.tmem_set_cap(cli_id, value)
|
||||
except Exception, e:
|
||||
return xen_api_error(e)
|
||||
return xen_api_success_void()
|
||||
|
||||
def host_tmem_set_compress(self, _, host_ref, cli_id, value):
|
||||
node = XendNode.instance()
|
||||
try:
|
||||
node.tmem_set_compress(cli_id, value)
|
||||
except Exception, e:
|
||||
return xen_api_error(e)
|
||||
return xen_api_success_void()
|
||||
|
||||
# class methods
|
||||
def host_get_all(self, session):
|
||||
return xen_api_success((XendNode.instance().uuid,))
|
||||
|
||||
@@ -141,3 +141,29 @@ XS_VMROOT = "/vm/"
|
||||
NR_PCI_DEV = 32
|
||||
AUTO_PHP_SLOT = NR_PCI_DEV
|
||||
AUTO_PHP_SLOT_STR = "%02x" % NR_PCI_DEV
|
||||
|
||||
#
|
||||
# tmem
|
||||
#
|
||||
|
||||
TMEM_CONTROL = 0
|
||||
TMEM_NEW_POOL = 1
|
||||
TMEM_DESTROY_POOL = 2
|
||||
TMEM_NEW_PAGE = 3
|
||||
TMEM_PUT_PAGE = 4
|
||||
TMEM_GET_PAGE = 5
|
||||
TMEM_FLUSH_PAGE = 6
|
||||
TMEM_FLUSH_OBJECT = 7
|
||||
TMEM_READ = 8
|
||||
TMEM_WRITE = 9
|
||||
TMEM_XCHG = 10
|
||||
|
||||
TMEMC_THAW = 0
|
||||
TMEMC_FREEZE = 1
|
||||
TMEMC_FLUSH = 2
|
||||
TMEMC_DESTROY = 3
|
||||
TMEMC_LIST = 4
|
||||
TMEMC_SET_WEIGHT = 5
|
||||
TMEMC_SET_CAP = 6
|
||||
TMEMC_SET_COMPRESS = 7
|
||||
|
||||
@@ -26,6 +26,7 @@ from xen.util import pci as PciUtil
|
||||
from xen.util import vscsi_util
|
||||
from xen.xend import XendAPIStore
|
||||
from xen.xend import osdep
|
||||
from xen.xend.XendConstants import *
|
||||
|
||||
import uuid, arch
|
||||
from XendPBD import XendPBD
|
||||
@@ -940,6 +941,69 @@ class XendNode:
|
||||
def info_dict(self):
|
||||
return dict(self.info())
|
||||
|
||||
# tmem
|
||||
def tmem_list(self, cli_id, use_long):
|
||||
pool_id = -1
|
||||
subop = TMEMC_LIST
|
||||
arg1 = 32768
|
||||
arg2 = use_long
|
||||
buf = ''
|
||||
return self.xc.tmem_control(pool_id, subop, cli_id, arg1, arg2, buf)
|
||||
|
||||
def tmem_thaw(self, cli_id):
|
||||
pool_id = -1
|
||||
subop = TMEMC_THAW
|
||||
arg1 = 0
|
||||
arg2 = 0
|
||||
buf = ''
|
||||
return self.xc.tmem_control(pool_id, subop, cli_id, arg1, arg2, buf)
|
||||
|
||||
def tmem_freeze(self, cli_id):
|
||||
pool_id = -1
|
||||
subop = TMEMC_FREEZE
|
||||
arg1 = 0
|
||||
arg2 = 0
|
||||
buf = ''
|
||||
return self.xc.tmem_control(pool_id, subop, cli_id, arg1, arg2, buf)
|
||||
|
||||
def tmem_flush(self, cli_id, pages):
|
||||
pool_id = -1
|
||||
subop = TMEMC_FLUSH
|
||||
arg1 = pages
|
||||
arg2 = 0
|
||||
buf = ''
|
||||
return self.xc.tmem_control(pool_id, subop, cli_id, arg1, arg2, buf)
|
||||
|
||||
def tmem_destroy(self, cli_id):
|
||||
pool_id = -1
|
||||
subop = TMEMC_DESTROY
|
||||
arg1 = 0
|
||||
arg2 = 0
|
||||
buf = ''
|
||||
return self.xc.tmem_control(pool_id, subop, cli_id, arg1, arg2, buf)
|
||||
|
||||
def tmem_set_weight(self, cli_id, arg1):
|
||||
pool_id = -1
|
||||
subop = TMEMC_SET_WEIGHT
|
||||
arg2 = 0
|
||||
buf = ''
|
||||
return self.xc.tmem_control(pool_id, subop, cli_id, arg1, arg2, buf)
|
||||
|
||||
def tmem_set_cap(self, cli_id, arg1):
|
||||
pool_id = -1
|
||||
subop = TMEMC_SET_CAP
|
||||
arg2 = 0
|
||||
buf = ''
|
||||
return self.xc.tmem_control(pool_id, subop, cli_id, arg1, arg2, buf)
|
||||
|
||||
def tmem_set_compress(self, cli_id, arg1):
|
||||
pool_id = -1
|
||||
subop = TMEMC_SET_COMPRESS
|
||||
arg2 = 0
|
||||
buf = ''
|
||||
return self.xc.tmem_control(pool_id, subop, cli_id, arg1, arg2, buf)
|
||||
|
||||
|
||||
def instance():
|
||||
global inst
|
||||
try:
|
||||
|
||||
@@ -26,6 +26,7 @@ import XendOptions
|
||||
from XendLogging import log
|
||||
from XendError import VmError
|
||||
import osdep
|
||||
from xen.xend.XendConstants import *
|
||||
|
||||
RETRY_LIMIT = 20
|
||||
RETRY_LIMIT_INCR = 5
|
||||
@@ -109,6 +110,9 @@ def free(need_mem, dominfo):
|
||||
last_free = None
|
||||
rlimit = RETRY_LIMIT
|
||||
|
||||
# stop tmem from absorbing any more memory (must THAW when done!)
|
||||
xc.tmem_control(0,TMEMC_FREEZE,-1, 0, 0, "")
|
||||
|
||||
# If unreasonable memory size is required, we give up waiting
|
||||
# for ballooning or scrubbing, as if had retried.
|
||||
physinfo = xc.physinfo()
|
||||
@@ -122,6 +126,17 @@ def free(need_mem, dominfo):
|
||||
if need_mem >= max_free_mem:
|
||||
retries = rlimit
|
||||
|
||||
freeable_mem = free_mem + scrub_mem
|
||||
if freeable_mem < need_mem and need_mem < max_free_mem:
|
||||
# flush memory from tmem to scrub_mem and reobtain physinfo
|
||||
need_tmem_kb = need_mem - freeable_mem
|
||||
tmem_kb = xc.tmem_control(0,TMEMC_FLUSH,-1, need_tmem_kb, 0, "")
|
||||
log.debug("Balloon: tmem relinquished %d KiB of %d KiB requested.",
|
||||
tmem_kb, need_tmem_kb)
|
||||
physinfo = xc.physinfo()
|
||||
free_mem = physinfo['free_memory']
|
||||
scrub_mem = physinfo['scrub_memory']
|
||||
|
||||
# Check whethercurrent machine is a numa system and the new
|
||||
# created hvm has all its vcpus in the same node, if all the
|
||||
# conditions above are fit. We will wait until all the pages
|
||||
@@ -216,4 +231,6 @@ def free(need_mem, dominfo):
|
||||
' be shrunk any further'))
|
||||
|
||||
finally:
|
||||
# allow tmem to accept pages again
|
||||
xc.tmem_control(0,TMEMC_THAW,-1, 0, 0, "")
|
||||
del xc
|
||||
@@ -198,7 +198,11 @@ class XMLRPCServer:
|
||||
self.server.register_function(fn, "xend.domain.%s" % name[7:])
|
||||
|
||||
# Functions in XendNode and XendDmesg
|
||||
for type, lst, n in [(XendNode, ['info', 'pciinfo', 'send_debug_keys'],
|
||||
for type, lst, n in [(XendNode,
|
||||
['info', 'pciinfo', 'send_debug_keys',
|
||||
'tmem_list', 'tmem_freeze', 'tmem_thaw',
|
||||
'tmem_flush', 'tmem_destroy', 'tmem_set_weight',
|
||||
'tmem_set_cap', 'tmem_set_compress'],
|
||||
'node'),
|
||||
(XendDmesg, ['info', 'clear'], 'node.dmesg')]:
|
||||
inst = type.instance()
|
||||
|
||||
+222
-2
@@ -199,6 +199,15 @@ SUBCOMMAND_HELP = {
|
||||
'scsi-list' : ('<Domain> [--long]',
|
||||
'List all SCSI devices currently attached.'),
|
||||
|
||||
# tmem
|
||||
'tmem-list' : ('[-l|--long] [<Domain>|-a|--all]', 'List tmem pools.'),
|
||||
'tmem-thaw' : ('[<Domain>|-a|--all]', 'Thaw tmem pools.'),
|
||||
'tmem-freeze' : ('[<Domain>|-a|--all]', 'Freeze tmem pools.'),
|
||||
'tmem-destroy' : ('[<Domain>|-a|--all]', 'Destroy tmem pools.'),
|
||||
'tmem-set' : ('[<Domain>|-a|--all] [weight=<weight>] [cap=<cap>] '
|
||||
'[compress=<compress>]',
|
||||
'Change tmem settings.'),
|
||||
|
||||
# security
|
||||
|
||||
'addlabel' : ('<label> {dom <ConfigFile>|res <resource>|mgt <managed domain>}\n'
|
||||
@@ -283,6 +292,21 @@ SUBCOMMAND_OPTIONS = {
|
||||
'info': (
|
||||
('-c', '--config', 'List Xend configuration parameters'),
|
||||
),
|
||||
'tmem-list': (
|
||||
('-l', '--long', 'List tmem stats.'),
|
||||
),
|
||||
'tmem-thaw': (
|
||||
('-a', '--all', 'Thaw all tmem.'),
|
||||
),
|
||||
'tmem-freeze': (
|
||||
('-a', '--all', 'Freeze all tmem.'),
|
||||
),
|
||||
'tmem-destroy': (
|
||||
('-a', '--all', 'Destroy all tmem.'),
|
||||
),
|
||||
'tmem-set': (
|
||||
('-a', '--all', 'Operate on all tmem.'),
|
||||
),
|
||||
}
|
||||
|
||||
common_commands = [
|
||||
@@ -397,9 +421,17 @@ acm_commands = [
|
||||
"getpolicy",
|
||||
]
|
||||
|
||||
tmem_commands = [
|
||||
"tmem-list",
|
||||
"tmem-thaw",
|
||||
"tmem-freeze",
|
||||
"tmem-destroy",
|
||||
"tmem-set",
|
||||
]
|
||||
|
||||
all_commands = (domain_commands + host_commands + scheduler_commands +
|
||||
device_commands + vnet_commands + acm_commands +
|
||||
['shell', 'event-monitor'])
|
||||
tmem_commands + ['shell', 'event-monitor'])
|
||||
|
||||
|
||||
##
|
||||
@@ -2837,7 +2869,188 @@ def xm_network_show(args):
|
||||
|
||||
print format2 % r
|
||||
|
||||
|
||||
def xm_tmem_list(args):
|
||||
try:
|
||||
(options, params) = getopt.gnu_getopt(args, 'la', ['long','all'])
|
||||
except getopt.GetoptError, opterr:
|
||||
err(opterr)
|
||||
usage('tmem-list')
|
||||
|
||||
use_long = False
|
||||
for (k, v) in options:
|
||||
if k in ['-l', '--long']:
|
||||
use_long = True
|
||||
|
||||
all = False
|
||||
for (k, v) in options:
|
||||
if k in ['-a', '--all']:
|
||||
all = True
|
||||
|
||||
if not all and len(params) == 0:
|
||||
err('You must specify -a or --all or a domain id.')
|
||||
usage('tmem-list')
|
||||
|
||||
if all:
|
||||
domid = -1
|
||||
else:
|
||||
try:
|
||||
domid = int(params[0])
|
||||
params = params[1:]
|
||||
except:
|
||||
err('Unrecognized domain id: %s' % params[0])
|
||||
usage('tmem-list')
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
print server.xenapi.host.tmem_list(domid,use_long)
|
||||
else:
|
||||
print server.xend.node.tmem_list(domid,use_long)
|
||||
|
||||
def parse_tmem_args(args, name):
|
||||
try:
|
||||
(options, params) = getopt.gnu_getopt(args, 'a', ['all'])
|
||||
except getopt.GetoptError, opterr:
|
||||
err(opterr)
|
||||
usage(name)
|
||||
|
||||
all = False
|
||||
for (k, v) in options:
|
||||
if k in ['-a', '--all']:
|
||||
all = True
|
||||
|
||||
if not all and len(params) == 0:
|
||||
err('You must specify -a or --all or a domain id.')
|
||||
usage(name)
|
||||
|
||||
if all:
|
||||
domid = -1
|
||||
else:
|
||||
try:
|
||||
domid = int(params[0])
|
||||
params = params[1:]
|
||||
except:
|
||||
err('Unrecognized domain id: %s' % params[0])
|
||||
usage(name)
|
||||
|
||||
return domid, params
|
||||
|
||||
def xm_tmem_destroy(args):
|
||||
(domid, _) = parse_tmem_args(args, 'tmem-destroy')
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.host.tmem_destroy(domid)
|
||||
else:
|
||||
server.xend.node.tmem_destroy(domid)
|
||||
|
||||
def xm_tmem_thaw(args):
|
||||
(domid, _) = parse_tmem_args(args, 'tmem-thaw')
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.host.tmem_thaw(domid)
|
||||
else:
|
||||
server.xend.node.tmem_thaw(domid)
|
||||
|
||||
def xm_tmem_freeze(args):
|
||||
(domid, _) = parse_tmem_args(args, 'tmem-freeze')
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.host.tmem_freeze(domid)
|
||||
else:
|
||||
server.xend.node.tmem_freeze(domid)
|
||||
|
||||
def xm_tmem_flush(args):
|
||||
try:
|
||||
(options, params) = getopt.gnu_getopt(args, 'a', ['all'])
|
||||
except getopt.GetoptError, opterr:
|
||||
err(opterr)
|
||||
usage(name)
|
||||
|
||||
all = False
|
||||
for (k, v) in options:
|
||||
if k in ['-a', '--all']:
|
||||
all = True
|
||||
|
||||
if not all and len(params) == 0:
|
||||
err('You must specify -a or --all or a domain id.')
|
||||
usage('tmem-flush')
|
||||
|
||||
if all:
|
||||
domid = -1
|
||||
else:
|
||||
try:
|
||||
domid = int(params[0])
|
||||
params = params[1:]
|
||||
except:
|
||||
err('Unrecognized domain id: %s' % params[0])
|
||||
usage('tmem-flush')
|
||||
|
||||
pages = -1
|
||||
for (k, v) in options:
|
||||
if k in ['-p', '--pages']:
|
||||
pages = v
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.host.tmem_flush(domid,pages)
|
||||
else:
|
||||
server.xend.node.tmem_flush(domid,pages)
|
||||
|
||||
def xm_tmem_set(args):
|
||||
try:
|
||||
(options, params) = getopt.gnu_getopt(args, 'a', ['all'])
|
||||
except getopt.GetoptError, opterr:
|
||||
err(opterr)
|
||||
usage(name)
|
||||
|
||||
all = False
|
||||
for (k, v) in options:
|
||||
if k in ['-a', '--all']:
|
||||
all = True
|
||||
|
||||
if not all and len(params) == 0:
|
||||
err('You must specify -a or --all or a domain id.')
|
||||
usage('tmem-set')
|
||||
|
||||
if all:
|
||||
domid = -1
|
||||
else:
|
||||
try:
|
||||
domid = int(params[0])
|
||||
params = params[1:]
|
||||
except:
|
||||
err('Unrecognized domain id: %s' % params[0])
|
||||
usage('tmem-set')
|
||||
|
||||
weight = None
|
||||
cap = None
|
||||
compress = None
|
||||
for item in params:
|
||||
if item.startswith('weight='):
|
||||
try:
|
||||
weight = int(item[7:])
|
||||
except:
|
||||
err('weight should be a integer')
|
||||
usage('tmem-set')
|
||||
if item.startswith('cap='):
|
||||
cap = int(item[4:])
|
||||
if item.startswith('compress='):
|
||||
compress = int(item[9:])
|
||||
|
||||
if weight is None and cap is None and compress is None:
|
||||
err('Unrecognized tmem configuration option: %s' % item)
|
||||
usage('tmem-set')
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
if weight is not None:
|
||||
server.xenapi.host.tmem_set_weight(domid, weight)
|
||||
if cap is not None:
|
||||
server.xenapi.host.tmem_set_cap(domid, cap)
|
||||
if compress is not None:
|
||||
server.xenapi.host.tmem_set_compress(domid, compress)
|
||||
else:
|
||||
if weight is not None:
|
||||
server.xend.node.tmem_set_weight(domid, weight)
|
||||
if cap is not None:
|
||||
server.xend.node.tmem_set_cap(domid, cap)
|
||||
if compress is not None:
|
||||
server.xend.node.tmem_set_compress(domid, compress)
|
||||
|
||||
|
||||
commands = {
|
||||
"shell": xm_shell,
|
||||
"event-monitor": xm_event_monitor,
|
||||
@@ -2912,6 +3125,13 @@ commands = {
|
||||
"scsi-attach": xm_scsi_attach,
|
||||
"scsi-detach": xm_scsi_detach,
|
||||
"scsi-list": xm_scsi_list,
|
||||
# tmem
|
||||
"tmem-thaw": xm_tmem_thaw,
|
||||
"tmem-freeze": xm_tmem_freeze,
|
||||
"tmem-flush": xm_tmem_flush,
|
||||
"tmem-destroy": xm_tmem_destroy,
|
||||
"tmem-list": xm_tmem_list,
|
||||
"tmem-set": xm_tmem_set,
|
||||
}
|
||||
|
||||
## The commands supported by a separate argument parser in xend.xm.
|
||||
|
||||