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@xensource.com>
This commit is contained in:
emellor@leeni.uk.xensource.com committed 2005-10-17 14:07:47 +01:00
1 parent 37964af428
commit 238ca03bd4
6 files changed
+196 -168

No files matched your search

+2 -5
View File
@@ -317,11 +317,9 @@ static PyObject *pyxc_domain_getinfo(PyObject *self,
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 @@ static PyMethodDef pyxc_methods[] = {
" 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,
+7 -5
View File
@@ -199,6 +199,9 @@ class Xend:
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 @@ class Xend:
'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),
+8 -1
View File
@@ -129,7 +129,14 @@ class XendDomain:
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):
+64 -55
View File
@@ -133,8 +133,6 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [
# 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
@@ -392,6 +390,8 @@ class XendDomainInfo:
self.refresh_shutdown_lock = threading.Condition()
## private:
def augmentInfo(self):
"""Augment self.info, as given to us through {@link #recreate}, with
values taken from the store. This recovers those values known to xend
@@ -544,25 +544,36 @@ class XendDomainInfo:
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 = {
'uuid': self.uuid,
@@ -596,18 +607,26 @@ class XendDomainInfo:
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,9 +654,17 @@ class XendDomainInfo:
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,12 +899,12 @@ class XendDomainInfo:
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 @@ class XendDomainInfo:
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,13 +973,34 @@ class XendDomainInfo:
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,
digits, or characters in '_-.:/+'.
@@ -1335,22 +1378,6 @@ class XendDomainInfo:
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 @@ class XendDomainInfo:
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
+12 -4
View File
@@ -165,17 +165,25 @@ class SrvDomain(SrvDir):
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']],
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
+103 -98
View File
@@ -71,8 +71,7 @@ longhelp = """Usage: xm <subcommand> [args]
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 @@ xm full list of subcommands:
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 @@ def xm_restore(args):
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 @@ def xm_list(args):
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:
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:
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)
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 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_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)
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()
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 @@ def cpu_make_map(cpulist):
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 @@ def xm_vcpu_pin(args):
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 @@ def xm_mem_max(args):
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])
def xm_set_vcpus(args):
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)
server.xend_domain_set_vcpus(args[0], int(args[1]))
def xm_domid(args):
name = args[0]
@@ -586,9 +593,7 @@ commands = {
"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,
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.