Skip to content

Commit d41ea9d

Browse files
committed
libvirt: Reduce calls to qemu-img during update_available_resource
I464bc2b88123a012cd12213beac4b572c3c20a56 introduced a second call to ``qemu-img`` that can easily be collapsed into one with the addition of a new call within the disk_api. Related-Bug: #1785827 Change-Id: Ibfd0527ed79f60282b542034d7cb97b424becba3
1 parent 536acbf commit d41ea9d

File tree

3 files changed

+45
-45
lines changed

3 files changed

+45
-45
lines changed

nova/tests/unit/virt/libvirt/test_driver.py

Lines changed: 33 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4642,7 +4642,8 @@ def test_serial_console_release_port(
46424642
[mock.call(host='127.0.0.1', port=10000),
46434643
mock.call(host='127.0.0.1', port=10001)])
46444644

4645-
@mock.patch('nova.virt.disk.api.get_disk_size', return_value=0)
4645+
@mock.patch('nova.virt.disk.api.get_disk_info',
4646+
return_value=mock.Mock(disk_size=0))
46464647
@mock.patch('nova.virt.libvirt.storage.lvm.get_volume_size',
46474648
return_value='fake-size')
46484649
def test_detach_encrypted_volumes(self, mock_get_volume_size,
@@ -9421,12 +9422,9 @@ def mock_lookup_side_effect(name):
94219422
return mock_virDomain
94229423
mock_lookup.side_effect = mock_lookup_side_effect
94239424

9424-
mock_getsize = mock.Mock()
9425-
mock_getsize.return_value = "10737418240"
9426-
mock_get_virtual_size = mock.Mock()
9427-
mock_get_virtual_size.return_value = "10737418240"
9428-
9429-
return (mock_getsize, mock_get_virtual_size, mock_lookup)
9425+
mock_qemu_img_info = mock.Mock(disk_size=10737418240,
9426+
virtual_size=10737418240)
9427+
return (mock_qemu_img_info, mock_lookup)
94309428

94319429
def test_is_shared_block_storage_rbd(self):
94329430
self.flags(images_type='rbd', group='libvirt')
@@ -9519,7 +9517,7 @@ def test_is_shared_block_storage_volume_backed(self):
95199517
{'connection_info': 'info', 'mount_device': '/dev/vda'}]}
95209518
instance = objects.Instance(**self.test_instance)
95219519
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9522-
(mock_getsize, mock_get_virtual_size, mock_lookup) =\
9520+
(mock_qemu_img_info, mock_lookup) =\
95239521
self._is_shared_block_storage_test_create_mocks(disks)
95249522
data = objects.LibvirtLiveMigrateData(is_volume_backed=True,
95259523
is_shared_instance_path=False)
@@ -9543,21 +9541,18 @@ def test_is_shared_block_storage_volume_backed_with_disk(self):
95439541
{'connection_info': 'info', 'mount_device': '/dev/vda'}]}
95449542
instance = objects.Instance(**self.test_instance)
95459543
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9546-
(mock_getsize, mock_get_virtual_size, mock_lookup) =\
9544+
(mock_qemu_img_info, mock_lookup) =\
95479545
self._is_shared_block_storage_test_create_mocks(disks)
95489546
data = objects.LibvirtLiveMigrateData(is_volume_backed=True,
95499547
is_shared_instance_path=False)
95509548
with test.nested(
95519549
mock.patch.object(libvirt_driver.disk_api,
9552-
'get_allocated_disk_size', mock_getsize),
9553-
mock.patch.object(libvirt_driver.disk_api,
9554-
'get_disk_size', mock_get_virtual_size),
9550+
'get_disk_info', mock_qemu_img_info),
95559551
mock.patch.object(host.Host, '_get_domain', mock_lookup)):
95569552
self.assertFalse(drvr._is_shared_block_storage(
95579553
instance, data,
95589554
block_device_info = bdi))
9559-
mock_getsize.assert_called_once_with('/instance/disk.local')
9560-
mock_get_virtual_size.assert_called_once_with('/instance/disk.local')
9555+
mock_qemu_img_info.assert_called_once_with('/instance/disk.local')
95619556
mock_lookup.assert_called_once_with(instance)
95629557

