Skip to content

Commit f5e35dc

Browse files
committed
Correct memory validation for live migration
Since live migration has been moved to the conductor, there was no possibility for the conductor to verify if the destination had enough RAM just because it didn't know the allocation ratios given by the scheduler. Now that ComputeNodes provide a ram_allocation_field, we can fix that check and provide the same validation than RAMFilter to make sure that the destination is good. Closes-Bug: #1451831 Closes-Bug: #1214943 Change-Id: Ie6c768fc915553da73160ea51961078bfbacec77
1 parent bbaa721 commit f5e35dc

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

nova/conductor/tasks/live_migrate.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,17 @@ def _check_destination_is_not_source(self):
110110
instance_id=self.instance.uuid, host=self.destination)
111111

112112
def _check_destination_has_enough_memory(self):
113-
avail = self._get_compute_info(self.destination)['free_ram_mb']
113+
compute = self._get_compute_info(self.destination)
114+
free_ram_mb = compute.free_ram_mb
115+
total_ram_mb = compute.memory_mb
114116
mem_inst = self.instance.memory_mb
117+
# NOTE(sbauza): Now the ComputeNode object reports an allocation ratio
118+
# that can be provided by the compute_node if new or by the controller
119+
ram_ratio = compute.ram_allocation_ratio
115120

121+
# NOTE(sbauza): Mimic the RAMFilter logic in order to have the same
122+
# ram validation
123+
avail = total_ram_mb * ram_ratio - (total_ram_mb - free_ram_mb)
116124
if not mem_inst or avail <= mem_inst:
117125
instance_uuid = self.instance.uuid
118126
dest = self.destination

nova/tests/unit/conductor/tasks/test_live_migrate.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,13 @@ def test_check_requested_destination(self):
150150
objects.Service.get_by_compute_host(
151151
self.context, self.destination).AndReturn("service")
152152
self.task.servicegroup_api.service_is_up("service").AndReturn(True)
153-
hypervisor_details = {
154-
"hypervisor_type": "a",
155-
"hypervisor_version": 6.1,
156-
"free_ram_mb": 513
157-
}
153+
hypervisor_details = objects.ComputeNode(
154+
hypervisor_type="a",
155+
hypervisor_version=6.1,
156+
free_ram_mb=513,
157+
memory_mb=512,
158+
ram_allocation_ratio=1.0,
159+
)
158160
self.task._get_compute_info(self.destination)\
159161
.AndReturn(hypervisor_details)
160162
self.task._get_compute_info(self.instance_host)\
@@ -194,9 +196,15 @@ def test_check_requested_destination_fails_with_not_enough_memory(self):
194196

195197
self.task._check_host_is_up(self.destination)
196198
objects.ComputeNode.get_first_node_by_host_for_old_compat(self.context,
197-
self.destination).AndReturn({"free_ram_mb": 511})
199+
self.destination).AndReturn(
200+
objects.ComputeNode(free_ram_mb=513,
201+
memory_mb=1024,
202+
ram_allocation_ratio=0.9,
203+
))
198204

199205
self.mox.ReplayAll()
206+
# free_ram is bigger than instance.ram (512) but the allocation ratio
207+
# reduces the total available RAM to 410MB (1024 * 0.9 - (1024 - 513))
200208
self.assertRaises(exception.MigrationPreCheckError,
201209
self.task._check_requested_destination)
202210

0 commit comments

Comments
 (0)