Merge "Fujitsu Driver: Improve create snapshot"
This commit is contained in:
commit
0c871f587a
@ -140,6 +140,7 @@ FAKE_LUN_NO1 = '0x0014'
|
||||
# Snapshot1 in pool abcd1234_OSVD
|
||||
FAKE_LUN_ID2 = '600000E00D2A0000002A0115001E0000'
|
||||
FAKE_LUN_NO2 = '0x001E'
|
||||
FAKE_SDV_NO = '0x001E'
|
||||
# Volume2 in pool abcd1234_RG
|
||||
FAKE_LUN_ID3 = '600000E00D2800000028075301140000'
|
||||
FAKE_LUN_NO3 = '0x0114'
|
||||
@ -179,7 +180,7 @@ FAKE_POOLS = [{
|
||||
}]
|
||||
|
||||
FAKE_STATS = {
|
||||
'driver_version': '1.4.4',
|
||||
'driver_version': '1.4.5',
|
||||
'storage_protocol': 'iSCSI',
|
||||
'vendor_name': 'FUJITSU',
|
||||
'QoS_support': True,
|
||||
@ -189,7 +190,7 @@ FAKE_STATS = {
|
||||
'pools': FAKE_POOLS,
|
||||
}
|
||||
FAKE_STATS2 = {
|
||||
'driver_version': '1.4.4',
|
||||
'driver_version': '1.4.5',
|
||||
'storage_protocol': 'FC',
|
||||
'vendor_name': 'FUJITSU',
|
||||
'QoS_support': True,
|
||||
@ -302,7 +303,14 @@ FAKE_LOCATION2 = {
|
||||
'vol_name': 'FJosv_OgEZj1mSvKRvIKOExKktlg=='
|
||||
}
|
||||
|
||||
FAKE_SNAP_META = {
|
||||
'FJ_Pool_Name': 'abcd1234_OSVD',
|
||||
'FJ_SDV_Name': u'FJosv_OgEZj1mSvKRvIKOExKktlg==',
|
||||
'FJ_SDV_No': FAKE_SDV_NO,
|
||||
}
|
||||
|
||||
FAKE_SNAP_INFO = {
|
||||
'metadata': FAKE_SNAP_META,
|
||||
'provider_location': str(FAKE_LOCATION2)
|
||||
}
|
||||
|
||||
@ -1105,6 +1113,10 @@ class FJFCDriverTestCase(test.TestCase):
|
||||
conn = FakeEternusConnection()
|
||||
return conn
|
||||
|
||||
def volume_update(self, volume, diction):
|
||||
for key, value in diction.items():
|
||||
volume[key] = value
|
||||
|
||||
def test_get_volume_stats(self):
|
||||
ret = self.driver.get_volume_stats(True)
|
||||
|
||||
@ -1112,9 +1124,11 @@ class FJFCDriverTestCase(test.TestCase):
|
||||
|
||||
def test_create_and_delete_volume(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
model_info = self.driver.create_volume(TEST_VOLUME2)
|
||||
self.volume_update(TEST_VOLUME2, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO3, model_info)
|
||||
|
||||
self.driver.delete_volume(TEST_VOLUME)
|
||||
@ -1137,6 +1151,7 @@ class FJFCDriverTestCase(test.TestCase):
|
||||
'data': fake_mapdata}
|
||||
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
info = self.driver.initialize_connection(TEST_VOLUME,
|
||||
@ -1157,9 +1172,11 @@ class FJFCDriverTestCase(test.TestCase):
|
||||
|
||||
def test_create_and_delete_snapshot(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
snap_info = self.driver.create_snapshot(TEST_SNAP)
|
||||
self.volume_update(TEST_SNAP, snap_info)
|
||||
self.assertEqual(FAKE_SNAP_INFO, snap_info)
|
||||
|
||||
self.driver.delete_snapshot(TEST_SNAP)
|
||||
@ -1167,13 +1184,16 @@ class FJFCDriverTestCase(test.TestCase):
|
||||
|
||||
def test_create_volume_from_snapshot(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
snap_info = self.driver.create_snapshot(TEST_SNAP)
|
||||
self.volume_update(TEST_SNAP, snap_info)
|
||||
self.assertEqual(FAKE_SNAP_INFO, snap_info)
|
||||
|
||||
model_info = self.driver.create_volume_from_snapshot(TEST_CLONE,
|
||||
TEST_SNAP)
|
||||
self.volume_update(TEST_CLONE, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO2, model_info)
|
||||
|
||||
self.driver.delete_snapshot(TEST_SNAP)
|
||||
@ -1182,9 +1202,11 @@ class FJFCDriverTestCase(test.TestCase):
|
||||
|
||||
def test_create_cloned_volume(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
model_info = self.driver.create_cloned_volume(TEST_CLONE, TEST_VOLUME)
|
||||
self.volume_update(TEST_CLONE, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO2, model_info)
|
||||
|
||||
self.driver.delete_volume(TEST_CLONE)
|
||||
@ -1195,60 +1217,34 @@ class FJFCDriverTestCase(test.TestCase):
|
||||
# ThinProvisioningPool separately.
|
||||
TEST_VOLUME_LIST = [TEST_VOLUME, TEST_VOLUME2]
|
||||
FAKE_MODEL_INFO_LIST = [FAKE_MODEL_INFO1, FAKE_MODEL_INFO3]
|
||||
model_info_list = []
|
||||
for i in range(len(TEST_VOLUME_LIST)):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME_LIST[i])
|
||||
self.volume_update(TEST_VOLUME_LIST[i], model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO_LIST[i], model_info)
|
||||
model_info_list.append(model_info)
|
||||
|
||||
for i in range(len(TEST_VOLUME_LIST)):
|
||||
volume_info = {}
|
||||
for key in TEST_VOLUME_LIST[i]:
|
||||
if key == 'provider_location':
|
||||
volume_info[key] = model_info_list[i][key]
|
||||
elif key == 'metadata':
|
||||
volume_info[key] = model_info_list[i][key]
|
||||
else:
|
||||
volume_info[key] = TEST_VOLUME_LIST[i][key]
|
||||
|
||||
self.driver.extend_volume(volume_info, 10)
|
||||
self.driver.extend_volume(TEST_VOLUME_LIST[i], 10)
|
||||
|
||||
def test_create_volume_with_qos(self):
|
||||
self.driver.common._get_qos_specs = mock.Mock()
|
||||
self.driver.common._get_qos_specs.return_value = {'maxBWS': '700'}
|
||||
self.driver.common._set_qos = mock.Mock()
|
||||
model_info = self.driver.create_volume(TEST_VOLUME_QOS)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO_QOS, model_info)
|
||||
self.driver.common._set_qos.assert_called()
|
||||
|
||||
def test_update_migrated_volume(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
volume_info = {}
|
||||
for key in TEST_VOLUME:
|
||||
if key == 'provider_location':
|
||||
volume_info[key] = model_info[key]
|
||||
elif key == 'metadata':
|
||||
volume_info[key] = model_info[key]
|
||||
else:
|
||||
volume_info[key] = TEST_VOLUME[key]
|
||||
|
||||
model_info2 = self.driver.create_volume(TEST_VOLUME2)
|
||||
self.volume_update(TEST_VOLUME2, model_info2)
|
||||
self.assertEqual(FAKE_MODEL_INFO3, model_info2)
|
||||
|
||||
volume_info2 = {}
|
||||
for key in TEST_VOLUME:
|
||||
if key == 'provider_location':
|
||||
volume_info2[key] = model_info2[key]
|
||||
elif key == 'metadata':
|
||||
volume_info2[key] = model_info2[key]
|
||||
else:
|
||||
volume_info2[key] = TEST_VOLUME2[key]
|
||||
|
||||
model_update = self.driver.update_migrated_volume(self.context,
|
||||
volume_info,
|
||||
volume_info2,
|
||||
TEST_VOLUME,
|
||||
TEST_VOLUME2,
|
||||
'available')
|
||||
|
||||
FAKE_MIGRATED_MODEL_UPDATE = {
|
||||
@ -1405,6 +1401,10 @@ class FJISCSIDriverTestCase(test.TestCase):
|
||||
'target_iqns': ISCSI_TARGET_IQN,
|
||||
'target_lun': 0}
|
||||
|
||||
def volume_update(self, volume, diction):
|
||||
for key, value in diction.items():
|
||||
volume[key] = value
|
||||
|
||||
def test_get_volume_stats(self):
|
||||
ret = self.driver.get_volume_stats(True)
|
||||
|
||||
@ -1412,9 +1412,11 @@ class FJISCSIDriverTestCase(test.TestCase):
|
||||
|
||||
def test_create_and_delete_volume(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
model_info = self.driver.create_volume(TEST_VOLUME2)
|
||||
self.volume_update(TEST_VOLUME2, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO3, model_info)
|
||||
|
||||
self.driver.delete_volume(TEST_VOLUME)
|
||||
@ -1428,6 +1430,7 @@ class FJISCSIDriverTestCase(test.TestCase):
|
||||
'data': fake_mapdata}
|
||||
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
info = self.driver.initialize_connection(TEST_VOLUME,
|
||||
@ -1447,9 +1450,11 @@ class FJISCSIDriverTestCase(test.TestCase):
|
||||
|
||||
def test_create_and_delete_snapshot(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
snap_info = self.driver.create_snapshot(TEST_SNAP)
|
||||
self.volume_update(TEST_SNAP, snap_info)
|
||||
self.assertEqual(FAKE_SNAP_INFO, snap_info)
|
||||
|
||||
self.driver.delete_snapshot(TEST_SNAP)
|
||||
@ -1457,13 +1462,16 @@ class FJISCSIDriverTestCase(test.TestCase):
|
||||
|
||||
def test_create_volume_from_snapshot(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
snap_info = self.driver.create_snapshot(TEST_SNAP)
|
||||
self.volume_update(TEST_SNAP, snap_info)
|
||||
self.assertEqual(FAKE_SNAP_INFO, snap_info)
|
||||
|
||||
model_info = self.driver.create_volume_from_snapshot(TEST_CLONE,
|
||||
TEST_SNAP)
|
||||
self.volume_update(TEST_CLONE, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO2, model_info)
|
||||
|
||||
self.driver.delete_snapshot(TEST_SNAP)
|
||||
@ -1472,9 +1480,11 @@ class FJISCSIDriverTestCase(test.TestCase):
|
||||
|
||||
def test_create_cloned_volume(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
model_info = self.driver.create_cloned_volume(TEST_CLONE, TEST_VOLUME)
|
||||
self.volume_update(TEST_CLONE, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO2, model_info)
|
||||
|
||||
self.driver.delete_volume(TEST_CLONE)
|
||||
@ -1485,60 +1495,34 @@ class FJISCSIDriverTestCase(test.TestCase):
|
||||
# ThinProvisioningPool separately.
|
||||
TEST_VOLUME_LIST = [TEST_VOLUME, TEST_VOLUME2]
|
||||
FAKE_MODEL_INFO_LIST = [FAKE_MODEL_INFO1, FAKE_MODEL_INFO3]
|
||||
model_info_list = []
|
||||
for i in range(len(TEST_VOLUME_LIST)):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME_LIST[i])
|
||||
self.volume_update(TEST_VOLUME_LIST[i], model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO_LIST[i], model_info)
|
||||
model_info_list.append(model_info)
|
||||
|
||||
for i in range(len(TEST_VOLUME_LIST)):
|
||||
volume_info = {}
|
||||
for key in TEST_VOLUME_LIST[i]:
|
||||
if key == 'provider_location':
|
||||
volume_info[key] = model_info_list[i][key]
|
||||
elif key == 'metadata':
|
||||
volume_info[key] = model_info_list[i][key]
|
||||
else:
|
||||
volume_info[key] = TEST_VOLUME_LIST[i][key]
|
||||
|
||||
self.driver.extend_volume(volume_info, 10)
|
||||
self.driver.extend_volume(TEST_VOLUME_LIST[i], 10)
|
||||
|
||||
def test_create_volume_with_qos(self):
|
||||
self.driver.common._get_qos_specs = mock.Mock()
|
||||
self.driver.common._get_qos_specs.return_value = {'maxBWS': '700'}
|
||||
self.driver.common._set_qos = mock.Mock()
|
||||
model_info = self.driver.create_volume(TEST_VOLUME_QOS)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO_QOS, model_info)
|
||||
self.driver.common._set_qos.assert_called()
|
||||
|
||||
def test_update_migrated_volume(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
volume_info = {}
|
||||
for key in TEST_VOLUME:
|
||||
if key == 'provider_location':
|
||||
volume_info[key] = model_info[key]
|
||||
elif key == 'metadata':
|
||||
volume_info[key] = model_info[key]
|
||||
else:
|
||||
volume_info[key] = TEST_VOLUME[key]
|
||||
|
||||
model_info2 = self.driver.create_volume(TEST_VOLUME2)
|
||||
self.volume_update(TEST_VOLUME2, model_info2)
|
||||
self.assertEqual(FAKE_MODEL_INFO3, model_info2)
|
||||
|
||||
volume_info2 = {}
|
||||
for key in TEST_VOLUME:
|
||||
if key == 'provider_location':
|
||||
volume_info2[key] = model_info2[key]
|
||||
elif key == 'metadata':
|
||||
volume_info2[key] = model_info2[key]
|
||||
else:
|
||||
volume_info2[key] = TEST_VOLUME2[key]
|
||||
|
||||
model_update = self.driver.update_migrated_volume(self.context,
|
||||
volume_info,
|
||||
volume_info2,
|
||||
TEST_VOLUME,
|
||||
TEST_VOLUME2,
|
||||
'available')
|
||||
|
||||
FAKE_MIGRATED_MODEL_UPDATE = {
|
||||
@ -1919,13 +1903,21 @@ class FJCommonTestCase(test.TestCase):
|
||||
volume_no = self.driver.common._get_volume_number(vol_instance)
|
||||
self.assertEqual(FAKE_LUN_NO1, volume_no)
|
||||
|
||||
def volume_update(self, volume, diction):
|
||||
for key, value in diction.items():
|
||||
volume[key] = value
|
||||
|
||||
def test_get_eternus_model(self):
|
||||
ETERNUS_MODEL = self.driver.common._get_eternus_model()
|
||||
self.assertEqual(3, ETERNUS_MODEL)
|
||||
|
||||
def test_get_matadata(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
TEST_METADATA = self.driver.common.get_metadata(TEST_VOLUME)
|
||||
self.assertEqual({}, TEST_METADATA)
|
||||
self.assertEqual(FAKE_LUN_META1, TEST_METADATA)
|
||||
|
||||
def test_is_qos_or_format_support(self):
|
||||
QOS_SUPPORT = \
|
||||
@ -2016,35 +2008,29 @@ class FJCommonTestCase(test.TestCase):
|
||||
|
||||
def test_update_migrated_volume(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
volume_info = {}
|
||||
for key in TEST_VOLUME:
|
||||
if key == 'provider_location':
|
||||
volume_info[key] = model_info[key]
|
||||
elif key == 'metadata':
|
||||
volume_info[key] = model_info[key]
|
||||
else:
|
||||
volume_info[key] = TEST_VOLUME[key]
|
||||
|
||||
model_info2 = self.driver.create_volume(TEST_VOLUME2)
|
||||
self.volume_update(TEST_VOLUME2, model_info2)
|
||||
self.assertEqual(FAKE_MODEL_INFO3, model_info2)
|
||||
|
||||
volume_info2 = {}
|
||||
for key in TEST_VOLUME:
|
||||
if key == 'provider_location':
|
||||
volume_info2[key] = model_info2[key]
|
||||
elif key == 'metadata':
|
||||
volume_info2[key] = model_info2[key]
|
||||
else:
|
||||
volume_info2[key] = TEST_VOLUME2[key]
|
||||
|
||||
model_update = self.driver.common.update_migrated_volume(self.context,
|
||||
volume_info,
|
||||
volume_info2)
|
||||
TEST_VOLUME,
|
||||
TEST_VOLUME2)
|
||||
|
||||
FAKE_MIGRATED_MODEL_UPDATE = {
|
||||
'_name_id': TEST_VOLUME2['id'],
|
||||
'provider_location': model_info2['provider_location']
|
||||
}
|
||||
self.assertEqual(FAKE_MIGRATED_MODEL_UPDATE, model_update)
|
||||
|
||||
def test_create_snapshot(self):
|
||||
model_info = self.driver.create_volume(TEST_VOLUME)
|
||||
self.volume_update(TEST_VOLUME, model_info)
|
||||
self.assertEqual(FAKE_MODEL_INFO1, model_info)
|
||||
|
||||
snap_info = self.driver.common._create_snapshot(TEST_SNAP)
|
||||
self.assertEqual(FAKE_SNAP_INFO, snap_info)
|
||||
|
||||
self.driver.delete_volume(TEST_VOLUME)
|
||||
|
@ -70,10 +70,11 @@ class FJDXCommon(object):
|
||||
1.4.2 - Add the secondary check for copy-sessions when deleting volumes.
|
||||
1.4.3 - Add fragment capacity information of RAID Group.
|
||||
1.4.4 - Add support for update migrated volume.
|
||||
1.4.5 - Add metadata for snapshot.
|
||||
|
||||
"""
|
||||
|
||||
VERSION = "1.4.4"
|
||||
VERSION = "1.4.5"
|
||||
stats = {
|
||||
'driver_version': VERSION,
|
||||
'storage_protocol': None,
|
||||
@ -636,24 +637,18 @@ class FJDXCommon(object):
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
@lockutils.synchronized('ETERNUS-vol', 'cinder-', True)
|
||||
def create_snapshot(self, snapshot):
|
||||
"""Create snapshot using SnapOPC."""
|
||||
LOG.debug('create_snapshot, '
|
||||
'snapshot id: %(sid)s, volume id: %(vid)s.',
|
||||
{'sid': snapshot['id'], 'vid': snapshot['volume_id']})
|
||||
|
||||
self.conn = self._get_eternus_connection()
|
||||
snapshotname = snapshot['name']
|
||||
volumename = snapshot['volume_name']
|
||||
volume = snapshot['volume']
|
||||
d_volumename = self._get_volume_name(snapshot, use_id=True)
|
||||
s_volumename = self._get_volume_name(volume)
|
||||
vol_instance = self._find_lun(volume)
|
||||
repservice = self._find_eternus_service(CONSTANTS.REPL)
|
||||
|
||||
# Check the existence of volume.
|
||||
if vol_instance is None:
|
||||
if not vol_instance:
|
||||
# Volume not found on ETERNUS.
|
||||
msg = (_('create_snapshot, '
|
||||
'volumename: %(s_volumename)s, '
|
||||
@ -662,7 +657,37 @@ class FJDXCommon(object):
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
if repservice is None:
|
||||
model_update = self._create_snapshot(snapshot)
|
||||
|
||||
return model_update
|
||||
|
||||
@lockutils.synchronized('ETERNUS-vol', 'cinder-', True)
|
||||
def _create_snapshot(self, snapshot):
|
||||
|
||||
LOG.debug('create_snapshot, '
|
||||
'snapshot id: %(sid)s, volume id: %(vid)s.',
|
||||
{'sid': snapshot['id'], 'vid': snapshot['volume_id']})
|
||||
|
||||
self.conn = self._get_eternus_connection()
|
||||
snapshotname = snapshot['name']
|
||||
volume = snapshot['volume']
|
||||
volumename = snapshot['volume_name']
|
||||
d_volumename = self._get_volume_name(snapshot, use_id=True)
|
||||
s_volumename = self._get_volume_name(volume)
|
||||
vol_instance = self._find_lun(volume)
|
||||
smis_service = self._find_eternus_service(CONSTANTS.REPL)
|
||||
|
||||
# Check the existence of volume.
|
||||
if not vol_instance:
|
||||
# Volume not found on ETERNUS.
|
||||
msg = (_('create_snapshot, '
|
||||
'volumename: %(s_volumename)s, '
|
||||
'source volume not found on ETERNUS.')
|
||||
% {'s_volumename': s_volumename})
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
if not smis_service:
|
||||
msg = (_('create_snapshot, '
|
||||
'volumename: %(volumename)s, '
|
||||
'Replication Service not found.')
|
||||
@ -674,7 +699,7 @@ class FJDXCommon(object):
|
||||
eternus_pool = self._get_drvcfg('EternusSnapPool')
|
||||
# Check the existence of pool
|
||||
pool = self._find_pool(eternus_pool)
|
||||
if pool is None:
|
||||
if not pool:
|
||||
msg = (_('create_snapshot, '
|
||||
'eternus_pool: %(eternus_pool)s, '
|
||||
'pool not found.')
|
||||
@ -695,14 +720,26 @@ class FJDXCommon(object):
|
||||
'd_volumename': d_volumename,
|
||||
'pool': pool})
|
||||
|
||||
if self.model_name != CONSTANTS.DX_S2:
|
||||
smis_method = 'CreateElementReplica'
|
||||
params = {
|
||||
'ElementName': d_volumename,
|
||||
'TargetPool': pool,
|
||||
'SyncType': self._pywbem_uint(7, '16'),
|
||||
'SourceElement': vol_instance.path
|
||||
}
|
||||
else:
|
||||
smis_method = 'CreateReplica'
|
||||
params = {
|
||||
'ElementName': d_volumename,
|
||||
'TargetPool': pool,
|
||||
'CopyType': self._pywbem_uint(4, '16'),
|
||||
'SourceElement': vol_instance.path
|
||||
}
|
||||
# Invoke method for create snapshot
|
||||
rc, errordesc, job = self._exec_eternus_service(
|
||||
'CreateElementReplica',
|
||||
repservice,
|
||||
ElementName=d_volumename,
|
||||
TargetPool=pool,
|
||||
SyncType=self._pywbem_uint(7, '16'),
|
||||
SourceElement=vol_instance.path)
|
||||
smis_method, smis_service,
|
||||
**params)
|
||||
|
||||
if rc != 0:
|
||||
msg = (_('create_snapshot, '
|
||||
@ -724,6 +761,7 @@ class FJDXCommon(object):
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
else:
|
||||
element = job['TargetElement']
|
||||
d_volume_no = self._get_volume_number(element)
|
||||
|
||||
LOG.debug('create_snapshot, '
|
||||
'volumename:%(volumename)s, '
|
||||
@ -743,11 +781,17 @@ class FJDXCommon(object):
|
||||
'vol_name': d_volumename,
|
||||
}
|
||||
|
||||
sdv_no = self._get_volume_number(element)
|
||||
metadata = {'FJ_SDV_Name': d_volumename,
|
||||
'FJ_SDV_No': sdv_no,
|
||||
'FJ_SDV_No': d_volume_no,
|
||||
'FJ_Pool_Name': eternus_pool}
|
||||
return (element_path, metadata)
|
||||
d_metadata = self.get_metadata(snapshot)
|
||||
d_metadata.update(metadata)
|
||||
|
||||
model_update = {
|
||||
'provider_location': str(element_path),
|
||||
'metadata': d_metadata,
|
||||
}
|
||||
return model_update
|
||||
|
||||
def delete_snapshot(self, snapshot):
|
||||
"""Delete snapshot."""
|
||||
@ -1197,7 +1241,7 @@ class FJDXCommon(object):
|
||||
else:
|
||||
ret = []
|
||||
for e in elem.findall(".//" + tagname):
|
||||
if (e.text is not None) and (e.text not in ret):
|
||||
if e.text and (e.text not in ret):
|
||||
ret.append(e.text)
|
||||
|
||||
if not ret:
|
||||
@ -1250,8 +1294,7 @@ class FJDXCommon(object):
|
||||
"""Get volume_name on ETERNUS from volume on OpenStack."""
|
||||
LOG.debug('_get_volume_name, volume_id: %s.', volume['id'])
|
||||
|
||||
if (not use_id and 'provider_location' in volume and
|
||||
volume['provider_location']):
|
||||
if not use_id and volume['provider_location']:
|
||||
location = eval(volume['provider_location'])
|
||||
if 'vol_name' in location:
|
||||
LOG.debug('_get_volume_name, by provider_location, '
|
||||
@ -1609,7 +1652,7 @@ class FJDXCommon(object):
|
||||
|
||||
@lockutils.synchronized('ETERNUS-SMIS-getinstance', 'cinder-', True)
|
||||
@utils.retry(exception.VolumeBackendAPIException)
|
||||
def _get_eternus_instance(self, classname, allownone=False, **param_dict):
|
||||
def _get_eternus_instance(self, classname, AllowNone=False, **param_dict):
|
||||
"""Get Instance."""
|
||||
LOG.debug('_get_eternus_instance, '
|
||||
'classname: %(cls)s, param: %(param)s.',
|
||||
@ -1619,7 +1662,7 @@ class FJDXCommon(object):
|
||||
try:
|
||||
ret = self.conn.GetInstance(classname, **param_dict)
|
||||
except Exception as e:
|
||||
if e.args[0] == 6 and allownone:
|
||||
if e.args[0] == 6 and AllowNone:
|
||||
return ret
|
||||
else:
|
||||
msg = _('_get_eternus_instance, Error:%s.') % e
|
||||
@ -1703,6 +1746,7 @@ class FJDXCommon(object):
|
||||
location = eval(volume['provider_location'])
|
||||
classname = location['classname']
|
||||
bindings = location['keybindings']
|
||||
isSuccess = True
|
||||
|
||||
if classname and bindings:
|
||||
LOG.debug('_find_lun, '
|
||||
@ -1718,17 +1762,17 @@ class FJDXCommon(object):
|
||||
{'volume_instance_name': volume_instance_name})
|
||||
|
||||
vol_instance = self._get_eternus_instance(volume_instance_name,
|
||||
allownone=True,)
|
||||
AllowNone=True)
|
||||
|
||||
if vol_instance and vol_instance['ElementName'] == volumename:
|
||||
volumeinstance = vol_instance
|
||||
except Exception:
|
||||
volumeinstance = None
|
||||
isSuccess = False
|
||||
LOG.debug('_find_lun, '
|
||||
'Cannot get volume instance from provider location, '
|
||||
'Search all volume using EnumerateInstanceNames.')
|
||||
|
||||
if not volumeinstance:
|
||||
if not isSuccess and self.model_name == CONSTANTS.DX_S2:
|
||||
# For old version.
|
||||
LOG.debug('_find_lun, '
|
||||
'volumename: %(volumename)s.',
|
||||
|
@ -97,9 +97,15 @@ class FJDXFCDriver(driver.FibreChannelDriver):
|
||||
|
||||
def create_snapshot(self, snapshot):
|
||||
"""Creates a snapshot."""
|
||||
location, metadata = self.common.create_snapshot(snapshot)
|
||||
LOG.debug('create_snapshot, '
|
||||
'snap id: %(sid)s, volume id: %(vid)s, Enter method.',
|
||||
{'sid': snapshot['id'], 'vid': snapshot['volume_id']})
|
||||
|
||||
return {'provider_location': str(location)}
|
||||
model_update = self.common.create_snapshot(snapshot)
|
||||
|
||||
LOG.debug('create_snapshot, info: %s, Exit method.',
|
||||
model_update['metadata'])
|
||||
return model_update
|
||||
|
||||
def delete_snapshot(self, snapshot):
|
||||
"""Deletes a snapshot."""
|
||||
|
@ -104,9 +104,15 @@ class FJDXISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
def create_snapshot(self, snapshot):
|
||||
"""Creates a snapshot."""
|
||||
element_path, metadata = self.common.create_snapshot(snapshot)
|
||||
LOG.debug('create_snapshot, '
|
||||
'snap id: %(sid)s, volume id: %(vid)s, Enter method.',
|
||||
{'sid': snapshot['id'], 'vid': snapshot['volume_id']})
|
||||
|
||||
return {'provider_location': str(element_path)}
|
||||
model_update = self.common.create_snapshot(snapshot)
|
||||
|
||||
LOG.debug('create_snapshot, info: %s, Exit method.',
|
||||
model_update['metadata'])
|
||||
return model_update
|
||||
|
||||
def delete_snapshot(self, snapshot):
|
||||
"""Deletes a snapshot."""
|
||||
|
@ -0,0 +1,13 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Fujitsu ETERNUS DX driver: Add metadata to snapshot
|
||||
|
||||
After the snapshot is created, upload the information of the snapshot on
|
||||
the storage to the metadata.
|
||||
|
||||
The metadata has the following information:
|
||||
|
||||
- ``FJ_SDV_Name``
|
||||
- ``FJ_SDV_No``
|
||||
- ``FJ_Pool_Name``
|
Loading…
Reference in New Issue
Block a user