diff --git a/nova/block_device.py b/nova/block_device.py index 1f0ba62ccfe2..e209324e256d 100644 --- a/nova/block_device.py +++ b/nova/block_device.py @@ -388,6 +388,13 @@ def new_format_is_ephemeral(bdm): return False +def get_root_bdm(bdms): + try: + return (bdm for bdm in bdms if bdm.get('boot_index', -1) == 0).next() + except StopIteration: + return None + + def mappings_prepend_dev(mappings): """Prepend '/dev/' to 'device' entry of swap/ephemeral virtual type.""" for m in mappings: diff --git a/nova/compute/manager.py b/nova/compute/manager.py index e773eb399376..dd6e963f2428 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1297,10 +1297,8 @@ class ComputeManager(manager.SchedulerDependentManager): It also ensures that there is a root_device_name and is set to the first block device in the boot sequence (boot_index=0). """ - try: - root_bdm = (bdm for bdm in block_devices - if bdm['boot_index'] == 0).next() - except StopIteration: + root_bdm = block_device.get_root_bdm(block_devices) + if not root_bdm: return # Get the root_device_name from the root BDM or the instance diff --git a/nova/tests/test_block_device.py b/nova/tests/test_block_device.py index d0457a85978d..53dcdc09747a 100644 --- a/nova/tests/test_block_device.py +++ b/nova/tests/test_block_device.py @@ -129,6 +129,19 @@ class BlockDeviceTestCase(test.NoDBTestCase): _assert_volume_in_mapping('sdg', False) _assert_volume_in_mapping('sdh1', False) + def test_get_root_bdm(self): + root_bdm = {'device_name': 'vda', 'boot_index': 0} + bdms = [root_bdm, + {'device_name': 'vdb', 'boot_index': 1}, + {'device_name': 'vdc', 'boot_index': -1}, + {'device_name': 'vdd'}] + self.assertEqual(root_bdm, block_device.get_root_bdm(bdms)) + self.assertEqual(root_bdm, block_device.get_root_bdm([bdms[0]])) + self.assertEqual(None, block_device.get_root_bdm(bdms[1:])) + self.assertEqual(None, block_device.get_root_bdm(bdms[2:])) + self.assertEqual(None, block_device.get_root_bdm(bdms[3:])) + self.assertEqual(None, block_device.get_root_bdm([])) + class TestBlockDeviceDict(test.NoDBTestCase): def setUp(self): diff --git a/nova/virt/libvirt/blockinfo.py b/nova/virt/libvirt/blockinfo.py index b92c99522be0..a93b92ea330c 100644 --- a/nova/virt/libvirt/blockinfo.py +++ b/nova/virt/libvirt/blockinfo.py @@ -517,15 +517,11 @@ def get_disk_mapping(virt_type, instance, return mapping - try: - root_bdm = (bdm for bdm in - driver.block_device_info_get_mapping(block_device_info) - if bdm.get('boot_index') == 0).next() - except StopIteration: - # NOTE (ndipanov): This happens when we boot from image as - # there is no driver representation of local targeted images - # and they will not be in block_device_info list. - root_bdm = None + # NOTE (ndipanov): root_bdm can be None when we boot from image + # as there is no driver represenation of local targeted images + # and they will not be in block_device_info list. + root_bdm = block_device.get_root_bdm( + driver.block_device_info_get_mapping(block_device_info)) root_device_name = block_device.strip_dev( driver.block_device_info_get_root(block_device_info))