Fix exception due to BDM race in get_available_resource()

If we run the resource tracker periodic at the right time, we
may try to collect BDM info from a newly-created instance before
we have any BDM records for it. This patch excludes instances
that have no reported BDMs to avoid choking there. This also
adds a test which simulates an instance that is partially in
the database, but is not fully created.

Closes-Bug: #1602057
Change-Id: I12c9c1ae6ca27727e8742060647dbe7017cded08
This commit is contained in:
shi liang 2016-07-21 12:44:22 +08:00 committed by Dan Smith
parent d98712d76a
commit 66246c4c9b
2 changed files with 15 additions and 4 deletions

View File

@ -11994,7 +11994,8 @@ class LibvirtConnTestCase(test.NoDBTestCase):
DiagFakeDomain("instance0000001"),
DiagFakeDomain("instance0000002"),
DiagFakeDomain("instance0000003"),
DiagFakeDomain("instance0000004")]
DiagFakeDomain("instance0000004"),
DiagFakeDomain("instance0000005")]
mock_list.return_value = instance_domains
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
@ -12057,14 +12058,21 @@ class LibvirtConnTestCase(test.NoDBTestCase):
root_device_name='/dev/vdc'),
objects.Instance(
uuid=instance_uuids[3],
root_device_name='/dev/vdd')
root_device_name='/dev/vdd'),
]
mock_get.return_value = instances
# NOTE(danms): We need to have found bdms for our instances,
# but we don't really need them to be complete as we just need
# to make it to our side_effect above. Exclude the last domain
# to simulate the case where we have an instance with no BDMs.
mock_bdms.return_value = {uuid: [] for uuid in instance_uuids
if uuid != instance_domains[-1].UUIDString()}
result = drvr._get_disk_over_committed_size_total()
self.assertEqual(42949672960, result)
mock_list.assert_called_once_with()
self.assertEqual(4, get_disk_info.call_count)
self.assertEqual(5, get_disk_info.call_count)
filters = {'uuid': instance_uuids}
mock_get.assert_called_once_with(mock.ANY, filters, use_slave=True)
mock_bdms.assert_called_with(mock.ANY, instance_uuids)

View File

@ -6853,13 +6853,16 @@ class LibvirtDriver(driver.ComputeDriver):
xml = guest.get_xml_desc()
block_device_info = None
if guest.uuid in local_instances:
if guest.uuid in local_instances \
and (bdms and guest.uuid in bdms):
# Get block device info for instance
block_device_info = driver.get_block_device_info(
local_instances[guest.uuid], bdms[guest.uuid])
disk_infos = self._get_instance_disk_info(guest.name, xml,
block_device_info=block_device_info)
if not disk_infos:
continue
for info in disk_infos:
disk_over_committed_size += int(