# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID 2b92f50b769237c0eca0e524e9427dbc8b16964a
# Parent 446aa56ca4fee7d3ea2badfb59e8bb3540b507ae
Replace xm vcpu-enable and xm vcpu-disable with one command, xm set-vcpus,
which sets the number of active CPUs. Xend then toggles the VCPUs to ensure a
contiguous group of them are enabled.
Added a server command to get VCPU information, and use this info to fix
xm vcpu-list. That xm command now has extra information, too. CPU == -1 is no
longer used as an indicator for a VCPU that is disabled -- a separate state
field is available, and the CPU is set merely to '-'. Individual CPU time is
now available.
Deprecated xm list -v. -v is conventionally used for --verbose, so using it
to list vcpus is confusing. Furthermore, we already have an equivalent command
xm vcpu-list.
Tidied up the horrendous xm list / xm vcpu-list code.
Removed the vcpus field from the dict returned by xc_domain_getinfo, and the
vcpu_to_cpu map from the sxpr returned for xm list.
Move the dom0_enforce_vcpus code into XendDomain.
Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
diff -r 446aa56ca4fe -r 2b92f50b7692 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Mon Oct 17 12:50:28 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon Oct 17 13:07:47 2005
@@ -317,11 +317,9 @@
PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
- info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
+ info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
",s:l,s:L,s:l,s:i,s:i}",
"dom", info[i].domid,
- /* XXX 'vcpus' field is obsolete! */
- "vcpus", info[i].nr_online_vcpus,
"online_vcpus", info[i].nr_online_vcpus,
"max_vcpu_id", info[i].max_vcpu_id,
"dying", info[i].dying,
@@ -980,8 +978,7 @@
" maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
" cpu_time [long]: CPU time consumed, in nanoseconds\n"
" shutdown_reason [int]: Numeric code from guest OS, explaining "
- "reason why it shut itself down.\n"
- " vcpu_to_cpu [[int]]: List that maps VCPUS to CPUS\n" },
+ "reason why it shut itself down.\n" },
{ "vcpu_getinfo",
(PyCFunction)pyxc_vcpu_getinfo,
diff -r 446aa56ca4fe -r 2b92f50b7692 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py Mon Oct 17 12:50:28 2005
+++ b/tools/python/xen/xend/XendClient.py Mon Oct 17 13:07:47 2005
@@ -199,6 +199,9 @@
def xend_list_domains(self):
return self.xendGet(self.domainurl(), {'detail': '1'})
+ def xend_domain_vcpuinfo(self, dom):
+ return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'})
+
def xend_domain_create(self, conf):
return self.xendPost(self.domainurl(),
{'op' : 'create',
@@ -286,11 +289,10 @@
'target' : mem_target })
return val
- def xend_domain_vcpu_hotplug(self, id, vcpu, state):
- return self.xendPost(self.domainurl(id),
- {'op' : 'vcpu_hotplug',
- 'vcpu' : vcpu,
- 'state' : state })
+ def xend_domain_set_vcpus(self, dom, vcpus):
+ return self.xendPost(self.domainurl(dom),
+ {'op' : 'set_vcpus',
+ 'vcpus' : vcpus })
def xend_domain_vif_limit(self, id, vif, credit, period):
return self.xendPost(self.domainurl(id),
diff -r 446aa56ca4fe -r 2b92f50b7692 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Mon Oct 17 12:50:28 2005
+++ b/tools/python/xen/xend/XendDomain.py Mon Oct 17 13:07:47 2005
@@ -129,7 +129,14 @@
def dom0_setup(self):
"""Expects to be protected by the domains_lock."""
dom0 = self.domains[PRIV_DOMAIN]
- dom0.dom0_enforce_vcpus()
+
+ # get max number of vcpus to use for dom0 from config
+ target = int(xroot.get_dom0_vcpus())
+ log.debug("number of vcpus to use is %d", target)
+
+ # target == 0 means use all processors
+ if target > 0:
+ self.setVCpuCount(target)
def _add_domain(self, info):
diff -r 446aa56ca4fe -r 2b92f50b7692 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Mon Oct 17 12:50:28 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Mon Oct 17 13:07:47 2005
@@ -133,8 +133,6 @@
# its VCPUs. This is translated to
# <dompath>/cpu/<id>/availability = {online,offline} for use
# by the guest domain.
-# vcpu_to_cpu: the current mapping between virtual CPUs and the physical
-# CPU it is using.
# cpumap: a list of bitmaps, one for each VCPU, giving the physical
# CPUs that that VCPU may use.
# cpu: a configuration setting requesting that VCPU 0 is pinned to
@@ -391,6 +389,8 @@
self.state_updated = threading.Condition()
self.refresh_shutdown_lock = threading.Condition()
+
+ ## private:
def augmentInfo(self):
"""Augment self.info, as given to us through {@link #recreate}, with
@@ -544,24 +544,35 @@
def gatherVm(self, *args):
return xstransact.Gather(self.vmpath, *args)
+
+ ## public:
+
def storeVm(self, *args):
return xstransact.Store(self.vmpath, *args)
+
+ ## private:
+
def readDom(self, *args):
return xstransact.Read(self.dompath, *args)
def writeDom(self, *args):
return xstransact.Write(self.dompath, *args)
+
+ ## public:
+
def removeDom(self, *args):
return xstransact.Remove(self.dompath, *args)
- def gatherDom(self, *args):
- return xstransact.Gather(self.dompath, *args)
+
+ ## private:
def storeDom(self, *args):
return xstransact.Store(self.dompath, *args)
+
+ ## public:
def storeVmDetails(self):
to_store = {
@@ -596,18 +607,26 @@
if v:
to_store[k] = str(v)
+ to_store.update(self.vcpuDomDetails())
+
+ log.debug("Storing domain details: %s", to_store)
+
+ self.writeDom(to_store)
+
+
+ ## private:
+
+ def vcpuDomDetails(self):
def availability(n):
if self.info['vcpu_avail'] & (1 << n):
return 'online'
else:
return 'offline'
+ result = {}
for v in range(0, self.info['vcpus']):
- to_store["cpu/%d/availability" % v] = availability(v)
-
- log.debug("Storing domain details: %s", to_store)
-
- self.writeDom(to_store)
+ result["cpu/%d/availability" % v] = availability(v)
+ return result
def setDomid(self, domid):
@@ -635,8 +654,16 @@
def getUuid(self):
return self.uuid
+
def getVCpuCount(self):
return self.info['vcpus']
+
+
+ def setVCpuCount(self, vcpus):
+ self.info['vcpu_avail'] = (1 << vcpus) - 1
+ self.storeVm('vcpu_avail', self.info['vcpu_avail'])
+ self.writeDom(self.vcpuDomDetails())
+
def getSsidref(self):
return self.info['ssidref']
@@ -872,11 +899,11 @@
return self.getDeviceController(deviceClass).destroyDevice(devid)
- ## private:
-
def getDeviceSxprs(self, deviceClass):
return self.getDeviceController(deviceClass).sxprs()
+
+ ## private:
def getDeviceConfigurations(self, deviceClass):
return self.getDeviceController(deviceClass).configurations()
@@ -932,11 +959,6 @@
if self.infoIsSet('cpu_time'):
sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
sxpr.append(['vcpus', self.info['vcpus']])
- if self.infoIsSet('cpumap'):
- sxpr.append(['cpumap', self.info['cpumap']])
- if self.infoIsSet('vcpu_to_cpu'):
- sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
- sxpr.append(['vcpu_to_cpu', self.prettyVCpuMap()])
if self.infoIsSet('start_time'):
up_time = time.time() - self.info['start_time']
@@ -951,12 +973,33 @@
return sxpr
+ def getVCPUInfo(self):
+ try:
+ # We include the domain name and ID, to help xm.
+ sxpr = ['domain',
+ ['domid', self.domid],
+ ['name', self.info['name']],
+ ['vcpu_count', self.info['vcpus']]]
+
+ for i in range(0, self.info['vcpus']):
+ info = xc.vcpu_getinfo(self.domid, i)
+
+ sxpr.append(['vcpu',
+ ['number', i],
+ ['online', info['online']],
+ ['blocked', info['blocked']],
+ ['running', info['running']],
+ ['cpu_time', info['cpu_time'] / 1e9],
+ ['cpu', info['cpu']],
+ ['cpumap', info['cpumap']]])
+
+ return sxpr
+
+ except RuntimeError, exn:
+ raise XendError(str(exn))
+
+
## private:
-
- def prettyVCpuMap(self):
- return '|'.join(map(str,
- self.info['vcpu_to_cpu'][0:self.info['vcpus']]))
-
def check_name(self, name):
"""Check if a vm name is valid. Valid names contain alphabetic
characters,
@@ -1335,22 +1378,6 @@
xc.domain_setmaxmem(self.domid, maxmem_kb = m)
- def vcpu_hotplug(self, vcpu, state):
- """Disable or enable VCPU in domain.
- """
- if vcpu > self.info['vcpus']:
- log.error("Invalid VCPU %d" % vcpu)
- return
- if int(state) == 0:
- self.info['vcpu_avail'] &= ~(1 << vcpu)
- availability = "offline"
- else:
- self.info['vcpu_avail'] &= (1 << vcpu)
- availability = "online"
- self.storeVm('vcpu_avail', self.info['vcpu_avail'])
- self.storeDom("cpu/%d/availability" % vcpu, availability)
-
-
def send_sysrq(self, key):
asserts.isCharConvertible(key)
@@ -1371,24 +1398,6 @@
raise
- def dom0_enforce_vcpus(self):
- dom = 0
- # get max number of vcpus to use for dom0 from config
- target = int(xroot.get_dom0_vcpus())
- log.debug("number of vcpus to use is %d", target)
-
- # target = 0 means use all processors
- if target > 0:
- # count the number of online vcpus (cpu values in v2c map >= 0)
- vcpus_online = dom_get(dom)['vcpus']
- log.debug("found %d vcpus online", vcpus_online)
-
- # disable any extra vcpus that are online over the requested target
- for vcpu in range(target, vcpus_online):
- log.info("enforcement is disabling DOM%d VCPU%d", dom, vcpu)
- self.vcpu_hotplug(vcpu, 0)
-
-
def infoIsSet(self, name):
return name in self.info and self.info[name] is not None
diff -r 446aa56ca4fe -r 2b92f50b7692 tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Mon Oct 17 12:50:28 2005
+++ b/tools/python/xen/xend/server/SrvDomain.py Mon Oct 17 13:07:47 2005
@@ -165,17 +165,25 @@
val = fn(req.args, {'dom': self.dom.domid})
return val
- def op_vcpu_hotplug(self, op, req):
- return self.call(self.dom.vcpu_hotplug,
- [['vcpu', 'int'],
- ['state', 'int']],
- req)
+ def op_set_vcpus(self, op, req):
+ return self.call(self.dom.setVCpuCount,
+ [['vcpus', 'int']],
+ req)
+
+
+ def op_vcpuinfo(self, _1, req):
+ return self.call(self.dom.getVCPUInfo, [], req)
+
def render_POST(self, req):
return self.perform(req)
def render_GET(self, req):
op = req.args.get('op')
+
+ if op and op[0] in ['vcpuinfo']:
+ return self.perform(req)
+
#
# XXX SMH: below may be useful once again if we ever try to get
# the raw 'web' interface to xend working once more. But for now
diff -r 446aa56ca4fe -r 2b92f50b7692 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Mon Oct 17 12:50:28 2005
+++ b/tools/python/xen/xm/main.py Mon Oct 17 13:07:47 2005
@@ -71,8 +71,7 @@
xm full list of subcommands:
Domain Commands:
- console <DomId> attach to console of DomId
- cpus-list <DomId> <VCpu> get the list of cpus for a VCPU
+ console <DomId> attach to console of DomId
create <ConfigFile> create a domain
destroy <DomId> terminate a domain immediately
domid <DomName> convert a domain name to a domain id
@@ -88,10 +87,9 @@
shutdown [-w|-a] <DomId> shutdown a domain
sysrq <DomId> <letter> send a sysrq to a domain
unpause <DomId> unpause a paused domain
- vcpu-enable <DomId> <VCPU> enable VCPU in a domain
- vcpu-disable <DomId> <VCPU> disable VCPU in a domain
- vcpu-list <DomId> get the list of VCPUs for a domain
- vcpu-pin <DomId> <VCpu> <CPUS> set which cpus a VCPU can use.
+ set-vcpus <DomId> <VCPUs> enable the specified number of VCPUs in a domain
+ vcpu-list <DomId> list the VCPUs for a domain
+ vcpu-pin <DomId> <VCPU> <CPUs> set which cpus a VCPU can use.
Xen Host Commands:
dmesg [--clear] read or clear Xen's message buffer
@@ -209,6 +207,15 @@
if id is not None:
server.xend_domain_unpause(domid)
+
+def getDomains(domain_names):
+ from xen.xend.XendClient import server
+ if domain_names:
+ return map(server.xend_domain, domain_names)
+ else:
+ return server.xend_list_domains()
+
+
def xm_list(args):
use_long = 0
show_vcpus = 0
@@ -218,80 +225,105 @@
err(opterr)
sys.exit(1)
- n = len(params)
for (k, v) in options:
if k in ['-l', '--long']:
use_long = 1
if k in ['-v', '--vcpus']:
show_vcpus = 1
- from xen.xend.XendClient import server
- if n == 0:
+ if show_vcpus:
+ print >>sys.stderr, (
+ "xm list -v is deprecated. Please use xm vcpu-list.")
+ xm_vcpu_list(params)
+ return
+
+ doms = getDomains(params)
+
+ if use_long:
+ map(PrettyPrint.prettyprint, doms)
+ else:
+ xm_brief_list(doms)
+
+
+def parse_doms_info(info):
+ def get_info(n, t, d):
+ return t(sxp.child_value(info, n, d))
+
+ return {
+ 'dom' : get_info('domid', int, -1),
+ 'name' : get_info('name', str, '??'),
+ 'mem' : get_info('memory', int, 0),
+ 'vcpus' : get_info('vcpus', int, 0),
+ 'state' : get_info('state', str, '??'),
+ 'cpu_time' : get_info('cpu_time', float, 0),
+ 'ssidref' : get_info('ssidref', int, 0),
+ }
+
+
+def xm_brief_list(doms):
+ print 'Name ID Mem(MiB) VCPUs State Time(s)'
+ for dom in doms:
+ d = parse_doms_info(dom)
+ if (d['ssidref'] != 0):
+ d['ssidstr'] = (" s:%04x/p:%04x" %
+ ((d['ssidref'] >> 16) & 0xffff,
+ d['ssidref'] & 0xffff))
+ else:
+ d['ssidstr'] = ""
+ print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s
%(cpu_time)7.1f%(ssidstr)s" % d)
+
+
+def xm_vcpu_list(args):
+ print 'Name ID VCPU CPU State Time(s)
CPU Map'
+
+ from xen.xend.XendClient import server
+ if args:
+ dominfo = map(server.xend_domain_vcpuinfo, args)
+ else:
doms = server.xend_list_domains()
- else:
- doms = map(server.xend_domain, params)
-
- if use_long:
- for dom in doms:
- PrettyPrint.prettyprint(dom)
- else:
- domsinfo = map(parse_doms_info, doms)
-
- if show_vcpus:
- xm_show_vcpus(domsinfo)
- else:
- xm_brief_list(domsinfo)
-
-def parse_doms_info(info):
- dominfo = {}
- dominfo['dom'] = int(sxp.child_value(info, 'domid', '-1'))
- dominfo['name'] = sxp.child_value(info, 'name', '??')
- dominfo['mem'] = int(sxp.child_value(info, 'memory', '0'))
- dominfo['cpu'] = str(sxp.child_value(info, 'cpu', '0'))
- dominfo['vcpus'] = int(sxp.child_value(info, 'vcpus', '0'))
- # if there is more than 1 cpu, the value doesn't mean much
- if dominfo['vcpus'] > 1:
- dominfo['cpu'] = '-'
- dominfo['state'] = sxp.child_value(info, 'state', '??')
- dominfo['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
- # security identifiers
- if ((int(sxp.child_value(info, 'ssidref', '0'))) != 0):
- dominfo['ssidref1'] = int(sxp.child_value(info, 'ssidref', '0')) &
0xffff
- dominfo['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '0')) >>
16) & 0xffff
- # get out the vcpu information
- dominfo['vcpulist'] = []
- vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu', '-1').split('|')
- cpumap = sxp.child_value(info, 'cpumap', [])
- mask = ((int(sxp.child_value(info, 'vcpus', '0')))**2) - 1
- count = 0
- for cpu in vcpu_to_cpu:
- vcpuinfo = {}
- vcpuinfo['name'] = sxp.child_value(info, 'name', '??')
- vcpuinfo['dom'] = int(sxp.child_value(info, 'domid', '-1'))
- vcpuinfo['vcpu'] = int(count)
- vcpuinfo['cpu'] = int(cpu)
- #vcpuinfo['cpumap'] = int(cpumap[count])&mask
- count = count + 1
- #dominfo['vcpulist'].append(vcpuinfo)
- return dominfo
-
-def xm_brief_list(domsinfo):
- print 'Name ID Mem(MiB) CPU VCPUs State Time(s)'
- for dominfo in domsinfo:
- if dominfo.has_key("ssidref1"):
- print ("%(name)-16s %(dom)3d %(mem)8d %(cpu)3s %(vcpus)5d
%(state)5s %(cpu_time)7.1f s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo)
- else:
- print ("%(name)-16s %(dom)3d %(mem)8d %(cpu)3s %(vcpus)5d
%(state)5s %(cpu_time)7.1f" % dominfo)
-
-def xm_show_vcpus(domsinfo):
- print 'Name Id VCPU CPU CPUMAP'
- for dominfo in domsinfo:
- for vcpuinfo in dominfo['vcpulist']:
- print ("%(name)-16s %(dom)3d %(vcpu)4d %(cpu)3d 0x%(cpumap)x" %
- vcpuinfo)
-
-def xm_vcpu_list(args):
- xm_list(["-v"] + args)
+ dominfo = map(
+ lambda x: server.xend_domain_vcpuinfo(sxp.child_value(x, 'name')),
+ doms)
+
+ for dom in dominfo:
+ def get_info(n):
+ return sxp.child_value(dom, n)
+
+ name = get_info('name')
+ domid = int(get_info('domid'))
+
+
+ for vcpu in sxp.children(dom, 'vcpu'):
+ def vinfo(n, t):
+ return t(sxp.child_value(vcpu, n))
+
+ number = vinfo('number', int)
+ cpu = vinfo('cpu', int)
+ cpumap = vinfo('cpumap', int)
+ online = vinfo('online', int)
+ cpu_time = vinfo('cpu_time', float)
+ running = vinfo('running', int)
+ blocked = vinfo('blocked', int)
+
+ if online:
+ c = str(cpu)
+ if running:
+ s = 'r'
+ else:
+ s = '-'
+ if blocked:
+ s += 'b'
+ else:
+ s += '-'
+ s += '-'
+ else:
+ c = "-"
+ s = "--p"
+
+ print (
+ "%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s
%(cpu_time)7.1f 0x%(cpumap)x" %
+ locals())
+
def xm_reboot(args):
arg_check(args,1,"reboot")
@@ -338,8 +370,6 @@
return cpumap
def xm_vcpu_pin(args):
- arg_check(args, 3, "vcpu-pin")
-
dom = args[0]
vcpu = int(args[1])
cpumap = cpu_make_map(args[2])
@@ -348,8 +378,6 @@
server.xend_domain_pincpu(dom, vcpu, cpumap)
def xm_mem_max(args):
- arg_check(args, 2, "mem-max")
-
dom = args[0]
mem = int_unit(args[1], 'm')
@@ -357,36 +385,15 @@
server.xend_domain_maxmem_set(dom, mem)
def xm_mem_set(args):
- arg_check(args, 2, "mem-set")
-
dom = args[0]
mem_target = int_unit(args[1], 'm')
from xen.xend.XendClient import server
server.xend_domain_mem_target_set(dom, mem_target)
-# TODO: why does this lookup by name? and what if that fails!?
-def xm_vcpu_enable(args):
- arg_check(args, 2, "vcpu-enable")
-
- name = args[0]
- vcpu = int(args[1])
-
- from xen.xend.XendClient import server
- dom = server.xend_domain(name)
- id = sxp.child_value(dom, 'domid')
- server.xend_domain_vcpu_hotplug(id, vcpu, 1)
-
-def xm_vcpu_disable(args):
- arg_check(args, 2, "vcpu-disable")
-
- name = args[0]
- vcpu = int(args[1])
-
- from xen.xend.XendClient import server
- dom = server.xend_domain(name)
- id = sxp.child_value(dom, 'domid')
- server.xend_domain_vcpu_hotplug(id, vcpu, 0)
+def xm_set_vcpus(args):
+ from xen.xend.XendClient import server
+ server.xend_domain_set_vcpus(args[0], int(args[1]))
def xm_domid(args):
name = args[0]
@@ -586,9 +593,7 @@
"mem-set": xm_mem_set,
# cpu commands
"vcpu-pin": xm_vcpu_pin,
-# "cpus-list": xm_cpus_list,
- "vcpu-enable": xm_vcpu_enable,
- "vcpu-disable": xm_vcpu_disable,
+ "set-vcpus": xm_set_vcpus,
"vcpu-list": xm_vcpu_list,
# special
"pause": xm_pause,
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|