Skip to content

Commit 97096c8

Browse files
committed
Remove 'nova.virt.driver.ComputeDriver.estimate_instance_overhead'
With the removal of the Core, Ram and Disk filters in change I8a0d332877fbb9794700081e7954f2501b7e7c09, there's now only a single caller for the 'estimate_instance_overhead' function. This call results in the 'memory_mb_used', 'local_gb_used', 'vcpus_used', 'free_ram_mb' and 'free_disk_gb' fields of a compute nodes 'ComputeNode' object being modified when calculating usage as part of the resource tracker to include driver-specific overhead. However, these fields are no longer used for for anything except logging and the 'os-hypervisors' API. Since overhead is not reflected in placement (and therefore the scheduler), reporting them as part of the various usage values for both logging and that API is actually a bit of a lie and is likely to cause confusion among users. Remove the whole thing and make our logs and the 'os-hypervisors' API better match what's stored in placement. Change-Id: I033e8269194de54432079cbc970431e3dcea7ce5 Signed-off-by: Stephen Finucane <[email protected]>
1 parent 5406c8b commit 97096c8

File tree

12 files changed

+10
-202
lines changed

12 files changed

+10
-202
lines changed

doc/source/admin/configuration/schedulers.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1385,7 +1385,8 @@ XenAPI
13851385
You should configure the
13861386
:oslo.config:option:`reserved_host_memory_mb` config option to
13871387
account for this overhead, based on the size of your hosts and
1388-
instances.
1388+
instances. For more information, refer to
1389+
https://wiki.openstack.org/wiki/XenServer/Overhead.
13891390

13901391
Cells considerations
13911392
~~~~~~~~~~~~~~~~~~~~

nova/compute/resource_tracker.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,15 +1053,15 @@ def _update(self, context, compute_node, startup=False):
10531053
self.pci_tracker.save(context)
10541054

10551055
def _update_usage(self, usage, nodename, sign=1):
1056+
# TODO(stephenfin): We don't use the CPU, RAM and disk fields for much
1057+
# except 'Aggregate(Core|Ram|Disk)Filter', the 'os-hypervisors' API,
1058+
# and perhaps some out-of-tree filters. Once the in-tree stuff is
1059+
# removed or updated to use information from placement, we can think
1060+
# about dropping the fields from the 'ComputeNode' object entirely
10561061
mem_usage = usage['memory_mb']
10571062
disk_usage = usage.get('root_gb', 0)
10581063
vcpus_usage = usage.get('vcpus', 0)
10591064

1060-
overhead = self.driver.estimate_instance_overhead(usage)
1061-
mem_usage += overhead['memory_mb']
1062-
disk_usage += overhead.get('disk_gb', 0)
1063-
vcpus_usage += overhead.get('vcpus', 0)
1064-
10651065
cn = self.compute_nodes[nodename]
10661066
cn.memory_mb_used += sign * mem_usage
10671067
cn.local_gb_used += sign * disk_usage

nova/tests/unit/compute/test_resource_tracker.py

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -417,26 +417,12 @@
417417
}
418418

419419

420-
def overhead_zero(instance):
421-
# Emulate that the driver does not adjust the memory
422-
# of the instance...
423-
return {
424-
'memory_mb': 0,
425-
'disk_gb': 0,
426-
'vcpus': 0,
427-
}
428-
429-
430-
def setup_rt(hostname, virt_resources=_VIRT_DRIVER_AVAIL_RESOURCES,
431-
estimate_overhead=overhead_zero):
420+
def setup_rt(hostname, virt_resources=_VIRT_DRIVER_AVAIL_RESOURCES):
432421
"""Sets up the resource tracker instance with mock fixtures.
433422
434423
:param virt_resources: Optional override of the resource representation
435424
returned by the virt driver's
436425
`get_available_resource()` method.
437-
:param estimate_overhead: Optional override of a function that should
438-
return overhead of memory given an instance
439-
object. Defaults to returning zero overhead.
440426
"""
441427
query_client_mock = mock.MagicMock()
442428
report_client_mock = mock.MagicMock()
@@ -449,7 +435,6 @@ def setup_rt(hostname, virt_resources=_VIRT_DRIVER_AVAIL_RESOURCES,
449435
# TODO(mriedem): Need to make this mocked virt driver implement upt.
450436
vd.update_provider_tree.side_effect = NotImplementedError
451437
vd.get_host_ip_addr.return_value = _NODENAME
452-
vd.estimate_instance_overhead.side_effect = estimate_overhead
453438
vd.rebalances_nodes = False
454439

455440
with test.nested(
@@ -481,11 +466,9 @@ def setUp(self):
481466
reserved_host_memory_mb=0,
482467
reserved_host_cpus=0)
483468

484-
def _setup_rt(self, virt_resources=_VIRT_DRIVER_AVAIL_RESOURCES,
485-
estimate_overhead=overhead_zero):
469+
def _setup_rt(self, virt_resources=_VIRT_DRIVER_AVAIL_RESOURCES):
486470
(self.rt, self.sched_client_mock, self.report_client_mock,
487-
self.driver_mock) = setup_rt(
488-
_HOSTNAME, virt_resources, estimate_overhead)
471+
self.driver_mock) = setup_rt(_HOSTNAME, virt_resources)
489472

