diff --git a/nova/tests/unit/virt/libvirt/test_blockinfo.py b/nova/tests/unit/virt/libvirt/test_blockinfo.py index 5a0dbb40ce3b..4e245093af63 100644 --- a/nova/tests/unit/virt/libvirt/test_blockinfo.py +++ b/nova/tests/unit/virt/libvirt/test_blockinfo.py @@ -1289,6 +1289,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase): @mock.patch('nova.virt.libvirt.blockinfo.get_info_from_bdm') def test_get_root_info_bdm(self, mock_get_info): + # call get_root_info() with DriverBlockDevice instance = objects.Instance(**self.test_instance) image_meta = objects.ImageMeta.from_dict(self.test_image_meta) root_bdm = {'mount_device': '/dev/vda', @@ -1318,6 +1319,49 @@ class LibvirtBlockInfoTest(test.NoDBTestCase): {}, 'virtio') mock_get_info.reset_mock() + @mock.patch('nova.virt.libvirt.blockinfo.get_info_from_bdm') + def test_get_root_info_bdm_with_deepcopy(self, mock_get_info): + # call get_root_info() with BlockDeviceMapping + instance = objects.Instance(**self.test_instance) + image_meta = objects.ImageMeta.from_dict(self.test_image_meta) + root_bdm = objects.BlockDeviceMapping(self.context, + **fake_block_device.FakeDbBlockDeviceDict( + {'id': 3, 'instance_uuid': uuids.instance, + 'device_name': '/dev/sda', + 'source_type': 'blank', + 'destination_type': 'local', + 'device_type': 'cdrom', + 'disk_bus': 'virtio', + 'volume_id': 'fake-volume-id-1', + 'boot_index': 0})) + # No root_device_name + blockinfo.get_root_info( + instance, 'kvm', image_meta, root_bdm, 'virtio', 'ide') + mock_get_info.assert_called_once_with( + instance, 'kvm', image_meta, root_bdm, {}, 'virtio') + mock_get_info.reset_mock() + # Both device names + blockinfo.get_root_info( + instance, 'kvm', image_meta, root_bdm, 'virtio', 'scsi', + root_device_name='/dev/sda') + mock_get_info.assert_called_once_with( + instance, 'kvm', image_meta, root_bdm, {}, 'virtio') + mock_get_info.reset_mock() + # Missing device names + original_bdm = copy.deepcopy(root_bdm) + root_bdm.device_name = '' + blockinfo.get_root_info( + instance, 'kvm', image_meta, root_bdm, 'virtio', 'scsi', + root_device_name='/dev/sda') + mock_get_info.assert_called_with( + instance, 'kvm', image_meta, mock.ANY, {}, 'virtio') + actual_call = mock_get_info.call_args + _, _, _, actual_bdm, _, _ = actual_call[0] + self.assertEqual( + original_bdm.obj_to_primitive(), + actual_bdm.obj_to_primitive() + ) + def test_get_boot_order_simple(self): disk_info = { 'disk_bus': 'virtio', diff --git a/nova/virt/libvirt/blockinfo.py b/nova/virt/libvirt/blockinfo.py index 4efc6fbaeb11..4d03dc38ea25 100644 --- a/nova/virt/libvirt/blockinfo.py +++ b/nova/virt/libvirt/blockinfo.py @@ -69,6 +69,7 @@ variables / types used """ +import copy import itertools import operator @@ -444,12 +445,13 @@ def get_root_info(instance, virt_type, image_meta, root_bdm, 'dev': block_device.strip_dev(root_device_name), 'boot_index': '1'} + root_bdm_copy = root_bdm if not get_device_name(root_bdm) and root_device_name: - root_bdm = root_bdm.copy() - root_bdm['device_name'] = root_device_name + root_bdm_copy = copy.deepcopy(root_bdm) + root_bdm_copy['device_name'] = root_device_name return get_info_from_bdm( - instance, virt_type, image_meta, root_bdm, {}, disk_bus, + instance, virt_type, image_meta, root_bdm_copy, {}, disk_bus, )