ia64/xen-unstable

changeset 7410:2b92f50b7692

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>
author emellor@leeni.uk.xensource.com
date Mon Oct 17 14:07:47 2005 +0100 (2005-10-17)
parents 446aa56ca4fe
children 5e4e11d059a1
files tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendClient.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xm/main.py
line diff
     1.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Mon Oct 17 13:50:28 2005 +0100
     1.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Mon Oct 17 14:07:47 2005 +0100
     1.3 @@ -317,11 +317,9 @@ static PyObject *pyxc_domain_getinfo(PyO
     1.4          PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
     1.5          for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
     1.6              PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
     1.7 -        info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
     1.8 +        info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
     1.9                                    ",s:l,s:L,s:l,s:i,s:i}",
    1.10                                    "dom",       info[i].domid,
    1.11 -                                  /* XXX 'vcpus' field is obsolete! */
    1.12 -                                  "vcpus",     info[i].nr_online_vcpus,
    1.13                                    "online_vcpus", info[i].nr_online_vcpus,
    1.14                                    "max_vcpu_id", info[i].max_vcpu_id,
    1.15                                    "dying",     info[i].dying,
    1.16 @@ -980,8 +978,7 @@ static PyMethodDef pyxc_methods[] = {
    1.17        " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
    1.18        " cpu_time [long]: CPU time consumed, in nanoseconds\n"
    1.19        " shutdown_reason [int]: Numeric code from guest OS, explaining "
    1.20 -      "reason why it shut itself down.\n" 
    1.21 -      " vcpu_to_cpu [[int]]: List that maps VCPUS to CPUS\n" },
    1.22 +      "reason why it shut itself down.\n" },
    1.23  
    1.24      { "vcpu_getinfo", 
    1.25        (PyCFunction)pyxc_vcpu_getinfo, 
     2.1 --- a/tools/python/xen/xend/XendClient.py	Mon Oct 17 13:50:28 2005 +0100
     2.2 +++ b/tools/python/xen/xend/XendClient.py	Mon Oct 17 14:07:47 2005 +0100
     2.3 @@ -199,6 +199,9 @@ class Xend:
     2.4      def xend_list_domains(self):
     2.5          return self.xendGet(self.domainurl(), {'detail': '1'})
     2.6  
     2.7 +    def xend_domain_vcpuinfo(self, dom):
     2.8 +        return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'})
     2.9 +
    2.10      def xend_domain_create(self, conf):
    2.11          return self.xendPost(self.domainurl(),
    2.12                               {'op'      : 'create',
    2.13 @@ -286,11 +289,10 @@ class Xend:
    2.14                               'target'    : mem_target })
    2.15          return val
    2.16  
    2.17 -    def xend_domain_vcpu_hotplug(self, id, vcpu, state):
    2.18 -        return self.xendPost(self.domainurl(id),
    2.19 -                            {'op'         : 'vcpu_hotplug',
    2.20 -                             'vcpu'       : vcpu,
    2.21 -                             'state'      : state })
    2.22 +    def xend_domain_set_vcpus(self, dom, vcpus):
    2.23 +        return self.xendPost(self.domainurl(dom),
    2.24 +                            {'op'    : 'set_vcpus',
    2.25 +                             'vcpus' : vcpus })
    2.26  
    2.27      def xend_domain_vif_limit(self, id, vif, credit, period):
    2.28          return self.xendPost(self.domainurl(id),
     3.1 --- a/tools/python/xen/xend/XendDomain.py	Mon Oct 17 13:50:28 2005 +0100
     3.2 +++ b/tools/python/xen/xend/XendDomain.py	Mon Oct 17 14:07:47 2005 +0100
     3.3 @@ -129,7 +129,14 @@ class XendDomain:
     3.4      def dom0_setup(self):
     3.5          """Expects to be protected by the domains_lock."""
     3.6          dom0 = self.domains[PRIV_DOMAIN]
     3.7 -        dom0.dom0_enforce_vcpus()
     3.8 +
     3.9 +        # get max number of vcpus to use for dom0 from config
    3.10 +        target = int(xroot.get_dom0_vcpus())
    3.11 +        log.debug("number of vcpus to use is %d", target)
    3.12 +   
    3.13 +        # target == 0 means use all processors
    3.14 +        if target > 0:
    3.15 +            self.setVCpuCount(target)
    3.16  
    3.17  
    3.18      def _add_domain(self, info):
     4.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Mon Oct 17 13:50:28 2005 +0100
     4.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Oct 17 14:07:47 2005 +0100
     4.3 @@ -133,8 +133,6 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [
     4.4  #                its VCPUs.  This is translated to
     4.5  #                <dompath>/cpu/<id>/availability = {online,offline} for use
     4.6  #                by the guest domain.
     4.7 -#   vcpu_to_cpu: the current mapping between virtual CPUs and the physical
     4.8 -#                CPU it is using.
     4.9  #   cpumap:      a list of bitmaps, one for each VCPU, giving the physical
    4.10  #                CPUs that that VCPU may use.
    4.11  #   cpu:         a configuration setting requesting that VCPU 0 is pinned to
    4.12 @@ -392,6 +390,8 @@ class XendDomainInfo:
    4.13          self.refresh_shutdown_lock = threading.Condition()
    4.14  
    4.15  
    4.16 +    ## private:
    4.17 +
    4.18      def augmentInfo(self):
    4.19          """Augment self.info, as given to us through {@link #recreate}, with
    4.20          values taken from the store.  This recovers those values known to xend
    4.21 @@ -544,25 +544,36 @@ class XendDomainInfo:
    4.22      def gatherVm(self, *args):
    4.23          return xstransact.Gather(self.vmpath, *args)
    4.24  
    4.25 +
    4.26 +    ## public:
    4.27 +
    4.28      def storeVm(self, *args):
    4.29          return xstransact.Store(self.vmpath, *args)
    4.30  
    4.31 +
    4.32 +    ## private:
    4.33 +
    4.34      def readDom(self, *args):
    4.35          return xstransact.Read(self.dompath, *args)
    4.36  
    4.37      def writeDom(self, *args):
    4.38          return xstransact.Write(self.dompath, *args)
    4.39  
    4.40 +
    4.41 +    ## public:
    4.42 +
    4.43      def removeDom(self, *args):
    4.44          return xstransact.Remove(self.dompath, *args)
    4.45  
    4.46 -    def gatherDom(self, *args):
    4.47 -        return xstransact.Gather(self.dompath, *args)
    4.48 +
    4.49 +    ## private:
    4.50  
    4.51      def storeDom(self, *args):
    4.52          return xstransact.Store(self.dompath, *args)
    4.53  
    4.54  
    4.55 +    ## public:
    4.56 +
    4.57      def storeVmDetails(self):
    4.58          to_store = {
    4.59              'uuid':               self.uuid,
    4.60 @@ -596,18 +607,26 @@ class XendDomainInfo:
    4.61              if v:
    4.62                  to_store[k] = str(v)
    4.63  
    4.64 +        to_store.update(self.vcpuDomDetails())
    4.65 +
    4.66 +        log.debug("Storing domain details: %s", to_store)
    4.67 +
    4.68 +        self.writeDom(to_store)
    4.69 +
    4.70 +
    4.71 +    ## private:
    4.72 +
    4.73 +    def vcpuDomDetails(self):
    4.74          def availability(n):
    4.75              if self.info['vcpu_avail'] & (1 << n):
    4.76                  return 'online'
    4.77              else:
    4.78                  return 'offline'
    4.79  
    4.80 +        result = {}
    4.81          for v in range(0, self.info['vcpus']):
    4.82 -            to_store["cpu/%d/availability" % v] = availability(v)
    4.83 -
    4.84 -        log.debug("Storing domain details: %s", to_store)
    4.85 -
    4.86 -        self.writeDom(to_store)
    4.87 +            result["cpu/%d/availability" % v] = availability(v)
    4.88 +        return result
    4.89  
    4.90  
    4.91      def setDomid(self, domid):
    4.92 @@ -635,9 +654,17 @@ class XendDomainInfo:
    4.93      def getUuid(self):
    4.94          return self.uuid
    4.95  
    4.96 +
    4.97      def getVCpuCount(self):
    4.98          return self.info['vcpus']
    4.99  
   4.100 +
   4.101 +    def setVCpuCount(self, vcpus):
   4.102 +        self.info['vcpu_avail'] = (1 << vcpus) - 1
   4.103 +        self.storeVm('vcpu_avail', self.info['vcpu_avail'])
   4.104 +        self.writeDom(self.vcpuDomDetails())
   4.105 +
   4.106 +
   4.107      def getSsidref(self):
   4.108          return self.info['ssidref']
   4.109  
   4.110 @@ -872,12 +899,12 @@ class XendDomainInfo:
   4.111          return self.getDeviceController(deviceClass).destroyDevice(devid)
   4.112  
   4.113  
   4.114 -    ## private:
   4.115 -
   4.116      def getDeviceSxprs(self, deviceClass):
   4.117          return self.getDeviceController(deviceClass).sxprs()
   4.118  
   4.119  
   4.120 +    ## private:
   4.121 +
   4.122      def getDeviceConfigurations(self, deviceClass):
   4.123          return self.getDeviceController(deviceClass).configurations()
   4.124  
   4.125 @@ -932,11 +959,6 @@ class XendDomainInfo:
   4.126          if self.infoIsSet('cpu_time'):
   4.127              sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
   4.128          sxpr.append(['vcpus', self.info['vcpus']])
   4.129 -        if self.infoIsSet('cpumap'):
   4.130 -            sxpr.append(['cpumap', self.info['cpumap']])
   4.131 -        if self.infoIsSet('vcpu_to_cpu'):
   4.132 -            sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
   4.133 -            sxpr.append(['vcpu_to_cpu', self.prettyVCpuMap()])
   4.134              
   4.135          if self.infoIsSet('start_time'):
   4.136              up_time =  time.time() - self.info['start_time']
   4.137 @@ -951,12 +973,33 @@ class XendDomainInfo:
   4.138          return sxpr
   4.139  
   4.140  
   4.141 -    ## private:
   4.142 +    def getVCPUInfo(self):
   4.143 +        try:
   4.144 +            # We include the domain name and ID, to help xm.
   4.145 +            sxpr = ['domain',
   4.146 +                    ['domid',      self.domid],
   4.147 +                    ['name',       self.info['name']],
   4.148 +                    ['vcpu_count', self.info['vcpus']]]
   4.149 +
   4.150 +            for i in range(0, self.info['vcpus']):
   4.151 +                info = xc.vcpu_getinfo(self.domid, i)
   4.152  
   4.153 -    def prettyVCpuMap(self):
   4.154 -        return '|'.join(map(str,
   4.155 -                            self.info['vcpu_to_cpu'][0:self.info['vcpus']]))
   4.156 +                sxpr.append(['vcpu',
   4.157 +                             ['number',   i],
   4.158 +                             ['online',   info['online']],
   4.159 +                             ['blocked',  info['blocked']],
   4.160 +                             ['running',  info['running']],
   4.161 +                             ['cpu_time', info['cpu_time'] / 1e9],
   4.162 +                             ['cpu',      info['cpu']],
   4.163 +                             ['cpumap',   info['cpumap']]])
   4.164  
   4.165 +            return sxpr
   4.166 +
   4.167 +        except RuntimeError, exn:
   4.168 +            raise XendError(str(exn))
   4.169 +                      
   4.170 +
   4.171 +    ## private:
   4.172  
   4.173      def check_name(self, name):
   4.174          """Check if a vm name is valid. Valid names contain alphabetic characters,
   4.175 @@ -1335,22 +1378,6 @@ class XendDomainInfo:
   4.176              xc.domain_setmaxmem(self.domid, maxmem_kb = m)
   4.177  
   4.178  
   4.179 -    def vcpu_hotplug(self, vcpu, state):
   4.180 -        """Disable or enable VCPU in domain.
   4.181 -        """
   4.182 -        if vcpu > self.info['vcpus']:
   4.183 -            log.error("Invalid VCPU %d" % vcpu)
   4.184 -            return
   4.185 -        if int(state) == 0:
   4.186 -            self.info['vcpu_avail'] &= ~(1 << vcpu)
   4.187 -            availability = "offline"
   4.188 -        else:
   4.189 -            self.info['vcpu_avail'] &= (1 << vcpu)
   4.190 -            availability = "online"
   4.191 -        self.storeVm('vcpu_avail', self.info['vcpu_avail'])
   4.192 -        self.storeDom("cpu/%d/availability" % vcpu, availability)
   4.193 -
   4.194 -
   4.195      def send_sysrq(self, key):
   4.196          asserts.isCharConvertible(key)
   4.197  
   4.198 @@ -1371,24 +1398,6 @@ class XendDomainInfo:
   4.199                      raise
   4.200  
   4.201  
   4.202 -    def dom0_enforce_vcpus(self):
   4.203 -        dom = 0
   4.204 -        # get max number of vcpus to use for dom0 from config
   4.205 -        target = int(xroot.get_dom0_vcpus())
   4.206 -        log.debug("number of vcpus to use is %d", target)
   4.207 -   
   4.208 -        # target = 0 means use all processors
   4.209 -        if target > 0:
   4.210 -            # count the number of online vcpus (cpu values in v2c map >= 0)
   4.211 -            vcpus_online = dom_get(dom)['vcpus']
   4.212 -            log.debug("found %d vcpus online", vcpus_online)
   4.213 -
   4.214 -            # disable any extra vcpus that are online over the requested target
   4.215 -            for vcpu in range(target, vcpus_online):
   4.216 -                log.info("enforcement is disabling DOM%d VCPU%d", dom, vcpu)
   4.217 -                self.vcpu_hotplug(vcpu, 0)
   4.218 -
   4.219 -
   4.220      def infoIsSet(self, name):
   4.221          return name in self.info and self.info[name] is not None
   4.222  
     5.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Mon Oct 17 13:50:28 2005 +0100
     5.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Mon Oct 17 14:07:47 2005 +0100
     5.3 @@ -165,17 +165,25 @@ class SrvDomain(SrvDir):
     5.4          val = fn(req.args, {'dom': self.dom.domid})
     5.5          return val
     5.6  
     5.7 -    def op_vcpu_hotplug(self, op, req):
     5.8 -        return self.call(self.dom.vcpu_hotplug,
     5.9 -                         [['vcpu', 'int'],
    5.10 -                          ['state', 'int']],
    5.11 +    def op_set_vcpus(self, op, req):
    5.12 +        return self.call(self.dom.setVCpuCount,
    5.13 +                         [['vcpus', 'int']],
    5.14                           req)
    5.15  
    5.16 +
    5.17 +    def op_vcpuinfo(self, _1, req):
    5.18 +        return self.call(self.dom.getVCPUInfo, [], req)
    5.19 +
    5.20 +
    5.21      def render_POST(self, req):
    5.22          return self.perform(req)
    5.23          
    5.24      def render_GET(self, req):
    5.25          op = req.args.get('op')
    5.26 +
    5.27 +        if op and op[0] in ['vcpuinfo']:
    5.28 +            return self.perform(req)
    5.29 +
    5.30          #
    5.31          # XXX SMH: below may be useful once again if we ever try to get
    5.32          # the raw 'web' interface to xend working once more. But for now
     6.1 --- a/tools/python/xen/xm/main.py	Mon Oct 17 13:50:28 2005 +0100
     6.2 +++ b/tools/python/xen/xm/main.py	Mon Oct 17 14:07:47 2005 +0100
     6.3 @@ -71,8 +71,7 @@ longhelp = """Usage: xm <subcommand> [ar
     6.4  xm full list of subcommands:
     6.5  
     6.6    Domain Commands:
     6.7 -    console <DomId>         attach to console of DomId
     6.8 -    cpus-list <DomId> <VCpu>          get the list of cpus for a VCPU
     6.9 +    console <DomId>           attach to console of DomId
    6.10      create  <ConfigFile>      create a domain
    6.11      destroy <DomId>           terminate a domain immediately
    6.12      domid   <DomName>         convert a domain name to a domain id
    6.13 @@ -88,10 +87,9 @@ xm full list of subcommands:
    6.14      shutdown [-w|-a] <DomId>  shutdown a domain
    6.15      sysrq   <DomId> <letter>  send a sysrq to a domain
    6.16      unpause <DomId>           unpause a paused domain
    6.17 -    vcpu-enable <DomId> <VCPU>        enable VCPU in a domain
    6.18 -    vcpu-disable <DomId> <VCPU>       disable VCPU in a domain
    6.19 -    vcpu-list <DomId>                 get the list of VCPUs for a domain
    6.20 -    vcpu-pin <DomId> <VCpu> <CPUS>    set which cpus a VCPU can use. 
    6.21 +    set-vcpus <DomId> <VCPUs> enable the specified number of VCPUs in a domain
    6.22 +    vcpu-list <DomId>         list the VCPUs for a domain
    6.23 +    vcpu-pin <DomId> <VCPU> <CPUs>    set which cpus a VCPU can use. 
    6.24  
    6.25    Xen Host Commands:
    6.26      dmesg   [--clear]         read or clear Xen's message buffer
    6.27 @@ -209,6 +207,15 @@ def xm_restore(args):
    6.28      if id is not None:
    6.29          server.xend_domain_unpause(domid)
    6.30  
    6.31 +
    6.32 +def getDomains(domain_names):
    6.33 +    from xen.xend.XendClient import server
    6.34 +    if domain_names:
    6.35 +        return map(server.xend_domain, domain_names)
    6.36 +    else:
    6.37 +        return server.xend_list_domains()
    6.38 +
    6.39 +
    6.40  def xm_list(args):
    6.41      use_long = 0
    6.42      show_vcpus = 0
    6.43 @@ -218,80 +225,105 @@ def xm_list(args):
    6.44          err(opterr)
    6.45          sys.exit(1)
    6.46      
    6.47 -    n = len(params)
    6.48      for (k, v) in options:
    6.49          if k in ['-l', '--long']:
    6.50              use_long = 1
    6.51          if k in ['-v', '--vcpus']:
    6.52              show_vcpus = 1
    6.53  
    6.54 -    from xen.xend.XendClient import server
    6.55 -    if n == 0:
    6.56 -        doms = server.xend_list_domains()
    6.57 -    else:
    6.58 -        doms = map(server.xend_domain, params)
    6.59 -               
    6.60 +    if show_vcpus:
    6.61 +        print >>sys.stderr, (
    6.62 +            "xm list -v is deprecated.  Please use xm vcpu-list.")
    6.63 +        xm_vcpu_list(params)
    6.64 +        return
    6.65 +
    6.66 +    doms = getDomains(params)
    6.67 +
    6.68      if use_long:
    6.69 -        for dom in doms:
    6.70 -            PrettyPrint.prettyprint(dom)
    6.71 +        map(PrettyPrint.prettyprint, doms)
    6.72      else:
    6.73 -        domsinfo = map(parse_doms_info, doms)
    6.74 +        xm_brief_list(doms)
    6.75  
    6.76 -        if show_vcpus:
    6.77 -            xm_show_vcpus(domsinfo)
    6.78 -        else:
    6.79 -            xm_brief_list(domsinfo)
    6.80  
    6.81  def parse_doms_info(info):
    6.82 -    dominfo = {}
    6.83 -    dominfo['dom'] = int(sxp.child_value(info, 'domid', '-1'))
    6.84 -    dominfo['name'] = sxp.child_value(info, 'name', '??')
    6.85 -    dominfo['mem'] = int(sxp.child_value(info, 'memory', '0'))
    6.86 -    dominfo['cpu'] = str(sxp.child_value(info, 'cpu', '0'))
    6.87 -    dominfo['vcpus'] = int(sxp.child_value(info, 'vcpus', '0'))
    6.88 -    # if there is more than 1 cpu, the value doesn't mean much
    6.89 -    if dominfo['vcpus'] > 1:
    6.90 -        dominfo['cpu'] = '-'
    6.91 -    dominfo['state'] = sxp.child_value(info, 'state', '??')
    6.92 -    dominfo['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
    6.93 -    # security identifiers
    6.94 -    if ((int(sxp.child_value(info, 'ssidref', '0'))) != 0):
    6.95 -        dominfo['ssidref1'] =  int(sxp.child_value(info, 'ssidref', '0')) & 0xffff
    6.96 -        dominfo['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '0')) >> 16) & 0xffff
    6.97 -    # get out the vcpu information
    6.98 -    dominfo['vcpulist'] = []
    6.99 -    vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu', '-1').split('|')
   6.100 -    cpumap = sxp.child_value(info, 'cpumap', [])
   6.101 -    mask = ((int(sxp.child_value(info, 'vcpus', '0')))**2) - 1
   6.102 -    count = 0
   6.103 -    for cpu in vcpu_to_cpu:
   6.104 -        vcpuinfo = {}
   6.105 -        vcpuinfo['name']   = sxp.child_value(info, 'name', '??')
   6.106 -        vcpuinfo['dom']    = int(sxp.child_value(info, 'domid', '-1'))
   6.107 -        vcpuinfo['vcpu']   = int(count)
   6.108 -        vcpuinfo['cpu']    = int(cpu)
   6.109 -        #vcpuinfo['cpumap'] = int(cpumap[count])&mask
   6.110 -        count = count + 1
   6.111 -        #dominfo['vcpulist'].append(vcpuinfo)
   6.112 -    return dominfo
   6.113 -        
   6.114 -def xm_brief_list(domsinfo):
   6.115 -    print 'Name              ID  Mem(MiB)  CPU  VCPUs  State   Time(s)'
   6.116 -    for dominfo in domsinfo:
   6.117 -        if dominfo.has_key("ssidref1"):
   6.118 -            print ("%(name)-16s %(dom)3d  %(mem)8d  %(cpu)3s  %(vcpus)5d  %(state)5s  %(cpu_time)7.1f     s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo)
   6.119 +    def get_info(n, t, d):
   6.120 +        return t(sxp.child_value(info, n, d))
   6.121 +    
   6.122 +    return {
   6.123 +        'dom'      : get_info('domid',    int,   -1),
   6.124 +        'name'     : get_info('name',     str,   '??'),
   6.125 +        'mem'      : get_info('memory',   int,   0),
   6.126 +        'vcpus'    : get_info('vcpus',    int,   0),
   6.127 +        'state'    : get_info('state',    str,   '??'),
   6.128 +        'cpu_time' : get_info('cpu_time', float, 0),
   6.129 +        'ssidref'  : get_info('ssidref',  int,   0),
   6.130 +        }
   6.131 +
   6.132 +
   6.133 +def xm_brief_list(doms):
   6.134 +    print 'Name                              ID Mem(MiB) VCPUs State  Time(s)'
   6.135 +    for dom in doms:
   6.136 +        d = parse_doms_info(dom)
   6.137 +        if (d['ssidref'] != 0):
   6.138 +            d['ssidstr'] = (" s:%04x/p:%04x" % 
   6.139 +                            ((d['ssidref'] >> 16) & 0xffff,
   6.140 +                              d['ssidref']        & 0xffff))
   6.141          else:
   6.142 -            print ("%(name)-16s %(dom)3d  %(mem)8d  %(cpu)3s  %(vcpus)5d  %(state)5s  %(cpu_time)7.1f" % dominfo)
   6.143 +            d['ssidstr'] = ""
   6.144 +        print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f%(ssidstr)s" % d)
   6.145  
   6.146 -def xm_show_vcpus(domsinfo):
   6.147 -    print 'Name              Id  VCPU  CPU  CPUMAP'
   6.148 -    for dominfo in domsinfo:
   6.149 -        for vcpuinfo in dominfo['vcpulist']:
   6.150 -            print ("%(name)-16s %(dom)3d  %(vcpu)4d  %(cpu)3d  0x%(cpumap)x" %
   6.151 -                   vcpuinfo)
   6.152  
   6.153  def xm_vcpu_list(args):
   6.154 -    xm_list(["-v"] + args)
   6.155 +    print 'Name                              ID  VCPU  CPU  State  Time(s)  CPU Map'
   6.156 +
   6.157 +    from xen.xend.XendClient import server
   6.158 +    if args:
   6.159 +        dominfo = map(server.xend_domain_vcpuinfo, args)
   6.160 +    else:
   6.161 +        doms = server.xend_list_domains()
   6.162 +        dominfo = map(
   6.163 +            lambda x: server.xend_domain_vcpuinfo(sxp.child_value(x, 'name')),
   6.164 +            doms)
   6.165 +
   6.166 +    for dom in dominfo:
   6.167 +        def get_info(n):
   6.168 +            return sxp.child_value(dom, n)
   6.169 +
   6.170 +        name  =     get_info('name')
   6.171 +        domid = int(get_info('domid'))
   6.172 +
   6.173 +
   6.174 +        for vcpu in sxp.children(dom, 'vcpu'):
   6.175 +            def vinfo(n, t):
   6.176 +                return t(sxp.child_value(vcpu, n))
   6.177 +
   6.178 +            number   = vinfo('number',   int)
   6.179 +            cpu      = vinfo('cpu',      int)
   6.180 +            cpumap   = vinfo('cpumap',   int)
   6.181 +            online   = vinfo('online',   int)
   6.182 +            cpu_time = vinfo('cpu_time', float)
   6.183 +            running  = vinfo('running',  int)
   6.184 +            blocked  = vinfo('blocked',  int)
   6.185 +
   6.186 +            if online:
   6.187 +                c = str(cpu)
   6.188 +                if running:
   6.189 +                    s = 'r'
   6.190 +                else:
   6.191 +                    s = '-'
   6.192 +                if blocked:
   6.193 +                    s += 'b'
   6.194 +                else:
   6.195 +                    s += '-'
   6.196 +                s += '-'
   6.197 +            else:
   6.198 +                c = "-"
   6.199 +                s = "--p"
   6.200 +
   6.201 +            print (
   6.202 +                "%(name)-32s %(domid)3d  %(number)4d  %(c)3s   %(s)-3s   %(cpu_time)7.1f  0x%(cpumap)x" %
   6.203 +                locals())
   6.204 +
   6.205  
   6.206  def xm_reboot(args):
   6.207      arg_check(args,1,"reboot")
   6.208 @@ -338,8 +370,6 @@ def cpu_make_map(cpulist):
   6.209      return cpumap
   6.210  
   6.211  def xm_vcpu_pin(args):
   6.212 -    arg_check(args, 3, "vcpu-pin")
   6.213 -    
   6.214      dom  = args[0]
   6.215      vcpu = int(args[1])
   6.216      cpumap = cpu_make_map(args[2])
   6.217 @@ -348,8 +378,6 @@ def xm_vcpu_pin(args):
   6.218      server.xend_domain_pincpu(dom, vcpu, cpumap)
   6.219  
   6.220  def xm_mem_max(args):
   6.221 -    arg_check(args, 2, "mem-max")
   6.222 -    
   6.223      dom = args[0]
   6.224      mem = int_unit(args[1], 'm')
   6.225  
   6.226 @@ -357,36 +385,15 @@ def xm_mem_max(args):
   6.227      server.xend_domain_maxmem_set(dom, mem)
   6.228      
   6.229  def xm_mem_set(args):
   6.230 -    arg_check(args, 2, "mem-set")
   6.231 -    
   6.232      dom = args[0]
   6.233      mem_target = int_unit(args[1], 'm')
   6.234  
   6.235      from xen.xend.XendClient import server
   6.236      server.xend_domain_mem_target_set(dom, mem_target)
   6.237      
   6.238 -# TODO: why does this lookup by name?  and what if that fails!?
   6.239 -def xm_vcpu_enable(args):
   6.240 -    arg_check(args, 2, "vcpu-enable")
   6.241 -    
   6.242 -    name = args[0]
   6.243 -    vcpu = int(args[1])
   6.244 -    
   6.245 +def xm_set_vcpus(args):
   6.246      from xen.xend.XendClient import server
   6.247 -    dom = server.xend_domain(name)
   6.248 -    id = sxp.child_value(dom, 'domid')
   6.249 -    server.xend_domain_vcpu_hotplug(id, vcpu, 1)
   6.250 -
   6.251 -def xm_vcpu_disable(args):
   6.252 -    arg_check(args, 2, "vcpu-disable")
   6.253 -    
   6.254 -    name = args[0]
   6.255 -    vcpu = int(args[1])
   6.256 -    
   6.257 -    from xen.xend.XendClient import server
   6.258 -    dom = server.xend_domain(name)
   6.259 -    id = sxp.child_value(dom, 'domid')
   6.260 -    server.xend_domain_vcpu_hotplug(id, vcpu, 0)
   6.261 +    server.xend_domain_set_vcpus(args[0], int(args[1]))
   6.262  
   6.263  def xm_domid(args):
   6.264      name = args[0]
   6.265 @@ -586,9 +593,7 @@ commands = {
   6.266      "mem-set": xm_mem_set,
   6.267      # cpu commands
   6.268      "vcpu-pin": xm_vcpu_pin,
   6.269 -#    "cpus-list": xm_cpus_list,
   6.270 -    "vcpu-enable": xm_vcpu_enable,
   6.271 -    "vcpu-disable": xm_vcpu_disable,
   6.272 +    "set-vcpus": xm_set_vcpus,
   6.273      "vcpu-list": xm_vcpu_list,
   6.274      # special
   6.275      "pause": xm_pause,