def test_get_device_letter(self): self.assertEqual('', block_device.get_device_letter('')) self.assertEqual('a', block_device.get_device_letter('/dev/sda1')) self.assertEqual('b', block_device.get_device_letter('/dev/xvdb')) self.assertEqual('d', block_device.get_device_letter('/dev/d')) self.assertEqual('a', block_device.get_device_letter('a')) self.assertEqual('b', block_device.get_device_letter('sdb2')) self.assertEqual('c', block_device.get_device_letter('vdc')) self.assertEqual('c', block_device.get_device_letter('hdc')) self.assertIsNone(block_device.get_device_letter(None))
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( 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 driver.is_xenapi(): 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 driver.is_xenapi(): 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 test_get_device_letter(self): self.assertEqual(block_device.get_device_letter(''), '') self.assertEqual(block_device.get_device_letter('/dev/sda1'), 'a') self.assertEqual(block_device.get_device_letter('/dev/xvdb'), 'b') self.assertEqual(block_device.get_device_letter('/dev/d'), 'd') self.assertEqual(block_device.get_device_letter('a'), 'a') self.assertEqual(block_device.get_device_letter('sdb2'), 'b') self.assertEqual(block_device.get_device_letter('vdc'), 'c') self.assertEqual(block_device.get_device_letter('hdc'), 'c')
def test_get_device_letter(self): self.assertEqual(block_device.get_device_letter(""), "") self.assertEqual(block_device.get_device_letter("/dev/sda1"), "a") self.assertEqual(block_device.get_device_letter("/dev/xvdb"), "b") self.assertEqual(block_device.get_device_letter("/dev/d"), "d") self.assertEqual(block_device.get_device_letter("a"), "a") self.assertEqual(block_device.get_device_letter("sdb2"), "b") self.assertEqual(block_device.get_device_letter("vdc"), "c") self.assertEqual(block_device.get_device_letter("hdc"), "c")
def get_bdm_image_metadata(context, image_api, volume_api, block_device_mapping, legacy_bdm=True): """Attempt to retrive image metadata from a given block_device_mapping. If we are booting from a volume, we need to get the volume details from Cinder and make sure we pass the metadata back accordingly. :param context: request context :param image_api: Image API :param volume_api: Volume API :param block_device_mapping: :param legacy_bdm: """ if not block_device_mapping: return {} for bdm in block_device_mapping: if (legacy_bdm and block_device.get_device_letter( bdm.get('device_name', '')) != 'a'): continue elif not legacy_bdm and bdm.get('boot_index') != 0: continue volume_id = bdm.get('volume_id') snapshot_id = bdm.get('snapshot_id') if snapshot_id: # NOTE(alaski): A volume snapshot inherits metadata from the # originating volume, but the API does not expose metadata # on the snapshot itself. So we query the volume for it below. snapshot = volume_api.get_snapshot(context, snapshot_id) volume_id = snapshot['volume_id'] if bdm.get('image_id'): try: image_id = bdm['image_id'] image_meta = image_api.get(context, image_id) return image_meta except Exception: raise exception.InvalidBDMImage(id=image_id) elif volume_id: try: volume = volume_api.get(context, volume_id) except exception.CinderConnectionFailed: raise except Exception: raise exception.InvalidBDMVolume(id=volume_id) if not volume.get('bootable', True): raise exception.InvalidBDMVolumeNotBootable(id=volume_id) return get_image_metadata_from_volume(volume) return {}
def get_root_info(instance, virt_type, image_meta, root_bdm, disk_bus, cdrom_bus, root_device_name=None): # NOTE (ndipanov): This is a hack to avoid considering an image # BDM with local target, as we don't support them # yet. Only applies when passed non-driver format no_root_bdm = (not root_bdm or (root_bdm.get('source_type') == 'image' and root_bdm.get('destination_type') == 'local')) if no_root_bdm: # NOTE(mriedem): In case the image_meta object was constructed from # an empty dict, like in the case of evacuate, we have to first check # if disk_format is set on the ImageMeta object. if (image_meta.obj_attr_is_set('disk_format') and image_meta.disk_format == 'iso'): root_device_bus = cdrom_bus root_device_type = 'cdrom' else: root_device_bus = disk_bus root_device_type = 'disk' if root_device_name: root_device_bus = get_disk_bus_for_disk_dev( virt_type, root_device_name) else: root_device_name = find_disk_dev_for_disk_bus({}, root_device_bus) return { 'bus': root_device_bus, 'type': root_device_type, 'dev': block_device.strip_dev(root_device_name), 'boot_index': '1' } if not get_device_name(root_bdm) and root_device_name: root_bdm = root_bdm.copy() # it can happen, eg for libvirt+Xen, that the root_device_name is # incompatible with the disk bus. In that case fix the root_device_name if virt_type == 'xen': dev_prefix = get_dev_prefix_for_disk_bus(disk_bus) if not root_device_name.startswith(dev_prefix): letter = block_device.get_device_letter(root_device_name) root_device_name = '%s%s' % (dev_prefix, letter) root_bdm['device_name'] = root_device_name return get_info_from_bdm(instance, virt_type, image_meta, root_bdm, {}, disk_bus)
def get_root_info(instance, virt_type, image_meta, root_bdm, disk_bus, cdrom_bus, root_device_name=None): # NOTE (ndipanov): This is a hack to avoid considering an image # BDM with local target, as we don't support them # yet. Only applies when passed non-driver format no_root_bdm = (not root_bdm or ( root_bdm.get('source_type') == 'image' and root_bdm.get('destination_type') == 'local')) if no_root_bdm: # NOTE(mriedem): In case the image_meta object was constructed from # an empty dict, like in the case of evacuate, we have to first check # if disk_format is set on the ImageMeta object. if (image_meta.obj_attr_is_set('disk_format') and image_meta.disk_format == 'iso'): root_device_bus = cdrom_bus root_device_type = 'cdrom' else: root_device_bus = disk_bus root_device_type = 'disk' if root_device_name: root_device_bus = get_disk_bus_for_disk_dev(virt_type, root_device_name) else: root_device_name = find_disk_dev_for_disk_bus({}, root_device_bus) return {'bus': root_device_bus, 'type': root_device_type, 'dev': block_device.strip_dev(root_device_name), 'boot_index': '1'} if not get_device_name(root_bdm) and root_device_name: root_bdm = root_bdm.copy() # it can happen, eg for libvirt+Xen, that the root_device_name is # incompatible with the disk bus. In that case fix the root_device_name if virt_type == 'xen': dev_prefix = get_dev_prefix_for_disk_bus(disk_bus) if not root_device_name.startswith(dev_prefix): letter = block_device.get_device_letter(root_device_name) root_device_name = '%s%s' % (dev_prefix, letter) root_bdm['device_name'] = root_device_name return get_info_from_bdm(instance, virt_type, image_meta, root_bdm, {}, disk_bus)