NEC Driver: Support revert to snapshot

Adding support to revert a volume to a snapshot in NEC driver.
This patch implements revert_to_snapshot().

This patch also deletes unused classes(class UnpairWaitForBackup,
class UnpairWaitForDDRBackup).

Change-Id: I1bf5bd3856009e92921cbbd7f91734e070d5e86f
This commit is contained in:
Naoki Saito 2019-08-07 17:33:08 +09:00
parent d229aa3cb1
commit a6f4caabd3
7 changed files with 168 additions and 22 deletions

View File

@ -16,6 +16,7 @@
import ddt
import mock
import time
from cinder import context
from cinder import exception
@ -1439,3 +1440,62 @@ class ManageUnmanage_Snap_test(volume_helper.MStorageDSVDriver, test.TestCase):
newsnap,
snaps[0]['reference'])
self.assertEqual(6, size_in_gb)
class RevertToSnapshotTestCase(volume_helper.MStorageDSVDriver, test.TestCase):
def setUp(self):
super(RevertToSnapshotTestCase, self).setUp()
self._set_config(conf.Configuration(None), 'dummy', 'dummy')
self.do_setup(None)
self.mock_object(self._cli, 'view_all', return_value=xml_out)
def test_revert_to_snapshot(self):
vol = DummyVolume("1febb976-86d0-42ed-9bc0-4aa3e158f27d")
snap = DummySnapshot("63410c76-2f12-4473-873d-74a63dfcd3e2")
self.mock_object(time, 'sleep')
self.mock_object(self._cli, '_execute',
return_value=('success', 0, 0))
self.mock_object(self._cli, 'query_BV_SV_status',
return_value='snap/active')
self.revert_to_snapshot(None, vol, snap)
self._cli._execute.assert_called_once_with(
'iSMsc_restore -bv yEUHrXa5AHMjOZZLb93eP -bvflg ld '
'-sv 31HxzqBiAFTUxxOlcVn3EA -svflg ld -derivsv keep -nowait')
vol.id = constants.VOLUME_ID
with self.assertRaisesRegex(exception.NotFound,
'Logical Disk `LX:vD03hJCiHvGpvP4iSevKk` '
'has unbound already.'):
self.revert_to_snapshot(None, vol, snap)
vol.id = '1febb976-86d0-42ed-9bc0-4aa3e158f27d'
snap.id = constants.SNAPSHOT_ID
with self.assertRaisesRegex(exception.NotFound,
'Logical Disk `LX:18FkaTGqa43xSFL8aX4A2N` '
'has unbound already.'):
self.revert_to_snapshot(None, vol, snap)
snap.id = '63410c76-2f12-4473-873d-74a63dfcd3e2'
self.mock_object(self._cli, 'query_BV_SV_status',
return_value='rst/exec')
with self.assertRaisesRegex(exception.VolumeBackendAPIException,
'The snapshot does not exist or is '
'not in snap/active status. '
'bvname=LX:yEUHrXa5AHMjOZZLb93eP, '
'svname=LX:31HxzqBiAFTUxxOlcVn3EA, '
'status=rst/exec'):
self.revert_to_snapshot(None, vol, snap)
return_status = ['snap/active', 'rst/exec', 'snap/active']
self.mock_object(self._cli, 'query_BV_SV_status',
side_effect=return_status)
self.revert_to_snapshot(None, vol, snap)
return_status = ['snap/active', 'rst/exec', 'snap/fault']
self.mock_object(self._cli, 'query_BV_SV_status',
side_effect=return_status)
with self.assertRaisesRegex(exception.VolumeBackendAPIException,
'Failed to restore from snapshot. '
'bvname=LX:yEUHrXa5AHMjOZZLb93eP, '
'svname=LX:31HxzqBiAFTUxxOlcVn3EA, '
'status=snap/fault'):
self.revert_to_snapshot(None, vol, snap)

View File

