ia64/xen-unstable

changeset 14517:4baae9f9fdbb

Update VM's VCPU handling to match the documentation wrt VCPUs_max and
VCPUs_at_startup. Add VM.set_VCPUs_number_live, VM.add_to_VCPUs_params_live,
VM_metrics.VCPUs_{CPU,flags,params}.

Use these new calls to implement xm vcpu-list and xm sched-credit through
the Xen-API. Mark a number of other calls as unimplemented through that API.

Signed-off-by: Tom Wilkie <tom.wilkie@gmail.com>
Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Thu Mar 22 14:31:03 2007 +0000 (2007-03-22)
parents 5c529af40697
children 5f526fcc8e58
files tools/python/xen/xend/XendAPI.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendVMMetrics.py tools/python/xen/xm/main.py tools/python/xen/xm/xenapi_create.py
line diff
     1.1 --- a/tools/python/xen/xend/XendAPI.py	Thu Mar 22 14:27:05 2007 +0000
     1.2 +++ b/tools/python/xen/xend/XendAPI.py	Thu Mar 22 14:31:03 2007 +0000
     1.3 @@ -1034,9 +1034,8 @@ class XendAPI(object):
     1.4  
     1.5      VM_attr_ro = ['power_state',
     1.6                    'resident_on',
     1.7 -                  'memory_static_max',                  
     1.8 +                  'memory_static_max',
     1.9                    'memory_static_min',
    1.10 -                  'VCPUs_number',
    1.11                    'consoles',
    1.12                    'VIFs',
    1.13                    'VBDs',
    1.14 @@ -1054,6 +1053,8 @@ class XendAPI(object):
    1.15                    'auto_power_on',
    1.16                    'memory_dynamic_max',
    1.17                    'memory_dynamic_min',
    1.18 +                  'VCPUs_max',
    1.19 +                  'VCPUs_at_startup',
    1.20                    'VCPUs_params',
    1.21                    'actions_after_shutdown',
    1.22                    'actions_after_reboot',
    1.23 @@ -1081,9 +1082,11 @@ class XendAPI(object):
    1.24                    ('suspend', None),
    1.25                    ('resume', None),
    1.26                    ('send_sysrq', None),
    1.27 +                  ('set_VCPUs_number_live', None),
    1.28                    ('add_to_HVM_boot_params', None),
    1.29                    ('remove_from_HVM_boot_params', None),
    1.30                    ('add_to_VCPUs_params', None),
    1.31 +                  ('add_to_VCPUs_params_live', None),
    1.32                    ('remove_from_VCPUs_params', None),
    1.33                    ('add_to_platform', None),
    1.34                    ('remove_from_platform', None),
    1.35 @@ -1104,6 +1107,8 @@ class XendAPI(object):
    1.36          'memory_dynamic_max',
    1.37          'memory_dynamic_min',
    1.38          'memory_static_min',
    1.39 +        'VCPUs_max',
    1.40 +        'VCPUs_at_startup',
    1.41          'VCPUs_params',
    1.42          'actions_after_shutdown',
    1.43          'actions_after_reboot',
    1.44 @@ -1150,10 +1155,6 @@ class XendAPI(object):
    1.45          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.46          return xen_api_success(dom.get_memory_static_min())
    1.47      
    1.48 -    def VM_get_VCPUs_number(self, session, vm_ref):
    1.49 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.50 -        return xen_api_success(dom.getVCpuCount())
    1.51 -    
    1.52      def VM_get_VIFs(self, session, vm_ref):
    1.53          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.54          return xen_api_success(dom.get_vifs())
    1.55 @@ -1178,6 +1179,14 @@ class XendAPI(object):
    1.56          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.57          return xen_api_success(dom.get_metrics())
    1.58  
    1.59 +    def VM_get_VCPUs_max(self, _, vm_ref):
    1.60 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.61 +        return xen_api_todo()
    1.62 +
    1.63 +    def VM_get_VCPUs_at_startup(self, _, vm_ref):
    1.64 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.65 +        return xen_api_todo()
    1.66 +
    1.67      # attributes (rw)
    1.68      def VM_get_name_label(self, session, vm_ref):
    1.69          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.70 @@ -1302,6 +1311,36 @@ class XendAPI(object):
    1.71          dom.info['vcpus_params'][key] = value
    1.72          return self._VM_save(dom)
    1.73  
    1.74 +    def VM_add_to_VCPUs_params_live(self, session, vm_ref, key, value):
    1.75 +        self.VM_add_to_VCPUs_params(session, vm_ref, key, value)
    1.76 +        self._VM_VCPUs_params_refresh(vm_ref)
    1.77 +        return xen_api_success_void()
    1.78 +
    1.79 +    def _VM_VCPUs_params_refresh(self, vm_ref):
    1.80 +        xendom  = XendDomain.instance()
    1.81 +        xeninfo = xendom.get_vm_by_uuid(vm_ref)
    1.82 +
    1.83 +        #update the cpumaps
    1.84 +        for key, value in xeninfo.info['vcpus_params'].items():
    1.85 +            if key.startswith("cpumap"):
    1.86 +                vcpu = int(key[6:])
    1.87 +                try:
    1.88 +                    xendom.domain_pincpu(xeninfo.getDomid(), vcpu, value)
    1.89 +                except Exception, ex:
    1.90 +                    log.exception(ex)
    1.91 +
    1.92 +        #need to update sched params aswell
    1.93 +        if 'weight' in xeninfo.info['vcpus_params'] \
    1.94 +           and 'cap' in xeninfo.info['vcpus_params']:
    1.95 +            weight = xeninfo.info['vcpus_params']['weight']
    1.96 +            cap = xeninfo.info['vcpus_params']['cap']
    1.97 +            xendom.domain_sched_credit_set(xeninfo.getDomid(), weight, cap)
    1.98 +
    1.99 +    def VM_set_VCPUs_number_live(self, _, vm_ref, num):
   1.100 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.101 +        dom.setVCpuCount(int(num))
   1.102 +        return xen_api_success_void()
   1.103 +     
   1.104      def VM_remove_from_VCPUs_params(self, session, vm_ref, key):
   1.105          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.106          if 'vcpus_params' in dom.info \
   1.107 @@ -1450,7 +1489,8 @@ class XendAPI(object):
   1.108              'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
   1.109              'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
   1.110              'VCPUs_params': xeninfo.get_vcpus_params(),
   1.111 -            'VCPUs_number': xeninfo.getVCpuCount(),
   1.112 +            'VCPUs_at_startup': xeninfo.getVCpuCount(),
   1.113 +            'VCPUs_max': xeninfo.getVCpuCount(),
   1.114              'actions_after_shutdown': xeninfo.get_on_shutdown(),
   1.115              'actions_after_reboot': xeninfo.get_on_reboot(),
   1.116              'actions_after_suspend': xeninfo.get_on_suspend(),
   1.117 @@ -1472,6 +1512,7 @@ class XendAPI(object):
   1.118              'other_config': xeninfo.info.get('other_config', {}),
   1.119              'domid': domid is None and -1 or domid,
   1.120              'is_control_domain': xeninfo == xendom.privilegedDomain(),
   1.121 +            'metrics': xeninfo.get_metrics()
   1.122          }
   1.123          return xen_api_success(record)
   1.124  
   1.125 @@ -1547,8 +1588,11 @@ class XendAPI(object):
   1.126      # ----------------------------------------------------------------
   1.127  
   1.128      VM_metrics_attr_ro = ['memory_actual',
   1.129 -                           'vcpus_number',
   1.130 -                           'vcpus_utilisation']
   1.131 +                          'VCPUs_number',
   1.132 +                          'VCPUs_utilisation',
   1.133 +                          'VCPUs_CPU',
   1.134 +                          'VCPUs_flags',
   1.135 +                          'VCPUs_params']
   1.136      VM_metrics_attr_rw = []
   1.137      VM_metrics_methods = []
   1.138  
   1.139 @@ -1564,11 +1608,21 @@ class XendAPI(object):
   1.140      def VM_metrics_get_memory_actual(self, _, ref):
   1.141          return xen_api_success(self._VM_metrics_get(ref).get_memory_actual())
   1.142  
   1.143 -    def VM_metrics_get_vcpus_number(self, _, ref):
   1.144 -        return xen_api_success(self._VM_metrics_get(ref).get_vcpus_number())
   1.145 +    def VM_metrics_get_VCPUs_number(self, _, ref):
   1.146 +        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_number())
   1.147 +
   1.148 +    def VM_metrics_get_VCPUs_utilisation(self, _, ref):
   1.149 +        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_utilisation())
   1.150  
   1.151 -    def VM_metrics_get_vcpus_utilisation(self, _, ref):
   1.152 -        return xen_api_success(self._VM_metrics_get(ref).get_vcpus_utilisation())
   1.153 +    def VM_metrics_get_VCPUs_CPU(self, _, ref):
   1.154 +        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_CPU())
   1.155 +    
   1.156 +    def VM_metrics_get_VCPUs_flags(self, _, ref):
   1.157 +        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_flags())
   1.158 +
   1.159 +    def VM_metrics_get_VCPUs_params(self, _, ref):
   1.160 +        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_params())
   1.161 +
   1.162  
   1.163      # Xen API: Class VBD
   1.164      # ----------------------------------------------------------------
     2.1 --- a/tools/python/xen/xend/XendConfig.py	Thu Mar 22 14:27:05 2007 +0000
     2.2 +++ b/tools/python/xen/xend/XendConfig.py	Thu Mar 22 14:31:03 2007 +0000
     2.3 @@ -81,18 +81,18 @@ def scrub_password(data):
     2.4  #
     2.5  # CPU fields:
     2.6  #
     2.7 -# vcpus_number -- the maximum number of vcpus that this domain may ever have.
     2.8 +# VCPUs_max    -- the maximum number of vcpus that this domain may ever have.
     2.9  #                 aka XendDomainInfo.getVCpuCount().
    2.10  # vcpus        -- the legacy configuration name for above.
    2.11  # max_vcpu_id  -- vcpus_number - 1.  This is given to us by Xen.
    2.12  #
    2.13  # cpus         -- the list of pCPUs available to each vCPU.
    2.14  #
    2.15 -#   vcpu_avail:  a bitmap telling the guest domain whether it may use each of
    2.16 -#                its VCPUs.  This is translated to
    2.17 -#                <dompath>/cpu/<id>/availability = {online,offline} for use
    2.18 -#                by the guest domain.
    2.19 -# online_vpcus -- the number of VCPUs currently up, as reported by Xen.  This
    2.20 +# vcpu_avail   -- a bitmap telling the guest domain whether it may use each of
    2.21 +#                 its VCPUs.  This is translated to
    2.22 +#                 <dompath>/cpu/<id>/availability = {online,offline} for use
    2.23 +#                 by the guest domain.
    2.24 +# VCPUs_live   -- the number of VCPUs currently up, as reported by Xen.  This
    2.25  #                 is changed by changing vcpu_avail, and waiting for the
    2.26  #                 domain to respond.
    2.27  #
    2.28 @@ -103,7 +103,7 @@ def scrub_password(data):
    2.29  
    2.30  XENAPI_CFG_TO_LEGACY_CFG = {
    2.31      'uuid': 'uuid',
    2.32 -    'vcpus_number': 'vcpus',
    2.33 +    'VCPUs_max': 'vcpus',
    2.34      'cpus': 'cpus',
    2.35      'name_label': 'name',
    2.36      'actions_after_shutdown': 'on_poweroff',
    2.37 @@ -139,9 +139,10 @@ XENAPI_CFG_TYPES = {
    2.38      'memory_dynamic_min': int,
    2.39      'memory_dynamic_max': int,
    2.40      'cpus': list,
    2.41 -    'vcpus_policy': str,
    2.42      'vcpus_params': dict,
    2.43 -    'vcpus_number': int,
    2.44 +    'VCPUs_max': int,
    2.45 +    'VCPUs_at_startup': int,
    2.46 +    'VCPUs_live': int,
    2.47      'actions_after_shutdown': str,
    2.48      'actions_after_reboot': str,
    2.49      'actions_after_crash': str,
    2.50 @@ -318,7 +319,9 @@ class XendConfig(dict):
    2.51              'cpus': [],
    2.52              'cpu_weight': 256,
    2.53              'cpu_cap': 0,
    2.54 -            'vcpus_number': 1,
    2.55 +            'VCPUs_max': 1,
    2.56 +            'VCPUs_live': 1,
    2.57 +            'VCPUs_at_startup': 1,
    2.58              'vcpus_params': {},
    2.59              'console_refs': [],
    2.60              'vif_refs': [],
    2.61 @@ -371,8 +374,8 @@ class XendConfig(dict):
    2.62                                        event)
    2.63  
    2.64      def _vcpus_sanity_check(self):
    2.65 -        if 'vcpus_number' in self and 'vcpu_avail' not in self:
    2.66 -            self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
    2.67 +        if 'VCPUs_max' in self and 'vcpu_avail' not in self:
    2.68 +            self['vcpu_avail'] = (1 << self['VCPUs_max']) - 1
    2.69  
    2.70      def _uuid_sanity_check(self):
    2.71          """Make sure UUID is in proper string format with hyphens."""
    2.72 @@ -406,7 +409,7 @@ class XendConfig(dict):
    2.73      def _dominfo_to_xapi(self, dominfo):
    2.74          self['domid'] = dominfo['domid']
    2.75          self['online_vcpus'] = dominfo['online_vcpus']
    2.76 -        self['vcpus_number'] = dominfo['max_vcpu_id'] + 1
    2.77 +        self['VCPUs_max'] = dominfo['max_vcpu_id'] + 1
    2.78  
    2.79          self['memory_dynamic_min'] = dominfo['mem_kb'] * 1024
    2.80          self['memory_dynamic_max'] = dominfo['mem_kb'] * 1024
    2.81 @@ -562,12 +565,12 @@ class XendConfig(dict):
    2.82              image_vcpus = sxp.child_value(image_sxp, 'vcpus')
    2.83              if image_vcpus != None:
    2.84                  try:
    2.85 -                    if 'vcpus_number' not in cfg:
    2.86 -                        cfg['vcpus_number'] = int(image_vcpus)
    2.87 -                    elif cfg['vcpus_number'] != int(image_vcpus):
    2.88 -                        cfg['vcpus_number'] = int(image_vcpus)
    2.89 +                    if 'VCPUs_max' not in cfg:
    2.90 +                        cfg['VCPUs_max'] = int(image_vcpus)
    2.91 +                    elif cfg['VCPUs_max'] != int(image_vcpus):
    2.92 +                        cfg['VCPUs_max'] = int(image_vcpus)
    2.93                          log.warn('Overriding vcpus from %d to %d using image'
    2.94 -                                 'vcpus value.', cfg['vcpus_number'])
    2.95 +                                 'vcpus value.', cfg['VCPUs_max'])
    2.96                  except ValueError, e:
    2.97                      raise XendConfigError('integer expeceted: %s: %s' %
    2.98                                            image_sxp, e)
     3.1 --- a/tools/python/xen/xend/XendDomain.py	Thu Mar 22 14:27:05 2007 +0000
     3.2 +++ b/tools/python/xen/xend/XendDomain.py	Thu Mar 22 14:31:03 2007 +0000
     3.3 @@ -1230,7 +1230,9 @@ class XendDomain:
     3.4              try:
     3.5                  rc = xc.vcpu_setaffinity(dominfo.getDomid(), int(v), cpumap)
     3.6              except Exception, ex:
     3.7 -                raise XendError(str(ex))
     3.8 +                log.exception(ex)
     3.9 +                raise XendError("Cannot pin vcpu: %s to cpu: %s - %s" % \
    3.10 +                                (v, cpumap, str(ex)))
    3.11          return rc
    3.12  
    3.13      def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime,
     4.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Mar 22 14:27:05 2007 +0000
     4.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Mar 22 14:31:03 2007 +0000
     4.3 @@ -614,9 +614,9 @@ class XendDomainInfo:
     4.4              sxpr = ['domain',
     4.5                      ['domid',      self.domid],
     4.6                      ['name',       self.info['name_label']],
     4.7 -                    ['vcpu_count', self.info['vcpus_number']]]
     4.8 -
     4.9 -            for i in range(0, self.info['vcpus_number']):
    4.10 +                    ['vcpu_count', self.info['VCPUs_max']]]
    4.11 +
    4.12 +            for i in range(0, self.info['VCPUs_max']):
    4.13                  info = xc.vcpu_getinfo(self.domid, i)
    4.14  
    4.15                  sxpr.append(['vcpu',
    4.16 @@ -678,7 +678,7 @@ class XendDomainInfo:
    4.17          # settings to take precedence over any entries in the store.
    4.18          if priv:
    4.19              xeninfo = dom_get(self.domid)
    4.20 -            self.info['vcpus_number'] = xeninfo['online_vcpus']
    4.21 +            self.info['VCPUs_max'] = xeninfo['online_vcpus']
    4.22              self.info['vcpu_avail'] = (1 << xeninfo['online_vcpus']) - 1
    4.23  
    4.24          # read image value
    4.25 @@ -831,7 +831,7 @@ class XendDomainInfo:
    4.26                  return 'offline'
    4.27  
    4.28          result = {}
    4.29 -        for v in range(0, self.info['vcpus_number']):
    4.30 +        for v in range(0, self.info['VCPUs_max']):
    4.31              result["cpu/%d/availability" % v] = availability(v)
    4.32          return result
    4.33  
    4.34 @@ -952,7 +952,7 @@ class XendDomainInfo:
    4.35          return self.info['features']
    4.36  
    4.37      def getVCpuCount(self):
    4.38 -        return self.info['vcpus_number']
    4.39 +        return self.info['VCPUs_max']
    4.40  
    4.41      def setVCpuCount(self, vcpus):
    4.42          if vcpus <= 0:
    4.43 @@ -964,16 +964,16 @@ class XendDomainInfo:
    4.44              # update dom differently depending on whether we are adjusting
    4.45              # vcpu number up or down, otherwise _vcpuDomDetails does not
    4.46              # disable the vcpus
    4.47 -            if self.info['vcpus_number'] > vcpus:
    4.48 +            if self.info['VCPUs_max'] > vcpus:
    4.49                  # decreasing
    4.50                  self._writeDom(self._vcpuDomDetails())
    4.51 -                self.info['vcpus_number'] = vcpus
    4.52 +                self.info['VCPUs_live'] = vcpus
    4.53              else:
    4.54                  # same or increasing
    4.55 -                self.info['vcpus_number'] = vcpus
    4.56 +                self.info['VCPUs_live'] = vcpus
    4.57                  self._writeDom(self._vcpuDomDetails())
    4.58          else:
    4.59 -            self.info['vcpus_number'] = vcpus
    4.60 +            self.info['VCPUs_live'] = vcpus
    4.61              xen.xend.XendDomain.instance().managed_config_save(self)
    4.62          log.info("Set VCPU count on domain %s to %d", self.info['name_label'],
    4.63                   vcpus)
    4.64 @@ -1427,7 +1427,7 @@ class XendDomainInfo:
    4.65          self._recreateDom()
    4.66  
    4.67          # Set maximum number of vcpus in domain
    4.68 -        xc.domain_max_vcpus(self.domid, int(self.info['vcpus_number']))
    4.69 +        xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
    4.70  
    4.71          # register the domain in the list 
    4.72          from xen.xend import XendDomain
    4.73 @@ -1464,7 +1464,7 @@ class XendDomainInfo:
    4.74              # this is done prior to memory allocation to aide in memory
    4.75              # distribution for NUMA systems.
    4.76              if self.info['cpus'] is not None and len(self.info['cpus']) > 0:
    4.77 -                for v in range(0, self.info['vcpus_number']):
    4.78 +                for v in range(0, self.info['VCPUs_max']):
    4.79                      xc.vcpu_setaffinity(self.domid, v, self.info['cpus'])
    4.80  
    4.81              # Use architecture- and image-specific calculations to determine
    4.82 @@ -1860,7 +1860,7 @@ class XendDomainInfo:
    4.83          if arch.type == "x86":
    4.84              # 1MB per vcpu plus 4Kib/Mib of RAM.  This is higher than 
    4.85              # the minimum that Xen would allocate if no value were given.
    4.86 -            overhead_kb = self.info['vcpus_number'] * 1024 + \
    4.87 +            overhead_kb = self.info['VCPUs_max'] * 1024 + \
    4.88                            (self.info['memory_static_max'] / 1024 / 1024) * 4
    4.89              overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
    4.90              # The domain might already have some shadow memory
    4.91 @@ -2258,8 +2258,8 @@ class XendDomainInfo:
    4.92      def get_vcpus_util(self):
    4.93          vcpu_util = {}
    4.94          xennode = XendNode.instance()
    4.95 -        if 'vcpus_number' in self.info and self.domid != None:
    4.96 -            for i in range(0, self.info['vcpus_number']):
    4.97 +        if 'VCPUs_max' in self.info and self.domid != None:
    4.98 +            for i in range(0, self.info['VCPUs_max']):
    4.99                  util = xennode.get_vcpu_util(self.domid, i)
   4.100                  vcpu_util[str(i)] = util
   4.101                  
     5.1 --- a/tools/python/xen/xend/XendVMMetrics.py	Thu Mar 22 14:27:05 2007 +0000
     5.2 +++ b/tools/python/xen/xend/XendVMMetrics.py	Thu Mar 22 14:31:03 2007 +0000
     5.3 @@ -13,9 +13,13 @@
     5.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     5.5  #============================================================================
     5.6  # Copyright (c) 2006-2007 Xensource Inc.
     5.7 +# Copyright (c) 2007 Tom Wilkie
     5.8  #============================================================================
     5.9  
    5.10  from xen.xend.XendLogging import log
    5.11 +import xen.lowlevel.xc
    5.12 +
    5.13 +xc = xen.lowlevel.xc.xc()
    5.14  
    5.15  instances = {}
    5.16  
    5.17 @@ -46,25 +50,75 @@ class XendVMMetrics:
    5.18          return self.uuid
    5.19  
    5.20      def get_memory_actual(self):
    5.21 -        return self.get_record()["memory_actual"]
    5.22 +        domInfo = self.xend_domain_instance.getDomInfo()
    5.23 +        if domInfo:
    5.24 +            return domInfo["mem_kb"] * 1024
    5.25 +        else:
    5.26 +            return 0
    5.27  
    5.28 -    def get_vcpus_number(self):
    5.29 -        return self.get_record()["vcpus_number"]
    5.30 -    
    5.31 -    def get_vcpus_utilisation(self):
    5.32 -        return self.xend_domain_instance.get_vcpus_util()
    5.33 -
    5.34 -    def get_record(self):
    5.35 +    def get_VCPUs_number(self):
    5.36          domInfo = self.xend_domain_instance.getDomInfo()
    5.37          if domInfo:
    5.38 -            return { 'uuid'              : self.uuid,
    5.39 -                     'memory_actual'     : domInfo["mem_kb"] * 1024,
    5.40 -                     'vcpus_number'      : domInfo["online_vcpus"],
    5.41 -                     'vcpus_utilisation' : self.get_vcpus_utilisation()
    5.42 -                   }
    5.43 +            return domInfo["online_vcpus"]
    5.44 +        else:
    5.45 +            return 0
    5.46 +    
    5.47 +    def get_VCPUs_utilisation(self):
    5.48 +        return self.xend_domain_instance.get_vcpus_util()
    5.49 +
    5.50 +    def get_VCPUs_CPU(self):
    5.51 +        domid = self.xend_domain_instance.getDomid()
    5.52 +        if domid is not None:
    5.53 +            vcpus_cpu = {}
    5.54 +            vcpus_max = self.xend_domain_instance.info['VCPUs_max']
    5.55 +            for i in range(0, vcpus_max):
    5.56 +                info = xc.vcpu_getinfo(domid, i)
    5.57 +                vcpus_cpu[i] = info['cpu']
    5.58 +            return vcpus_cpu
    5.59          else:
    5.60 -            return { 'uuid'              : self.uuid,
    5.61 -                     'memory_actual'     : 0,
    5.62 -                     'vcpus_number'      : 0,
    5.63 -                     'vcpus_utilisation' : {}
    5.64 -                   }
    5.65 +            return {}
    5.66 +
    5.67 +    def get_VCPUs_flags(self):
    5.68 +        domid = self.xend_domain_instance.getDomid()
    5.69 +        if domid is not None:
    5.70 +            vcpus_flags = {}
    5.71 +            vcpus_max = self.xend_domain_instance.info['VCPUs_max']
    5.72 +            for i in range(0, vcpus_max):
    5.73 +                info = xc.vcpu_getinfo(domid, i)
    5.74 +                flags = []
    5.75 +                def set_flag(flag):
    5.76 +                    if info[flag] == 1:
    5.77 +                        flags.append(flag)
    5.78 +                set_flag('blocked')
    5.79 +                set_flag('online')
    5.80 +                set_flag('running')
    5.81 +                vcpus_flags[i] = ",".join(flags)
    5.82 +            return vcpus_flags
    5.83 +        else:
    5.84 +            return {}
    5.85 +
    5.86 +    def get_VCPUs_params(self):
    5.87 +        domid = self.xend_domain_instance.getDomid()
    5.88 +        if domid is not None:
    5.89 +            params_live = {}
    5.90 +            vcpus_max = self.xend_domain_instance.info['VCPUs_max']
    5.91 +            for i in range(0, vcpus_max):
    5.92 +                info = xc.vcpu_getinfo(domid, i)
    5.93 +                params_live['cpumap%i' % i] = \
    5.94 +                    ",".join(map(str, info['cpumap']))
    5.95 +
    5.96 +            params_live.update(xc.sched_credit_domain_get(domid))
    5.97 +            
    5.98 +            return params_live
    5.99 +        else:
   5.100 +            return {}
   5.101 +
   5.102 +    def get_record(self):
   5.103 +        return { 'uuid'              : self.uuid,
   5.104 +                 'memory_actual'     : self.get_memory_actual(),
   5.105 +                 'VCPUs_number'      : self.get_VCPUs_number(),
   5.106 +                 'VCPUs_utilisation' : self.get_VCPUs_utilisation(),
   5.107 +                 'VCPUs_CPU'         : self.get_VCPUs_CPU(),
   5.108 +                 'VCPUs_flags'       : self.get_VCPUs_flags(),
   5.109 +                 'VCPUs_params'      : self.get_VCPUs_params()
   5.110 +               }
     6.1 --- a/tools/python/xen/xm/main.py	Thu Mar 22 14:27:05 2007 +0000
     6.2 +++ b/tools/python/xen/xm/main.py	Thu Mar 22 14:31:03 2007 +0000
     6.3 @@ -502,6 +502,13 @@ def get_default_Network():
     6.4      return [network_ref
     6.5              for network_ref in server.xenapi.network.get_all()][0]
     6.6  
     6.7 +class XenAPIUnsupportedException(Exception):
     6.8 +    pass
     6.9 +
    6.10 +def xenapi_unsupported():
    6.11 +    if serverType == SERVER_XEN_API:
    6.12 +        raise XenAPIUnsupportedException, "This function is not supported by Xen-API"
    6.13 +
    6.14  def map2sxp(m):
    6.15      return [[k, m[k]] for k in m.keys()]
    6.16  
    6.17 @@ -550,10 +557,13 @@ def err(msg):
    6.18  
    6.19  
    6.20  def get_single_vm(dom):
    6.21 -    uuids = server.xenapi.VM.get_by_name_label(dom)
    6.22 -    n = len(uuids)
    6.23 -    if n == 1:
    6.24 -        return uuids[0]
    6.25 +    if serverType == SERVER_XEN_API:
    6.26 +        uuids = server.xenapi.VM.get_by_name_label(dom)
    6.27 +        n = len(uuids)
    6.28 +        if n > 0:
    6.29 +            return uuids[0]
    6.30 +        else:
    6.31 +            raise OptionError("Domain '%s' not found." % dom)
    6.32      else:
    6.33          dominfo = server.xend.domain(dom, False)
    6.34          return dominfo['uuid']
    6.35 @@ -697,9 +707,9 @@ def getDomains(domain_names, state, full
    6.36              dom_metrics = server.xenapi.VM_metrics.get_record(dom_metrics_ref)
    6.37              dom_rec.update({'name':     dom_rec['name_label'],
    6.38                              'memory_actual': int(dom_metrics['memory_actual'])/1024,
    6.39 -                            'vcpus':    dom_metrics['vcpus_number'],
    6.40 +                            'vcpus':    dom_metrics['VCPUs_number'],
    6.41                              'state':    '-----',
    6.42 -                            'cpu_time': dom_metrics['vcpus_utilisation']})
    6.43 +                            'cpu_time': dom_metrics['VCPUs_utilisation']})
    6.44  			
    6.45              doms_sxp.append(['domain'] + map2sxp(dom_rec))
    6.46              doms_dict.append(dom_rec)
    6.47 @@ -885,11 +895,71 @@ def xm_label_list(doms):
    6.48  
    6.49  
    6.50  def xm_vcpu_list(args):
    6.51 -    if args:
    6.52 -        dominfo = map(server.xend.domain.getVCPUInfo, args)
    6.53 -    else:
    6.54 -        doms = server.xend.domains(False)
    6.55 -        dominfo = map(server.xend.domain.getVCPUInfo, doms)
    6.56 +    if serverType == SERVER_XEN_API:
    6.57 +        if args:
    6.58 +            vm_refs = map(get_single_vm, args)
    6.59 +        else:
    6.60 +            vm_refs = server.xenapi.VM.get_all()
    6.61 +            
    6.62 +        vm_records = dict(map(lambda vm_ref:
    6.63 +                                  (vm_ref, server.xenapi.VM.get_record(
    6.64 +                                      vm_ref)),
    6.65 +                              vm_refs))
    6.66 +
    6.67 +        vm_metrics = dict(map(lambda (ref, record):
    6.68 +                                  (ref,
    6.69 +                                   server.xenapi.VM_metrics.get_record(
    6.70 +                                       record['metrics'])),
    6.71 +                              vm_records.items()))
    6.72 +
    6.73 +        dominfo = []
    6.74 +
    6.75 +        # vcpu_list doesn't list 'managed' domains
    6.76 +        # when they are not running, so filter them out
    6.77 +
    6.78 +        vm_refs = [vm_ref
    6.79 +                  for vm_ref in vm_refs
    6.80 +                  if vm_records[vm_ref]["power_state"] != "Halted"]
    6.81 +
    6.82 +        for vm_ref in vm_refs:
    6.83 +            info = ['domain',
    6.84 +                    ['domid',      vm_records[vm_ref]['domid']],
    6.85 +                    ['name',       vm_records[vm_ref]['name_label']],
    6.86 +                    ['vcpu_count', vm_records[vm_ref]['VCPUs_max']]]
    6.87 +
    6.88 +            
    6.89 +
    6.90 +            for i in range(int(vm_records[vm_ref]['VCPUs_max'])):
    6.91 +                def chk_flag(flag):
    6.92 +                    return vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
    6.93 +                           .find(flag) > -1 and 1 or 0
    6.94 +                
    6.95 +                vcpu_info = ['vcpu',
    6.96 +                             ['number',
    6.97 +                                  i],
    6.98 +                             ['online',
    6.99 +                                  chk_flag("online")],
   6.100 +                             ['blocked',
   6.101 +                                  chk_flag("blocked")],
   6.102 +                             ['running',
   6.103 +                                  chk_flag("running")],
   6.104 +                             ['cpu_time',
   6.105 +                                  vm_metrics[vm_ref]['VCPUs_utilisation'][str(i)]],
   6.106 +                             ['cpu',
   6.107 +                                  vm_metrics[vm_ref]['VCPUs_CPU'][str(i)]],
   6.108 +                             ['cpumap',
   6.109 +                                  vm_metrics[vm_ref]['VCPUs_params']\
   6.110 +                                  ['cpumap%i' % i].split(",")]]
   6.111 +                
   6.112 +                info.append(vcpu_info)
   6.113 +
   6.114 +            dominfo.append(info)
   6.115 +    else:    
   6.116 +        if args:
   6.117 +            dominfo = map(server.xend.domain.getVCPUInfo, args)
   6.118 +        else:
   6.119 +            doms = server.xend.domains(False)
   6.120 +            dominfo = map(server.xend.domain.getVCPUInfo, doms)
   6.121  
   6.122      print '%-32s %3s %5s %5s %5s %9s %s' % \
   6.123            ('Name', 'ID', 'VCPU', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
   6.124 @@ -947,16 +1017,20 @@ def xm_vcpu_list(args):
   6.125              cpumap = map(lambda x: int(x), cpumap)
   6.126              cpumap.sort()
   6.127  
   6.128 -            for x in server.xend.node.info()[1:]:
   6.129 -                if len(x) > 1 and x[0] == 'nr_cpus':
   6.130 -                    nr_cpus = int(x[1])
   6.131 -                    # normalize cpumap by modulus nr_cpus, and drop duplicates
   6.132 -                    cpumap = dict.fromkeys(
   6.133 -                                map(lambda x: x % nr_cpus, cpumap)).keys()
   6.134 -                    if len(cpumap) == nr_cpus:
   6.135 -                        return "any cpu"
   6.136 -                    break
   6.137 - 
   6.138 +            if serverType == SERVER_XEN_API:
   6.139 +                nr_cpus = len(server.xenapi.host.get_host_CPUs(
   6.140 +                    server.xenapi.session.get_this_host()))
   6.141 +            else:
   6.142 +                for x in server.xend.node.info()[1:]:
   6.143 +                    if len(x) > 1 and x[0] == 'nr_cpus':
   6.144 +                        nr_cpus = int(x[1])
   6.145 +
   6.146 +            # normalize cpumap by modulus nr_cpus, and drop duplicates
   6.147 +            cpumap = dict.fromkeys(
   6.148 +                       map(lambda x: x % nr_cpus, cpumap)).keys()
   6.149 +            if len(cpumap) == nr_cpus:
   6.150 +                return "any cpu"
   6.151 +
   6.152              return format_pairs(list_to_rangepairs(cpumap))
   6.153  
   6.154          name  =     get_info('name')
   6.155 @@ -1154,13 +1228,17 @@ def xm_vcpu_pin(args):
   6.156          return cpus
   6.157  
   6.158      dom  = args[0]
   6.159 -    vcpu = args[1]
   6.160 +    vcpu = int(args[1])
   6.161      if args[2] == 'all':
   6.162          cpumap = cpu_make_map('0-63')
   6.163      else:
   6.164          cpumap = cpu_make_map(args[2])
   6.165 -    
   6.166 -    server.xend.domain.pincpu(dom, vcpu, cpumap)
   6.167 +
   6.168 +    if serverType == SERVER_XEN_API:
   6.169 +        server.xenapi.VM.add_to_VCPUs_params_live(
   6.170 +            get_single_vm(dom), "cpumap%i" % vcpu, ",".join(cpumap))
   6.171 +    else:
   6.172 +        server.xend.domain.pincpu(dom, vcpu, cpumap)
   6.173  
   6.174  def xm_mem_max(args):
   6.175      arg_check(args, "mem-max", 2)
   6.176 @@ -1194,7 +1272,7 @@ def xm_vcpu_set(args):
   6.177      vcpus = int(args[1])
   6.178  
   6.179      if serverType == SERVER_XEN_API:
   6.180 -        server.xenapi.VM.set_vcpus_live(get_single_vm(dom), vcpus)
   6.181 +        server.xenapi.VM.set_VCPUs_number_live(get_single_vm(dom), vcpus)
   6.182      else:
   6.183          server.xend.domain.setVCpuCount(dom, vcpus)
   6.184  
   6.185 @@ -1231,6 +1309,8 @@ def xm_domname(args):
   6.186          print sxp.child_value(dom, 'name')
   6.187  
   6.188  def xm_sched_sedf(args):
   6.189 +    xenapi_unsupported()
   6.190 +    
   6.191      def ns_to_ms(val):
   6.192          return float(val) * 0.000001
   6.193      
   6.194 @@ -1355,10 +1435,21 @@ def xm_sched_credit(args):
   6.195          
   6.196          for d in doms:
   6.197              try:
   6.198 -                info = server.xend.domain.sched_credit_get(d['domid'])
   6.199 +                if serverType == SERVER_XEN_API:
   6.200 +                    info = server.xenapi.VM_metrics.get_VCPUs_params(
   6.201 +                        server.xenapi.VM.get_metrics(
   6.202 +                            get_single_vm(d['name'])))
   6.203 +                else:
   6.204 +                    info = server.xend.domain.sched_credit_get(d['domid'])
   6.205              except xmlrpclib.Fault:
   6.206 +                pass
   6.207 +
   6.208 +            if 'weight' not in info or 'cap' not in info:
   6.209                  # domain does not support sched-credit?
   6.210                  info = {'weight': -1, 'cap': -1}
   6.211 +
   6.212 +            info['weight'] = int(info['weight'])
   6.213 +            info['cap']    = int(info['cap'])
   6.214              
   6.215              info['name']  = d['name']
   6.216              info['domid'] = int(d['domid'])
   6.217 @@ -1368,10 +1459,20 @@ def xm_sched_credit(args):
   6.218              # place holder for system-wide scheduler parameters
   6.219              err("No domain given.")
   6.220              usage('sched-credit')
   6.221 -        
   6.222 -        result = server.xend.domain.sched_credit_set(domid, weight, cap)
   6.223 -        if result != 0:
   6.224 -            err(str(result))
   6.225 +
   6.226 +        if serverType == SERVER_XEN_API:
   6.227 +            server.xenapi.VM.add_to_VCPUs_params_live(
   6.228 +                get_single_vm(domid),
   6.229 +                "weight",
   6.230 +                weight)
   6.231 +            server.xenapi.VM.add_to_VCPUs_params_live(
   6.232 +                get_single_vm(domid),
   6.233 +                "cap",
   6.234 +                cap)            
   6.235 +        else:
   6.236 +            result = server.xend.domain.sched_credit_set(domid, weight, cap)
   6.237 +            if result != 0:
   6.238 +                err(str(result))
   6.239  
   6.240  def xm_info(args):
   6.241      arg_check(args, "info", 0)
   6.242 @@ -1754,6 +1855,7 @@ def xm_block_list(args):
   6.243                     % ni)
   6.244  
   6.245  def xm_vtpm_list(args):
   6.246 +    xenapi_unsupported()
   6.247      (use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
   6.248  
   6.249      dom = params[0]
   6.250 @@ -1883,7 +1985,10 @@ def xm_network_attach(args):
   6.251              record = vif_record
   6.252              for key in keys[:-1]:
   6.253                  record = record[key]
   6.254 -            record[keys[-1]] = val 
   6.255 +            record[keys[-1]] = val
   6.256 +
   6.257 +        def get_net_from_bridge(bridge):
   6.258 +            raise "Not supported just yet"
   6.259           
   6.260          vif_conv = {
   6.261              'type':
   6.262 @@ -1991,6 +2096,7 @@ def xm_network_detach(args):
   6.263  
   6.264  
   6.265  def xm_vnet_list(args):
   6.266 +    xenapi_unsupported()
   6.267      try:
   6.268          (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
   6.269      except getopt.GetoptError, opterr:
   6.270 @@ -2019,6 +2125,7 @@ def xm_vnet_list(args):
   6.271              print vnet, ex
   6.272  
   6.273  def xm_vnet_create(args):
   6.274 +    xenapi_unsupported()
   6.275      arg_check(args, "vnet-create", 1)
   6.276      conf = args[0]
   6.277      if not os.access(conf, os.R_OK):
   6.278 @@ -2028,6 +2135,7 @@ def xm_vnet_create(args):
   6.279      server.xend_vnet_create(conf)
   6.280  
   6.281  def xm_vnet_delete(args):
   6.282 +    xenapi_unsupported()
   6.283      arg_check(args, "vnet-delete", 1)
   6.284      vnet = args[0]
   6.285      server.xend_vnet_delete(vnet)
   6.286 @@ -2044,7 +2152,7 @@ commands = {
   6.287      "domid": xm_domid,
   6.288      "domname": xm_domname,
   6.289      "dump-core": xm_dump_core,
   6.290 -    "reboot": xm_reboot,    
   6.291 +    "reboot": xm_reboot,
   6.292      "rename": xm_rename,
   6.293      "restore": xm_restore,
   6.294      "resume": xm_resume,
   6.295 @@ -2228,6 +2336,8 @@ def _run_cmd(cmd, cmd_name, args):
   6.296          err(str(e))
   6.297          _usage(cmd_name)
   6.298          print e.usage
   6.299 +    except XenAPIUnsupportedException, e:
   6.300 +        err(str(e))
   6.301      except Exception, e:
   6.302          if serverType != SERVER_XEN_API:
   6.303             from xen.util import security
     7.1 --- a/tools/python/xen/xm/xenapi_create.py	Thu Mar 22 14:27:05 2007 +0000
     7.2 +++ b/tools/python/xen/xm/xenapi_create.py	Thu Mar 22 14:31:03 2007 +0000
     7.3 @@ -253,11 +253,11 @@ class xenapi_create:
     7.4                  get_child_node_attribute(vm, "memory", "dynamic_max"),
     7.5              "memory_dynamic_min":
     7.6                  get_child_node_attribute(vm, "memory", "dynamic_min"),
     7.7 -            "vcpus_params":
     7.8 +            "VCPUs_params":
     7.9                  get_child_nodes_as_dict(vm, "vcpu_param", "key", "value"),
    7.10 -            "vcpus_max":
    7.11 +            "VCPUs_max":
    7.12                  vm.attributes["vcpus_max"].value,
    7.13 -            "vcpus_at_startup":
    7.14 +            "VCPUs_at_startup":
    7.15                  vm.attributes["vcpus_at_startup"].value,
    7.16              "actions_after_shutdown":
    7.17                  vm.attributes["actions_after_shutdown"].value,