From 5cf52914bd78fa553f853ad6ea2fba8a87d8075c Mon Sep 17 00:00:00 2001 From: "Walter A. Boring IV" Date: Fri, 27 Jun 2014 16:00:01 -0700 Subject: [PATCH] 3PAR Only remove FC Zone on last volume detach This patch checks to make sure that we don't include the initiator_target_map in the return of terminate_connection if there are volumes still attached for a particular host. The FibreChannel ZoneManager doesn't remove zones if there isn't an initiator_target_map in the return of terminate_connection. Change-Id: I98db5adb6da38454933a6e4b78085193f1d37680 Partial-Bug: #1308318 --- cinder/tests/test_hp3par.py | 32 ++++++++++++++++------ cinder/volume/drivers/san/hp/hp_3par_fc.py | 21 ++++++++++---- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/cinder/tests/test_hp3par.py b/cinder/tests/test_hp3par.py index cb554c6a4..45d81e8f1 100644 --- a/cinder/tests/test_hp3par.py +++ b/cinder/tests/test_hp3par.py @@ -1318,10 +1318,13 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase): # setup_mock_client drive with default configuration # and return the mock HTTP 3PAR client mock_client = self.setup_driver() - mock_client.getHostVLUNs.return_value = [ - {'active': True, - 'volumeName': self.VOLUME_3PAR_NAME, - 'lun': None, 'type': 0}] + + effects = [ + [{'active': True, 'volumeName': self.VOLUME_3PAR_NAME, + 'lun': None, 'type': 0}], + hpexceptions.HTTPNotFound] + + mock_client.getHostVLUNs.side_effect = effects expected = [ mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS), @@ -1331,13 +1334,19 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase): None, self.FAKE_HOST), mock.call.deleteHost(self.FAKE_HOST), + mock.call.getHostVLUNs(self.FAKE_HOST), mock.call.getPorts(), mock.call.logout()] - self.driver.terminate_connection(self.volume, self.connector) + conn_info = self.driver.terminate_connection(self.volume, + self.connector) mock_client.assert_has_calls(expected) + self.assertIn('data', conn_info) + self.assertIn('initiator_target_map', conn_info['data']) mock_client.reset_mock() + mock_client.getHostVLUNs.side_effect = effects + # mock some deleteHost exceptions that are handled delete_with_vlun = hpexceptions.HTTPConflict( error={'message': "has exported VLUN"}) @@ -1346,11 +1355,14 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase): mock_client.deleteHost = mock.Mock( side_effect=[delete_with_vlun, delete_with_hostset]) - self.driver.terminate_connection(self.volume, self.connector) + conn_info = self.driver.terminate_connection(self.volume, + self.connector) mock_client.assert_has_calls(expected) mock_client.reset_mock() + mock_client.getHostVLUNs.side_effect = effects - self.driver.terminate_connection(self.volume, self.connector) + conn_info = self.driver.terminate_connection(self.volume, + self.connector) mock_client.assert_has_calls(expected) def test_terminate_connection_more_vols(self): @@ -1373,11 +1385,13 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase): self.VOLUME_3PAR_NAME, None, self.FAKE_HOST), - mock.call.getPorts(), + mock.call.getHostVLUNs(self.FAKE_HOST), mock.call.logout()] - self.driver.terminate_connection(self.volume, self.connector) + conn_info = self.driver.terminate_connection(self.volume, + self.connector) mock_client.assert_has_calls(expect_less) + self.assertNotIn('initiator_target_map', conn_info['data']) def test_get_volume_stats(self): # setup_mock_client drive with default configuration diff --git a/cinder/volume/drivers/san/hp/hp_3par_fc.py b/cinder/volume/drivers/san/hp/hp_3par_fc.py index 413a17db6..45db9047b 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_fc.py +++ b/cinder/volume/drivers/san/hp/hp_3par_fc.py @@ -62,10 +62,11 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver): 2.0.2 - Add back-end assisted volume migrate 2.0.3 - Added initiator-target map for FC Zone Manager 2.0.4 - Added support for managing/unmanaging of volumes + 2.0.5 - Only remove FC Zone on last volume detach """ - VERSION = "2.0.4" + VERSION = "2.0.5" def __init__(self, *args, **kwargs): super(HP3PARFCDriver, self).__init__(*args, **kwargs) @@ -229,12 +230,20 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver): self.common.terminate_connection(volume, hostname, wwn=connector['wwpns']) - target_wwns, init_targ_map = self._build_initiator_target_map( - connector) - info = {'driver_volume_type': 'fibre_channel', - 'data': {'target_wwn': target_wwns, - 'initiator_target_map': init_targ_map}} + 'data': {}} + + try: + self.common.client.getHostVLUNs(hostname) + except hpexceptions.HTTPNotFound: + # No more exports for this host. + LOG.info(_("Need to remove FC Zone, building initiator " + "target map")) + target_wwns, init_targ_map = self._build_initiator_target_map( + connector) + + info['data'] = {'target_wwn': target_wwns, + 'initiator_target_map': init_targ_map} return info finally: -- 2.45.2