@ -584,6 +584,46 @@ class MStorageISMCLI(object):
cmd = 'iSMcfg generationdel -bvname %s -count 1' % bvname
self._execute(cmd)
def snapshot_restore(self, bvname, svname):
"""Snapshot restore."""
query_status = self.query_BV_SV_status(bvname[3:], svname[3:])
if query_status == 'snap/active':
cmd = ('iSMsc_restore -bv %(bv)s -bvflg ld -sv %(sv)s '
'-svflg ld -derivsv keep -nowait'
% {'bv': bvname[3:], 'sv': svname[3:]})
self._execute(cmd)
retry_count = 0
while True:
query_status = self.query_BV_SV_status(bvname[3:], svname[3:])
if query_status == 'rst/exec':
# Restoration is in progress.
sleep_time = get_sleep_time_for_clone(retry_count)
LOG.debug('Sleep %d seconds Start', sleep_time)
time.sleep(sleep_time)
retry_count += 1
elif query_status == 'snap/active':
# Restoration was successful.
break
else:
# Restoration failed.
msg = (_('Failed to restore from snapshot. '
'bvname=%(bvname)s, svname=%(svname)s, '
'status=%(status)s') %
{'bvname': bvname, 'svname': svname,
'status': query_status})
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
else:
msg = (_('The snapshot does not exist or is '
'not in snap/active status. '
'bvname=%(bvname)s, svname=%(svname)s, '
'status=%(status)s') %
{'bvname': bvname, 'svname': svname,
'status': query_status})
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
def query_BV_SV_status(self, bvname, svname):
cmd = ('iSMsc_query -bv %(bv)s -bvflg ld -sv %(sv)s -svflg ld '
'-summary | '
@ -593,7 +633,12 @@ class MStorageISMCLI(object):
% {'bv': bvname, 'sv': svname, 'line': svname})
out, err, status = self._execute(cmd)
query_status = out[34:48].strip()
delimiter = ') '
start = out.find(delimiter)
if start == -1:
return None
start += len(delimiter)
query_status = out[start:].split(' ')[0]
LOG.debug('snap/state:%s.', query_status)
return query_status
@ -729,16 +774,6 @@ class UnpairWait(object):
pass
class UnpairWaitForBackup(UnpairWait):
def __init__(self, volume_properties, cli):
super(UnpairWaitForBackup, self).__init__(volume_properties, cli)
def _execute(self):
LOG.debug('UnpairWaitForBackup start.')
self._wait(True)
class UnpairWaitForRestore(UnpairWait):
def __init__(self, volume_properties, cli):
super(UnpairWaitForRestore, self).__init__(volume_properties, cli)
@ -815,16 +850,6 @@ class UnpairWaitForMigrate(UnpairWait):
self._volume_properties['rvname'])
class UnpairWaitForDDRBackup(UnpairWaitForBackup):
def __init__(self, volume_properties, cli):
super(UnpairWaitForDDRBackup, self).__init__(volume_properties, cli)
def _execute(self):
LOG.debug('UnpairWaitForDDRBackup start.')
self._wait(False)
class UnpairWaitForDDRRestore(UnpairWaitForRestore):
def __init__(self, volume_properties, cli):
super(UnpairWaitForDDRRestore, self).__init__(volume_properties, cli)

View File

@ -50,6 +50,7 @@ class MStorageISCSIDriver(volume_helper.MStorageDSVDriver,
1.11.1 - Add support pytyon 3.
Add support for multi-attach.
Add support of more than 4 iSCSI portals for a node.
Add support to revert a volume to a snapshot.
"""
VERSION = '1.11.1'
@ -114,6 +115,7 @@ class MStorageFCDriver(volume_helper.MStorageDSVDriver,
1.11.1 - Add support pytyon 3.
Add support for multi-attach.
Add support of more than 4 iSCSI portals for a node.
Add support to revert a volume to a snapshot.
"""
VERSION = '1.11.1'

View File

@ -1825,3 +1825,55 @@ class MStorageDSVDriver(MStorageDriver):
'snap_id': snapshot.id,
'snapvol_id': snapshot.volume_id,
'specs': specs})
def revert_to_snapshot(self, context, volume, snapshot):
"""called to perform revert volume from snapshot.
:param context: Our working context.
:param volume: the volume to be reverted.
:param snapshot: the snapshot data revert to volume.
:return None
"""
msgparm = ('Volume ID = %(vol_id)s, '
'Snapshot ID = %(snap_id)s, '
'Snapshot Volume ID = %(snapvol_id)s'
% {'vol_id': volume.id,
'snap_id': snapshot.id,
'snapvol_id': snapshot.volume_id})
try:
self._revert_to_snapshot(context, volume, snapshot)
LOG.info('Reverted to Snapshot (%s)', msgparm)
except exception.CinderException as e:
with excutils.save_and_reraise_exception():
LOG.warning('Failed to revert to Snapshot '
'(%(msgparm)s) (%(exception)s)',
{'msgparm': msgparm, 'exception': e})
def _revert_to_snapshot(self, context, volume, snapshot):
LOG.debug('_revert_to_snapshot (Volume ID = %(vol_id)s, '
'Snapshot ID = %(snap_id)s) Start.',
{'vol_id': volume.id, 'snap_id': snapshot.id})
xml = self._cli.view_all(self._properties['ismview_path'])
pools, lds, ldsets, used_ldns, hostports, max_ld_count = (
self.configs(xml))
# get BV name.
bvname = (
self.get_ldname(volume.id,
self._properties['ld_name_format']))
if bvname not in lds:
msg = _('Logical Disk `%s` has unbound already.') % bvname
LOG.error(msg)
raise exception.NotFound(msg)
# get SV name.
svname = (
self.get_ldname(snapshot.id,
self._properties['ld_backupname_format']))
if svname not in lds:
msg = _('Logical Disk `%s` has unbound already.') % svname
LOG.error(msg)
raise exception.NotFound(msg)
self._cli.snapshot_restore(bvname, svname)
LOG.debug('_revert_to_snapshot(Volume ID = %s) End.', volume.id)

View File

@ -53,6 +53,8 @@ Supported operations
- Manage and unmanage a volume.
- Manage and unmanage a snapshot.
- Attach a volume to multiple instances at once (multi-attach).
- Revert a volume to a snapshot.
Preparation
~~~~~~~~~~~

View File

@ -852,7 +852,7 @@ driver.lenovo=missing
driver.linbit_linstor=missing
driver.lvm=complete
driver.macrosan=missing
driver.nec=missing
driver.nec=complete
driver.netapp_ontap=missing
driver.netapp_solidfire=complete
driver.nexenta=missing

View File

@ -0,0 +1,5 @@
---
features:
- |
NEC Driver: Added support to revert a volume to a snapshot.