direct-io.hg

changeset 13578:f7a52957b427

[XEND] Add simple VCPUs, VBDs, VIFs statistics monitoring

Keep track of xentop like statistics to expose through the Xen API

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Wed Jan 24 12:09:41 2007 +0000 (2007-01-24)
parents 4f5772324e67
children 6c087036b3ed
files tools/python/scripts/xapi.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendNode.py
line diff
     1.1 --- a/tools/python/scripts/xapi.py	Wed Jan 24 12:07:54 2007 +0000
     1.2 +++ b/tools/python/scripts/xapi.py	Wed Jan 24 12:09:41 2007 +0000
     1.3 @@ -200,6 +200,12 @@ def xapi_host_info(*args):
     1.4          print HOST_INFO_FORMAT % ('VMs', len(hostinfo['resident_VMs']))
     1.5          print HOST_INFO_FORMAT % ('UUID', host)        
     1.6  
     1.7 +        for host_cpu_uuid in hostinfo['host_CPUs']:
     1.8 +            host_cpu = execute(server.host_cpu.get_record, session,
     1.9 +                               host_cpu_uuid)
    1.10 +            print 'CPU %s Util: %.2f' % (host_cpu['number'],
    1.11 +                                         float(host_cpu['utilisation']))
    1.12 +        
    1.13  def xapi_host_set_name(*args):
    1.14      if len(args) < 1:
    1.15          raise OptionError("No hostname specified")
     2.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Jan 24 12:07:54 2007 +0000
     2.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Jan 24 12:09:41 2007 +0000
     2.3 @@ -2052,10 +2052,29 @@ class XendDomainInfo:
     2.4                      # handle that properly.
     2.5  
     2.6              config['MTU'] = 1500 # TODO
     2.7 -            config['io_read_kbs'] = 0.0
     2.8 -            config['io_write_kbs'] = 0.0
     2.9 +            
    2.10 +            if self.state not in (XEN_API_VM_POWER_STATE_HALTED,):
    2.11 +                xennode = XendNode.instance()
    2.12 +                rx_bps, tx_bps = xennode.get_vif_util(self.domid, devid)
    2.13 +                config['io_read_kbs'] = rx_bps/1024
    2.14 +                config['io_write_kbs'] = tx_bps/1024
    2.15 +            else:
    2.16 +                config['io_read_kbs'] = 0.0
    2.17 +                config['io_write_kbs'] = 0.0                
    2.18  
    2.19          if dev_class == 'vbd':
    2.20 +
    2.21 +            if self.state not in (XEN_API_VM_POWER_STATE_HALTED,):
    2.22 +                controller = self.getDeviceController(dev_class)
    2.23 +                devid, _1, _2 = controller.getDeviceDetails(config)
    2.24 +                xennode = XendNode.instance()
    2.25 +                rd_blkps, wr_blkps = xennode.get_vbd_util(self.domid, devid)
    2.26 +                config['io_read_kbs'] = rd_blkps
    2.27 +                config['io_write_kbs'] = wr_blkps
    2.28 +            else:
    2.29 +                config['io_read_kbs'] = 0.0
    2.30 +                config['io_write_kbs'] = 0.0                
    2.31 +            
    2.32              config['VDI'] = config.get('VDI', '')
    2.33              config['device'] = config.get('dev', '')
    2.34              if ':' in config['device']:
    2.35 @@ -2068,8 +2087,7 @@ class XendDomainInfo:
    2.36  
    2.37              config['driver'] = 'paravirtualised' # TODO
    2.38              config['image'] = config.get('uname', '')
    2.39 -            config['io_read_kbs'] = 0.0
    2.40 -            config['io_write_kbs'] = 0.0
    2.41 +
    2.42              if config.get('mode', 'r') == 'r':
    2.43                  config['mode'] = 'RO'
    2.44              else:
    2.45 @@ -2088,14 +2106,12 @@ class XendDomainInfo:
    2.46              raise XendError('Invalid property for device: %s' % field)
    2.47  
    2.48      def get_vcpus_util(self):
    2.49 -        # TODO: this returns the total accum cpu time, rather than util
    2.50 -        # TODO: spec says that key is int, however, python does not allow
    2.51 -        #       non-string keys to dictionaries.
    2.52          vcpu_util = {}
    2.53 +        xennode = XendNode.instance()
    2.54          if 'vcpus_number' in self.info and self.domid != None:
    2.55              for i in range(0, self.info['vcpus_number']):
    2.56 -                info = xc.vcpu_getinfo(self.domid, i)
    2.57 -                vcpu_util[str(i)] = info['cpu_time']/1000000000.0
    2.58 +                util = xennode.get_vcpu_util(self.domid, i)
    2.59 +                vcpu_util[str(i)] = util
    2.60                  
    2.61          return vcpu_util
    2.62  
     3.1 --- a/tools/python/xen/xend/XendNode.py	Wed Jan 24 12:07:54 2007 +0000
     3.2 +++ b/tools/python/xen/xend/XendNode.py	Wed Jan 24 12:09:41 2007 +0000
     3.3 @@ -30,6 +30,7 @@ from xen.xend.XendLogging import log
     3.4  from xen.xend.XendPIF import *
     3.5  from xen.xend.XendNetwork import *
     3.6  from xen.xend.XendStateStore import XendStateStore
     3.7 +from xen.xend.XendMonitor import XendMonitor
     3.8  
     3.9  class XendNode:
    3.10      """XendNode - Represents a Domain 0 Host."""
    3.11 @@ -46,6 +47,8 @@ class XendNode:
    3.12          
    3.13          self.xc = xen.lowlevel.xc.xc()
    3.14          self.state_store = XendStateStore(xendoptions().get_xend_state_path())
    3.15 +        self.monitor = XendMonitor()
    3.16 +        self.monitor.start()
    3.17  
    3.18          # load host state from XML file
    3.19          saved_host = self.state_store.load_state('host')
    3.20 @@ -285,9 +288,17 @@ class XendNode:
    3.21              raise XendError('Invalid CPU Reference')        
    3.22              
    3.23      def get_host_cpu_load(self, host_cpu_ref):
    3.24 +        host_cpu = self.cpus.get(host_cpu_ref)
    3.25 +        if not host_cpu:
    3.26 +            return 0.0
    3.27 +
    3.28 +        vcpu = int(host_cpu['number'])
    3.29 +        cpu_loads = self.monitor.get_domain_vcpus_util()
    3.30 +        if 0 in cpu_loads and vcpu in cpu_loads[0]:
    3.31 +            return cpu_loads[0][vcpu]
    3.32 +
    3.33          return 0.0
    3.34  
    3.35 -
    3.36      #
    3.37      # Network Functions
    3.38      #
    3.39 @@ -397,6 +408,34 @@ class XendNode:
    3.40      def xendinfo(self):
    3.41          return [['xend_config_format', 3]]
    3.42  
    3.43 +    #
    3.44 +    # utilisation tracking
    3.45 +    #
    3.46 +
    3.47 +    def get_vcpu_util(self, domid, vcpuid):
    3.48 +        cpu_loads = self.monitor.get_domain_vcpus_util()
    3.49 +        if domid in cpu_loads:
    3.50 +            return cpu_loads[domid].get(vcpuid, 0.0)
    3.51 +        return 0.0
    3.52 +
    3.53 +    def get_vif_util(self, domid, vifid):
    3.54 +        vif_loads = self.monitor.get_domain_vifs_util()
    3.55 +        if domid in vif_loads:
    3.56 +            return vif_loads[domid].get(vifid, (0.0, 0.0))
    3.57 +        return (0.0, 0.0)
    3.58 +
    3.59 +    def get_vbd_util(self, domid, vbdid):
    3.60 +        vbd_loads = self.monitor.get_domain_vbds_util()
    3.61 +        if domid in vbd_loads:
    3.62 +            return vbd_loads[domid].get(vbdid, (0.0, 0.0))
    3.63 +        return (0.0, 0.0)
    3.64 +
    3.65 +    def get_pif_util(self, pifid):
    3.66 +        pifs_util = self.monitor.get_pifs_util()
    3.67 +        if pifid in pifs_util:
    3.68 +            return pifs_util[pifid]
    3.69 +        return (0.0, 0.0)
    3.70 +
    3.71      # dictionary version of *info() functions to get rid of
    3.72      # SXPisms.
    3.73      def nodeinfo_dict(self):