From 85b0fbb67b7a22a073cc5776b3980141eb8670ee Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Fri, 8 Jan 2016 13:52:22 -0500 Subject: [PATCH] NetApp ONTAP: Fix extending volume beyond lun geometry In the case where a LUN is extended beyond it's supported geometry, a new LUN must be created and only the used blocks should be copied to the new LUN. Currently, we do not pass the block count, source block, and destination block information. This causes the extend to fail. Closes-Bug: 1532836 Change-Id: I31d93ecfeee9884d6796c66acfbe556363130c44 --- .../netapp/dataontap/test_block_7mode.py | 20 +++++++++++++++ .../netapp/dataontap/test_block_cmode.py | 25 +++++++++++++++++++ .../drivers/netapp/dataontap/block_7mode.py | 5 ++-- .../drivers/netapp/dataontap/block_cmode.py | 4 +-- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/cinder/tests/unit/volume/drivers/netapp/dataontap/test_block_7mode.py b/cinder/tests/unit/volume/drivers/netapp/dataontap/test_block_7mode.py index c178a70d5..1886deb2d 100644 --- a/cinder/tests/unit/volume/drivers/netapp/dataontap/test_block_7mode.py +++ b/cinder/tests/unit/volume/drivers/netapp/dataontap/test_block_7mode.py @@ -298,6 +298,26 @@ class NetAppBlockStorage7modeLibraryTestCase(test.TestCase): '/vol/fake/fakeLUN', '/vol/fake/newFakeLUN', 'fakeLUN', 'newFakeLUN', 'false', block_count=0, dest_block=0, src_block=0) + def test_clone_lun_blocks(self): + """Test for when clone lun is passed block information.""" + block_count = 10 + src_block = 10 + dest_block = 30 + self.library._get_lun_attr = mock.Mock(return_value={ + 'Volume': 'fakeLUN', 'Path': '/vol/fake/fakeLUN'}) + self.library.zapi_client = mock.Mock() + self.library.zapi_client.get_lun_by_args.return_value = [fake.FAKE_LUN] + self.library._add_lun_to_table = mock.Mock() + + self.library._clone_lun('fakeLUN', 'newFakeLUN', 'false', + block_count=block_count, src_block=src_block, + dest_block=dest_block) + + self.library.zapi_client.clone_lun.assert_called_once_with( + '/vol/fake/fakeLUN', '/vol/fake/newFakeLUN', 'fakeLUN', + 'newFakeLUN', 'false', block_count=block_count, + dest_block=dest_block, src_block=src_block) + def test_clone_lun_no_space_reservation(self): """Test for when space_reservation is not passed.""" self.library._get_lun_attr = mock.Mock(return_value={ diff --git a/cinder/tests/unit/volume/drivers/netapp/dataontap/test_block_cmode.py b/cinder/tests/unit/volume/drivers/netapp/dataontap/test_block_cmode.py index c2bba0888..f8176eabe 100644 --- a/cinder/tests/unit/volume/drivers/netapp/dataontap/test_block_cmode.py +++ b/cinder/tests/unit/volume/drivers/netapp/dataontap/test_block_cmode.py @@ -192,6 +192,31 @@ class NetAppBlockStorageCmodeLibraryTestCase(test.TestCase): 'fakeLUN', 'fakeLUN', 'newFakeLUN', 'false', block_count=0, dest_block=0, src_block=0, qos_policy_group_name=None) + def test_clone_lun_blocks(self): + """Test for when clone lun is passed block information.""" + block_count = 10 + src_block = 10 + dest_block = 30 + + self.library._get_lun_attr = mock.Mock(return_value={'Volume': + 'fakeLUN'}) + self.library.zapi_client = mock.Mock() + self.library.zapi_client.get_lun_by_args.return_value = [ + mock.Mock(spec=netapp_api.NaElement)] + lun = fake.FAKE_LUN + self.library._get_lun_by_args = mock.Mock(return_value=[lun]) + self.library._add_lun_to_table = mock.Mock() + self.library._update_stale_vols = mock.Mock() + + self.library._clone_lun('fakeLUN', 'newFakeLUN', 'false', + block_count=block_count, src_block=src_block, + dest_block=dest_block) + + self.library.zapi_client.clone_lun.assert_called_once_with( + 'fakeLUN', 'fakeLUN', 'newFakeLUN', 'false', + block_count=block_count, dest_block=dest_block, + src_block=src_block, qos_policy_group_name=None) + def test_clone_lun_no_space_reservation(self): """Test for when space_reservation is not passed.""" diff --git a/cinder/volume/drivers/netapp/dataontap/block_7mode.py b/cinder/volume/drivers/netapp/dataontap/block_7mode.py index cf3a749aa..e6851a7d5 100644 --- a/cinder/volume/drivers/netapp/dataontap/block_7mode.py +++ b/cinder/volume/drivers/netapp/dataontap/block_7mode.py @@ -205,8 +205,9 @@ class NetAppBlockStorage7modeLibrary(block_base.NetAppBlockStorageLibrary): clone_path = '%s/%s' % (parent, new_name) self.zapi_client.clone_lun(path, clone_path, name, new_name, - space_reserved, src_block=0, - dest_block=0, block_count=0) + space_reserved, src_block=src_block, + dest_block=dest_block, + block_count=block_count) self.vol_refresh_voluntary = True luns = self.zapi_client.get_lun_by_args(path=clone_path) diff --git a/cinder/volume/drivers/netapp/dataontap/block_cmode.py b/cinder/volume/drivers/netapp/dataontap/block_cmode.py index 896f42bfb..b2b067715 100644 --- a/cinder/volume/drivers/netapp/dataontap/block_cmode.py +++ b/cinder/volume/drivers/netapp/dataontap/block_cmode.py @@ -133,8 +133,8 @@ class NetAppBlockStorageCmodeLibrary(block_base.NetAppBlockStorageLibrary): volume = metadata['Volume'] self.zapi_client.clone_lun(volume, name, new_name, space_reserved, qos_policy_group_name=qos_policy_group_name, - src_block=0, dest_block=0, - block_count=0) + src_block=src_block, dest_block=dest_block, + block_count=block_count) LOG.debug("Cloned LUN with new name %s", new_name) lun = self.zapi_client.get_lun_by_args(vserver=self.vserver, path='/vol/%s/%s' -- 2.45.2