def get_device_name_for_instance(context, instance, bdms, device): """Validates (or generates) a device name for instance. If device is not set, it will generate a unique device appropriate for the instance. It uses the block device mapping table to find valid device names. If the device name is valid but applicable to a different backend (for example /dev/vdc is specified but the backend uses /dev/xvdc), the device name will be converted to the appropriate format. """ req_prefix = None req_letter = None if device: try: req_prefix, req_letter = block_device.match_device(device) except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=device) mappings = block_device.instance_block_mapping(instance, bdms) try: prefix = block_device.match_device(mappings['root'])[0] except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=mappings['root']) # NOTE(vish): remove this when xenapi is setting default_root_device if driver.compute_driver_matches('xenapi.XenAPIDriver'): prefix = '/dev/xvd' if req_prefix != prefix: LOG.debug(_("Using %(prefix)s instead of %(req_prefix)s"), {'prefix': prefix, 'req_prefix': req_prefix}) used_letters = set() for device_path in mappings.itervalues(): letter = block_device.strip_prefix(device_path) # NOTE(vish): delete numbers in case we have something like # /dev/sda1 letter = re.sub("\d+", "", letter) used_letters.add(letter) # NOTE(vish): remove this when xenapi is properly setting # default_ephemeral_device and default_swap_device if driver.compute_driver_matches('xenapi.XenAPIDriver'): instance_type = flavors.extract_flavor(instance) if instance_type['ephemeral_gb']: used_letters.add('b') if instance_type['swap']: used_letters.add('c') if not req_letter: req_letter = _get_unused_letter(used_letters) if req_letter in used_letters: raise exception.DevicePathInUse(path=device) device_name = prefix + req_letter return device_name
def get_next_device_name(instance, device_name_list, root_device_name=None, device=None): """Validates (or generates) a device name for instance. If device is not set, it will generate a unique device appropriate for the instance. It uses the root_device_name (if provided) and the list of used devices to find valid device names. If the device name is valid but applicable to a different backend (for example /dev/vdc is specified but the backend uses /dev/xvdc), the device name will be converted to the appropriate format. """ req_prefix = None req_letter = None if device: try: req_prefix, req_letter = block_device.match_device(device) except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=device) if not root_device_name: root_device_name = block_device.DEFAULT_ROOT_DEV_NAME try: prefix = block_device.match_device(root_device_name)[0] except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=root_device_name) # NOTE(vish): remove this when xenapi is setting default_root_device if driver.compute_driver_matches("xenapi.XenAPIDriver"): prefix = "/dev/xvd" if req_prefix != prefix: LOG.debug("Using %(prefix)s instead of %(req_prefix)s", {"prefix": prefix, "req_prefix": req_prefix}) used_letters = set() for device_path in device_name_list: letter = block_device.strip_prefix(device_path) # NOTE(vish): delete numbers in case we have something like # /dev/sda1 letter = re.sub("\d+", "", letter) used_letters.add(letter) # NOTE(vish): remove this when xenapi is properly setting # default_ephemeral_device and default_swap_device if driver.compute_driver_matches("xenapi.XenAPIDriver"): flavor = flavors.extract_flavor(instance) if flavor["ephemeral_gb"]: used_letters.add("b") if flavor["swap"]: used_letters.add("c") if not req_letter: req_letter = _get_unused_letter(used_letters) if req_letter in used_letters: raise exception.DevicePathInUse(path=device) return prefix + req_letter
def get_device_name_for_instance(context, instance, bdms, device): """Validates (or generates) a device name for instance. If device is not set, it will generate a unique device appropriate for the instance. It uses the block device mapping table to find valid device names. If the device name is valid but applicable to a different backend (for example /dev/vdc is specified but the backend uses /dev/xvdc), the device name will be converted to the appropriate format. """ req_prefix = None req_letter = None if device: try: req_prefix, req_letter = block_device.match_device(device) except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=device) mappings = block_device.instance_block_mapping(instance, bdms) try: prefix = block_device.match_device(mappings['root'])[0] except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=mappings['root']) # NOTE(vish): remove this when xenapi is setting default_root_device if driver.compute_driver_matches('xenapi.XenAPIDriver'): prefix = '/dev/xvd' if req_prefix != prefix: LOG.debug(_("Using %(prefix)s instead of %(req_prefix)s") % locals()) used_letters = set() for device_path in mappings.itervalues(): letter = block_device.strip_prefix(device_path) # NOTE(vish): delete numbers in case we have something like # /dev/sda1 letter = re.sub("\d+", "", letter) used_letters.add(letter) # NOTE(vish): remove this when xenapi is properly setting # default_ephemeral_device and default_swap_device if driver.compute_driver_matches('xenapi.XenAPIDriver'): instance_type = instance_types.extract_instance_type(instance) if instance_type['ephemeral_gb']: used_letters.add('b') if instance_type['swap']: used_letters.add('c') if not req_letter: req_letter = _get_unused_letter(used_letters) if req_letter in used_letters: raise exception.DevicePathInUse(path=device) device_name = prefix + req_letter return device_name
def get_device_name_for_instance(context, instance, device): """Validates (or generates) a device name for instance. If device is not set, it will generate a unique device appropriate for the instance. It uses the block device mapping table to find valid device names. If the device name is valid but applicable to a different backend (for example /dev/vdc is specified but the backend uses /dev/xvdc), the device name will be converted to the appropriate format. """ req_prefix = None req_letters = None if device: try: req_prefix, req_letters = block_device.match_device(device) except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=device) bdms = db.block_device_mapping_get_all_by_instance(context, instance["uuid"]) mappings = block_device.instance_block_mapping(instance, bdms) try: prefix = block_device.match_device(mappings["root"])[0] except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=mappings["root"]) # NOTE(vish): remove this when xenapi is setting default_root_device if driver.compute_driver_matches("xenapi.XenAPIDriver"): prefix = "/dev/xvd" if req_prefix != prefix: LOG.debug(_("Using %(prefix)s instead of %(req_prefix)s") % locals()) letters_list = [] for _name, device in mappings.iteritems(): letter = block_device.strip_prefix(device) # NOTE(vish): delete numbers in case we have something like # /dev/sda1 letter = re.sub("\d+", "", letter) letters_list.append(letter) used_letters = set(letters_list) # NOTE(vish): remove this when xenapi is properly setting # default_ephemeral_device and default_swap_device if driver.compute_driver_matches("xenapi.XenAPIDriver"): instance_type_id = instance["instance_type_id"] instance_type = instance_types.get_instance_type(instance_type_id) if instance_type["ephemeral_gb"]: used_letters.update("b") if instance_type["swap"]: used_letters.update("c") if not req_letters: req_letters = _get_unused_letters(used_letters) if req_letters in used_letters: raise exception.DevicePathInUse(path=device) return prefix + req_letters
def instance_block_mapping(instance, bdms): root_device_name = instance['root_device_name'] # NOTE(clayg): remove this when xenapi is setting default_root_device if root_device_name is None: if driver.compute_driver_matches('xenapi.XenAPIDriver'): root_device_name = '/dev/xvda' else: return _DEFAULT_MAPPINGS mappings = {} mappings['ami'] = strip_dev(root_device_name) mappings['root'] = root_device_name default_ephemeral_device = instance.get('default_ephemeral_device') if default_ephemeral_device: mappings['ephemeral0'] = default_ephemeral_device default_swap_device = instance.get('default_swap_device') if default_swap_device: mappings['swap'] = default_swap_device ebs_devices = [] blanks = [] # 'ephemeralN', 'swap' and ebs for bdm in bdms: # ebs volume case if bdm.destination_type == 'volume': ebs_devices.append(bdm.device_name) continue if bdm.source_type == 'blank': blanks.append(bdm) # NOTE(yamahata): I'm not sure how ebs device should be numbered. # Right now sort by device name for deterministic # result. if ebs_devices: ebs_devices.sort() for nebs, ebs in enumerate(ebs_devices): mappings['ebs%d' % nebs] = ebs swap = [bdm for bdm in blanks if bdm.guest_format == 'swap'] if swap: mappings['swap'] = swap.pop().device_name ephemerals = [bdm for bdm in blanks if bdm.guest_format != 'swap'] if ephemerals: for num, eph in enumerate(ephemerals): mappings['ephemeral%d' % num] = eph.device_name # plus cdrom if root_device is hda if 'hda' in mappings['root']: mappings['cdrom'] = 'hdb' return mappings
def instance_block_mapping(instance, bdms): root_device_name = instance["root_device_name"] # NOTE(clayg): remove this when xenapi is setting default_root_device if root_device_name is None: if driver.compute_driver_matches("xenapi.XenAPIDriver"): root_device_name = "/dev/xvda" else: return _DEFAULT_MAPPINGS mappings = {} mappings["ami"] = strip_dev(root_device_name) mappings["root"] = root_device_name default_ephemeral_device = instance.get("default_ephemeral_device") if default_ephemeral_device: mappings["ephemeral0"] = default_ephemeral_device default_swap_device = instance.get("default_swap_device") if default_swap_device: mappings["swap"] = default_swap_device ebs_devices = [] blanks = [] # 'ephemeralN', 'swap' and ebs for bdm in bdms: # ebs volume case if bdm.destination_type == "volume": ebs_devices.append(bdm.device_name) continue if bdm.source_type == "blank": blanks.append(bdm) # NOTE(yamahata): I'm not sure how ebs device should be numbered. # Right now sort by device name for deterministic # result. if ebs_devices: ebs_devices.sort() for nebs, ebs in enumerate(ebs_devices): mappings["ebs%d" % nebs] = ebs swap = [bdm for bdm in blanks if bdm.guest_format == "swap"] if swap: mappings["swap"] = swap.pop().device_name ephemerals = [bdm for bdm in blanks if bdm.guest_format != "swap"] if ephemerals: for num, eph in enumerate(ephemerals): mappings["ephemeral%d" % num] = eph.device_name return mappings
def instance_block_mapping(instance, bdms): root_device_name = instance["root_device_name"] # NOTE(clayg): remove this when xenapi is setting default_root_device if root_device_name is None: if driver.compute_driver_matches("xenapi.XenAPIDriver"): root_device_name = "/dev/xvda" else: return _DEFAULT_MAPPINGS mappings = {} mappings["ami"] = strip_dev(root_device_name) mappings["root"] = root_device_name default_ephemeral_device = instance.get("default_ephemeral_device") if default_ephemeral_device: mappings["ephemeral0"] = default_ephemeral_device default_swap_device = instance.get("default_swap_device") if default_swap_device: mappings["swap"] = default_swap_device ebs_devices = [] # 'ephemeralN', 'swap' and ebs for bdm in bdms: if bdm["no_device"]: continue # ebs volume case if bdm["volume_id"] or bdm["snapshot_id"]: ebs_devices.append(bdm["device_name"]) continue virtual_name = bdm["virtual_name"] if not virtual_name: continue if is_swap_or_ephemeral(virtual_name): mappings[virtual_name] = bdm["device_name"] # NOTE(yamahata): I'm not sure how ebs device should be numbered. # Right now sort by device name for deterministic # result. if ebs_devices: nebs = 0 ebs_devices.sort() for ebs in ebs_devices: mappings["ebs%d" % nebs] = ebs nebs += 1 return mappings
def instance_block_mapping(instance, bdms): root_device_name = instance['root_device_name'] # NOTE(clayg): remove this when xenapi is setting default_root_device if root_device_name is None: if driver.compute_driver_matches('xenapi.XenAPIDriver'): root_device_name = '/dev/xvda' else: return _DEFAULT_MAPPINGS mappings = {} mappings['ami'] = strip_dev(root_device_name) mappings['root'] = root_device_name default_ephemeral_device = instance.get('default_ephemeral_device') if default_ephemeral_device: mappings['ephemeral0'] = default_ephemeral_device default_swap_device = instance.get('default_swap_device') if default_swap_device: mappings['swap'] = default_swap_device ebs_devices = [] # 'ephemeralN', 'swap' and ebs for bdm in bdms: if bdm['no_device']: continue # ebs volume case if (bdm['volume_id'] or bdm['snapshot_id']): ebs_devices.append(bdm['device_name']) continue virtual_name = bdm['virtual_name'] if not virtual_name: continue if is_swap_or_ephemeral(virtual_name): mappings[virtual_name] = bdm['device_name'] # NOTE(yamahata): I'm not sure how ebs device should be numbered. # Right now sort by device name for deterministic # result. if ebs_devices: nebs = 0 ebs_devices.sort() for ebs in ebs_devices: mappings['ebs%d' % nebs] = ebs nebs += 1 return mappings
def get_next_device_name(instance, device_name_list, root_device_name=None, device=None): """Validates (or generates) a device name for instance. If device is not set, it will generate a unique device appropriate for the instance. It uses the root_device_name (if provided) and the list of used devices to find valid device names. If the device name is valid but applicable to a different backend (for example /dev/vdc is specified but the backend uses /dev/xvdc), the device name will be converted to the appropriate format. """ req_prefix = None req_letter = None if device: try: req_prefix, req_letter = block_device.match_device(device) except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=device) if not root_device_name: root_device_name = block_device.DEFAULT_ROOT_DEV_NAME try: prefix = block_device.match_device(root_device_name)[0] except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=root_device_name) # NOTE(vish): remove this when xenapi is setting default_root_device if driver.compute_driver_matches('xenapi.XenAPIDriver'): prefix = '/dev/xvd' if req_prefix != prefix: LOG.debug(_("Using %(prefix)s instead of %(req_prefix)s"), { 'prefix': prefix, 'req_prefix': req_prefix }) used_letters = set() for device_path in device_name_list: letter = block_device.strip_prefix(device_path) # NOTE(vish): delete numbers in case we have something like # /dev/sda1 letter = re.sub("\d+", "", letter) used_letters.add(letter) # NOTE(vish): remove this when xenapi is properly setting # default_ephemeral_device and default_swap_device if driver.compute_driver_matches('xenapi.XenAPIDriver'): flavor = flavors.extract_flavor(instance) if flavor['ephemeral_gb']: used_letters.add('b') if flavor['swap']: used_letters.add('c') if not req_letter: req_letter = _get_unused_letter(used_letters) if req_letter in used_letters: raise exception.DevicePathInUse(path=device) return prefix + req_letter
def get_next_device_name(instance, device_name_list, root_device_name=None, device=None): """Validates (or generates) a device name for instance. If device is not set, it will generate a unique device appropriate for the instance. It uses the root_device_name (if provided) and the list of used devices to find valid device names. If the device name is valid but applicable to a different backend (for example /dev/vdc is specified but the backend uses /dev/xvdc), the device name will be converted to the appropriate format. """ is_xen = driver.compute_driver_matches('xenapi.XenAPIDriver') req_prefix = None req_letter = None if device: try: req_prefix, req_letter = block_device.match_device(device) except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=device) if not root_device_name: root_device_name = block_device.DEFAULT_ROOT_DEV_NAME try: prefix = block_device.match_device( block_device.prepend_dev(root_device_name))[0] except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=root_device_name) # NOTE(vish): remove this when xenapi is setting default_root_device if is_xen: prefix = '/dev/xvd' if req_prefix != prefix: LOG.debug("Using %(prefix)s instead of %(req_prefix)s", {'prefix': prefix, 'req_prefix': req_prefix}) used_letters = set() for device_path in device_name_list: letter = block_device.get_device_letter(device_path) used_letters.add(letter) # NOTE(vish): remove this when xenapi is properly setting # default_ephemeral_device and default_swap_device if is_xen: flavor = instance.get_flavor() if flavor.ephemeral_gb: used_letters.add('b') if flavor.swap: used_letters.add('c') if not req_letter: req_letter = _get_unused_letter(used_letters) if req_letter in used_letters: raise exception.DevicePathInUse(path=device) return prefix + req_letter
def get_next_device_name(instance, device_name_list, root_device_name=None, device=None): """Validates (or generates) a device name for instance. If device is not set, it will generate a unique device appropriate for the instance. It uses the root_device_name (if provided) and the list of used devices to find valid device names. If the device name is valid but applicable to a different backend (for example /dev/vdc is specified but the backend uses /dev/xvdc), the device name will be converted to the appropriate format. """ is_xen = driver.compute_driver_matches('xenapi.XenAPIDriver') is_libvirt = driver.compute_driver_matches('libvirt.LibvirtDriver') req_prefix = None req_letter = None if device: try: req_prefix, req_letter = block_device.match_device(device) except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=device) if not root_device_name: root_device_name = block_device.DEFAULT_ROOT_DEV_NAME try: prefix = block_device.match_device( block_device.prepend_dev(root_device_name))[0] except (TypeError, AttributeError, ValueError): raise exception.InvalidDevicePath(path=root_device_name) # NOTE(vish): remove this when xenapi is setting default_root_device if is_xen: prefix = '/dev/xvd' if is_libvirt: prefix = req_prefix if prefix is None: prefix = '/dev/vd' if req_prefix != prefix: LOG.debug("Using %(prefix)s instead of %(req_prefix)s", {'prefix': prefix, 'req_prefix': req_prefix}) used_letters = set() for device_path in device_name_list: letter = block_device.get_device_letter(device_path) used_letters.add(letter) # NOTE(vish): remove this when xenapi is properly setting # default_ephemeral_device and default_swap_device if is_xen: flavor = instance.get_flavor() if flavor.ephemeral_gb: used_letters.add('b') if flavor.swap: used_letters.add('c') if not req_letter: req_letter = _get_unused_letter(used_letters) if req_letter in used_letters: raise exception.DevicePathInUse(path=device) return prefix + req_letter