diff --git a/doc/source/devref/filter_scheduler.rst b/doc/source/devref/filter_scheduler.rst index 9f51462d3bc..92ee8981961 100644 --- a/doc/source/devref/filter_scheduler.rst +++ b/doc/source/devref/filter_scheduler.rst @@ -58,7 +58,9 @@ code. For example class |RamFilter| has the next realization: instance_type = filter_properties.get('instance_type') requested_ram = instance_type['memory_mb'] free_ram_mb = host_state.free_ram_mb - return free_ram_mb * FLAGS.ram_allocation_ratio >= requested_ram + total_usable_ram_mb = host_state.total_usable_ram_mb + used_ram_mb = total_usable_ram_mb - free_ram_mb + return total_usable_ram_mb * FLAGS.ram_allocation_ratio - used_ram_mb >= requested_ram Here `ram_allocation_ratio` means the virtual RAM to physical RAM allocation ratio (it is 1.5 by default). Really, nice and simple. diff --git a/nova/scheduler/filters/ram_filter.py b/nova/scheduler/filters/ram_filter.py index 65889d426b1..4bc84c243d2 100644 --- a/nova/scheduler/filters/ram_filter.py +++ b/nova/scheduler/filters/ram_filter.py @@ -37,4 +37,7 @@ def host_passes(self, host_state, filter_properties): instance_type = filter_properties.get('instance_type') requested_ram = instance_type['memory_mb'] free_ram_mb = host_state.free_ram_mb - return free_ram_mb * FLAGS.ram_allocation_ratio >= requested_ram + total_usable_ram_mb = host_state.total_usable_ram_mb + used_ram_mb = total_usable_ram_mb - free_ram_mb + return (total_usable_ram_mb * FLAGS.ram_allocation_ratio - + used_ram_mb >= requested_ram) diff --git a/nova/scheduler/host_manager.py b/nova/scheduler/host_manager.py index f5ba724d5db..289ac274415 100644 --- a/nova/scheduler/host_manager.py +++ b/nova/scheduler/host_manager.py @@ -124,7 +124,9 @@ def update_from_compute_node(self, compute): all_disk_mb -= FLAGS.reserved_host_disk_mb if FLAGS.reserved_host_memory_mb > 0: all_ram_mb -= FLAGS.reserved_host_memory_mb + #NOTE(jogo) free_ram_mb can be negative self.free_ram_mb = all_ram_mb + self.total_usable_ram_mb = all_ram_mb self.free_disk_mb = all_disk_mb self.vcpus_total = vcpus_total diff --git a/nova/tests/scheduler/test_host_filters.py b/nova/tests/scheduler/test_host_filters.py index f56a14565ab..19b42fd2830 100644 --- a/nova/tests/scheduler/test_host_filters.py +++ b/nova/tests/scheduler/test_host_filters.py @@ -182,10 +182,22 @@ def test_ram_filter_fails_on_memory(self): capabilities = {'enabled': True} service = {'disabled': False} host = fakes.FakeHostState('host1', 'compute', - {'free_ram_mb': 1023, 'capabilities': capabilities, - 'service': service}) + {'free_ram_mb': 1023, 'total_usable_ram_mb': 1024, + 'capabilities': capabilities, 'service': service}) self.assertFalse(filt_cls.host_passes(host, filter_properties)) + def test_ram_filter_oversubscribe(self): + self._stub_service_is_up(True) + filt_cls = self.class_map['RamFilter']() + self.flags(ram_allocation_ratio=2.0) + filter_properties = {'instance_type': {'memory_mb': 1024}} + capabilities = {'enabled': True} + service = {'disabled': False} + host = fakes.FakeHostState('host1', 'compute', + {'free_ram_mb': -1024, 'total_usable_ram_mb': 2048, + 'capabilities': capabilities, 'service': service}) + self.assertTrue(filt_cls.host_passes(host, filter_properties)) + def test_compute_filter_fails_on_service_disabled(self): self._stub_service_is_up(True) filt_cls = self.class_map['ComputeFilter']()