ia64/xen-unstable

changeset 15459:ab95b9764b20

Add a duplication definition check for devices.

This patch adds a duplication definition check for devices.
It checks the following definitions.
- vbd : uname and device name
- vif : mac

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author Ian Campbell <ian.campbell@xensource.com>
date Fri Jun 29 14:38:18 2007 +0100 (2007-06-29)
parents b377a102f0eb
children 2cdf8fef8d93
files tools/python/xen/xend/XendConfig.py
line diff
     1.1 --- a/tools/python/xen/xend/XendConfig.py	Thu Jun 28 20:35:50 2007 +0100
     1.2 +++ b/tools/python/xen/xend/XendConfig.py	Fri Jun 29 14:38:18 2007 +0100
     1.3 @@ -28,6 +28,7 @@ from xen.xend.XendDevices import XendDev
     1.4  from xen.xend.PrettyPrint import prettyprintstring
     1.5  from xen.xend.XendConstants import DOM_STATE_HALTED
     1.6  from xen.xend.server.netif import randomMAC
     1.7 +from xen.util.blkif import blkdev_name_to_number
     1.8  
     1.9  log = logging.getLogger("xend.XendConfig")
    1.10  log.setLevel(logging.WARN)
    1.11 @@ -934,6 +935,55 @@ class XendConfig(dict):
    1.12  
    1.13          return sxpr    
    1.14      
    1.15 +    def _blkdev_name_to_number(self, dev):
    1.16 +        try:
    1.17 +            devid = int(dev)
    1.18 +        except ValueError:
    1.19 +            # devid is not a number but a string containing either device
    1.20 +            # name (e.g. xvda) or device_type/device_id (e.g. vbd/51728)
    1.21 +            dev2 = type(dev) is str and dev.split('/')[-1] or None
    1.22 +            if dev2 == None:
    1.23 +                log.debug("Could not check the device %s", dev)
    1.24 +                return None
    1.25 +            try:
    1.26 +                devid = int(dev2)
    1.27 +            except ValueError:
    1.28 +                devid = blkdev_name_to_number(dev2)
    1.29 +                if devid == None:
    1.30 +                    log.debug("The device %s is not device name", dev2)
    1.31 +                    return None
    1.32 +        return devid
    1.33 +    
    1.34 +    def device_duplicate_check(self, dev_type, dev_info, defined_config):
    1.35 +        defined_devices_sxpr = self.all_devices_sxpr(target = defined_config)
    1.36 +        
    1.37 +        if dev_type == 'vbd':
    1.38 +            dev_uname = dev_info.get('uname')
    1.39 +            blkdev_name = dev_info.get('dev')
    1.40 +            devid = self._blkdev_name_to_number(blkdev_name)
    1.41 +            if devid == None:
    1.42 +                return
    1.43 +            
    1.44 +            for o_dev_type, o_dev_info in defined_devices_sxpr:
    1.45 +                if dev_type == o_dev_type:
    1.46 +                    if dev_uname == sxp.child_value(o_dev_info, 'uname'):
    1.47 +                        raise XendConfigError('The uname "%s" is already defined' %
    1.48 +                                              dev_uname)
    1.49 +                    o_blkdev_name = sxp.child_value(o_dev_info, 'dev')
    1.50 +                    o_devid = self._blkdev_name_to_number(o_blkdev_name)
    1.51 +                    if o_devid != None and devid == o_devid:
    1.52 +                        raise XendConfigError('The device "%s" is already defined' %
    1.53 +                                              blkdev_name)
    1.54 +                    
    1.55 +        elif dev_type == 'vif':
    1.56 +            dev_mac = dev_info.get('mac')
    1.57 +            
    1.58 +            for o_dev_type, o_dev_info in defined_devices_sxpr:
    1.59 +                if dev_type == o_dev_type:
    1.60 +                    if dev_mac == sxp.child_value(o_dev_info, 'mac'):
    1.61 +                        raise XendConfigError('The mac "%s" is already defined' %
    1.62 +                                              dev_mac)
    1.63 +    
    1.64      def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None,
    1.65                     target = None):
    1.66          """Add a device configuration in SXP format or XenAPI struct format.
    1.67 @@ -998,6 +1048,8 @@ class XendConfig(dict):
    1.68                  if not dev_info.get('mac'):
    1.69                      dev_info['mac'] = randomMAC()
    1.70  
    1.71 +            self.device_duplicate_check(dev_type, dev_info, target)
    1.72 +
    1.73              # create uuid if it doesn't exist
    1.74              dev_uuid = dev_info.get('uuid', None)
    1.75              if not dev_uuid:
    1.76 @@ -1275,15 +1327,19 @@ class XendConfig(dict):
    1.77          return False
    1.78  
    1.79  
    1.80 -    def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None):
    1.81 +    def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None, target = None):
    1.82          """Get Device SXPR by either giving the device UUID or (type, config).
    1.83  
    1.84          @rtype: list of lists
    1.85          @return: device config sxpr
    1.86          """
    1.87          sxpr = []
    1.88 -        if dev_uuid != None and dev_uuid in self['devices']:
    1.89 -            dev_type, dev_info = self['devices'][dev_uuid]
    1.90 +
    1.91 +        if target == None:
    1.92 +            target = self
    1.93 +
    1.94 +        if dev_uuid != None and dev_uuid in target['devices']:
    1.95 +            dev_type, dev_info = target['devices'][dev_uuid]
    1.96  
    1.97          if dev_type == None or dev_info == None:
    1.98              raise XendConfigError("Required either UUID or device type and "
    1.99 @@ -1300,8 +1356,12 @@ class XendConfig(dict):
   1.100  
   1.101          return sxpr
   1.102  
   1.103 -    def ordered_device_refs(self):
   1.104 +    def ordered_device_refs(self, target = None):
   1.105          result = []
   1.106 +
   1.107 +        if target == None:
   1.108 +            target = self
   1.109 +
   1.110          # vkbd devices *must* be before vfb devices, otherwise
   1.111          # there is a race condition when setting up devices
   1.112          # where the daemon spawned for the vfb may write stuff
   1.113 @@ -1309,27 +1369,30 @@ class XendConfig(dict):
   1.114          # setup permissions on the vkbd backend path. This race
   1.115          # results in domain creation failing with 'device already
   1.116          # connected' messages
   1.117 -        result.extend([u for u in self['devices'].keys() if self['devices'][u][0] == 'vkbd'])
   1.118 +        result.extend([u for u in target['devices'].keys() if target['devices'][u][0] == 'vkbd'])
   1.119  
   1.120 -        result.extend(self['console_refs'] +
   1.121 -                      self['vbd_refs'] +
   1.122 -                      self['vif_refs'] +
   1.123 -                      self['vtpm_refs'])
   1.124 +        result.extend(target.get('console_refs', []) +
   1.125 +                      target.get('vbd_refs', []) +
   1.126 +                      target.get('vif_refs', []) +
   1.127 +                      target.get('vtpm_refs', []))
   1.128  
   1.129 -        result.extend([u for u in self['devices'].keys() if u not in result])
   1.130 +        result.extend([u for u in target['devices'].keys() if u not in result])
   1.131          return result
   1.132  
   1.133 -    def all_devices_sxpr(self):
   1.134 +    def all_devices_sxpr(self, target = None):
   1.135          """Returns the SXPR for all devices in the current configuration."""
   1.136          sxprs = []
   1.137          pci_devs = []
   1.138  
   1.139 -        if 'devices' not in self:
   1.140 +        if target == None:
   1.141 +            target = self
   1.142 +
   1.143 +        if 'devices' not in target:
   1.144              return sxprs
   1.145          
   1.146 -        ordered_refs = self.ordered_device_refs()
   1.147 +        ordered_refs = self.ordered_device_refs(target = target)
   1.148          for dev_uuid in ordered_refs:
   1.149 -            dev_type, dev_info = self['devices'][dev_uuid]
   1.150 +            dev_type, dev_info = target['devices'][dev_uuid]
   1.151              if dev_type == 'pci': # special case for pci devices
   1.152                  sxpr = [['uuid', dev_info['uuid']]]
   1.153                  for pci_dev_info in dev_info['devs']:
   1.154 @@ -1340,7 +1403,8 @@ class XendConfig(dict):
   1.155                  sxprs.append((dev_type, sxpr))
   1.156              else:
   1.157                  sxpr = self.device_sxpr(dev_type = dev_type,
   1.158 -                                        dev_info = dev_info)
   1.159 +                                        dev_info = dev_info,
   1.160 +                                        target   = target)
   1.161                  sxprs.append((dev_type, sxpr))
   1.162  
   1.163          return sxprs