]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fixing LeftHand live migration error
authorAnthony Lee <anthony.mic.lee@hp.com>
Thu, 7 Aug 2014 20:58:34 +0000 (13:58 -0700)
committerAnthony Lee <anthony.mic.lee@hp.com>
Thu, 7 Aug 2014 21:12:11 +0000 (14:12 -0700)
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
cinder/volume/drivers/san/hp/hp_lefthand_rest_proxy.py

index e9ef3f55a7124d336a29b5507947679ed2d72a08..5528730e16fd0a2d823a7bcce53f543cc783c157 100644 (file)
@@ -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(
index 9486711b6966a017cd281374b3aca55f8ecae2b9..a133f848e2db9db8ef423da8eb2aa068a95ad3ed 100644 (file)
@@ -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)