ia64/xen-unstable

changeset 12111:c88a78f8bed9

[XEND] Proper support for devices with UUID. Removing old workaround
with augmented VM UUIDs with devids.

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Fri Oct 06 16:27:06 2006 +0100 (2006-10-06)
parents c0d9f8b9c0e5
children 029e04982e94
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/server/DevController.py
line diff
     1.1 --- a/tools/python/xen/xend/XendAPI.py	Fri Oct 06 12:46:46 2006 +0100
     1.2 +++ b/tools/python/xen/xend/XendAPI.py	Fri Oct 06 16:27:06 2006 +0100
     1.3 @@ -948,9 +948,14 @@ class XendAPI:
     1.4      # object methods
     1.5      def vbd_get_record(self, session, vbd_ref):
     1.6          xendom = XendDomain.instance()
     1.7 -        return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref,
     1.8 -                                                      'driver'))
     1.9 -
    1.10 +        vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
    1.11 +        if not vm:
    1.12 +            return xen_api_error(XEND_ERROR_VIF_INVALID)
    1.13 +        cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
    1.14 +        if not cfg:
    1.15 +            return xen_api_error(XEND_ERROR_UNKNOWN)
    1.16 +        return xen_api_success(cfg)
    1.17 +    
    1.18      # class methods
    1.19      def vbd_create(self, session, vbd_struct):
    1.20          xendom = XendDomain.instance()
    1.21 @@ -968,20 +973,20 @@ class XendAPI:
    1.22      # attributes (rw)
    1.23      def vbd_get_vm(self, session, vbd_ref):
    1.24          xendom = XendDomain.instance()
    1.25 -        return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref, 'VM'))
    1.26 +        return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM'))
    1.27      def vbd_get_vdi(self, session, vbd_ref):
    1.28          return xen_api_error(XEND_ERROR_UNSUPPORTED)
    1.29      def vbd_get_device(self, session, vbd_ref):
    1.30          xendom = XendDomain.instance()
    1.31 -        return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref,
    1.32 +        return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
    1.33                                                        'device'))
    1.34      def vbd_get_mode(self, session, vbd_ref):
    1.35          xendom = XendDomain.instance()
    1.36 -        return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref,
    1.37 +        return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
    1.38                                                        'mode'))
    1.39      def vbd_get_driver(self, session, vbd_ref):
    1.40          xendom = XendDomain.instance()
    1.41 -        return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref,
    1.42 +        return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
    1.43                                                        'driver'))
    1.44  
    1.45      # Xen API: Class VIF
    1.46 @@ -1001,6 +1006,23 @@ class XendAPI:
    1.47  
    1.48      VIF_attr_inst = VIF_attr_rw
    1.49  
    1.50 +    # object methods
    1.51 +    def vif_get_record(self, session, vif_ref):
    1.52 +        xendom = XendDomain.instance()
    1.53 +        vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
    1.54 +        if not vm:
    1.55 +            return xen_api_error(XEND_ERROR_VIF_INVALID)
    1.56 +        cfg = vm.get_dev_xenapi_config('vif', vif_ref)
    1.57 +        if not cfg:
    1.58 +            return xen_api_error(XEND_ERROR_UNKNOWN)
    1.59 +        valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
    1.60 +                         self.Base_attr_ro + self.Base_attr_rw
    1.61 +        for k in cfg.keys():
    1.62 +            if k not in valid_vif_keys:
    1.63 +                del cfg[k]
    1.64 +            
    1.65 +        return xen_api_success(cfg)
    1.66 +
    1.67      # class methods
    1.68      def vif_create(self, session, vif_struct):
    1.69          xendom = XendDomain.instance()
     2.1 --- a/tools/python/xen/xend/XendConfig.py	Fri Oct 06 12:46:46 2006 +0100
     2.2 +++ b/tools/python/xen/xend/XendConfig.py	Fri Oct 06 16:27:06 2006 +0100
     2.3 @@ -717,6 +717,12 @@ class XendConfig(dict):
     2.4                  raise XendConfigError('Invalid restart event: %s = %s' % \
     2.5                                        (event, str(self[event])))
     2.6  
     2.7 +        # Verify that {vif,vbd}_refs are here too
     2.8 +        if 'vif_refs' not in self:
     2.9 +            self['vif_refs'] = []
    2.10 +        if 'vbd_refs' not in self:
    2.11 +            self['vbd_refs'] = []
    2.12 +
    2.13      def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
    2.14          if dev_type not in XendDevices.valid_devices():
    2.15              raise XendConfigError("XendConfig: %s not a valid device type" %
     3.1 --- a/tools/python/xen/xend/XendDomain.py	Fri Oct 06 12:46:46 2006 +0100
     3.2 +++ b/tools/python/xen/xend/XendDomain.py	Fri Oct 06 16:27:06 2006 +0100
     3.3 @@ -563,22 +563,25 @@ class XendDomain:
     3.4          finally:
     3.5              self.domains_lock.release()
     3.6  
     3.7 -    def get_dev_by_uuid(self, klass, dev_uuid, field):
     3.8 -        parts = dev_uuid.split('-%s-' % klass, 1)
     3.9 +    def get_vm_with_dev_uuid(self, klass, dev_uuid):
    3.10 +        self.domains_lock.acquire()
    3.11          try:
    3.12 -            if len(parts) > 1:
    3.13 -                dom = self.get_vm_by_uuid(parts[0])
    3.14 -                if not dom:
    3.15 -                    return None
    3.16 -                
    3.17 -                if field == 'VM':
    3.18 -                    return dom.get_uuid()
    3.19 -                if field == 'uuid':
    3.20 -                    return dev_uuid
    3.21 +            for dom in self.domains.values():
    3.22 +                if dom.has_device(klass, dev_uuid):
    3.23 +                    return dom
    3.24 +            return None
    3.25 +        finally:
    3.26 +            self.domains_lock.release()
    3.27  
    3.28 -                devid = int(parts[1])
    3.29 -                value = dom.get_device_property(klass, devid, field)
    3.30 -                return value
    3.31 +    def get_dev_property_by_uuid(self, klass, dev_uuid, field):
    3.32 +        self.domains_lock.acquire()
    3.33 +        try:
    3.34 +            dom = self.get_vm_with_dev_uuid(klass, dev_uuid)
    3.35 +            if not dom:
    3.36 +                return None
    3.37 +
    3.38 +            value = dom.get_device_property(klass, devid, field)
    3.39 +            return value
    3.40          except ValueError, e:
    3.41              pass
    3.42          
    3.43 @@ -588,18 +591,7 @@ class XendDomain:
    3.44          return (self.get_vm_by_uuid(vm_ref) != None)
    3.45  
    3.46      def is_valid_dev(self, klass, dev_uuid):
    3.47 -        parts = dev_uuid.split('-%s-' % klass, 1)
    3.48 -        try:
    3.49 -            if len(parts) > 1:
    3.50 -                dom = self.get_vm_by_uuid(parts[0])
    3.51 -                if not dom:
    3.52 -                    return False
    3.53 -                devid = int(parts[1])
    3.54 -                return dom.isDeviceValid(klass, devid)
    3.55 -        except ValueError, e:
    3.56 -            pass
    3.57 -            
    3.58 -        return False
    3.59 +        return (self.get_vm_with_dev_uuid(klass, dev_uuid) != None)
    3.60  
    3.61      def do_legacy_api_with_uuid(self, fn, vm_uuid, *args):
    3.62          self.domains_lock.acquire()
     4.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Oct 06 12:46:46 2006 +0100
     4.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Oct 06 16:27:06 2006 +0100
     4.3 @@ -1709,54 +1709,73 @@ class XendDomainInfo:
     4.4              return XEN_API_ON_CRASH_BEHAVIOUR.index(self.info['on_crash'])
     4.5          except ValueError, e:
     4.6              return XEN_API_ON_CRASH_BEHAVIOUR.index('destroy')
     4.7 -    
     4.8  
     4.9 -    def get_device_property(self, devclass, devid, field):
    4.10 -        controller =  self.getDeviceController(devclass)
    4.11 +    def get_dev_config_by_uuid(self, dev_class, dev_uuid):
    4.12 +        """ Get's a device configuration either from XendConfig or
    4.13 +        from the DevController."""
    4.14 +        if self.get_power_state() not in ('Halted',):
    4.15 +            dev = self.info['device'].get(dev_uuid)
    4.16 +            if dev:
    4.17 +                return dev[1].copy()
    4.18 +            return None
    4.19 +        else:
    4.20 +            controller = self.getDeviceController(dev_class)
    4.21 +            if not controller:
    4.22 +                return None
    4.23 +            all_configs = controller.getAllDeviceConfigurations()
    4.24 +            if not all_configs:
    4.25 +                return None
    4.26 +            for _devid, _devcfg in all_configs.items():
    4.27 +                if _devcfg.get('uuid') == dev_uuid:
    4.28 +                    devcfg = _devcfg.copy()
    4.29 +                    devcfg['id'] = _devid
    4.30 +                    return devcfg
    4.31  
    4.32 -        if devclass == 'vif':
    4.33 -            if field in ('name', 'MAC', 'type'):
    4.34 -                config = controller.getDeviceConfiguration(devid)
    4.35 -                if field == 'name':
    4.36 -                    return config['vifname']
    4.37 -                if field == 'mac':
    4.38 -                    return config['mac']
    4.39 -                if field == 'type':
    4.40 -                    return config['type']
    4.41 -            if field == 'device':
    4.42 -                return 'eth%s' % devid
    4.43 -            if field == 'network':
    4.44 -                return None # TODO
    4.45 -            if field == 'VM':
    4.46 -                return self.get_uuid()
    4.47 -            if field == 'MTU':
    4.48 -                return 0 # TODO
    4.49 -            # TODO: network bandwidth values
    4.50 -            return 0.0
    4.51 +        return None
    4.52 +                    
    4.53 +    def get_dev_xenapi_config(self, dev_class, dev_uuid):
    4.54 +        config = self.get_dev_config_by_uuid(dev_class, dev_uuid)
    4.55 +        if not config:
    4.56 +            return {}
    4.57 +        
    4.58 +        config['VM'] = self.get_uuid()
    4.59 +        
    4.60 +        if dev_class == 'vif':
    4.61 +            if not config.has_key('name'):
    4.62 +                config['name'] = config.get('vifname', '')
    4.63 +            if not config.has_key('MAC'):
    4.64 +                config['MAC'] = config.get('mac', '')
    4.65 +            if not config.has_key('type'):
    4.66 +                config['type'] = 'paravirtualised'
    4.67 +            if not config.has_key('device'):
    4.68 +                devid = config.get('id')
    4.69 +                if devid != None:
    4.70 +                    config['device'] = 'eth%d' % devid
    4.71 +                else:
    4.72 +                    config['device'] = ''
    4.73 +                    
    4.74 +            config['network'] = '' # Invalid for Xend
    4.75 +            config['MTU'] = 1500 # TODO
    4.76 +            config['network_read_kbs'] = 0.0
    4.77 +            config['network_write_kbs'] = 0.0
    4.78 +            config['IO_bandwidth_incoming_kbs'] = 0.0
    4.79 +            config['IO_bandwidth_outgoing_kbs'] = 0.0
    4.80  
    4.81 -        if devclass == 'vbd':
    4.82 -            if field == 'VM':
    4.83 -                return self.get_uuid()
    4.84 -            if field == 'VDI':
    4.85 -                return '' # TODO
    4.86 -            if field in ('device', 'mode', 'driver'):
    4.87 -                config = controller.getDeviceConfiguration(devid)
    4.88 -                if field == 'device':
    4.89 -                    return config['dev'] # TODO
    4.90 -                if field == 'mode':
    4.91 -                    return config['mode']
    4.92 -                if field == 'driver':
    4.93 -                    return config['uname'] # TODO
    4.94 +        if dev_class == 'vbd':
    4.95 +            config['VDI'] = '' # TODO
    4.96 +            config['device'] = config.get('dev', '')
    4.97 +            config['driver'] = config.get('uname', '')
    4.98 +            config['IO_bandwidth_incoming_kbs'] = 0.0
    4.99 +            config['IO_bandwidth_outgoing_kbs'] = 0.0                        
   4.100  
   4.101 -            # TODO network bandwidth values
   4.102 -            return 0.0
   4.103 -
   4.104 -        raise XendError("Unrecognised dev class or property")
   4.105 +        return config
   4.106  
   4.107 -
   4.108 -    def is_device_valid(self, devclass, devid):
   4.109 -        controller = self.getDeviceController(devclass)
   4.110 -        return (devid in controller.deviceIDs())
   4.111 +    def get_dev_property(self, dev_class, dev_uuid, field):
   4.112 +        config = self.get_dev_xenapi_config(dev_class, dev_uuid)
   4.113 +        try:
   4.114 +            return config[field]
   4.115 +        except KeyError:
   4.116 +            raise XendError('Invalid property for device: %s' % field)
   4.117  
   4.118      def get_vcpus_util(self):
   4.119          # TODO: this returns the total accum cpu time, rather than util
   4.120 @@ -1806,7 +1825,9 @@ class XendDomainInfo:
   4.121              raise XendError("Device creation failed")
   4.122  
   4.123          return dev_uuid
   4.124 -    
   4.125 +
   4.126 +    def has_device(self, dev_class, dev_uuid):
   4.127 +        return (dev_uuid in self.info['%s_refs' % dev_class])
   4.128  
   4.129      """
   4.130          def stateChar(name):
     5.1 --- a/tools/python/xen/xend/server/DevController.py	Fri Oct 06 12:46:46 2006 +0100
     5.2 +++ b/tools/python/xen/xend/server/DevController.py	Fri Oct 06 16:27:06 2006 +0100
     5.3 @@ -256,6 +256,13 @@ class DevController:
     5.4  
     5.5          return {'backend': int(backdomid)}
     5.6  
     5.7 +    def getAllDeviceConfigurations(self):
     5.8 +        all_configs = {}
     5.9 +        for devid in self.deviceIDs():
    5.10 +            config_dict = self.getDeviceConfiguration(devid)
    5.11 +            all_configs[devid] = config_dict
    5.12 +        return all_configs
    5.13 +
    5.14      ## protected:
    5.15  
    5.16      def getDeviceDetails(self, config):