From b5791432e5126f47b55e958f1686d3dd474b97f6 Mon Sep 17 00:00:00 2001 From: Anthony Lee Date: Thu, 7 Aug 2014 13:58:34 -0700 Subject: [PATCH] Fixing LeftHand live migration error Fixed a bug in the LeftHand driver that was causing an error to occur during live migration of an instance that is attached to a volume. The solution was to make sure server access is only requested for a volume if the iSCSI session doesn't already have access enabled on the LeftHand backend. Change-Id: I41046beb66f2a6138659ec3e4d1d3f37b37859b8 Closes-Bug: 1311350 --- cinder/tests/test_hplefthand.py | 49 ++++++++++++++++++- .../drivers/san/hp/hp_lefthand_rest_proxy.py | 20 +++++++- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/cinder/tests/test_hplefthand.py b/cinder/tests/test_hplefthand.py index e9ef3f55a..5528730e1 100644 --- a/cinder/tests/test_hplefthand.py +++ b/cinder/tests/test_hplefthand.py @@ -48,6 +48,7 @@ class HPLeftHandBaseDriver(): serverName = 'fakehost' server_id = 0 + server_uri = '/lhos/servers/0' snapshot_name = "fakeshapshot" snapshot_id = 3 @@ -805,7 +806,10 @@ class TestHPLeftHandRESTISCSIDriver(HPLeftHandBaseDriver, test.TestCase): # mock return value of getVolumeByName mock_client.getServerByName.side_effect = hpexceptions.HTTPNotFound() mock_client.createServer.return_value = {'id': self.server_id} - mock_client.getVolumeByName.return_value = {'id': self.volume_id} + mock_client.getVolumeByName.return_value = { + 'id': self.volume_id, + 'iscsiSessions': None + } # execute initialize_connection result = self.driver.initialize_connection( @@ -839,6 +843,44 @@ class TestHPLeftHandRESTISCSIDriver(HPLeftHandBaseDriver, test.TestCase): exception.VolumeBackendAPIException, self.driver.initialize_connection, self.volume, self.connector) + def test_initialize_connection_session_exists(self): + + # setup drive with default configuration + # and return the mock HTTP LeftHand client + mock_client = self.setup_driver() + + # mock return value of getVolumeByName + mock_client.getServerByName.side_effect = hpexceptions.HTTPNotFound() + mock_client.createServer.return_value = {'id': self.server_id} + mock_client.getVolumeByName.return_value = { + 'id': self.volume_id, + 'iscsiSessions': [{'server': {'uri': self.server_uri}}] + } + + # execute initialize_connection + result = self.driver.initialize_connection( + self.volume, + self.connector) + + # validate + self.assertEqual(result['driver_volume_type'], 'iscsi') + self.assertEqual(result['data']['target_discovered'], False) + self.assertEqual(result['data']['volume_id'], self.volume_id) + self.assertTrue('auth_method' not in result['data']) + + expected = self.driver_startup_call_stack + [ + mock.call.getServerByName('fakehost'), + mock.call.createServer + ( + 'fakehost', + 'iqn.1993-08.org.debian:01:222', + None + ), + mock.call.getVolumeByName('fakevolume')] + + # validate call chain + mock_client.assert_has_calls(expected) + def test_initialize_connection_with_chaps(self): # setup drive with default configuration @@ -851,7 +893,10 @@ class TestHPLeftHandRESTISCSIDriver(HPLeftHandBaseDriver, test.TestCase): 'id': self.server_id, 'chapAuthenticationRequired': True, 'chapTargetSecret': 'dont_tell'} - mock_client.getVolumeByName.return_value = {'id': self.volume_id} + mock_client.getVolumeByName.return_value = { + 'id': self.volume_id, + 'iscsiSessions': None + } # execute initialize_connection result = self.driver.initialize_connection( diff --git a/cinder/volume/drivers/san/hp/hp_lefthand_rest_proxy.py b/cinder/volume/drivers/san/hp/hp_lefthand_rest_proxy.py index 9486711b6..a133f848e 100644 --- a/cinder/volume/drivers/san/hp/hp_lefthand_rest_proxy.py +++ b/cinder/volume/drivers/san/hp/hp_lefthand_rest_proxy.py @@ -90,9 +90,11 @@ class HPLeftHandRESTProxy(ISCSIDriver): should check for snapshots 1.0.4 - Fixed bug #1285925, LeftHand AO volume create performance improvement + 1.0.5 - Fixed bug #1311350, Live-migration of an instance when + attached to a volume was causing an error. """ - VERSION = "1.0.4" + VERSION = "1.0.5" device_stats = {} @@ -265,7 +267,21 @@ class HPLeftHandRESTProxy(ISCSIDriver): try: server_info = self._create_server(connector) volume_info = self.client.getVolumeByName(volume['name']) - self.client.addServerAccess(volume_info['id'], server_info['id']) + + access_already_enabled = False + if volume_info['iscsiSessions'] is not None: + # Extract the server id for each session to check if the + # new server already has access permissions enabled. + for session in volume_info['iscsiSessions']: + server_id = int(session['server']['uri'].split('/')[3]) + if server_id == server_info['id']: + access_already_enabled = True + break + + if not access_already_enabled: + self.client.addServerAccess( + volume_info['id'], + server_info['id']) iscsi_properties = self._get_iscsi_properties(volume) -- 2.45.2