Check flashcopy mapping before deleting volume

Check the flashcopy mapping relationship before deleting volume.
Currently the volume stays in 'deleting' if there is fcmapping
for IBM storwize/SVC driver. Change it to stop the fcmapping
first if the volume is the target volume of the fcmapping.

DocImpact
Change-Id: I99fdbbeda4151d4e02ebd6a0ede9a49eb2abc618
Closes-Bug: 1534118
This commit is contained in:
Xiaoqin Li 2016-01-16 10:53:15 -08:00 committed by xiaoqin
parent 5097a9eff5
commit a2bac00c50
3 changed files with 64 additions and 6 deletions

View File

@ -3409,6 +3409,50 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
self.driver.delete_volume(vol1)
self._assert_vol_exists(vol1['name'], False)
def test_storwize_svc_delete_vol_with_fcmap(self):
vol1 = self._create_volume()
# create two snapshots
snap1 = self._generate_vol_info(vol1['name'], vol1['id'])
snap2 = self._generate_vol_info(vol1['name'], vol1['id'])
self.driver.create_snapshot(snap1)
self.driver.create_snapshot(snap2)
vol2 = self._generate_vol_info(None, None)
vol3 = self._generate_vol_info(None, None)
# Create vol from the second snapshot
if self.USESIM:
self.sim.error_injection('lsfcmap', 'speed_up')
self.driver.create_volume_from_snapshot(vol2, snap2)
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('copying', fcmap['status'])
self._assert_vol_exists(vol2['name'], True)
if self.USESIM:
self.sim.error_injection('lsfcmap', 'speed_up')
self.driver.create_cloned_volume(vol3, vol2)
if self.USESIM:
# validate copyrate was set on the flash copy
for i, fcmap in self.sim._fcmappings_list.items():
if fcmap['target'] == vol3['name']:
self.assertEqual('copying', fcmap['status'])
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_snapshot(snap2)
self._assert_vol_exists(snap2['name'], False)
self.driver.delete_snapshot(snap1)
self._assert_vol_exists(snap1['name'], False)
self.driver.delete_volume(vol1)
self._assert_vol_exists(vol1['name'], False)
def test_storwize_svc_volumes(self):
# Create a first volume
volume = self._generate_vol_info(None, None)

View File

@ -1419,7 +1419,8 @@ class StorwizeHelpers(object):
return None
return resp[0]
def _check_vdisk_fc_mappings(self, name, allow_snaps=True):
def _check_vdisk_fc_mappings(self, name,
allow_snaps=True, allow_fctgt=False):
"""FlashCopy mapping check helper."""
LOG.debug('Loopcall: _check_vdisk_fc_mappings(), vdisk %s.', name)
mapping_ids = self._get_vdisk_fc_mappings(name)
@ -1433,6 +1434,12 @@ class StorwizeHelpers(object):
copy_rate = attrs['copy_rate']
status = attrs['status']
if allow_fctgt and target == name and status == 'copying':
self.ssh.stopfcmap(map_id)
attrs = self._get_flashcopy_mapping_attributes(map_id)
if attrs:
status = attrs['status']
if copy_rate == '0':
if source == name:
# Vdisk with snapshots. Return False if snapshot
@ -1463,18 +1470,20 @@ class StorwizeHelpers(object):
if status == 'prepared':
self.ssh.stopfcmap(map_id)
self.ssh.rmfcmap(map_id)
elif status == 'idle_or_copied':
# Prepare failed
elif status in ['idle_or_copied', 'stopped']:
# Prepare failed or stopped
self.ssh.rmfcmap(map_id)
else:
wait_for_copy = True
if not wait_for_copy or not len(mapping_ids):
raise loopingcall.LoopingCallDone(retvalue=True)
def ensure_vdisk_no_fc_mappings(self, name, allow_snaps=True):
def ensure_vdisk_no_fc_mappings(self, name, allow_snaps=True,
allow_fctgt=False):
"""Ensure vdisk has no flashcopy mappings."""
timer = loopingcall.FixedIntervalLoopingCall(
self._check_vdisk_fc_mappings, name, allow_snaps)
self._check_vdisk_fc_mappings, name,
allow_snaps, allow_fctgt)
# Create a timer greenthread. The default volume service heart
# beat is every 10 seconds. The flashcopy usually takes hours
# before it finishes. Don't set the sleep interval shorter
@ -1558,7 +1567,8 @@ class StorwizeHelpers(object):
if not self.is_vdisk_defined(vdisk):
LOG.info(_LI('Tried to delete non-existent vdisk %s.'), vdisk)
return
self.ensure_vdisk_no_fc_mappings(vdisk)
self.ensure_vdisk_no_fc_mappings(vdisk, allow_snaps=True,
allow_fctgt=True)
self.ssh.rmvdisk(vdisk, force=force)
LOG.debug('Leave: delete_vdisk: vdisk %s.', vdisk)

View File

@ -0,0 +1,4 @@
---
fixes:
- Fixed StorWize/SVC error causing volume deletion to get
stuck in the 'deleting' state when using FlashCopy.