[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Replace xm vcpu-enable and xm vcpu-disable with one command, xm set-vcpus,
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |