From addd6caddaf2b0b808a414828d98486a9f7ffedd Mon Sep 17 00:00:00 2001 From: Alexandre Arents Date: Wed, 1 Apr 2020 15:44:18 +0000 Subject: [PATCH] libvirt: Calculate disk_over_committed for raw instances During update_available_resource periodic task, nova-compute reports total amount of disk_over_committed in order to determine current hypervisor's available_disk_least. Currently, disk_over_committed is set to 0 for raw instances, which is appropriate when [compute]/preallocate_images option is set to space as images are fully allocated and because file size is equal to allocated size. If not set, the raw disk file is sparsely allocated and over_committed_disk_size have to be calculated in order to not mislead available_disk_least value. This change introduces over_committed_disk_size calucation also for raw disk. Closes-Bug: #1870357 Change-Id: I9788ab12f5cfe0b1884f265482ceb9f533e9574e --- nova/tests/unit/virt/libvirt/test_driver.py | 39 ++++++++++++++++++--- nova/virt/libvirt/driver.py | 2 +- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index fcf93ac39e54..5d1490b2d02f 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -16407,10 +16407,10 @@ class LibvirtConnTestCase(test.NoDBTestCase, 'over_committed_disk_size': '10653532160'}], 'instance0000002': [{'type': 'raw', 'path': '/somepath/disk2', - 'virt_disk_size': '0', - 'backing_file': '/somepath/disk2', - 'disk_size': '10737418240', - 'over_committed_disk_size': '0'}]} + 'virt_disk_size': '10737418240', + 'backing_file': '', + 'disk_size': '5350000000', + 'over_committed_disk_size': '5387418240'}]} def get_info(cfg, block_device_info): return fake_disks.get(cfg.name) @@ -16430,7 +16430,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, mock_info.side_effect = get_info result = drvr._get_disk_over_committed_size_total() - self.assertEqual(result, 10653532160) + self.assertEqual(result, 16040950400) mock_list.assert_called_once_with(only_running=False) self.assertEqual(2, mock_info.call_count) @@ -16649,6 +16649,35 @@ class LibvirtConnTestCase(test.NoDBTestCase, self.assertEqual(disk_info[0]['disk_size'], disk_info[0]['virt_disk_size']) + @mock.patch('os.stat') + @mock.patch('os.path.getsize') + def test_get_instance_disk_info_from_config_raw_files(self, + mock_getsize, mock_stat): + """Test that over_committed_disk_size are calculated also for raw + images_type, since disk can be sparsely allocated if + [compute]/preallocate_images option is not set to space. + """ + config = vconfig.LibvirtConfigGuest() + disk_config = vconfig.LibvirtConfigGuestDisk() + disk_config.source_type = "file" + disk_config.source_path = "fake" + disk_config.driver_format = "raw" + config.devices.append(disk_config) + + disk_virtual_size = 53687091200 + disk_actual_size = 3687091200 + disk_actual_size_blocks = disk_actual_size / 512 + expected_over_committed_disk_size = disk_virtual_size -\ + disk_actual_size + + mock_getsize.return_value = disk_virtual_size + mock_stat.return_value = mock.Mock(st_blocks=disk_actual_size_blocks) + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + disk_info = drvr._get_instance_disk_info_from_config(config, None) + + self.assertEqual(expected_over_committed_disk_size, + disk_info[0]['over_committed_disk_size']) + def test_cpu_info(self): drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 3aee82323ac7..899500e6d3f0 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -9604,7 +9604,7 @@ class LibvirtDriver(driver.ComputeDriver): dk_size = os.stat(path).st_blocks * 512 virt_size = os.path.getsize(path) backing_file = "" - over_commit_size = 0 + over_commit_size = int(virt_size) - dk_size elif disk_type == 'block' and block_device_info: dk_size = lvm.get_volume_size(path)