From 927367cd9af6adf260bea4da4dcc5cc94eaa7b13 Mon Sep 17 00:00:00 2001 From: John Cates <jccates@us.ibm.com> Date: Wed, 11 Oct 2017 16:58:50 -0500 Subject: [PATCH] FlashSystems: permit snapshot/clone volumes larger than source Permit clone volumes and volumes created from snapshots to be larger than their source volumes; implemented in response to failures in the following CI tests: * VolumesSnapshotTestJSON.test_volume_from_snapshot * VolumesCloneTest.test_create_from_volume Change-Id: I21511e5c4db62563c61815c1671e8bb44ad3f427 Closes-Bug: #1560655 --- .../drivers/ibm/test_ibm_flashsystem.py | 7 ++- .../volume/drivers/ibm/flashsystem_common.py | 53 +++++++++++-------- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/cinder/tests/unit/volume/drivers/ibm/test_ibm_flashsystem.py b/cinder/tests/unit/volume/drivers/ibm/test_ibm_flashsystem.py index 63bec428f27..c27727a83e5 100644 --- a/cinder/tests/unit/volume/drivers/ibm/test_ibm_flashsystem.py +++ b/cinder/tests/unit/volume/drivers/ibm/test_ibm_flashsystem.py @@ -1028,12 +1028,15 @@ class FlashSystemDriverTestCase(test.TestCase): vol2 = self._generate_vol_info(None) self.driver.create_cloned_volume(vol2, vol1) - # case 2: when size does not match + # case 2: destination larger than source vol1 = self._generate_vol_info(None, vol_size=10) vol2 = self._generate_vol_info(None, vol_size=20) + self.driver.create_cloned_volume(vol2, vol1) + + # case 3: destination smaller than source self.assertRaises(exception.VolumeDriverException, self.driver.create_cloned_volume, - vol2, vol1) + vol1, vol2) def test_flashsystem_get_volume_stats(self): # case 1: good path diff --git a/cinder/volume/drivers/ibm/flashsystem_common.py b/cinder/volume/drivers/ibm/flashsystem_common.py index c37d4d4f53b..13607fcaa81 100644 --- a/cinder/volume/drivers/ibm/flashsystem_common.py +++ b/cinder/volume/drivers/ibm/flashsystem_common.py @@ -264,14 +264,17 @@ class FlashSystemDriver(san.SanDriver, {'src': src_vdisk_name, 'dest': dest_vdisk_name}) def _create_and_copy_vdisk_data(self, src_vdisk_name, src_vdisk_id, - dest_vdisk_name, dest_vdisk_id): - vdisk_attr = self._get_vdisk_attributes(src_vdisk_name) - self._driver_assert( - vdisk_attr is not None, - (_('_create_and_copy_vdisk_data: Failed to get attributes for ' - 'vdisk %s.') % src_vdisk_name)) + dest_vdisk_name, dest_vdisk_id, + dest_vdisk_size=None): + if dest_vdisk_size is None: + vdisk_attr = self._get_vdisk_attributes(src_vdisk_name) + self._driver_assert( + vdisk_attr is not None, + (_('_create_and_copy_vdisk_data: Failed to get attributes for ' + 'vdisk %s.') % src_vdisk_name)) + dest_vdisk_size = vdisk_attr['capacity'] - self._create_vdisk(dest_vdisk_name, vdisk_attr['capacity'], 'b', None) + self._create_vdisk(dest_vdisk_name, dest_vdisk_size, 'b', None) # create a timer to lock vdisk that will be used to data copy timer = loopingcall.FixedIntervalLoopingCall( @@ -297,7 +300,7 @@ class FlashSystemDriver(san.SanDriver, ssh_cmd = ['svctask', 'mkvdisk', '-name', name, '-mdiskgrp', FLASHSYSTEM_VOLPOOL_NAME, '-iogrp', six.text_type(FLASHSYSTEM_VOL_IOGRP), - '-size', size, '-unit', unit] + '-size', six.text_type(size), '-unit', unit] out, err = self._ssh(ssh_cmd) self._assert_ssh_return(out.strip(), '_create_vdisk', ssh_cmd, out, err) @@ -1101,9 +1104,9 @@ class FlashSystemDriver(san.SanDriver, 'enter: create_volume_from_snapshot: create %(vol)s from ' '%(snap)s.', {'vol': volume['name'], 'snap': snapshot['name']}) - if volume['size'] != snapshot['volume_size']: - msg = _('create_volume_from_snapshot: Volume size is different ' - 'from snapshot based volume.') + if volume['size'] < snapshot['volume_size']: + msg = _('create_volume_from_snapshot: Volume is smaller than ' + 'snapshot.') LOG.error(msg) raise exception.VolumeDriverException(message=msg) @@ -1114,10 +1117,13 @@ class FlashSystemDriver(san.SanDriver, 'The invalid status is: %s.') % status) raise exception.InvalidSnapshot(msg) - self._create_and_copy_vdisk_data(snapshot['name'], - snapshot['id'], - volume['name'], - volume['id']) + self._create_and_copy_vdisk_data( + snapshot['name'], + snapshot['id'], + volume['name'], + volume['id'], + dest_vdisk_size=volume['size'] * units.Gi + ) LOG.debug( 'leave: create_volume_from_snapshot: create %(vol)s from ' @@ -1129,16 +1135,19 @@ class FlashSystemDriver(san.SanDriver, LOG.debug('enter: create_cloned_volume: create %(vol)s from %(src)s.', {'src': src_volume['name'], 'vol': volume['name']}) - if src_volume['size'] != volume['size']: - msg = _('create_cloned_volume: Source and destination ' - 'size differ.') + if src_volume['size'] > volume['size']: + msg = _('create_cloned_volume: Source volume larger than ' + 'destination volume') LOG.error(msg) raise exception.VolumeDriverException(message=msg) - self._create_and_copy_vdisk_data(src_volume['name'], - src_volume['id'], - volume['name'], - volume['id']) + self._create_and_copy_vdisk_data( + src_volume['name'], + src_volume['id'], + volume['name'], + volume['id'], + dest_vdisk_size=volume['size'] * units.Gi + ) LOG.debug('leave: create_cloned_volume: create %(vol)s from %(src)s.', {'src': src_volume['name'], 'vol': volume['name']})