From 173d0bcb845e9b04641e8bc62d0d1e981a2b1d51 Mon Sep 17 00:00:00 2001 From: Drew Thorstensen Date: Mon, 14 Sep 2015 13:18:08 -0400 Subject: [PATCH] Ignore empty NPIV fabrics on disconnect A spawn may roll back all operations within the flow, even if the execute has not yet run against them. This means that a disconnect volume may occur before a connect volume if something in the flow failed before the volume actions. Currently, the vSCSI flow is prepared for this. However, the NPIV path would fail. This change set resolves the disconnect to tolerate empty fabrics on a disconnect. It will detect if a fabric has not yet been connected and log accordingly on the disconnect. Change-Id: I78c51fa3677d78d28f1efd66a29394a24538e145 Closes-Bug: 1493940 --- .../tests/virt/powervm/volume/test_npiv.py | 16 ++++++++++++++++ nova_powervm/virt/powervm/volume/npiv.py | 14 ++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/nova_powervm/tests/virt/powervm/volume/test_npiv.py b/nova_powervm/tests/virt/powervm/volume/test_npiv.py index 00ec5bfd..b1673972 100644 --- a/nova_powervm/tests/virt/powervm/volume/test_npiv.py +++ b/nova_powervm/tests/virt/powervm/volume/test_npiv.py @@ -199,6 +199,22 @@ class TestNPIVAdapter(test.TestCase): self.assertEqual(2, mock_remove_maps.call_count) self.assertEqual(1, self.ft_fx.patchers['update'].mock.call_count) + @mock.patch('pypowervm.tasks.vfc_mapper.remove_maps') + @mock.patch('nova_powervm.virt.powervm.volume.npiv.NPIVVolumeAdapter.' + '_get_fabric_meta') + def test_disconnect_volume_no_fabric_meta(self, mock_get_fabric_meta, + mock_remove_maps): + # Mock Data. The fabric_names is set to A by setUp. + # Force a None return + self.vol_drv.instance.task_state = 'deleting' + mock_get_fabric_meta.return_value = [] + + # Invoke + self.vol_drv.disconnect_volume() + + # No mappings should have been removed + self.assertFalse(mock_remove_maps.called) + @mock.patch('nova_powervm.virt.powervm.volume.npiv.NPIVVolumeAdapter.' '_remove_maps_for_fabric') def test_disconnect_volume_no_op(self, mock_remove_maps): diff --git a/nova_powervm/virt/powervm/volume/npiv.py b/nova_powervm/virt/powervm/volume/npiv.py index 4d8cd5c4..d5b3df7b 100644 --- a/nova_powervm/virt/powervm/volume/npiv.py +++ b/nova_powervm/virt/powervm/volume/npiv.py @@ -19,7 +19,7 @@ from oslo_log import log as logging from taskflow import task from nova.compute import task_states -from nova.i18n import _LI +from nova.i18n import _LI, _LW from pypowervm.tasks import vfc_mapper as pvm_vfcm from pypowervm.wrappers import virtual_io_server as pvm_vios @@ -380,6 +380,10 @@ class NPIVVolumeAdapter(v_driver.FibreChannelVolumeAdapter): :param fabric: The fabric to remove the mappings from. """ npiv_port_maps = self._get_fabric_meta(fabric) + if not npiv_port_maps: + # If no mappings exist, exit out of the method. + return + vios_wraps = self.stg_ftsk.feed for npiv_port_map in npiv_port_maps: @@ -474,7 +478,13 @@ class NPIVVolumeAdapter(v_driver.FibreChannelVolumeAdapter): """ meta_key = self._sys_meta_fabric_key(fabric) if self.instance.system_metadata.get(meta_key) is None: - return None + # If no mappings exist, log a warning. + LOG.warn(_LW("No NPIV mappings exist for instance %(inst)s on " + "fabric %(fabric)s. May not have connected to " + "the fabric yet or fabric configuration was recently " + "modified."), + {'inst': self.instance.name, 'fabric': fabric}) + return [] meta_value = self.instance.system_metadata[meta_key] wwpns = meta_value.split(",")