Merge "Storwize/SVC: Clone between different size volumes"
This commit is contained in:
commit
08b74ce328
@ -2956,7 +2956,8 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
snap1 = self._generate_vol_info(vol1['name'], vol1['id'])
|
||||
self.driver.create_snapshot(snap1)
|
||||
vol2 = self._generate_vol_info(None, None)
|
||||
vol3 = self._generate_vol_info(None, None)
|
||||
vol3 = testutils.create_volume(self.ctxt)
|
||||
vol4 = testutils.create_volume(self.ctxt)
|
||||
|
||||
# Try to create a volume from a non-existing snapshot
|
||||
snap_novol = self._generate_vol_info('undefined-vol', '12345')
|
||||
@ -2989,14 +2990,15 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
self.driver.create_volume_from_snapshot(vol2, snap1)
|
||||
self._assert_vol_exists(vol2['name'], True)
|
||||
|
||||
# Try to clone where source size != target size
|
||||
vol3['size'] += 1
|
||||
# Try to clone where source size > target size
|
||||
vol2['size'] = vol3['size'] + 1
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.driver.create_cloned_volume,
|
||||
vol3, vol2)
|
||||
self._assert_vol_exists(vol3['name'], False)
|
||||
vol3['size'] -= 1
|
||||
|
||||
# Try to clone where source size = target size
|
||||
vol2['size'] = vol3['size']
|
||||
if self.USESIM:
|
||||
self.sim.error_injection('lsfcmap', 'speed_up')
|
||||
self.driver.create_cloned_volume(vol3, vol2)
|
||||
@ -3007,7 +3009,21 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
self.assertEqual('49', fcmap['copyrate'])
|
||||
self._assert_vol_exists(vol3['name'], True)
|
||||
|
||||
# Try to clone where source size < target size
|
||||
vol4['size'] = vol2['size'] + 1
|
||||
if self.USESIM:
|
||||
self.sim.error_injection('lsfcmap', 'speed_up')
|
||||
self.driver.create_cloned_volume(vol4, vol2)
|
||||
if self.USESIM:
|
||||
# Validate copyrate was set on the flash copy
|
||||
for i, fcmap in self.sim._fcmappings_list.items():
|
||||
if fcmap['target'] == vol2['name']:
|
||||
self.assertEqual('49', fcmap['copyrate'])
|
||||
self._assert_vol_exists(vol4['name'], True)
|
||||
|
||||
# Delete in the 'opposite' order to make sure it works
|
||||
self.driver.delete_volume(vol4)
|
||||
self._assert_vol_exists(vol4['name'], False)
|
||||
self.driver.delete_volume(vol3)
|
||||
self._assert_vol_exists(vol3['name'], False)
|
||||
self.driver.delete_volume(vol2)
|
||||
|
@ -2201,9 +2201,16 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
return replica_status
|
||||
|
||||
def create_cloned_volume(self, tgt_volume, src_volume):
|
||||
if src_volume['size'] != tgt_volume['size']:
|
||||
msg = (_('create_cloned_volume: Source and destination '
|
||||
'size differ.'))
|
||||
"""Creates a clone of the specified volume."""
|
||||
|
||||
if src_volume['size'] > tgt_volume['size']:
|
||||
msg = (_("create_cloned_volume: source volume %(src_vol)s "
|
||||
"size is %(src_size)dGB and doesn't fit in target "
|
||||
"volume %(tgt_vol)s of size %(tgt_size)dGB.") %
|
||||
{'src_vol': src_volume['name'],
|
||||
'src_size': src_volume['size'],
|
||||
'tgt_vol': tgt_volume['name'],
|
||||
'tgt_size': tgt_volume['size']})
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(message=msg)
|
||||
|
||||
@ -2214,6 +2221,19 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
self._helpers.create_copy(src_volume['name'], tgt_volume['name'],
|
||||
src_volume['id'], self.configuration,
|
||||
opts, True, pool=pool)
|
||||
|
||||
# The source volume size is equal to target volume size
|
||||
# in most of the cases. But in some scenario, the target
|
||||
# volume size may be bigger than the source volume size.
|
||||
# SVC does not support flashcopy between two volumes
|
||||
# with two different size. So use source volume size to
|
||||
# create target volume first and then extend target
|
||||
# volume to orginal size.
|
||||
if tgt_volume['size'] > src_volume['size']:
|
||||
# extend the new created target volume to expected size.
|
||||
self._extend_volume_op(tgt_volume, tgt_volume['size'],
|
||||
src_volume['size'])
|
||||
|
||||
if opts['qos']:
|
||||
self._helpers.add_vdisk_qos(tgt_volume['name'], opts['qos'])
|
||||
|
||||
@ -2232,16 +2252,21 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
return replica_status
|
||||
|
||||
def extend_volume(self, volume, new_size):
|
||||
LOG.debug('enter: extend_volume: volume %s', volume['id'])
|
||||
self._extend_volume_op(volume, new_size)
|
||||
|
||||
def _extend_volume_op(self, volume, new_size, old_size=None):
|
||||
LOG.debug('enter: _extend_volume_op: volume %s', volume['id'])
|
||||
ret = self._helpers.ensure_vdisk_no_fc_mappings(volume['name'],
|
||||
allow_snaps=False)
|
||||
if not ret:
|
||||
msg = (_('extend_volume: Extending a volume with snapshots is not '
|
||||
'supported.'))
|
||||
msg = (_('_extend_volume_op: Extending a volume with snapshots is '
|
||||
'not supported.'))
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
|
||||
extend_amt = int(new_size) - volume['size']
|
||||
if old_size is None:
|
||||
old_size = volume['size']
|
||||
extend_amt = int(new_size) - old_size
|
||||
ctxt = context.get_admin_context()
|
||||
rep_mirror_type = self._get_volume_replicated_type_mirror(ctxt,
|
||||
volume)
|
||||
@ -2268,7 +2293,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
if rep_mirror_type and rep_status != "failed-over":
|
||||
self.replications.get(rep_mirror_type).create_relationship(
|
||||
volume, target_vol_name)
|
||||
LOG.debug('leave: extend_volume: volume %s', volume['id'])
|
||||
LOG.debug('leave: _extend_volume_op: volume %s', volume['id'])
|
||||
|
||||
def add_vdisk_copy(self, volume, dest_pool, vol_type):
|
||||
return self._helpers.add_vdisk_copy(volume, dest_pool,
|
||||
|
Loading…
x
Reference in New Issue
Block a user