diff --git a/doc/source/admin/file-backed-memory.rst b/doc/source/admin/file-backed-memory.rst index 99cff4fcc3dc..22fbc9518216 100644 --- a/doc/source/admin/file-backed-memory.rst +++ b/doc/source/admin/file-backed-memory.rst @@ -21,9 +21,9 @@ file-backed memory to placement in place of the total system memory capacity. This allows the node to run more instances than would normally fit within system memory. -When available in libivrt and qemu, instance memory will be discarded by qemu -at shutdown by calling madvise(MADV_REMOVE), to avoid flushing any dirty memory -to the backing store on exit. +When available in libvirt and qemu, instance memory will be discarded by qemu +at shutdown by calling ``madvise(MADV_REMOVE)``, to avoid flushing any dirty +memory to the backing store on exit. To enable file-backed memory, follow the steps below: @@ -42,12 +42,12 @@ Prerequisites and Limitations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Libvirt - File-backed memory requires libvirt version 4.0.0 or newer - Discard capability requires libvirt ersion 4.4.0 or newer + File-backed memory requires libvirt version 4.0.0 or newer. Discard + capability requires libvirt version 4.4.0 or newer. Qemu - File-backed memory requires qemu version 2.6.0 or newer - Discard capability requires qemu version 2.10.0 or newer + File-backed memory requires qemu version 2.6.0 or newer.Discard capability + requires qemu version 2.10.0 or newer. Memory overcommit File-backed memory is not compatible with memory overcommit. diff --git a/nova/tests/unit/objects/test_migrate_data.py b/nova/tests/unit/objects/test_migrate_data.py index 43f3618b1acd..c45792d76a20 100644 --- a/nova/tests/unit/objects/test_migrate_data.py +++ b/nova/tests/unit/objects/test_migrate_data.py @@ -236,12 +236,13 @@ class _TestLibvirtLiveMigrateData(object): supported_perf_events=[], serial_listen_addr='127.0.0.1', target_connect_addr='127.0.0.1', - dst_wants_file_backed_memory=False) + dst_wants_file_backed_memory=False, + file_backed_memory_discard=False) data = lambda x: x['nova_object.data'] primitive = data(obj.obj_to_primitive()) - self.assertIn('dst_wants_file_backed_memory', primitive) + self.assertIn('file_backed_memory_discard', primitive) primitive = data(obj.obj_to_primitive(target_version='1.0')) self.assertNotIn('target_connect_addr', primitive) self.assertNotIn('supported_perf_events', primitive) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 8f1678ead8ad..7ec14b701183 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -8829,16 +8829,14 @@ class LibvirtConnTestCase(test.NoDBTestCase, @mock.patch.object(libvirt_driver.LibvirtDriver, '_create_shared_storage_test_file') @mock.patch.object(fakelibvirt.Connection, 'compareCPU') - def test_check_can_live_migrate_dest_file_backed_discard( - self, mock_cpu, mock_test_file, mock_svc, mock_lib_version, - mock_version): + def _test_check_can_live_migrate_dest_file_backed_discard( + self, libvirt_version, qemu_version, mock_cpu, mock_test_file, + mock_svc, mock_lib_version, mock_version): self.flags(file_backed_memory=1024, group='libvirt') - mock_lib_version.return_value = versionutils.convert_version_to_int( - libvirt_driver.MIN_LIBVIRT_FILE_BACKED_DISCARD_VERSION) - mock_version.return_value = versionutils.convert_version_to_int( - libvirt_driver.MIN_QEMU_FILE_BACKED_DISCARD_VERSION) + mock_lib_version.return_value = libvirt_version + mock_version.return_value = qemu_version instance_ref = objects.Instance(**self.test_instance) instance_ref.vcpu_model = test_vcpu_model.fake_vcpumodel @@ -8862,92 +8860,43 @@ class LibvirtConnTestCase(test.NoDBTestCase, return_value = drvr.check_can_live_migrate_destination(self.context, instance_ref, None, compute_info, False) - self.assertTrue(return_value.dst_wants_file_backed_memory) - self.assertTrue(return_value.file_backed_memory_discard) + return return_value - @mock.patch.object(fakelibvirt.Connection, 'getVersion') - @mock.patch.object(fakelibvirt.Connection, 'getLibVersion') - @mock.patch.object(objects.Service, 'get_by_compute_host') - @mock.patch.object(libvirt_driver.LibvirtDriver, - '_create_shared_storage_test_file') - @mock.patch.object(fakelibvirt.Connection, 'compareCPU') - def test_check_can_live_migrate_dest_file_backed_discard_bad_libvirt( - self, mock_cpu, mock_test_file, mock_svc, mock_lib_version, - mock_version): + def test_check_can_live_migrate_dest_file_backed_discard(self): + libvirt_version = versionutils.convert_version_to_int( + libvirt_driver.MIN_LIBVIRT_FILE_BACKED_DISCARD_VERSION) + qemu_version = versionutils.convert_version_to_int( + libvirt_driver.MIN_QEMU_FILE_BACKED_DISCARD_VERSION) - self.flags(file_backed_memory=1024, group='libvirt') + data = self._test_check_can_live_migrate_dest_file_backed_discard( + libvirt_version, qemu_version) - mock_lib_version.return_value = versionutils.convert_version_to_int( + self.assertTrue(data.dst_wants_file_backed_memory) + self.assertTrue(data.file_backed_memory_discard) + + def test_check_can_live_migrate_dest_file_backed_discard_bad_libvirt(self): + libvirt_version = versionutils.convert_version_to_int( libvirt_driver.MIN_LIBVIRT_FILE_BACKED_DISCARD_VERSION) - 1 - mock_version.return_value = versionutils.convert_version_to_int( + qemu_version = versionutils.convert_version_to_int( libvirt_driver.MIN_QEMU_FILE_BACKED_DISCARD_VERSION) - instance_ref = objects.Instance(**self.test_instance) - instance_ref.vcpu_model = test_vcpu_model.fake_vcpumodel + data = self._test_check_can_live_migrate_dest_file_backed_discard( + libvirt_version, qemu_version) - drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) - compute_info = {'disk_available_least': 400, - 'cpu_info': 'asdf', - } + self.assertTrue(data.dst_wants_file_backed_memory) + self.assertFalse(data.file_backed_memory_discard) - filename = "file" - - svc = objects.Service() - svc.version = 32 - mock_svc.return_value = svc - - # _check_cpu_match - mock_cpu.return_value = 1 - # mounted_on_same_shared_storage - mock_test_file.return_value = filename - # No need for the src_compute_info - return_value = drvr.check_can_live_migrate_destination(self.context, - instance_ref, None, compute_info, False) - - self.assertTrue(return_value.dst_wants_file_backed_memory) - self.assertFalse(return_value.file_backed_memory_discard) - - @mock.patch.object(fakelibvirt.Connection, 'getVersion') - @mock.patch.object(fakelibvirt.Connection, 'getLibVersion') - @mock.patch.object(objects.Service, 'get_by_compute_host') - @mock.patch.object(libvirt_driver.LibvirtDriver, - '_create_shared_storage_test_file') - @mock.patch.object(fakelibvirt.Connection, 'compareCPU') - def test_check_can_live_migrate_dest_file_backed_discard_bad_qemu( - self, mock_cpu, mock_test_file, mock_svc, mock_lib_version, - mock_version): - - self.flags(file_backed_memory=1024, group='libvirt') - - mock_lib_version.return_value = versionutils.convert_version_to_int( + def test_check_can_live_migrate_dest_file_backed_discard_bad_qemu(self): + libvirt_version = versionutils.convert_version_to_int( libvirt_driver.MIN_LIBVIRT_FILE_BACKED_DISCARD_VERSION) - mock_version.return_value = versionutils.convert_version_to_int( + qemu_version = versionutils.convert_version_to_int( libvirt_driver.MIN_QEMU_FILE_BACKED_DISCARD_VERSION) - 1 - instance_ref = objects.Instance(**self.test_instance) - instance_ref.vcpu_model = test_vcpu_model.fake_vcpumodel + data = self._test_check_can_live_migrate_dest_file_backed_discard( + libvirt_version, qemu_version) - drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) - compute_info = {'disk_available_least': 400, - 'cpu_info': 'asdf', - } - - filename = "file" - - svc = objects.Service() - svc.version = 32 - mock_svc.return_value = svc - - # _check_cpu_match - mock_cpu.return_value = 1 - # mounted_on_same_shared_storage - mock_test_file.return_value = filename - # No need for the src_compute_info - return_value = drvr.check_can_live_migrate_destination(self.context, - instance_ref, None, compute_info, False) - - self.assertTrue(return_value.dst_wants_file_backed_memory) - self.assertFalse(return_value.file_backed_memory_discard) + self.assertTrue(data.dst_wants_file_backed_memory) + self.assertFalse(data.file_backed_memory_discard) @mock.patch.object(objects.Service, 'get_by_compute_host') @mock.patch.object(fakelibvirt.Connection, 'compareCPU')