95639558
def test_is_shared_block_storage_nfs(self):
@@ -12370,12 +12365,8 @@ def test_pre_live_migration_with_perf_events(self):
1237012365
migrate_data=migrate_data)
1237112366
self.assertEqual(['cmt'], res.supported_perf_events)
1237212367

12373-
@mock.patch('nova.virt.disk.api.get_disk_size',
12374-
side_effect=[10737418240, 21474836480])
12375-
@mock.patch('nova.virt.disk.api.get_allocated_disk_size',
12376-
side_effect=[10737418240, 3328599655])
12377-
def test_get_instance_disk_info_works_correctly(self, mock_get_alloc,
12378-
mock_get_disk_size):
12368+
@mock.patch('nova.virt.disk.api.get_disk_info')
12369+
def test_get_instance_disk_info_works_correctly(self, mock_qemu_img_info):
1237912370
# Test data
1238012371
instance = objects.Instance(**self.test_instance)
1238112372
dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
@@ -12392,6 +12383,11 @@ def test_get_instance_disk_info_works_correctly(self, mock_get_alloc,
1239212383
vdmock = mock.Mock(autospec=fakelibvirt.virDomain)
1239312384
vdmock.XMLDesc.return_value = dummyxml
1239412385

12386+
mock_qemu_img_info.side_effect = [
12387+
mock.Mock(disk_size=10737418240, virtual_size=10737418240),
12388+
mock.Mock(disk_size=3328599655, virtual_size=21474836480)
12389+
]
12390+
1239512391
def fake_lookup(_uuid):
1239612392
if _uuid == instance.uuid:
1239712393
return vdmock
@@ -12416,12 +12412,9 @@ def fake_lookup(_uuid):
1241612412
self.assertEqual(info[1]['over_committed_disk_size'], 18146236825)
1241712413

1241812414
vdmock.XMLDesc.assert_called_once_with(0)
12419-
mock_get_alloc.assert_has_calls([mock.call('/test/disk'),
12420-
mock.call('/test/disk.local')])
12421-
self.assertEqual(2, mock_get_alloc.call_count)
12422-
mock_get_disk_size.assert_has_calls([mock.call('/test/disk'),
12415+
mock_qemu_img_info.assert_has_calls([mock.call('/test/disk'),
1242312416
mock.call('/test/disk.local')])
12424-
self.assertEqual(2, mock_get_disk_size.call_count)
12417+
self.assertEqual(2, mock_qemu_img_info.call_count)
1242512418

1242612419
def test_post_live_migration(self):
1242712420
vol = {'block_device_mapping': [
@@ -12508,12 +12501,9 @@ def _test(mock_get_bdms, mock_attachment_get, mock_disconnect):
1250812501
instance)
1250912502
_test()
1251012503

12511-
@mock.patch('nova.virt.disk.api.get_disk_size',
12512-
side_effect=[10737418240, 21474836480])
12513-
@mock.patch('nova.virt.disk.api.get_allocated_disk_size',
12514-
side_effect=[10737418240, 3328599655])
12504+
@mock.patch('nova.virt.disk.api.get_disk_info')
1251512505
def test_get_instance_disk_info_excludes_volumes(
12516-
self, mock_get_alloc, mock_get_disk_size):
12506+
self, mock_qemu_img_info):
1251712507
# Test data
1251812508
instance = objects.Instance(**self.test_instance)
1251912509
dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
@@ -12536,6 +12526,11 @@ def test_get_instance_disk_info_excludes_volumes(
1253612526
vdmock = mock.Mock(autospec=fakelibvirt.virDomain)
1253712527
vdmock.XMLDesc.return_value = dummyxml
1253812528

12529+
mock_qemu_img_info.side_effect = [
12530+
mock.Mock(disk_size=10737418240, virtual_size=10737418240),
12531+
mock.Mock(disk_size=3328599655, virtual_size=21474836480)
12532+
]
12533+
1253912534
def fake_lookup(_uuid):
1254012535
if _uuid == instance.uuid:
1254112536
return vdmock
@@ -12565,19 +12560,12 @@ def fake_lookup(_uuid):
1256512560
self.assertEqual(info[1]['over_committed_disk_size'], 18146236825)
1256612561

1256712562
vdmock.XMLDesc.assert_called_once_with(0)
12568-
mock_get_alloc.assert_has_calls([mock.call('/test/disk'),
12569-
mock.call('/test/disk.local')])
12570-
self.assertEqual(2, mock_get_alloc.call_count)
12571-
mock_get_disk_size.assert_has_calls([mock.call('/test/disk'),
12563+
mock_qemu_img_info.assert_has_calls([mock.call('/test/disk'),
1257212564
mock.call('/test/disk.local')])
12573-
self.assertEqual(2, mock_get_disk_size.call_count)
12565+
self.assertEqual(2, mock_qemu_img_info.call_count)
1257412566

12575-
@mock.patch('nova.virt.disk.api.get_disk_size',
12576-
return_value=10737418240)
12577-
@mock.patch('nova.virt.disk.api.get_allocated_disk_size',
12578-
return_value=10737418240)
12579-
def test_get_instance_disk_info_no_bdinfo_passed(
12580-
self, mock_get_alloc, mock_get_disk_size):
12567+
@mock.patch('nova.virt.disk.api.get_disk_info')
12568+
def test_get_instance_disk_info_no_bdinfo_passed(self, mock_qemu_img_info):
1258112569
# NOTE(ndipanov): _get_disk_overcomitted_size_total calls this method
1258212570
# without access to Nova's block device information. We want to make
1258312571
# sure that we guess volumes mostly correctly in that case as well
@@ -12598,6 +12586,9 @@ def test_get_instance_disk_info_no_bdinfo_passed(
1259812586
vdmock = mock.Mock(autospec=fakelibvirt.virDomain)
1259912587
vdmock.XMLDesc.return_value = dummyxml
1260012588

12589+
mock_qemu_img_info.return_value = mock.Mock(disk_size=10737418240,
12590+
virtual_size=10737418240)
12591+
1260112592
def fake_lookup(_uuid):
1260212593
if _uuid == instance.uuid:
1260312594
return vdmock
@@ -12616,8 +12607,7 @@ def fake_lookup(_uuid):
1261612607
self.assertEqual(info[0]['over_committed_disk_size'], 0)
1261712608

1261812609
vdmock.XMLDesc.assert_called_once_with(0)
12619-
mock_get_alloc.assert_called_once_with(path)
12620-
mock_get_disk_size.assert_called_once_with(path)
12610+
mock_qemu_img_info.assert_called_once_with(path)
1262112611

1262212612
def test_spawn_with_network_info(self):
1262312613
def fake_getLibVersion():

nova/virt/disk/api.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ def resize2fs(image, check_exit_code=False, run_as_root=False):
8989
nova.privsep.fs.unprivileged_resize2fs(image, check_exit_code)
9090

9191

92+
def get_disk_info(path):
93+
"""Get QEMU info of a disk image
94+
95+
:param path: Path to the disk image
96+
:returns: oslo_utils.imageutils.QemuImgInfo object for the image.
97+
"""
98+
return images.qemu_img_info(path)
99+
100+
92101
def get_disk_size(path):
93102
"""Get the (virtual) size of a disk image
94103

nova/virt/libvirt/driver.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8057,17 +8057,18 @@ def _get_instance_disk_info_from_config(self, guest_config,
80578057
# get the real disk size or
80588058
# raise a localized error if image is unavailable
80598059
if disk_type == 'file':
8060+
qemu_img_info = disk_api.get_disk_info(path)
80608061
if driver_type == 'ploop':
80618062
dk_size = 0
80628063
for dirpath, dirnames, filenames in os.walk(path):
80638064
for f in filenames:
80648065
fp = os.path.join(dirpath, f)
80658066
dk_size += os.path.getsize(fp)
80668067
else:
8067-
dk_size = disk_api.get_allocated_disk_size(path)
8068+
dk_size = qemu_img_info.disk_size
80688069

80698070
# NOTE(lyarwood): Fetch the virtual size for all file disks.
8070-
virt_size = disk_api.get_disk_size(path)
8071+
virt_size = qemu_img_info.virtual_size
80718072

80728073
elif disk_type == 'block' and block_device_info:
80738074
# FIXME(lyarwood): There's no reason to use a separate call

0 commit comments

Comments
 (0)