diff --git a/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_mirror_fc.py b/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_mirror_fc.py index 643faa4e135..37aff891755 100644 --- a/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_mirror_fc.py +++ b/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_mirror_fc.py @@ -1288,7 +1288,9 @@ class HBSDMIRRORFCDriverTest(test.TestCase): @mock.patch.object(requests.Session, "request") def test_update_migrated_volume(self, request): request.side_effect = [FakeResponse(200, GET_LDEV_RESULT), - FakeResponse(200, COMPLETED_SUCCEEDED_RESULT)] + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT), + FakeResponse(200, GET_LDEV_RESULT), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT)] self.assertRaises( NotImplementedError, self.driver.update_migrated_volume, @@ -1296,7 +1298,31 @@ class HBSDMIRRORFCDriverTest(test.TestCase): TEST_VOLUME[0], TEST_VOLUME[1], "available") - self.assertEqual(2, request.call_count) + self.assertEqual(4, request.call_count) + args, kwargs = request.call_args_list[3] + self.assertEqual(kwargs['json']['label'], + TEST_VOLUME[0]['id'].replace("-", "")) + + @mock.patch.object(requests.Session, "request") + def test_update_migrated_volume_replication(self, request): + request.side_effect = [FakeResponse(200, GET_LDEV_RESULT_REP), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT), + FakeResponse(200, GET_LDEV_RESULT_REP), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT)] + self.assertRaises( + NotImplementedError, + self.driver.update_migrated_volume, + self.ctxt, + TEST_VOLUME[0], + TEST_VOLUME[4], + "available") + self.assertEqual(6, request.call_count) + original_volume_nickname = TEST_VOLUME[0]['id'].replace("-", "") + for i in (4, 5): + args, kwargs = request.call_args_list[i] + self.assertEqual(kwargs['json']['label'], original_volume_nickname) def test_unmanage_snapshot(self): """The driver don't support unmange_snapshot.""" diff --git a/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_fc.py b/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_fc.py index 9946bacc8ea..f2596ca20d2 100644 --- a/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_fc.py +++ b/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_fc.py @@ -1310,7 +1310,10 @@ class HBSDRESTFCDriverTest(test.TestCase): TEST_VOLUME[0], TEST_VOLUME[1], "available") - self.assertEqual(1, request.call_count) + self.assertEqual(2, request.call_count) + args, kwargs = request.call_args_list[1] + self.assertEqual(kwargs['json']['label'], + TEST_VOLUME[0]['id'].replace("-", "")) def test_unmanage_snapshot(self): """The driver don't support unmange_snapshot.""" diff --git a/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_iscsi.py b/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_iscsi.py index 004ad5d3ef9..796ff187564 100644 --- a/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_iscsi.py +++ b/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_iscsi.py @@ -870,7 +870,10 @@ class HBSDRESTISCSIDriverTest(test.TestCase): TEST_VOLUME[0], TEST_VOLUME[1], "available") - self.assertEqual(1, request.call_count) + self.assertEqual(2, request.call_count) + args, kwargs = request.call_args_list[1] + self.assertEqual(kwargs['json']['label'], + TEST_VOLUME[0]['id'].replace("-", "")) def test_unmanage_snapshot(self): """The driver don't support unmange_snapshot.""" diff --git a/cinder/tests/unit/volume/drivers/hpe/xp/__init__.py b/cinder/tests/unit/volume/drivers/hpe/xp/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cinder/tests/unit/volume/drivers/hpe/xp/test_hpe_xp_rest_fc.py b/cinder/tests/unit/volume/drivers/hpe/xp/test_hpe_xp_rest_fc.py index c59f5870af8..f0ec496becc 100644 --- a/cinder/tests/unit/volume/drivers/hpe/xp/test_hpe_xp_rest_fc.py +++ b/cinder/tests/unit/volume/drivers/hpe/xp/test_hpe_xp_rest_fc.py @@ -1,4 +1,4 @@ -# Copyright (C) 2022, 2023, Hewlett Packard Enterprise, Ltd. +# Copyright (C) 2022, 2024, Hewlett Packard Enterprise, Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -955,7 +955,10 @@ class HPEXPRESTFCDriverTest(test.TestCase): TEST_VOLUME[0], TEST_VOLUME[1], "available") - self.assertEqual(1, request.call_count) + self.assertEqual(2, request.call_count) + args, kwargs = request.call_args_list[1] + self.assertEqual(kwargs['json']['label'], + TEST_VOLUME[0]['id'].replace("-", "")) def test_unmanage_snapshot(self): """The driver don't support unmange_snapshot.""" diff --git a/cinder/tests/unit/volume/drivers/hpe/xp/test_hpe_xp_rest_iscsi.py b/cinder/tests/unit/volume/drivers/hpe/xp/test_hpe_xp_rest_iscsi.py index 18f5c8531b1..cffdab86760 100644 --- a/cinder/tests/unit/volume/drivers/hpe/xp/test_hpe_xp_rest_iscsi.py +++ b/cinder/tests/unit/volume/drivers/hpe/xp/test_hpe_xp_rest_iscsi.py @@ -1,4 +1,4 @@ -# Copyright (C) 2022, 2023. Hewlett Packard Enterprise, Ltd. +# Copyright (C) 2022, 2024, Hewlett Packard Enterprise, Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -768,7 +768,10 @@ class HPEXPRESTISCSIDriverTest(test.TestCase): TEST_VOLUME[0], TEST_VOLUME[1], "available") - self.assertEqual(1, request.call_count) + self.assertEqual(2, request.call_count) + args, kwargs = request.call_args_list[1] + self.assertEqual(kwargs['json']['label'], + TEST_VOLUME[0]['id'].replace("-", "")) def test_unmanage_snapshot(self): """The driver don't support unmange_snapshot.""" diff --git a/cinder/tests/unit/volume/drivers/nec/v/test_internal_nec_rest_fc.py b/cinder/tests/unit/volume/drivers/nec/v/test_internal_nec_rest_fc.py index e2c1db2bc39..cb43ce20909 100644 --- a/cinder/tests/unit/volume/drivers/nec/v/test_internal_nec_rest_fc.py +++ b/cinder/tests/unit/volume/drivers/nec/v/test_internal_nec_rest_fc.py @@ -1,4 +1,4 @@ -# Copyright (C) 2021, 2023, NEC corporation +# Copyright (C) 2021, 2024, NEC corporation # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -945,7 +945,10 @@ class VStorageRESTFCDriverTest(test.TestCase): TEST_VOLUME[0], TEST_VOLUME[1], "available") - self.assertEqual(1, request.call_count) + self.assertEqual(2, request.call_count) + args, kwargs = request.call_args_list[1] + self.assertEqual(kwargs['json']['label'], + TEST_VOLUME[0]['id'].replace("-", "")) def test_unmanage_snapshot(self): """The driver don't support unmange_snapshot.""" diff --git a/cinder/tests/unit/volume/drivers/nec/v/test_internal_nec_rest_iscsi.py b/cinder/tests/unit/volume/drivers/nec/v/test_internal_nec_rest_iscsi.py index 2c76e2a5172..61a038b108e 100644 --- a/cinder/tests/unit/volume/drivers/nec/v/test_internal_nec_rest_iscsi.py +++ b/cinder/tests/unit/volume/drivers/nec/v/test_internal_nec_rest_iscsi.py @@ -1,4 +1,4 @@ -# Copyright (C) 2021, 2023, NEC corporation +# Copyright (C) 2021, 2024, NEC corporation # # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -804,7 +804,10 @@ class VStorageRESTISCSIDriverTest(test.TestCase): TEST_VOLUME[0], TEST_VOLUME[1], "available") - self.assertEqual(1, request.call_count) + self.assertEqual(2, request.call_count) + args, kwargs = request.call_args_list[1] + self.assertEqual(kwargs['json']['label'], + TEST_VOLUME[0]['id'].replace("-", "")) def test_unmanage_snapshot(self): """The driver don't support unmange_snapshot.""" diff --git a/cinder/volume/drivers/hitachi/hbsd_common.py b/cinder/volume/drivers/hitachi/hbsd_common.py index da015ba6fe7..ed972d6f234 100644 --- a/cinder/volume/drivers/hitachi/hbsd_common.py +++ b/cinder/volume/drivers/hitachi/hbsd_common.py @@ -1,4 +1,4 @@ -# Copyright (C) 2020, 2023, Hitachi, Ltd. +# Copyright (C) 2020, 2024, Hitachi, Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -1102,6 +1102,13 @@ class HBSDCommon(): """Migrate the specified volume.""" return False + def update_migrated_volume(self, volume, new_volume): + """Update LDEV settings after generic volume migration.""" + ldev = self.get_ldev(new_volume) + # We do not need to check if ldev is not None because it is guaranteed + # that ldev is not None because migration has been successful so far. + self.modify_ldev_name(ldev, volume['id'].replace("-", "")) + def retype(self, ctxt, volume, new_type, diff, host): """Retype the specified volume.""" return False diff --git a/cinder/volume/drivers/hitachi/hbsd_fc.py b/cinder/volume/drivers/hitachi/hbsd_fc.py index e4233ea1353..25a20479878 100644 --- a/cinder/volume/drivers/hitachi/hbsd_fc.py +++ b/cinder/volume/drivers/hitachi/hbsd_fc.py @@ -1,4 +1,4 @@ -# Copyright (C) 2020, 2023, Hitachi, Ltd. +# Copyright (C) 2020, 2024, Hitachi, Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -191,6 +191,7 @@ class HBSDFCDriver(driver.FibreChannelDriver): self, ctxt, volume, new_volume, original_volume_status): """Do any remaining jobs after migration.""" self.common.discard_zero_page(new_volume) + self.common.update_migrated_volume(volume, new_volume) super(HBSDFCDriver, self).update_migrated_volume( ctxt, volume, new_volume, original_volume_status) diff --git a/cinder/volume/drivers/hitachi/hbsd_iscsi.py b/cinder/volume/drivers/hitachi/hbsd_iscsi.py index 95ac706c0f7..21fcc0d1e57 100644 --- a/cinder/volume/drivers/hitachi/hbsd_iscsi.py +++ b/cinder/volume/drivers/hitachi/hbsd_iscsi.py @@ -1,4 +1,4 @@ -# Copyright (C) 2020, 2023, Hitachi, Ltd. +# Copyright (C) 2020, 2024, Hitachi, Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -187,6 +187,7 @@ class HBSDISCSIDriver(driver.ISCSIDriver): self, ctxt, volume, new_volume, original_volume_status): """Do any remaining jobs after migration.""" self.common.discard_zero_page(new_volume) + self.common.update_migrated_volume(volume, new_volume) super(HBSDISCSIDriver, self).update_migrated_volume( ctxt, volume, new_volume, original_volume_status) diff --git a/cinder/volume/drivers/hitachi/hbsd_replication.py b/cinder/volume/drivers/hitachi/hbsd_replication.py index 6054a97a9ef..09395f375c4 100644 --- a/cinder/volume/drivers/hitachi/hbsd_replication.py +++ b/cinder/volume/drivers/hitachi/hbsd_replication.py @@ -1,4 +1,4 @@ -# Copyright (C) 2022, 2023, Hitachi, Ltd. +# Copyright (C) 2022, 2024, Hitachi, Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -940,6 +940,23 @@ class HBSDREPLICATION(rest.HBSDREST): else: return self.rep_primary.migrate_volume(volume, host) + def update_migrated_volume(self, volume, new_volume): + """Update LDEV settings after generic volume migration.""" + self._require_rep_primary() + ldev = self.rep_primary.get_ldev(new_volume) + # We do not need to check if ldev is not None because it is guaranteed + # that ldev is not None because migration has been successful so far. + if self._has_rep_pair(ldev): + self._require_rep_secondary() + thread = greenthread.spawn( + self.rep_secondary.update_migrated_volume, volume, new_volume) + try: + self.rep_primary.update_migrated_volume(volume, new_volume) + finally: + thread.wait() + else: + self.rep_primary.update_migrated_volume(volume, new_volume) + def _resync_rep_pair(self, pvol, svol): copy_group_name = self._create_rep_copy_group_name(pvol) rep_type = self.driver_info['mirror_attr'] diff --git a/releasenotes/notes/hitachi_fix-ldevnickname-0a0756449e7448d9.yaml b/releasenotes/notes/hitachi_fix-ldevnickname-0a0756449e7448d9.yaml new file mode 100644 index 00000000000..2f16814dfee --- /dev/null +++ b/releasenotes/notes/hitachi_fix-ldevnickname-0a0756449e7448d9.yaml @@ -0,0 +1,6 @@ +fixes: + - | + Hitachi driver `bug #2071697 + '_: Fix to set + correct object ID as LDEV nickname when running host-assisted + migration with ``retype`` or ``migration`` commands.