summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Booth <mbooth@redhat.com>2017-12-01 16:39:49 +0000
committerZhang Hua <joshua.zhang@canonical.com>2019-01-25 03:25:40 +0000
commit1a4debb3dd2726299bbee0c07b7fc052ac72555b (patch)
tree61fe3cec29c9ee1e227d7bb34c3fabed146f46e3
parent745bd464f0afdea5cabed7c1d601a2fd7be28516 (diff)
downloadnova-1a4debb3dd2726299bbee0c07b7fc052ac72555b.tar.gz
Fix disk size during live migration with disk over-commit
Prior to microversion 2.25, the migration api supported a 'disk_over_commit' parameter, which indicated that we should do disk size check on the destination host taking into account disk over-commit. Versions since 2.25 no longer have this parameter, but we continue to support the older microversion. This disk size check was broken when disk over commit was in use on the host. In LibvirtDriver._assert_dest_node_has_enough_disk() we correctly calculate the required space using allocated disk size rather than virtual disk size when doing an over-committed check. However, we were checking against 'disk_available_least' as reported by the destination host. This value is: the amount of disk space which the host would have if all instances fully allocated their storage. On an over-committed host it will therefore be negative, despite there actually being space on the destination host. The check we actually want to do for disk over commit is: does the target host have enough free space to take the allocated size of this instance's disks? We leave checking over-allocation ratios to the scheduler. Note that if we use disk_available_least here and the destination host is over-allocated, this will always fail because free space will be negative, even though we're explicitly ok with that. Using disk_available_least would make sense for the non-overcommit case, where the test would be: would the target host have enough free space for this instance if the instance fully allocated all its storage, and everything else on the target also fully allocated its storage? As noted, we no longer actually run that test, though. We fix the issue for legacy microversions by fixing the destination host's reported disk space according to the given disk_over_commit parameter. Change-Id: I8a705114d47384fcd00955d4a4f204072fed57c2 Resolves-bug: #1708572 (cherry picked from commit e097c001c8e11110efe8879da57264fcb7bdfdf2)
-rwxr-xr-xnova/tests/unit/virt/libvirt/test_driver.py33
-rw-r--r--nova/virt/libvirt/driver.py5
2 files changed, 37 insertions, 1 deletions
diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py
index ed35653550..1a0439db2d 100755
--- a/nova/tests/unit/virt/libvirt/test_driver.py
+++ b/nova/tests/unit/virt/libvirt/test_driver.py
@@ -7819,6 +7819,39 @@ 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_all_pass_with_over_commit(
+ self, mock_cpu, mock_test_file, mock_svc):
+ instance_ref = objects.Instance(**self.test_instance)
+ instance_ref.vcpu_model = test_vcpu_model.fake_vcpumodel
+ drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
+ compute_info = {'disk_available_least': -1000,
+ 'local_gb': 100,
+ 'cpu_info': 'asdf',
+ }
+ filename = "file"
+
+ # _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, True, True)
+ return_value.is_volume_backed = False
+ self.assertThat({"filename": "file",
+ 'image_type': 'default',
+ 'disk_available_mb': 102400,
+ "disk_over_commit": True,
+ "block_migration": True,
+ "is_volume_backed": False},
+ matchers.DictMatches(return_value.to_legacy_dict()))
+
+ @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_all_pass_no_block_migration(
self, mock_cpu, mock_test_file, mock_svc):
instance_ref = objects.Instance(**self.test_instance)
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 56448f84ab..55e05e2e80 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -6042,7 +6042,10 @@ class LibvirtDriver(driver.ComputeDriver):
:param disk_over_commit: if true, allow disk over commit
:returns: a LibvirtLiveMigrateData object
"""
- disk_available_gb = dst_compute_info['disk_available_least']
+ if disk_over_commit:
+ disk_available_gb = dst_compute_info['local_gb']
+ else:
+ disk_available_gb = dst_compute_info['disk_available_least']
disk_available_mb = (
(disk_available_gb * units.Ki) - CONF.reserved_host_disk_mb)