Merge "Storwize:create_volume_from_snapshot with different size"
This commit is contained in:
commit
1e32adbafa
@ -3298,13 +3298,56 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||||||
self.driver.delete_volume(vol1)
|
self.driver.delete_volume(vol1)
|
||||||
self.driver.delete_snapshot(snap1)
|
self.driver.delete_snapshot(snap1)
|
||||||
|
|
||||||
def test_storwize_svc_create_volfromsnap_clone(self):
|
def test_storwize_svc_create_cloned_volume(self):
|
||||||
|
vol1 = self._create_volume()
|
||||||
|
vol2 = testutils.create_volume(self.ctxt)
|
||||||
|
vol3 = testutils.create_volume(self.ctxt)
|
||||||
|
|
||||||
|
# Try to clone where source size > target size
|
||||||
|
vol1['size'] = vol2['size'] + 1
|
||||||
|
self.assertRaises(exception.InvalidInput,
|
||||||
|
self.driver.create_cloned_volume,
|
||||||
|
vol2, vol1)
|
||||||
|
self._assert_vol_exists(vol2['name'], False)
|
||||||
|
|
||||||
|
# Try to clone where source size = target size
|
||||||
|
vol1['size'] = vol2['size']
|
||||||
|
if self.USESIM:
|
||||||
|
self.sim.error_injection('lsfcmap', 'speed_up')
|
||||||
|
self.driver.create_cloned_volume(vol2, vol1)
|
||||||
|
if self.USESIM:
|
||||||
|
# validate copyrate was set on the flash copy
|
||||||
|
for i, fcmap in self.sim._fcmappings_list.items():
|
||||||
|
if fcmap['target'] == vol1['name']:
|
||||||
|
self.assertEqual('49', fcmap['copyrate'])
|
||||||
|
self._assert_vol_exists(vol2['name'], True)
|
||||||
|
|
||||||
|
# Try to clone where source size < target size
|
||||||
|
vol3['size'] = vol1['size'] + 1
|
||||||
|
if self.USESIM:
|
||||||
|
self.sim.error_injection('lsfcmap', 'speed_up')
|
||||||
|
self.driver.create_cloned_volume(vol3, vol1)
|
||||||
|
if self.USESIM:
|
||||||
|
# Validate copyrate was set on the flash copy
|
||||||
|
for i, fcmap in self.sim._fcmappings_list.items():
|
||||||
|
if fcmap['target'] == vol1['name']:
|
||||||
|
self.assertEqual('49', fcmap['copyrate'])
|
||||||
|
self._assert_vol_exists(vol3['name'], True)
|
||||||
|
|
||||||
|
# Delete in the 'opposite' order to make sure it works
|
||||||
|
self.driver.delete_volume(vol3)
|
||||||
|
self._assert_vol_exists(vol3['name'], False)
|
||||||
|
self.driver.delete_volume(vol2)
|
||||||
|
self._assert_vol_exists(vol2['name'], False)
|
||||||
|
self.driver.delete_volume(vol1)
|
||||||
|
self._assert_vol_exists(vol1['name'], False)
|
||||||
|
|
||||||
|
def test_storwize_svc_create_volume_from_snapshot(self):
|
||||||
vol1 = self._create_volume()
|
vol1 = self._create_volume()
|
||||||
snap1 = self._generate_vol_info(vol1['name'], vol1['id'])
|
snap1 = self._generate_vol_info(vol1['name'], vol1['id'])
|
||||||
self.driver.create_snapshot(snap1)
|
self.driver.create_snapshot(snap1)
|
||||||
vol2 = self._generate_vol_info(None, None)
|
vol2 = self._generate_vol_info(None, None)
|
||||||
vol3 = testutils.create_volume(self.ctxt)
|
vol3 = self._generate_vol_info(None, None)
|
||||||
vol4 = testutils.create_volume(self.ctxt)
|
|
||||||
|
|
||||||
# Try to create a volume from a non-existing snapshot
|
# Try to create a volume from a non-existing snapshot
|
||||||
snap_novol = self._generate_vol_info('undefined-vol', '12345')
|
snap_novol = self._generate_vol_info('undefined-vol', '12345')
|
||||||
@ -3323,54 +3366,29 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
|||||||
vol2, snap1)
|
vol2, snap1)
|
||||||
self._assert_vol_exists(vol2['name'], False)
|
self._assert_vol_exists(vol2['name'], False)
|
||||||
|
|
||||||
# Try to create where source size != target size
|
# Try to create where volume size < snapshot size
|
||||||
vol2['size'] += 1
|
snap1['volume_size'] += 1
|
||||||
self.assertRaises(exception.InvalidInput,
|
self.assertRaises(exception.InvalidInput,
|
||||||
self.driver.create_volume_from_snapshot,
|
self.driver.create_volume_from_snapshot,
|
||||||
vol2, snap1)
|
vol2, snap1)
|
||||||
self._assert_vol_exists(vol2['name'], False)
|
self._assert_vol_exists(vol2['name'], False)
|
||||||
vol2['size'] -= 1
|
snap1['volume_size'] -= 1
|
||||||
|
|
||||||
# Succeed
|
# Try to create where volume size > snapshot size
|
||||||
|
vol2['size'] += 1
|
||||||
if self.USESIM:
|
if self.USESIM:
|
||||||
self.sim.error_injection('lsfcmap', 'speed_up')
|
self.sim.error_injection('lsfcmap', 'speed_up')
|
||||||
self.driver.create_volume_from_snapshot(vol2, snap1)
|
self.driver.create_volume_from_snapshot(vol2, snap1)
|
||||||
self._assert_vol_exists(vol2['name'], True)
|
self._assert_vol_exists(vol2['name'], True)
|
||||||
|
vol2['size'] -= 1
|
||||||
|
|
||||||
# Try to clone where source size > target size
|
# Try to create where volume size = snapshot size
|
||||||
vol2['size'] = vol3['size'] + 1
|
|
||||||
self.assertRaises(exception.InvalidInput,
|
|
||||||
self.driver.create_cloned_volume,
|
|
||||||
vol3, vol2)
|
|
||||||
self._assert_vol_exists(vol3['name'], False)
|
|
||||||
|
|
||||||
# Try to clone where source size = target size
|
|
||||||
vol2['size'] = vol3['size']
|
|
||||||
if self.USESIM:
|
if self.USESIM:
|
||||||
self.sim.error_injection('lsfcmap', 'speed_up')
|
self.sim.error_injection('lsfcmap', 'speed_up')
|
||||||
self.driver.create_cloned_volume(vol3, vol2)
|
self.driver.create_volume_from_snapshot(vol3, snap1)
|
||||||
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(vol3['name'], True)
|
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
|
# 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.driver.delete_volume(vol3)
|
||||||
self._assert_vol_exists(vol3['name'], False)
|
self._assert_vol_exists(vol3['name'], False)
|
||||||
self.driver.delete_volume(vol2)
|
self.driver.delete_volume(vol2)
|
||||||
|
@ -2250,9 +2250,14 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||||||
self._helpers.delete_vdisk(snapshot['name'], False)
|
self._helpers.delete_vdisk(snapshot['name'], False)
|
||||||
|
|
||||||
def create_volume_from_snapshot(self, volume, snapshot):
|
def create_volume_from_snapshot(self, volume, snapshot):
|
||||||
if volume['size'] != snapshot['volume_size']:
|
if snapshot['volume_size'] > volume['size']:
|
||||||
msg = (_('create_volume_from_snapshot: Source and destination '
|
msg = (_("create_volume_from_snapshot: snapshot %(snapshot_name)s "
|
||||||
'size differ.'))
|
"size is %(snapshot_size)dGB and doesn't fit in target "
|
||||||
|
"volume %(volume_name)s of size %(volume_size)dGB.") %
|
||||||
|
{'snapshot_name': snapshot['name'],
|
||||||
|
'snapshot_size': snapshot['volume_size'],
|
||||||
|
'volume_name': volume['name'],
|
||||||
|
'volume_size': volume['size']})
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise exception.InvalidInput(message=msg)
|
raise exception.InvalidInput(message=msg)
|
||||||
|
|
||||||
@ -2263,6 +2268,17 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
|||||||
self._helpers.create_copy(snapshot['name'], volume['name'],
|
self._helpers.create_copy(snapshot['name'], volume['name'],
|
||||||
snapshot['id'], self.configuration,
|
snapshot['id'], self.configuration,
|
||||||
opts, True, pool=pool)
|
opts, True, pool=pool)
|
||||||
|
# The volume size is equal to the snapshot size in most
|
||||||
|
# of the cases. But in some scenario, the volume size
|
||||||
|
# may be bigger than the source volume size.
|
||||||
|
# SVC does not support flashcopy between two volumes
|
||||||
|
# with two different size. So use the snapshot size to
|
||||||
|
# create volume first and then extend the volume to-
|
||||||
|
# the target size.
|
||||||
|
if volume['size'] > snapshot['volume_size']:
|
||||||
|
# extend the new created target volume to expected size.
|
||||||
|
self._extend_volume_op(volume, volume['size'],
|
||||||
|
snapshot['volume_size'])
|
||||||
if opts['qos']:
|
if opts['qos']:
|
||||||
self._helpers.add_vdisk_qos(volume['name'], opts['qos'])
|
self._helpers.add_vdisk_qos(volume['name'], opts['qos'])
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user