diff options
author | Ian Campbell <ian.campbell@xensource.com> | 2007-06-29 14:38:18 +0100 |
---|---|---|
committer | Ian Campbell <ian.campbell@xensource.com> | 2007-06-29 14:38:18 +0100 |
commit | 1dd1b5a9f6ad61d3a6df79ba66785644115656ad (patch) | |
tree | 62dd1eb5e142d7668a941bff44afc38e2764f596 /tools | |
parent | 9659b6cb45a1b6f2f4e441f9fe8ac01a5792f1d9 (diff) | |
download | xen-1dd1b5a9f6ad61d3a6df79ba66785644115656ad.tar.gz xen-1dd1b5a9f6ad61d3a6df79ba66785644115656ad.tar.bz2 xen-1dd1b5a9f6ad61d3a6df79ba66785644115656ad.zip |
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>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/python/xen/xend/XendConfig.py | 94 |
1 files changed, 79 insertions, 15 deletions
diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 4bb6dd7857..16ebea6f09 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -28,6 +28,7 @@ from xen.xend.XendDevices import XendDevices from xen.xend.PrettyPrint import prettyprintstring from xen.xend.XendConstants import DOM_STATE_HALTED from xen.xend.server.netif import randomMAC +from xen.util.blkif import blkdev_name_to_number log = logging.getLogger("xend.XendConfig") log.setLevel(logging.WARN) @@ -934,6 +935,55 @@ class XendConfig(dict): return sxpr + def _blkdev_name_to_number(self, dev): + try: + devid = int(dev) + except ValueError: + # devid is not a number but a string containing either device + # name (e.g. xvda) or device_type/device_id (e.g. vbd/51728) + dev2 = type(dev) is str and dev.split('/')[-1] or None + if dev2 == None: + log.debug("Could not check the device %s", dev) + return None + try: + devid = int(dev2) + except ValueError: + devid = blkdev_name_to_number(dev2) + if devid == None: + log.debug("The device %s is not device name", dev2) + return None + return devid + + def device_duplicate_check(self, dev_type, dev_info, defined_config): + defined_devices_sxpr = self.all_devices_sxpr(target = defined_config) + + if dev_type == 'vbd': + dev_uname = dev_info.get('uname') + blkdev_name = dev_info.get('dev') + devid = self._blkdev_name_to_number(blkdev_name) + if devid == None: + return + + for o_dev_type, o_dev_info in defined_devices_sxpr: + if dev_type == o_dev_type: + if dev_uname == sxp.child_value(o_dev_info, 'uname'): + raise XendConfigError('The uname "%s" is already defined' % + dev_uname) + o_blkdev_name = sxp.child_value(o_dev_info, 'dev') + o_devid = self._blkdev_name_to_number(o_blkdev_name) + if o_devid != None and devid == o_devid: + raise XendConfigError('The device "%s" is already defined' % + blkdev_name) + + elif dev_type == 'vif': + dev_mac = dev_info.get('mac') + + for o_dev_type, o_dev_info in defined_devices_sxpr: + if dev_type == o_dev_type: + if dev_mac == sxp.child_value(o_dev_info, 'mac'): + raise XendConfigError('The mac "%s" is already defined' % + dev_mac) + def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None, target = None): """Add a device configuration in SXP format or XenAPI struct format. @@ -998,6 +1048,8 @@ class XendConfig(dict): if not dev_info.get('mac'): dev_info['mac'] = randomMAC() + self.device_duplicate_check(dev_type, dev_info, target) + # create uuid if it doesn't exist dev_uuid = dev_info.get('uuid', None) if not dev_uuid: @@ -1275,15 +1327,19 @@ class XendConfig(dict): return False - def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None): + def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None, target = None): """Get Device SXPR by either giving the device UUID or (type, config). @rtype: list of lists @return: device config sxpr """ sxpr = [] - if dev_uuid != None and dev_uuid in self['devices']: - dev_type, dev_info = self['devices'][dev_uuid] + + if target == None: + target = self + + if dev_uuid != None and dev_uuid in target['devices']: + dev_type, dev_info = target['devices'][dev_uuid] if dev_type == None or dev_info == None: raise XendConfigError("Required either UUID or device type and " @@ -1300,8 +1356,12 @@ class XendConfig(dict): return sxpr - def ordered_device_refs(self): + def ordered_device_refs(self, target = None): result = [] + + if target == None: + target = self + # vkbd devices *must* be before vfb devices, otherwise # there is a race condition when setting up devices # where the daemon spawned for the vfb may write stuff @@ -1309,27 +1369,30 @@ class XendConfig(dict): # setup permissions on the vkbd backend path. This race # results in domain creation failing with 'device already # connected' messages - result.extend([u for u in self['devices'].keys() if self['devices'][u][0] == 'vkbd']) + result.extend([u for u in target['devices'].keys() if target['devices'][u][0] == 'vkbd']) - result.extend(self['console_refs'] + - self['vbd_refs'] + - self['vif_refs'] + - self['vtpm_refs']) + result.extend(target.get('console_refs', []) + + target.get('vbd_refs', []) + + target.get('vif_refs', []) + + target.get('vtpm_refs', [])) - result.extend([u for u in self['devices'].keys() if u not in result]) + result.extend([u for u in target['devices'].keys() if u not in result]) return result - def all_devices_sxpr(self): + def all_devices_sxpr(self, target = None): """Returns the SXPR for all devices in the current configuration.""" sxprs = [] pci_devs = [] - if 'devices' not in self: + if target == None: + target = self + + if 'devices' not in target: return sxprs - ordered_refs = self.ordered_device_refs() + ordered_refs = self.ordered_device_refs(target = target) for dev_uuid in ordered_refs: - dev_type, dev_info = self['devices'][dev_uuid] + dev_type, dev_info = target['devices'][dev_uuid] if dev_type == 'pci': # special case for pci devices sxpr = [['uuid', dev_info['uuid']]] for pci_dev_info in dev_info['devs']: @@ -1340,7 +1403,8 @@ class XendConfig(dict): sxprs.append((dev_type, sxpr)) else: sxpr = self.device_sxpr(dev_type = dev_type, - dev_info = dev_info) + dev_info = dev_info, + target = target) sxprs.append((dev_type, sxpr)) return sxprs |