Avoid update resource if compute node not updated

There's a race condition that compute record might be created
and updated through objects.compute_node.update_from_virt_driver
function, but some fields free_disk_gb are not updated yet
so accessing from scheduler service will find a 'None' value
and lead to exception

Change-Id: Ia68298a3f01d89bbf302ac734389f7282176c553
Closes-Bug: 1610679
This commit is contained in:
jichenjc
2016-07-23 23:21:39 +08:00
parent 1d7443857f
commit 36a0ba9c81
3 changed files with 32 additions and 12 deletions

View File

@@ -181,6 +181,11 @@ class HostState(object):
def _update_from_compute_node(self, compute):
"""Update information about a host from a ComputeNode object."""
# NOTE(jichenjc): if the compute record is just created but not updated
# some field such as free_disk_gb can be None
if compute.updated_at is None:
return
if (self.updated and compute.updated_at
and self.updated > compute.updated_at):
return

View File

@@ -16,6 +16,7 @@
Fakes For Scheduler tests.
"""
import datetime
import six
from nova import objects
@@ -58,7 +59,8 @@ COMPUTE_NODES = [
objects.ComputeNode(
id=1, local_gb=1024, memory_mb=1024, vcpus=1,
disk_available_least=None, free_ram_mb=512, vcpus_used=1,
free_disk_gb=512, local_gb_used=0, updated_at=None,
free_disk_gb=512, local_gb_used=0,
updated_at=datetime.datetime(2015, 11, 11, 11, 0, 0),
host='host1', hypervisor_hostname='node1', host_ip='127.0.0.1',
hypervisor_version=0, numa_topology=None,
hypervisor_type='foo', supported_hv_specs=[],
@@ -68,7 +70,8 @@ COMPUTE_NODES = [
objects.ComputeNode(
id=2, local_gb=2048, memory_mb=2048, vcpus=2,
disk_available_least=1024, free_ram_mb=1024, vcpus_used=2,
free_disk_gb=1024, local_gb_used=0, updated_at=None,
free_disk_gb=1024, local_gb_used=0,
updated_at=datetime.datetime(2015, 11, 11, 11, 0, 0),
host='host2', hypervisor_hostname='node2', host_ip='127.0.0.1',
hypervisor_version=0, numa_topology=None,
hypervisor_type='foo', supported_hv_specs=[],
@@ -78,7 +81,8 @@ COMPUTE_NODES = [
objects.ComputeNode(
id=3, local_gb=4096, memory_mb=4096, vcpus=4,
disk_available_least=3333, free_ram_mb=3072, vcpus_used=1,
free_disk_gb=3072, local_gb_used=0, updated_at=None,
free_disk_gb=3072, local_gb_used=0,
updated_at=datetime.datetime(2015, 11, 11, 11, 0, 0),
host='host3', hypervisor_hostname='node3', host_ip='127.0.0.1',
hypervisor_version=0, numa_topology=NUMA_TOPOLOGY._to_json(),
hypervisor_type='foo', supported_hv_specs=[],
@@ -88,7 +92,8 @@ COMPUTE_NODES = [
objects.ComputeNode(
id=4, local_gb=8192, memory_mb=8192, vcpus=8,
disk_available_least=8192, free_ram_mb=8192, vcpus_used=0,
free_disk_gb=8888, local_gb_used=0, updated_at=None,
free_disk_gb=8888, local_gb_used=0,
updated_at=datetime.datetime(2015, 11, 11, 11, 0, 0),
host='host4', hypervisor_hostname='node4', host_ip='127.0.0.1',
hypervisor_version=0, numa_topology=None,
hypervisor_type='foo', supported_hv_specs=[],

View File

@@ -899,8 +899,8 @@ class HostStateTestCase(test.NoDBTestCase):
stats=stats, memory_mb=1, free_disk_gb=0, local_gb=0,
local_gb_used=0, free_ram_mb=0, vcpus=0, vcpus_used=0,
disk_available_least=None,
updated_at=None, host_ip='127.0.0.1',
hypervisor_type='htype',
updated_at=datetime.datetime(2015, 11, 11, 11, 0, 0),
host_ip='127.0.0.1', hypervisor_type='htype',
hypervisor_hostname='hostname', cpu_info='cpu_info',
supported_hv_specs=[],
hypervisor_version=hyper_ver_int, numa_topology=None,
@@ -942,8 +942,8 @@ class HostStateTestCase(test.NoDBTestCase):
stats=stats, memory_mb=0, free_disk_gb=0, local_gb=0,
local_gb_used=0, free_ram_mb=0, vcpus=0, vcpus_used=0,
disk_available_least=None,
updated_at=None, host_ip='127.0.0.1',
hypervisor_type='htype',
updated_at=datetime.datetime(2015, 11, 11, 11, 0, 0),
host_ip='127.0.0.1', hypervisor_type='htype',
hypervisor_hostname='hostname', cpu_info='cpu_info',
supported_hv_specs=[],
hypervisor_version=hyper_ver_int, numa_topology=None,
@@ -975,8 +975,8 @@ class HostStateTestCase(test.NoDBTestCase):
stats=stats, memory_mb=0, free_disk_gb=0, local_gb=0,
local_gb_used=0, free_ram_mb=0, vcpus=0, vcpus_used=0,
disk_available_least=None,
updated_at=None, host_ip='127.0.0.1',
hypervisor_type='htype',
updated_at=datetime.datetime(2015, 11, 11, 11, 0, 0),
host_ip='127.0.0.1', hypervisor_type='htype',
hypervisor_hostname='hostname', cpu_info='cpu_info',
supported_hv_specs=[],
hypervisor_version=hyper_ver_int, numa_topology=None,
@@ -1135,8 +1135,8 @@ class HostStateTestCase(test.NoDBTestCase):
memory_mb=0, free_disk_gb=0, local_gb=0,
local_gb_used=0, free_ram_mb=0, vcpus=0, vcpus_used=0,
disk_available_least=None,
updated_at=None, host_ip='127.0.0.1',
hypervisor_type='htype',
updated_at=datetime.datetime(2015, 11, 11, 11, 0, 0),
host_ip='127.0.0.1', hypervisor_type='htype',
hypervisor_hostname='hostname', cpu_info='cpu_info',
supported_hv_specs=[],
hypervisor_version=hyper_ver_int,
@@ -1156,3 +1156,13 @@ class HostStateTestCase(test.NoDBTestCase):
self.assertEqual({'0': 10, '1': 43},
host.metrics[1].numa_membw_values)
self.assertIsInstance(host.numa_topology, six.string_types)
def test_stat_consumption_from_compute_node_not_ready(self):
compute = objects.ComputeNode(free_ram_mb=100,
updated_at=None)
host = host_manager.HostState("fakehost", "fakenode")
host._update_from_compute_node(compute)
# Because compute record not ready, the update of free ram
# will not happen and the value will still be 0
self.assertEqual(0, host.free_ram_mb)