490473
def _setup_ptree(self, compute):
491474
"""Set up a ProviderTree with a compute node root, and mock the

nova/tests/unit/virt/hyperv/test_driver.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,6 @@ def test_list_instances(self):
137137
self.driver.list_instances()
138138
self.driver._vmops.list_instances.assert_called_once_with()
139139

140-
def test_estimate_instance_overhead(self):
141-
self.driver.estimate_instance_overhead(mock.sentinel.instance)
142-
self.driver._vmops.estimate_instance_overhead.assert_called_once_with(
143-
mock.sentinel.instance)
144-
145140
def test_spawn(self):
146141
self.driver.spawn(
147142
mock.sentinel.context, mock.sentinel.instance,

nova/tests/unit/virt/hyperv/test_vmops.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,6 @@ def test_list_instances(self):
8282
self._vmops._vmutils.list_instances.assert_called_once_with()
8383
self.assertEqual(response, [mock_instance])
8484

85-
def test_estimate_instance_overhead(self):
86-
instance_info = {'memory_mb': 512}
87-
overhead = self._vmops.estimate_instance_overhead(instance_info)
88-
self.assertEqual(0, overhead['memory_mb'])
89-
self.assertEqual(1, overhead['disk_gb'])
90-
91-
instance_info = {'memory_mb': 500}
92-
overhead = self._vmops.estimate_instance_overhead(instance_info)
93-
self.assertEqual(0, overhead['disk_gb'])
94-
9585
def _test_get_info(self, vm_exists):
9686
mock_instance = fake_instance.fake_instance_obj(self.context)
9787
mock_info = mock.MagicMock(spec_set=dict)

nova/tests/unit/virt/libvirt/test_driver.py

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -7305,78 +7305,6 @@ def test_instance_exists(self, mock_get_guest):
73057305
mock_get_guest.side_effect = exception.InternalError(err='something')
73067306
self.assertFalse(drvr.instance_exists(None))
73077307

7308-
def test_estimate_instance_overhead_spawn(self):
7309-
# test that method when called with instance ref
7310-
instance_topology = objects.InstanceNUMATopology(
7311-
emulator_threads_policy=(
7312-
fields.CPUEmulatorThreadsPolicy.ISOLATE),
7313-
cells=[objects.InstanceNUMACell(
7314-
id=0, cpuset=set([0]), memory=1024)])
7315-
instance_info = objects.Instance(**self.test_instance)
7316-
instance_info.numa_topology = instance_topology
7317-
7318-
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
7319-
overhead = drvr.estimate_instance_overhead(instance_info)
7320-
self.assertEqual(1, overhead['vcpus'])
7321-
7322-
def test_estimate_instance_overhead_spawn_no_overhead(self):
7323-
# test that method when called with instance ref, no overhead
7324-
instance_topology = objects.InstanceNUMATopology(
7325-
emulator_threads_policy=(
7326-
fields.CPUEmulatorThreadsPolicy.SHARE),
7327-
cells=[objects.InstanceNUMACell(
7328-
id=0, cpuset=set([0]), memory=1024)])
7329-
instance_info = objects.Instance(**self.test_instance)
7330-
instance_info.numa_topology = instance_topology
7331-
7332-
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
7333-
overhead = drvr.estimate_instance_overhead(instance_info)
7334-
self.assertEqual(0, overhead['vcpus'])
7335-
7336-
def test_estimate_instance_overhead_migrate(self):
7337-
# test that method when called with flavor ref
7338-
instance_info = objects.Flavor(extra_specs={
7339-
'hw:emulator_threads_policy': (
7340-
fields.CPUEmulatorThreadsPolicy.ISOLATE),
7341-
'hw:cpu_policy': fields.CPUAllocationPolicy.DEDICATED,
7342-
})
7343-
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
7344-
overhead = drvr.estimate_instance_overhead(instance_info)
7345-
self.assertEqual(1, overhead['vcpus'])
7346-
7347-
def test_estimate_instance_overhead_migrate_no_overhead(self):
7348-
# test that method when called with flavor ref, no overhead
7349-
instance_info = objects.Flavor(extra_specs={
7350-
'hw:emulator_threads_policy': (
7351-
fields.CPUEmulatorThreadsPolicy.SHARE),
7352-
'hw:cpu_policy': fields.CPUAllocationPolicy.DEDICATED,
7353-
})
7354-
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
7355-
overhead = drvr.estimate_instance_overhead(instance_info)
7356-
self.assertEqual(0, overhead['vcpus'])
7357-
7358-
def test_estimate_instance_overhead_usage(self):
7359-
# test that method when called with usage dict
7360-
instance_info = objects.Flavor(extra_specs={
7361-
'hw:emulator_threads_policy': (
7362-
fields.CPUEmulatorThreadsPolicy.ISOLATE),
7363-
'hw:cpu_policy': fields.CPUAllocationPolicy.DEDICATED,
7364-
})
7365-
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
7366-
overhead = drvr.estimate_instance_overhead(instance_info)
7367-
self.assertEqual(1, overhead['vcpus'])
7368-
7369-
def test_estimate_instance_overhead_usage_no_overhead(self):
7370-
# test that method when called with usage dict, no overhead
7371-
instance_info = objects.Flavor(extra_specs={
7372-
'hw:emulator_threads_policy': (
7373-
fields.CPUEmulatorThreadsPolicy.SHARE),
7374-
'hw:cpu_policy': fields.CPUAllocationPolicy.DEDICATED,
7375-
})
7376-
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
7377-
overhead = drvr.estimate_instance_overhead(instance_info)
7378-
self.assertEqual(0, overhead['vcpus'])
7379-
73807308
@mock.patch.object(host.Host, "list_instance_domains")
73817309
def test_list_instances(self, mock_list):
73827310
vm1 = FakeVirtDomain(id=3, name="instance00000001")

nova/tests/unit/virt/xenapi/test_driver.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414

15-
16-
import math
17-
1815
import mock
1916
import os_resource_classes as orc
2017
from oslo_utils.fixture import uuidsentinel as uuids
@@ -105,19 +102,6 @@ def test_available_resource(self):
105102
self.assertEqual(1, resources['disk_available_least'])
106103
mock_get.assert_called_once_with(refresh=True)
107104

108-
def test_overhead(self):
109-
driver = self._get_driver()
110-
instance = {'memory_mb': 30720, 'vcpus': 4}
111-
112-
# expected memory overhead per:
113-
# https://wiki.openstack.org/wiki/XenServer/Overhead
114-
expected = ((instance['memory_mb'] * xenapi_driver.OVERHEAD_PER_MB) +
115-
(instance['vcpus'] * xenapi_driver.OVERHEAD_PER_VCPU) +
116-
xenapi_driver.OVERHEAD_BASE)
117-
expected = math.ceil(expected)
118-
overhead = driver.estimate_instance_overhead(instance)
119-
self.assertEqual(expected, overhead['memory_mb'])
120-
121105
def test_set_bootable(self):
122106
driver = self._get_driver()
123107

nova/virt/driver.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -255,20 +255,6 @@ def instance_exists(self, instance):
255255
except NotImplementedError:
256256
return instance.name in self.list_instances()
257257

258-
def estimate_instance_overhead(self, instance_info):
259-
"""Estimate the virtualization overhead required to build an instance
260-
of the given flavor.
261-
262-
Defaults to zero, drivers should override if per-instance overhead
263-
calculations are desired.
264-
265-
:param instance_info: Instance/flavor to calculate overhead for.
266-
:returns: Dict of estimated overhead values.
267-
"""
268-
return {'memory_mb': 0,
269-
'disk_gb': 0,
270-
'vcpus': 0}
271-
272258
def list_instances(self):
273259
"""Return the names of all the instances known to the virtualization
274260
layer, as a list.

