From 1bf15d155300c03ddfcb2d2361ac9af3e33f545e Mon Sep 17 00:00:00 2001 From: Chhavi Agarwal Date: Mon, 5 Oct 2015 10:23:41 -0500 Subject: [PATCH] Check if vios_w returned from find_vios It's possible during VM Migration to fail before the vfc mappings have been created. If this happens the revert attempts to remove the mappings, but find_vios_for_vfc_wwpns will return None because there aren't any mappings. Change-Id: I717cd998c496c8f66660f03f07b58641d24755d7 Closes-Bug: #1502726 Closes-Bug: #1502892 --- .../tests/virt/powervm/volume/test_npiv.py | 19 ++++++++++++++- nova_powervm/virt/powervm/volume/npiv.py | 24 ++++++++++++------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/nova_powervm/tests/virt/powervm/volume/test_npiv.py b/nova_powervm/tests/virt/powervm/volume/test_npiv.py index 86632a5a..916228a2 100644 --- a/nova_powervm/tests/virt/powervm/volume/test_npiv.py +++ b/nova_powervm/tests/virt/powervm/volume/test_npiv.py @@ -463,6 +463,8 @@ class TestNPIVAdapter(test_vol.TestVolumeAdapter): self.assertEqual([1, 2], mig_data.get('npiv_fabric_slots_A')) self.assertEqual([3], mig_data.get('npiv_fabric_slots_B')) + @mock.patch('pypowervm.tasks.vfc_mapper.remove_maps') + @mock.patch('pypowervm.tasks.vfc_mapper.find_vios_for_vfc_wwpns') @mock.patch('pypowervm.tasks.vfc_mapper.' 'build_migration_mappings_for_fabric') @mock.patch('nova_powervm.virt.powervm.mgmt.get_mgmt_partition') @@ -472,7 +474,7 @@ class TestNPIVAdapter(test_vol.TestVolumeAdapter): '_fabric_names') def test_pre_live_migration_on_destination( self, mock_fabric_names, mock_get_fabric_meta, mock_mgmt_lpar_id, - mock_build_mig_map): + mock_build_mig_map, mock_find_vios_for_vfc_wwpns, mock_remove_map): mock_fabric_names.return_value = ['A', 'B'] mock_get_fabric_meta.side_effect = [[], []] mock_mgmt_lpar_id.return_value = mock.Mock(uuid='1') @@ -493,3 +495,18 @@ class TestNPIVAdapter(test_vol.TestVolumeAdapter): # Order of the mappings is not important. self.assertEqual(set(['b', 'a']), set(dest_mig_data.get('vfc_lpm_mappings'))) + + mock_find_vios_for_vfc_wwpns.return_value = None, None + dest_mig_data = {} + mock_fabric_names.return_value = ['A', 'B'] + mock_get_fabric_meta.side_effect = [ + [('11', 'AA BB'), ('22', 'CC DD')], + [('33', 'EE FF')]] + mock_build_mig_map.side_effect = [['a'], ['b']] + + # Execute the test + with self.assertLogs(npiv.__name__, level='WARNING'): + self.vol_drv.pre_live_migration_on_destination( + src_mig_data, dest_mig_data) + # remove_map should not be called since vios_w is None + self.assertEqual(0, mock_remove_map.call_count) diff --git a/nova_powervm/virt/powervm/volume/npiv.py b/nova_powervm/virt/powervm/volume/npiv.py index ed23de07..421024c4 100644 --- a/nova_powervm/virt/powervm/volume/npiv.py +++ b/nova_powervm/virt/powervm/volume/npiv.py @@ -159,11 +159,18 @@ class NPIVVolumeAdapter(v_driver.FibreChannelVolumeAdapter): vios_w, vfc_map = pvm_vfcm.find_vios_for_vfc_wwpns( vios_wraps, npiv_port_map[1].split()) - # Add the subtask to remove the mapping from the management - # partition. - self.stg_ftsk.wrapper_tasks[vios_w.uuid].add_functor_subtask( - pvm_vfcm.remove_maps, mgmt_uuid, - client_adpt=vfc_map.client_adapter, logspec=ls) + if vios_w is not None: + # Add the subtask to remove the mapping from the management + # partition. + task_wrapper = self.stg_ftsk.wrapper_tasks[vios_w.uuid] + task_wrapper.add_functor_subtask( + pvm_vfcm.remove_maps, mgmt_uuid, + client_adpt=vfc_map.client_adapter, logspec=ls) + else: + LOG.warn(_LW("No storage connections found between the " + "Virtual I/O Servers and FC Fabric " + "%(fabric)s. The connection might be removed " + "already."), {'fabric': fabric}) # TODO(thorst) Find a better place for this execute. Works for now # as the stg_ftsk is all local. Also won't do anything if there @@ -463,9 +470,10 @@ class NPIVVolumeAdapter(v_driver.FibreChannelVolumeAdapter): if vios_w is not None: # Add the subtask to remove the specific map - self.stg_ftsk.wrapper_tasks[vios_w.uuid].add_functor_subtask( - pvm_vfcm.remove_maps, self.vm_uuid, port_map=npiv_port_map, - logspec=ls) + task_wrapper = self.stg_ftsk.wrapper_tasks[vios_w.uuid] + task_wrapper.add_functor_subtask( + pvm_vfcm.remove_maps, self.vm_uuid, + port_map=npiv_port_map, logspec=ls) else: LOG.warn(_LW("No storage connections found between the " "Virtual I/O Servers and FC Fabric %(fabric)s."),