Update to handle extra devs on recreate

When you recreate a server, there are certain situations where you may
discover an additional device (ex. an extra VIOS is available on the
target) that shouldn't be connected.

This change fixes those scenarios.

Change-Id: I1919e7b430300e85e7b28d28cae2ec18649aab43
Closes-Bug: #1590978
This commit is contained in:
Drew Thorstensen
2016-06-09 17:09:09 -04:00
parent f2fe41628a
commit b8fe7cb1c7
4 changed files with 45 additions and 5 deletions

View File

@@ -35,10 +35,10 @@ class TestNovaSlotManager(test.TestCase):
# Test when NVRAM store exists
# The Swift-backed implementation of PowerVM SlotMapStore is returned
self.store_api.fetch_slot_map = mock.MagicMock(return_value=None)
self.assertIsInstance(
slot.build_slot_mgr(self.inst, self.store_api, adapter=None,
vol_drv_iter=None),
slot.SwiftSlotManager)
slot_mgr = slot.build_slot_mgr(self.inst, self.store_api, adapter=None,
vol_drv_iter=None)
self.assertIsInstance(slot_mgr, slot.SwiftSlotManager)
self.assertFalse(slot_mgr.is_rebuild)
# Test when no NVRAM store is set up
# The no-op implementation of PowerVM SlotMapStore is returned
@@ -47,6 +47,11 @@ class TestNovaSlotManager(test.TestCase):
vol_drv_iter=None),
slot.NoopSlotManager)
# Test that the rebuild flag is set when it is flagged as a rebuild
slot_mgr = slot.build_slot_mgr(
self.inst, self.store_api, adapter='adpt', vol_drv_iter='test')
self.assertTrue(slot_mgr.is_rebuild)
class TestSwiftSlotManager(test.TestCase):

View File

@@ -164,6 +164,34 @@ class TestVSCSIAdapter(BaseVSCSITest):
self.vol_drv.cleanup_volume_at_destination(good_data)
mock_cln.assert_called_once_with('udid1')
@mock.patch('pypowervm.tasks.scsi_mapper.add_map')
@mock.patch('pypowervm.tasks.scsi_mapper.build_vscsi_mapping')
@mock.patch('pypowervm.tasks.hdisk.lua_recovery')
@mock.patch('nova_powervm.virt.powervm.vm.get_vm_id')
def test_connect_volume_rebuild_new_vio(self, mock_get_vm_id, mock_lua,
mock_build_map, mock_add_map):
"""Check if bad slot map.
If the slot map on a rebuild returns None, we should NOT connect it.
"""
# Make sure the rebuild is set to True
self.slot_mgr.build_map.get_vscsi_slot.return_value = None, None
self.slot_mgr.is_rebuild = True
# Set up that the device is on the VIOS
mock_get_vm_id.return_value = 'partition_id'
mock_build_map.side_effect = Exception
mock_lua.return_value = (
hdisk.LUAStatus.DEVICE_AVAILABLE, 'devname', 'udid')
# Run the method. It will fail only because there isn't a second
# VIOS that does support the connect.
self.assertRaises(p_exc.VolumeAttachFailed,
self.vol_drv.connect_volume, self.slot_mgr)
# Make sure an add map is not invoked
self.assertEqual(0, mock_add_map.call_count)
@mock.patch('pypowervm.tasks.scsi_mapper.add_map')
@mock.patch('pypowervm.tasks.scsi_mapper.build_vscsi_mapping')
@mock.patch('pypowervm.tasks.hdisk.lua_recovery')

View File

@@ -85,6 +85,7 @@ class NovaSlotManager(slot_map.SlotMapStore):
self.vol_drv_iter = vol_drv_iter if vol_drv_iter else ()
self._build_map = None
self._vios_wraps = []
self.is_rebuild = (self.adapter and vol_drv_iter)
@property
def build_map(self):
@@ -94,7 +95,7 @@ class NovaSlotManager(slot_map.SlotMapStore):
adapters.
"""
if self._build_map is None:
if self.adapter and self.vol_drv_iter:
if self.is_rebuild:
self.init_recreate_map(self.adapter, self.vol_drv_iter)
else:
self._build_map = slot_map.BuildSlotMap(self)

View File

@@ -249,6 +249,12 @@ class VscsiVolumeAdapter(v_driver.FibreChannelVolumeAdapter):
# Get the slot and LUA to assign.
slot, lua = slot_mgr.build_map.get_vscsi_slot(vios_w, udid)
if slot_mgr.is_rebuild and not slot:
LOG.debug('Detected a device with UDID %s on VIOS %s on the '
'rebuild that did not exist on the source. '
'Ignoring.', udid, vios_w.uuid)
return False
if hdisk.good_discovery(status, device_name):
# Found a hdisk on this Virtual I/O Server. Add the action to
# map it to the VM when the stg_ftsk is executed.