diff --git a/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_adapter.py b/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_adapter.py index 939793f0c..1eab4a59e 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_adapter.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_adapter.py @@ -1168,6 +1168,8 @@ class TestCommonAdapter(test.TestCase): fake_mirror.secondary_client.get_serial.assert_called_with() fake_mirror.secondary_client.get_lun.assert_called_with( name=vol1.name) + self.assertEqual(fake_mirror.secondary_client, + common_adapter.client) self.assertEqual(device['backend_id'], backend_id) for update in updates: self.assertEqual(fields.ReplicationStatus.FAILED_OVER, @@ -1206,6 +1208,8 @@ class TestCommonAdapter(test.TestCase): fake_mirror.secondary_client.get_serial.assert_called_with() fake_mirror.secondary_client.get_lun.assert_called_with( name=vol1.name) + self.assertEqual(fake_mirror.secondary_client, + common_adapter.client) self.assertEqual('default', backend_id) for update in updates: self.assertEqual(fields.ReplicationStatus.ENABLED, diff --git a/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_common.py b/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_common.py index 9d3dba626..e69515a79 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_common.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_common.py @@ -237,6 +237,12 @@ class TestReplicationDeviceList(test.TestCase): self.assertEqual(1, len(devices_list)) self.assertIsNotNone(devices_list[0]) + def test_get_backend_ids(self): + backend_ids = common.ReplicationDeviceList.get_backend_ids( + self.configuration) + self.assertEqual(1, len(backend_ids)) + self.assertIn('array_id_1', backend_ids) + class TestVNXMirrorView(test.TestCase): def setUp(self): diff --git a/cinder/volume/drivers/dell_emc/vnx/adapter.py b/cinder/volume/drivers/dell_emc/vnx/adapter.py index 4a5466f5d..63df4f2b3 100644 --- a/cinder/volume/drivers/dell_emc/vnx/adapter.py +++ b/cinder/volume/drivers/dell_emc/vnx/adapter.py @@ -75,7 +75,13 @@ class CommonAdapter(object): self.config.storage_vnx_security_file_dir, self.queue_path) # Replication related - self.mirror_view = self.build_mirror_view(self.config, True) + if (self.active_backend_id in + common.ReplicationDeviceList.get_backend_ids(self.config)): + # The backend is in failed-over state + self.mirror_view = self.build_mirror_view(self.config, False) + self.client = self.mirror_view.primary_client + else: + self.mirror_view = self.build_mirror_view(self.config, True) self.serial_number = self.client.get_serial() self.storage_pools = self.parse_pools() self.force_delete_lun_in_sg = ( @@ -1235,7 +1241,7 @@ class CommonAdapter(object): LOG.error(msg, {'volume_id': volume.id, 'target': secondary_backend_id, 'error': ex},) - new_status = fields.ReplicationStatus.ERROR + new_status = fields.ReplicationStatus.FAILOVER_ERROR else: # Transfer ownership to secondary_backend_id and # update provider_location field @@ -1261,6 +1267,10 @@ class CommonAdapter(object): volume_update_list.append({ 'volume_id': volume.id, 'updates': {'status': 'error'}}) + # After failover, the secondary is now the primary, + # any sequential request will be redirected to it. + self.client = mirror_view.secondary_client + return secondary_backend_id, volume_update_list def get_pool_name(self, volume): diff --git a/cinder/volume/drivers/dell_emc/vnx/common.py b/cinder/volume/drivers/dell_emc/vnx/common.py index aa7f278d7..558189788 100644 --- a/cinder/volume/drivers/dell_emc/vnx/common.py +++ b/cinder/volume/drivers/dell_emc/vnx/common.py @@ -445,6 +445,15 @@ class ReplicationDeviceList(list): def __getitem__(self, item): return self.list[item] + @classmethod + def get_backend_ids(cls, config): + """Returns all configured device_id.""" + rep_list = cls(config) + backend_ids = [] + for item in rep_list.devices: + backend_ids.append(item.backend_id) + return backend_ids + class VNXMirrorView(object): def __init__(self, primary_client, secondary_client):