ia64/xen-unstable

changeset 19683:d02c3b25c7c0

Revert 19657:9ff5c79b0ceb

Breaks automated localhost migration tests:
for xx in x:
TypeError: iteration over non-sequence

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Sat May 30 13:21:08 2009 +0100 (2009-05-30)
parents bfa933a4628d
children 46468a3b2d5f
files tools/python/xen/xend/XendConfig.py
line diff
     1.1 --- a/tools/python/xen/xend/XendConfig.py	Sat May 30 10:24:21 2009 +0100
     1.2 +++ b/tools/python/xen/xend/XendConfig.py	Sat May 30 13:21:08 2009 +0100
     1.3 @@ -19,7 +19,6 @@ import logging
     1.4  import re
     1.5  import time
     1.6  import types
     1.7 -import XendDomain
     1.8  
     1.9  from xen.xend import sxp
    1.10  from xen.xend import uuid
    1.11 @@ -1164,142 +1163,65 @@ class XendConfig(dict):
    1.12                      return None
    1.13          return devid
    1.14      
    1.15 -    def device_tuple_value_from_dev_info(self, dev_info, key):
    1.16 -         for x in dev_info:
    1.17 -             if (type(x) != str):
    1.18 -                 for xx in x:
    1.19 -                     if (xx[0] == key):
    1.20 -                         return xx[1]
    1.21 -         return None
    1.22 -
    1.23 -    # This function translates all block device modes (incl. aliases) to
    1.24 -    # one common label per each device mode. Those modes can be:
    1.25 -    #  read-only (ro), write-exclusive (wx) and write-shared (ws)
    1.26 -    def block_device_mode_translate(self, mode):
    1.27 -         # Device modes can be read-only (ro), write-exclusive (wx) or
    1.28 -         # write-shared (ws), otherwise an error is raised
    1.29 -         if mode == "w" or mode == "wr":
    1.30 -             return "wx"
    1.31 -         elif mode == "r" or mode == "ro":
    1.32 -             return "ro"
    1.33 -         elif mode == "!" or mode == "w!":
    1.34 -             return "ws"
    1.35 -
    1.36 -         # If no mode defined we consider this as write-exclusive
    1.37 -         return "wx"
    1.38 -
    1.39 -    # Detect device duplicates for vbd, tap and vif devices for domain and
    1.40 -    # duplicate unames in global context not to destroy virtual block devices
    1.41      def device_duplicate_check(self, dev_type, dev_info, defined_config, config):
    1.42 -         # Enumerate all devices for all domains
    1.43 -         allSxprs = []
    1.44 -         val = XendDomain.instance().domains.values()
    1.45 -         for v in val:
    1.46 -             sxpr = v.getDeviceSxprs(dev_type)
    1.47 -             for key in sxpr:
    1.48 -                try:
    1.49 -                    index = allSxprs.index(key)
    1.50 -                except:
    1.51 -                    allSxprs.append(key)
    1.52 -
    1.53 -         # Enumerate devices for current domain
    1.54 -         sxpr = self.all_devices_sxpr(target = defined_config)
    1.55 -
    1.56 -         # For vif interface we won't check cross-domain
    1.57 -         if sxpr == None and dev_type == 'vif':
    1.58 -            return
    1.59 -
    1.60 -         # Preset None values to all variables we'll be checking
    1.61 -         new_uname = None
    1.62 -         uname = None
    1.63 -         dev = None
    1.64 -         mac = None
    1.65 -         mode = None
    1.66 -
    1.67 -         # Disk device
    1.68 -         if dev_type in ['vbd', 'tap']:
    1.69 -             for x in config:
    1.70 -                 if type(x) != str and (x[0] in ['uname', 'dev', 'mode']):
    1.71 -                     if x[0] == 'uname':
    1.72 -                         new_uname = x[1]
    1.73 -                     if x[0] == 'dev':
    1.74 -                         dev = x[1]
    1.75 -                     if x[0] == 'mode':
    1.76 -                         mode = x[1]
    1.77 -
    1.78 -             # If we don't have uname entry (happens in virt-manager) return
    1.79 -             if new_uname == None:
    1.80 -                 return
    1.81 +        defined_devices_sxpr = self.all_devices_sxpr(target = defined_config)
    1.82 +        
    1.83 +        if dev_type == 'vbd' or dev_type == 'tap':
    1.84 +            dev_uname = dev_info.get('uname')
    1.85 +            blkdev_name = dev_info.get('dev')
    1.86 +            devid = self._blkdev_name_to_number(blkdev_name)
    1.87 +            if devid == None or dev_uname == None:
    1.88 +                return
    1.89 +            
    1.90 +            for o_dev_type, o_dev_info in defined_devices_sxpr:
    1.91 +                if o_dev_type == 'vbd' or o_dev_type == 'tap':
    1.92 +                    blkdev_file = blkdev_uname_to_file(dev_uname)
    1.93 +                    o_dev_uname = sxp.child_value(o_dev_info, 'uname')
    1.94 +                    if o_dev_uname != None:
    1.95 +                        o_blkdev_file = blkdev_uname_to_file(o_dev_uname)
    1.96 +                        if blkdev_file == o_blkdev_file:
    1.97 +                            raise XendConfigError('The file "%s" is already used' %
    1.98 +                                                  blkdev_file)
    1.99 +                    if dev_uname == o_dev_uname:
   1.100 +                        raise XendConfigError('The uname "%s" is already defined' %
   1.101 +                                             dev_uname)
   1.102 +                    o_blkdev_name = sxp.child_value(o_dev_info, 'dev')
   1.103 +                    o_devid = self._blkdev_name_to_number(o_blkdev_name)
   1.104 +                    if o_devid != None and devid == o_devid:
   1.105 +                        name_array = blkdev_name.split(':', 2)
   1.106 +                        if len(name_array) == 2 and name_array[1] == 'cdrom':
   1.107 +                            #
   1.108 +                            # Since the device is a cdrom, we are most likely
   1.109 +                            # inserting, changing, or removing a cd.  We can
   1.110 +                            # update the old device instead of creating a new
   1.111 +                            # one.
   1.112 +                            #
   1.113 +                            if o_dev_uname != None and dev_uname == None:
   1.114 +                                #
   1.115 +                                # We are removing a cd.  We can simply update
   1.116 +                                # the uname on the existing device.
   1.117 +                                #
   1.118 +                                merge_sxp = sxp.from_string("('vbd' ('uname' ''))")
   1.119 +                            else:
   1.120 +                                merge_sxp = config
   1.121  
   1.122 -             new_uname = new_uname.split(":")[len(new_uname.split(":"))-1]
   1.123 -             # We need to allow when uname is zero length, eg. hdc:cdrom device
   1.124 -             if len(new_uname) == 0:
   1.125 -                 log.debug("Null uname when attaching disk device, allowing %s..."
   1.126 -                           % dev)
   1.127 -                 return
   1.128 -
   1.129 -             log.debug("Checking for duplicate for uname: %s, dev: %s, mode: %s"
   1.130 -                       % (new_uname, dev, mode))
   1.131 -             # No device in dev found
   1.132 -             if dev == None:
   1.133 -                 return
   1.134 -
   1.135 -             devid = self._blkdev_name_to_number(dev)
   1.136 -             if devid == None:
   1.137 -                 return
   1.138 -
   1.139 -             for o_dev_info in sxpr:
   1.140 -                 # Get information only for tap/vbd block devices
   1.141 -                 if o_dev_info[0] in ['tap', 'vbd']:
   1.142 -                     uname = self.device_tuple_value_from_dev_info(o_dev_info, "uname")
   1.143 -                     dev = self.device_tuple_value_from_dev_info(o_dev_info, "dev")
   1.144 -                     dev_uname = None
   1.145 -                     if uname != None:
   1.146 -                         dev_uname = uname.split(":")[len(uname.split(":"))-1]
   1.147 -                     if new_uname == dev_uname:
   1.148 -                         raise XendConfigError('The uname "%s" is already defined' %
   1.149 -                                               dev_uname)
   1.150 +                            dev_uuid = sxp.child_value(o_dev_info, 'uuid')
   1.151 +                            if dev_uuid != None and \
   1.152 +                               self.device_update(dev_uuid, cfg_sxp = merge_sxp):
   1.153 +                                return dev_uuid
   1.154  
   1.155 -                     blkdev = dev.split(":")[0]
   1.156 -                     blkdevid = self._blkdev_name_to_number(blkdev)
   1.157 -                     if blkdevid != None and devid == blkdevid:
   1.158 -                         raise XendConfigError('The device "%s" is already defined' %
   1.159 -                                               blkdev)
   1.160 -
   1.161 -             tMode = self.block_device_mode_translate(mode)
   1.162 -
   1.163 -             # Device/uname not found in the context of current domain but we
   1.164 -             # need to have a look to global context. We deny addition of device
   1.165 -             # in those cases:
   1.166 -             #   1. We're adding read-only disk that's already used as write-exclusive
   1.167 -             #   2. We're adding write-shared disk that's already used as write-exclusive
   1.168 -             #   3. We're adding write-exclusive disk that's already used
   1.169 -             #   4. We're adding read-only disk that's already used as write-shared
   1.170 -             for o_dev_info in allSxprs:
   1.171 -                 backend = self.device_tuple_value_from_dev_info(o_dev_info, "backend")
   1.172 -                 params = xstransact.Read(backend, "params")
   1.173 -                 aMode = self.block_device_mode_translate(
   1.174 -                                     xstransact.Read(backend, "mode") )
   1.175 -                 dev_uname = params.split(":")[len(params.split(":"))-1]
   1.176 -                 if new_uname == dev_uname:
   1.177 -                     if ((tMode == "ro" and aMode == "wx")
   1.178 -                       or (tMode == "ws" and aMode == "wx")
   1.179 -                       or (tMode == "ro" and aMode == "ws")
   1.180 -                       or (tMode == "wx")):
   1.181 -                         raise XendConfigError('The uname "%s" is already used by another domain' %
   1.182 -                                                   dev_uname)
   1.183 -
   1.184 -         # Virtual network adapter
   1.185 -         elif dev_type == 'vif':
   1.186 -             dev_mac = dev_info.get('mac')
   1.187 -
   1.188 -             for o_dev_type, o_dev_info in sxpr: 
   1.189 -                 if dev_type == o_dev_type:
   1.190 -                     if dev_mac.lower() == sxp.child_value(o_dev_info, 'mac').lower():
   1.191 -                         raise XendConfigError('The mac "%s" is already defined' %
   1.192 -                                               dev_mac)
   1.193 -
   1.194 -         return None
   1.195 +                        raise XendConfigError('The device "%s" is already defined' %
   1.196 +                                              blkdev_name)
   1.197 +                    
   1.198 +        elif dev_type == 'vif':
   1.199 +            dev_mac = dev_info.get('mac')
   1.200 +            
   1.201 +            for o_dev_type, o_dev_info in defined_devices_sxpr:
   1.202 +                if dev_type == o_dev_type:
   1.203 +                    if dev_mac.lower() == sxp.child_value(o_dev_info, 'mac').lower():
   1.204 +                        raise XendConfigError('The mac "%s" is already defined' %
   1.205 +                                              dev_mac)
   1.206 +        return None
   1.207      
   1.208      def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None,
   1.209                     target = None):