nova/virt/hyperv/driver.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,6 @@ def list_instance_uuids(self):
157157
def list_instances(self):
158158
return self._vmops.list_instances()
159159

160-
def estimate_instance_overhead(self, instance_info):
161-
return self._vmops.estimate_instance_overhead(instance_info)
162-
163160
def spawn(self, context, instance, image_meta, injected_files,
164161
admin_password, allocations, network_info=None,
165162
block_device_info=None):

nova/virt/hyperv/vmops.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,6 @@ def list_instance_uuids(self):
116116
def list_instances(self):
117117
return self._vmutils.list_instances()
118118

119-
def estimate_instance_overhead(self, instance_info):
120-
# NOTE(claudiub): When an instance starts, Hyper-V creates a VM memory
121-
# file on the local disk. The file size is the same as the VM's amount
122-
# of memory. Since disk_gb must be an integer, and memory is MB, round
123-
# up from X512 MB.
124-
return {'memory_mb': 0,
125-
'disk_gb': (instance_info['memory_mb'] + 512) // units.Ki}
126-
127119
def get_info(self, instance):
128120
"""Get information about the VM."""
129121
LOG.debug("get_info called for instance", instance=instance)

nova/virt/libvirt/driver.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -890,24 +890,6 @@ def instance_exists(self, instance):
890890
except (exception.InternalError, exception.InstanceNotFound):
891891
return False
892892

893-
def estimate_instance_overhead(self, instance_info):
894-
overhead = super(LibvirtDriver, self).estimate_instance_overhead(
895-
instance_info)
896-
if isinstance(instance_info, objects.Flavor):
897-
# A flavor object is passed during case of migrate
898-
emu_policy = hardware.get_emulator_thread_policy_constraint(
899-
instance_info)
900-
if emu_policy == fields.CPUEmulatorThreadsPolicy.ISOLATE:
901-
overhead['vcpus'] += 1
902-
else:
903-
# An instance object is passed during case of spawing or a
904-
# dict is passed when computing resource for an instance
905-
numa_topology = hardware.instance_topology_from_instance(
906-
instance_info)
907-
if numa_topology and numa_topology.emulator_threads_isolated:
908-
overhead['vcpus'] += 1
909-
return overhead
910-
911893
def list_instances(self):
912894
names = []
913895
for guest in self._host.list_guests(only_running=False):

nova/virt/xenapi/driver.py

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
- suffix "_rec" for record objects
2424
"""
2525

26-
import math
27-
2826
import os_resource_classes as orc
2927
from os_xenapi.client import session
3028
from oslo_log import log as logging
@@ -48,10 +46,6 @@
4846

4947
CONF = nova.conf.CONF
5048

51-
OVERHEAD_BASE = 3
52-
OVERHEAD_PER_MB = 0.00781
53-
OVERHEAD_PER_VCPU = 1.5
54-
5549

5650
def invalid_option(option_name, recommended_value):
5751
LOG.exception(_('Current value of '
@@ -155,30 +149,6 @@ def instance_exists(self, instance):
155149
"""
156150
return self._vmops.instance_exists(instance.name)
157151

158-
def estimate_instance_overhead(self, instance_info):
159-
"""Get virtualization overhead required to build an instance of the
160-
given flavor.
161-
162-
:param instance_info: Instance/flavor to calculate overhead for.
163-
:returns: Overhead memory in MB.
164-
"""
165-
166-
# XenServer memory overhead is proportional to the size of the
167-
# VM. Larger flavor VMs become more efficient with respect to
168-
# overhead.
169-
170-
# interpolated formula to predict overhead required per vm.
171-
# based on data from:
172-
# https://wiki.openstack.org/wiki/XenServer/Overhead
173-
# Some padding is done to each value to fit all available VM data
174-
memory_mb = instance_info['memory_mb']
175-
vcpus = instance_info.get('vcpus', 1)
176-
overhead = ((memory_mb * OVERHEAD_PER_MB) +
177-
(vcpus * OVERHEAD_PER_VCPU) +
178-
OVERHEAD_BASE)
179-
overhead = math.ceil(overhead)
180-
return {'memory_mb': overhead}
181-
182152
def list_instances(self):
183153
"""List VM instances."""
184154
return self._vmops.list_instances()

0 commit comments

Comments
 (0)