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 e097c001c8)
This commit is contained in:
Matthew Booth 2017-12-01 16:39:49 +00:00 committed by Zhang Hua
parent 745bd464f0
commit 1a4debb3dd
2 changed files with 37 additions and 1 deletions

View File

@ -7815,6 +7815,39 @@ class LibvirtConnTestCase(test.NoDBTestCase,
"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_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')

View File

@ -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)