Storwize: add data reduction pool support
Data reduction pool is a new style pool on Storwize/SVC storage. Thin provisioned/compressed vdisk copies created in a data_reduction pool are quite different from regular pool. This patch adds thin-provision and compressed volumes support on data reduction pool. Change-Id: Icb09cbacc3cfe63017d17847799c0904e06cf8a7 Implements: blueprint svc-drpool-support
This commit is contained in:
parent
4b96310411
commit
822fb701de
@ -538,7 +538,8 @@ class StorwizeSVCManagementSimulator(object):
|
||||
'vdisk_count', 'capacity', 'extent_size',
|
||||
'free_capacity', 'virtual_capacity', 'used_capacity',
|
||||
'real_capacity', 'overallocation', 'warning',
|
||||
'easy_tier', 'easy_tier_status', 'site_id'])
|
||||
'easy_tier', 'easy_tier_status', 'site_id',
|
||||
'data_reduction'])
|
||||
for i in range(pool_num):
|
||||
row_data = [str(i + 1),
|
||||
self._flags['storwize_svc_volpool_name'][i], 'online',
|
||||
@ -546,24 +547,32 @@ class StorwizeSVCManagementSimulator(object):
|
||||
'3573412790272', '256', '3529926246400',
|
||||
'1693247906775',
|
||||
'26843545600', '38203734097', '47', '80', 'auto',
|
||||
'inactive', '']
|
||||
'inactive', '', 'no']
|
||||
rows.append(row_data)
|
||||
rows.append([str(pool_num + 1), 'openstack2', 'online',
|
||||
'1', '0', '3573412790272', '256',
|
||||
'3529432325160', '1693247906775', '26843545600',
|
||||
'38203734097', '47', '80', 'auto', 'inactive', ''])
|
||||
'38203734097', '47', '80', 'auto', 'inactive', '', 'no'])
|
||||
rows.append([str(pool_num + 2), 'openstack3', 'offline',
|
||||
'1', '0', '3573412790272', '128',
|
||||
'3529432325160', '1693247906775', '26843545600',
|
||||
'38203734097', '47', '80', 'auto', 'inactive', ''])
|
||||
'38203734097', '47', '80', 'auto', 'inactive', '', 'yes'])
|
||||
rows.append([str(pool_num + 3), 'hyperswap1', 'online',
|
||||
'1', '0', '3573412790272', '256',
|
||||
'3529432325160', '1693247906775', '26843545600',
|
||||
'38203734097', '47', '80', 'auto', 'inactive', '1'])
|
||||
'38203734097', '47', '80', 'auto', 'inactive', '1', 'no'])
|
||||
rows.append([str(pool_num + 4), 'hyperswap2', 'online',
|
||||
'1', '0', '3573412790272', '128',
|
||||
'3529432325160', '1693247906775', '26843545600',
|
||||
'38203734097', '47', '80', 'auto', 'inactive', '2'])
|
||||
'38203734097', '47', '80', 'auto', 'inactive', '2', 'no'])
|
||||
rows.append([str(pool_num + 5), 'dr_pool1', 'online',
|
||||
'1', '0', '3573412790272', '128', '3529432325160',
|
||||
'1693247906775', '26843545600', '38203734097', '47', '80',
|
||||
'auto', 'inactive', '1', 'yes'])
|
||||
rows.append([str(pool_num + 6), 'dr_pool2', 'online',
|
||||
'1', '0', '3573412790272', '128', '3529432325160',
|
||||
'1693247906775', '26843545600', '38203734097', '47', '80',
|
||||
'auto', 'inactive', '2', 'yes'])
|
||||
if 'obj' not in kwargs:
|
||||
return self._print_info_cmd(rows=rows, **kwargs)
|
||||
else:
|
||||
@ -577,12 +586,16 @@ class StorwizeSVCManagementSimulator(object):
|
||||
row = each_row
|
||||
break
|
||||
elif pool_name == 'openstack2':
|
||||
row = rows[-4]
|
||||
row = rows[-6]
|
||||
elif pool_name == 'openstack3':
|
||||
row = rows[-3]
|
||||
row = rows[-5]
|
||||
elif pool_name == 'hyperswap1':
|
||||
row = rows[-2]
|
||||
row = rows[-4]
|
||||
elif pool_name == 'hyperswap2':
|
||||
row = rows[-3]
|
||||
elif pool_name == 'dr_pool1':
|
||||
row = rows[-2]
|
||||
elif pool_name == 'dr_pool2':
|
||||
row = rows[-1]
|
||||
else:
|
||||
return self._errors['CMMVC5754E']
|
||||
@ -961,7 +974,8 @@ port_speed!N/A
|
||||
'primary': 'yes',
|
||||
'mdisk_grp_id': str(mdiskgrp_id),
|
||||
'mdisk_grp_name': mdiskgrp,
|
||||
'easy_tier': volume_info['easy_tier'],
|
||||
'easy_tier': (volume_info[
|
||||
'easy_tier'] if 'easy_tier' in volume_info else 'on'),
|
||||
'compressed_copy': volume_info['compressed_copy']}
|
||||
volume_info['copies'] = {'0': vol_cp}
|
||||
if is_mirror_vol:
|
||||
@ -971,7 +985,8 @@ port_speed!N/A
|
||||
'primary': 'no',
|
||||
'mdisk_grp_id': str(sec_pool_id),
|
||||
'mdisk_grp_name': sec_pool,
|
||||
'easy_tier': volume_info['easy_tier'],
|
||||
'easy_tier': (volume_info['easy_tier']
|
||||
if 'easy_tier' in volume_info else 'on'),
|
||||
'compressed_copy': volume_info['compressed_copy']}
|
||||
volume_info['copies']['1'] = vol_cp1
|
||||
|
||||
@ -2716,7 +2731,7 @@ port_speed!N/A
|
||||
site_volume_info['RC_name'] = ''
|
||||
site_volume_info['RC_id'] = ''
|
||||
|
||||
if 'buffersize' in kwargs:
|
||||
if 'thin' in kwargs or 'compressed' in kwargs:
|
||||
site_volume_info['formatted'] = 'no'
|
||||
# Fake numbers
|
||||
site_volume_info['used_capacity'] = '786432'
|
||||
@ -4816,6 +4831,15 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
vol = testutils.create_volume(self.ctxt, **prop)
|
||||
return vol
|
||||
|
||||
def _generate_vol_info_on_dr_pool(self, vol_type=None, size=10):
|
||||
pool = 'dr_pool1'
|
||||
prop = {'size': size,
|
||||
'host': 'openstack@svc#%s' % pool}
|
||||
if vol_type:
|
||||
prop['volume_type_id'] = vol_type.id
|
||||
vol = testutils.create_volume(self.ctxt, **prop)
|
||||
return vol
|
||||
|
||||
def _generate_snap_info(self, vol_id, size=10):
|
||||
prop = {'volume_id': vol_id,
|
||||
'volume_size': size}
|
||||
@ -5853,6 +5877,24 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
'failed')
|
||||
self.driver.delete_volume(volume)
|
||||
|
||||
# retype a volume in dr_pool
|
||||
loc = ('StorwizeSVCDriver:' + self.driver._state['system_id'] +
|
||||
':openstack3')
|
||||
cap = {'location_info': loc, 'extent_size': '128'}
|
||||
self.driver._stats = {'location_info': loc}
|
||||
host = {'host': 'openstack@svc#openstack3', 'capabilities': cap}
|
||||
volume = testutils.create_volume(
|
||||
self.ctxt, volume_type_id=old_type.id,
|
||||
host='openstack@svc#hyperswap3')
|
||||
volume['host'] = host['host']
|
||||
new_type = objects.VolumeType.get_by_id(ctxt,
|
||||
new_type_ref['id'])
|
||||
|
||||
self.driver.create_volume(volume)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.retype, ctxt, volume,
|
||||
new_type, diff, host)
|
||||
|
||||
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
|
||||
'disable_vdisk_qos')
|
||||
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
|
||||
@ -7164,7 +7206,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
easytier_type = self._create_volume_type(spec,
|
||||
'easytier_type')
|
||||
vol = self._generate_vol_info(easytier_type)
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.create_volume, vol)
|
||||
|
||||
# create hyperswap volume without peer_pool
|
||||
@ -7553,6 +7595,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
# retype from hyperswap volume to replication volume
|
||||
spec3 = {'replication_enabled': '<is> True',
|
||||
'replication_type': '<in> metro'}
|
||||
self.driver._replica_target['pool_name'] = 'openstack2'
|
||||
replication_type = self._create_volume_type(spec3,
|
||||
'test_replication_type')
|
||||
diff, _equal = volume_types.volume_types_diff(
|
||||
@ -7740,6 +7783,239 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
add_volumes_update)
|
||||
self.assertEqual([], remove_volumes_update)
|
||||
|
||||
@ddt.data({'spec': {'rsize': -1}},
|
||||
{'spec': {'mirror_pool': 'dr_pool2'}},
|
||||
{'spec': {'drivers:volume_topology': 'hyperswap',
|
||||
'peer_pool': 'dr_pool2'}})
|
||||
@ddt.unpack
|
||||
def test_storwize_volumes_on_dr_pool_success_case(self, spec):
|
||||
with mock.patch.object(storwize_svc_common.StorwizeHelpers,
|
||||
'get_system_info') as get_system_info:
|
||||
fake_system_info = {'code_level': (7, 7, 0, 0),
|
||||
'topology': 'hyperswap',
|
||||
'system_name': 'storwize-svc-sim',
|
||||
'system_id': '0123456789ABCDEF'}
|
||||
get_system_info.return_value = fake_system_info
|
||||
self.driver.do_setup(None)
|
||||
|
||||
dr_type = self._create_volume_type(spec, 'type_dr')
|
||||
vol = testutils.create_volume(self.ctxt, volume_type_id=dr_type.id,
|
||||
host='openstack@svc#hyperswap1')
|
||||
self.driver.create_volume(vol)
|
||||
|
||||
vol2 = testutils.create_volume(self.ctxt, volume_type_id=dr_type.id,
|
||||
host='openstack@svc#hyperswap1')
|
||||
ref = {'source-name': vol.name}
|
||||
self.driver.manage_existing(vol2, ref)
|
||||
|
||||
@ddt.data({'spec': {'warning': 30}},
|
||||
{'spec': {'rsize': 5}},
|
||||
{'spec': {'easytier': False}},
|
||||
{'spec': {'autoexpand': False}},
|
||||
{'spec': {'grainsize': 128}})
|
||||
@ddt.unpack
|
||||
def test_storwize_create_thin_volume_on_dr_pool_failure_case(self, spec):
|
||||
# create basic thin volume on dr_pool
|
||||
with mock.patch.object(storwize_svc_common.StorwizeHelpers,
|
||||
'get_system_info') as get_system_info:
|
||||
fake_system_info = {'code_level': (7, 7, 0, 0),
|
||||
'topology': 'hyperswap',
|
||||
'system_name': 'storwize-svc-sim',
|
||||
'system_id': '0123456789ABCDEF'}
|
||||
get_system_info.return_value = fake_system_info
|
||||
self.driver.do_setup(None)
|
||||
|
||||
thin_dr_type = self._create_volume_type(spec, 'type_thin')
|
||||
vol = self._generate_vol_info_on_dr_pool(thin_dr_type)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.create_volume, vol)
|
||||
|
||||
# create mirror volume on dr_pool
|
||||
self._set_flag('storwize_svc_mirror_pool', 'dr_pool1')
|
||||
mirror_dr_type = self._create_volume_type(spec, 'type_mirror')
|
||||
vol = self._generate_vol_info(mirror_dr_type)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.create_volume, vol)
|
||||
self._reset_flags()
|
||||
|
||||
# create hyperswap volume on dr_pool
|
||||
spec.update({'drivers:volume_topology': 'hyperswap',
|
||||
'peer_pool': 'dr_pool2'})
|
||||
hyper_dr_type = self._create_volume_type(spec, 'hyper_dr_type')
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self._create_hyperswap_volume, hyper_dr_type)
|
||||
|
||||
@ddt.data({'spec': {'warning': 30}},
|
||||
{'spec': {'rsize': 5}},
|
||||
{'spec': {'easytier': False}},
|
||||
{'spec': {'autoexpand': False}},
|
||||
{'spec': {'grainsize': 128}})
|
||||
@ddt.unpack
|
||||
def test_storwize_manage_volume_on_dr_pool_failure_case(self, spec):
|
||||
with mock.patch.object(storwize_svc_common.StorwizeHelpers,
|
||||
'get_system_info') as get_system_info:
|
||||
fake_system_info = {'code_level': (7, 7, 0, 0),
|
||||
'topology': 'hyperswap',
|
||||
'system_name': 'storwize-svc-sim',
|
||||
'system_id': '0123456789ABCDEF'}
|
||||
get_system_info.return_value = fake_system_info
|
||||
self.driver.do_setup(None)
|
||||
|
||||
extra_spec = {}
|
||||
thin_type = self._create_volume_type(extra_spec, 'thin_type')
|
||||
vol_type1 = self._create_volume_type(spec, 'vol_type1')
|
||||
thin_volume = self._generate_vol_info_on_dr_pool(thin_type)
|
||||
self.driver.create_volume(thin_volume)
|
||||
vol1 = self._generate_vol_info_on_dr_pool(vol_type1)
|
||||
ref1 = {'source-name': thin_volume.name}
|
||||
self.assertRaises(exception.ManageExistingVolumeTypeMismatch,
|
||||
self.driver.manage_existing, vol1, ref1)
|
||||
|
||||
extra_spec = {'mirror_pool': 'dr_pool1'}
|
||||
mirror_type = self._create_volume_type(extra_spec, 'type_mirror')
|
||||
mirror_volume = self._generate_vol_info(mirror_type)
|
||||
self.driver.create_volume(mirror_volume)
|
||||
spec.update({'mirror_pool': 'dr_pool1'})
|
||||
vol_type2 = self._create_volume_type(spec, 'vol_type2')
|
||||
vol2 = self._generate_vol_info(vol_type2)
|
||||
ref2 = {'source-name': mirror_volume.name}
|
||||
self.assertRaises(exception.ManageExistingVolumeTypeMismatch,
|
||||
self.driver.manage_existing, vol2, ref2)
|
||||
spec.pop('mirror_pool')
|
||||
|
||||
extra_spec = {'drivers:volume_topology': 'hyperswap',
|
||||
'peer_pool': 'dr_pool2'}
|
||||
hyper_type = self._create_volume_type(extra_spec, 'type_hyper')
|
||||
hyper_volume = testutils.create_volume(
|
||||
self.ctxt, volume_type_id=hyper_type.id,
|
||||
host='openstack@svc#hyperswap1')
|
||||
self.driver.create_volume(hyper_volume)
|
||||
spec.update(extra_spec)
|
||||
vol_type3 = self._create_volume_type(spec, 'vol_type3')
|
||||
vol3 = testutils.create_volume(
|
||||
self.ctxt, volume_type_id=vol_type3.id,
|
||||
host='openstack@svc#hyperswap1')
|
||||
ref3 = {'source-name': hyper_volume.name}
|
||||
self.assertRaises(exception.ManageExistingVolumeTypeMismatch,
|
||||
self.driver.manage_existing, vol3, ref3)
|
||||
|
||||
def test_storwize_migrate_volume_between_regular_dr_pool(self):
|
||||
spec = {'mirror_pool': 'openstack1'}
|
||||
mirror_vol_type = self._create_volume_type(spec, 'test_mirror_type')
|
||||
vol = self._generate_vol_info(mirror_vol_type)
|
||||
self.driver.create_volume(vol)
|
||||
loc = ('StorwizeSVCDriver:' + self.driver._state['system_id'] +
|
||||
':dr_pool2')
|
||||
cap = {'location_info': loc, 'extent_size': '256'}
|
||||
host = {'host': 'openstack@svc#dr_pool2', 'capabilities': cap}
|
||||
ctxt = context.get_admin_context()
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.migrate_volume, ctxt, vol, host)
|
||||
|
||||
vol2 = self._generate_vol_info_on_dr_pool(mirror_vol_type)
|
||||
self.driver.create_volume(vol2)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.migrate_volume, ctxt, vol2, host)
|
||||
|
||||
spec = {'mirror_pool': 'dr_pool1'}
|
||||
mirror_vol_type1 = self._create_volume_type(spec, 'test_mirror_type1')
|
||||
vol3 = self._generate_vol_info(mirror_vol_type1)
|
||||
self.driver.create_volume(vol3)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.migrate_volume, ctxt, vol3, host)
|
||||
|
||||
spec.update({'rsize': -1})
|
||||
thick_vol_type = self._create_volume_type(spec, 'thick_mirror_type')
|
||||
vol3 = self._generate_vol_info_on_dr_pool(thick_vol_type)
|
||||
self.driver.create_volume(vol3)
|
||||
self.driver.migrate_volume(ctxt, vol3, host)
|
||||
|
||||
vol4 = self._create_volume()
|
||||
self.driver.migrate_volume(ctxt, vol4, host)
|
||||
|
||||
spec = {'rsize': '10'}
|
||||
rsize_type = self._create_volume_type(spec, 'rsize_type')
|
||||
vol5 = self._generate_vol_info(rsize_type)
|
||||
self.driver.create_volume(vol5)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.migrate_volume, ctxt, vol5, host)
|
||||
|
||||
@ddt.data(({}, {'easytier': True, 'warning': 5, 'autoexpand': False}),
|
||||
({}, {'grainsize': 128}),
|
||||
({'mirror_pool': 'dr_pool2'}, {'mirror_pool': 'hyperswap1'}))
|
||||
@ddt.unpack
|
||||
def test_storwize_svc_retype_old_type_dr_pool(self, key_specs_old,
|
||||
key_specs_new):
|
||||
self.driver.do_setup(None)
|
||||
loc = ('StorwizeSVCDriver:' + self.driver._state['system_id'] +
|
||||
':dr_pool1')
|
||||
cap = {'location_info': loc, 'extent_size': '128'}
|
||||
self.driver._stats = {'location_info': loc}
|
||||
host = {'host': 'openstack@svc#dr_pool1', 'capabilities': cap}
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
old_type_ref = volume_types.create(ctxt, 'old', key_specs_old)
|
||||
new_type_ref = volume_types.create(ctxt, 'new', key_specs_new)
|
||||
|
||||
diff, _equal = volume_types.volume_types_diff(ctxt, old_type_ref['id'],
|
||||
new_type_ref['id'])
|
||||
|
||||
old_type = objects.VolumeType.get_by_id(ctxt,
|
||||
old_type_ref['id'])
|
||||
|
||||
volume = self._generate_vol_info_on_dr_pool(old_type)
|
||||
volume['host'] = host['host']
|
||||
new_type = objects.VolumeType.get_by_id(ctxt,
|
||||
new_type_ref['id'])
|
||||
|
||||
self.driver.create_volume(volume)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.retype, ctxt, volume,
|
||||
new_type, diff, host)
|
||||
|
||||
@ddt.data(({}, {'mirror_pool': 'dr_pool2', 'warning': 5}),
|
||||
({'mirror_pool': 'openstack2'}, {'mirror_pool': 'dr_pool2'}),
|
||||
({'mirror_pool': 'dr_pool2'}, {'mirror_pool': 'hyperswap1'}),
|
||||
({'autoexpand': False}, {'drivers:volume_topology': 'hyperswap',
|
||||
'peer_pool': 'dr_pool2',
|
||||
'autoexpand': False}))
|
||||
@ddt.unpack
|
||||
def test_storwize_svc_retype_new_type_dr_pool(self, key_specs_old,
|
||||
key_specs_new):
|
||||
with mock.patch.object(storwize_svc_common.StorwizeHelpers,
|
||||
'get_system_info') as get_system_info:
|
||||
fake_system_info = {'code_level': (7, 7, 0, 0),
|
||||
'topology': 'hyperswap',
|
||||
'system_name': 'storwize-svc-sim',
|
||||
'system_id': '0123456789ABCDEF'}
|
||||
get_system_info.return_value = fake_system_info
|
||||
self.driver.do_setup(None)
|
||||
loc = ('StorwizeSVCDriver:' + self.driver._state['system_id'] +
|
||||
':openstack')
|
||||
cap = {'location_info': loc, 'extent_size': '128'}
|
||||
self.driver._stats = {'location_info': loc}
|
||||
host = {'host': 'openstack@svc#openstack', 'capabilities': cap}
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
old_type_ref = volume_types.create(ctxt, 'old', key_specs_old)
|
||||
new_type_ref = volume_types.create(ctxt, 'new', key_specs_new)
|
||||
|
||||
diff, _equal = volume_types.volume_types_diff(ctxt, old_type_ref['id'],
|
||||
new_type_ref['id'])
|
||||
|
||||
old_type = objects.VolumeType.get_by_id(ctxt,
|
||||
old_type_ref['id'])
|
||||
|
||||
volume = self._generate_vol_info(old_type)
|
||||
volume['host'] = host['host']
|
||||
new_type = objects.VolumeType.get_by_id(ctxt,
|
||||
new_type_ref['id'])
|
||||
|
||||
self.driver.create_volume(volume)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.retype, ctxt, volume,
|
||||
new_type, diff, host)
|
||||
|
||||
|
||||
class CLIResponseTestCase(test.TestCase):
|
||||
def test_empty(self):
|
||||
@ -8283,6 +8559,83 @@ class StorwizeSVCReplicationTestCase(test.TestCase):
|
||||
self._create_test_volume,
|
||||
self.gmcv_with_cps86401_type)
|
||||
|
||||
@ddt.data(({"backend_id": "svc_aux_target_1",
|
||||
"san_ip": "192.168.10.22",
|
||||
"san_login": "admin",
|
||||
"san_password": "admin",
|
||||
"pool_name": "openstack"}, 'openstack@svc#dr_pool1'),
|
||||
({"backend_id": "svc_aux_target_1",
|
||||
"san_ip": "192.168.10.22",
|
||||
"san_login": "admin",
|
||||
"san_password": "admin",
|
||||
"pool_name": "dr_pool1"}, 'openstack@svc#openstack'))
|
||||
@ddt.unpack
|
||||
def test_storwize_replication_volume_with_dr_pools(self, target, vol_host):
|
||||
# Set replication target
|
||||
self.driver.configuration.set_override('replication_device',
|
||||
[target])
|
||||
|
||||
self.driver.do_setup(self.ctxt)
|
||||
|
||||
# Create metro mirror replication volume on dr_pool.
|
||||
volume = testutils.create_volume(
|
||||
self.ctxt, volume_type_id=self.mm_type.id,
|
||||
host=vol_host)
|
||||
model_update = self.driver.create_volume(volume)
|
||||
self.assertEqual(fields.ReplicationStatus.ENABLED,
|
||||
model_update['replication_status'])
|
||||
volume1 = testutils.create_volume(
|
||||
self.ctxt, volume_type_id=self.mm_type.id,
|
||||
host=vol_host)
|
||||
ref = {'source-name': volume.name}
|
||||
self.driver.manage_existing(volume1, ref)
|
||||
|
||||
spec = {'replication_enabled': '<is> True',
|
||||
'replication_type': '<in> metro',
|
||||
'easytier': 'False'}
|
||||
type_ref = volume_types.create(self.ctxt, 'type_dr', spec)
|
||||
dr_type = objects.VolumeType.get_by_id(self.ctxt, type_ref['id'])
|
||||
volume2 = testutils.create_volume(
|
||||
self.ctxt, volume_type_id=dr_type.id,
|
||||
host=vol_host)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.create_volume, volume2)
|
||||
|
||||
volume3 = testutils.create_volume(
|
||||
self.ctxt, volume_type_id=self.mm_type.id,
|
||||
host=vol_host)
|
||||
model_update = self.driver.create_volume(volume3)
|
||||
ref2 = {'source-name': volume3.name}
|
||||
self.assertRaises(exception.ManageExistingVolumeTypeMismatch,
|
||||
self.driver.manage_existing, volume2, ref2)
|
||||
|
||||
volume4 = testutils.create_volume(
|
||||
self.ctxt, volume_type_id=self.non_replica_type.id,
|
||||
host=vol_host)
|
||||
self.driver.create_volume(volume4)
|
||||
# Retype to mm replica
|
||||
host = {'host': vol_host}
|
||||
diff, _equal = volume_types.volume_types_diff(
|
||||
self.ctxt, self.non_replica_type['id'], self.mm_type['id'])
|
||||
retyped, model_update = self.driver.retype(
|
||||
self.ctxt, volume4, self.mm_type, diff, host)
|
||||
volume4['volume_type_id'] = self.mm_type['id']
|
||||
volume4['volume_type'] = self.mm_type
|
||||
self.assertEqual(fields.ReplicationStatus.ENABLED,
|
||||
model_update['replication_status'])
|
||||
self._validate_replic_vol_creation(volume4)
|
||||
|
||||
volume5 = testutils.create_volume(
|
||||
self.ctxt, volume_type_id=self.non_replica_type.id,
|
||||
host=vol_host)
|
||||
self.driver.create_volume(volume5)
|
||||
# retype with check dr_pool params failure
|
||||
diff, _equal = volume_types.volume_types_diff(
|
||||
self.ctxt, self.non_replica_type['id'], dr_type['id'])
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.retype, self.ctxt, volume5,
|
||||
dr_type, diff, host)
|
||||
|
||||
def _validate_replic_vol_creation(self, volume, isGMCV=False):
|
||||
self._assert_vol_exists(volume['name'], True)
|
||||
self._assert_vol_exists(
|
||||
|
@ -195,7 +195,7 @@ class StorwizeSVCReplicationGMCV(StorwizeSVCReplicationGlobalMirror):
|
||||
self.driver._helpers.create_vdisk(source_change_vol_name,
|
||||
six.text_type(vref['size']),
|
||||
'gb',
|
||||
src_attr['mdisk_grp_id'],
|
||||
src_attr['mdisk_grp_name'],
|
||||
src_change_opts)
|
||||
# Create target volume if it doesn't exist
|
||||
target_attr = self.target_helpers.get_vdisk_attributes(
|
||||
|
@ -78,7 +78,7 @@ storwize_svc_opts = [
|
||||
cfg.IntOpt('storwize_svc_vol_grainsize',
|
||||
default=256,
|
||||
help='Storage system grain size parameter for volumes '
|
||||
'(32/64/128/256)'),
|
||||
'(8/32/64/128/256)'),
|
||||
cfg.BoolOpt('storwize_svc_vol_compression',
|
||||
default=False,
|
||||
help='Storage system compression option for volumes'),
|
||||
@ -802,6 +802,14 @@ class StorwizeHelpers(object):
|
||||
attrs = self.get_pool_attrs(pool_name)
|
||||
return attrs is not None
|
||||
|
||||
def is_data_reduction_pool(self, pool_name):
|
||||
"""Check if pool is data reduction pool."""
|
||||
pool_data = self.get_pool_attrs(pool_name)
|
||||
if (pool_data and 'data_reduction' in pool_data and
|
||||
pool_data['data_reduction'] == 'yes'):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_available_io_groups(self):
|
||||
"""Return list of available IO groups."""
|
||||
iogrps = []
|
||||
@ -1286,7 +1294,7 @@ class StorwizeHelpers(object):
|
||||
@staticmethod
|
||||
def check_vdisk_opts(state, opts):
|
||||
# Check that grainsize is 32/64/128/256
|
||||
if opts['grainsize'] not in [32, 64, 128, 256]:
|
||||
if opts['grainsize'] not in [8, 32, 64, 128, 256]:
|
||||
raise exception.InvalidInput(
|
||||
reason=_('Illegal value specified for '
|
||||
'storwize_svc_vol_grainsize: set to either '
|
||||
@ -1481,29 +1489,110 @@ class StorwizeHelpers(object):
|
||||
self.check_vdisk_opts(state, opts)
|
||||
return opts
|
||||
|
||||
def check_data_reduction_pool_params(self, opts):
|
||||
"""Check the configured parameters if vol in data reduction pool."""
|
||||
if opts['warning'] != 0:
|
||||
msg = (_('You cannot specify -warning for thin-provisioned or '
|
||||
'compressed volumes that are in data reduction '
|
||||
'pools. The configured warning is '
|
||||
'%s.') % opts['warning'])
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
if not opts['easytier']:
|
||||
msg = (_('You cannot specify -easytier for thin-provisioned '
|
||||
'or compressed volumes that are in data reduction '
|
||||
'pools. The configured easytier is '
|
||||
'%s') % opts['easytier'])
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
if opts['grainsize'] != 256 and opts['grainsize'] != 8:
|
||||
msg = (_('You cannot specify -grainsize for thin-provisioned '
|
||||
'or compressed volumes that are in data reduction '
|
||||
'pools. This type of volume will be created with a '
|
||||
'grainsize of 8 KB. The configured grainsize is '
|
||||
'%s.') % opts['grainsize'])
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
if opts['rsize'] != 2:
|
||||
if opts['volume_topology'] == 'hyperswap':
|
||||
msg = (_('You cannot specify -buffersize for Hyperswap volumes'
|
||||
' that are in data reduction pools, The configured '
|
||||
'buffersize is %s.') % opts['rsize'])
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
else:
|
||||
msg = (_('You cannot specify -rsize for thin-provisioned '
|
||||
'or compressed volumes that are in data reduction '
|
||||
'pools. The -rsize parameter will be ignored in '
|
||||
'mkvdisk. Only its presence or absence is used to '
|
||||
'determine if the disk is a data reduction volume '
|
||||
'copy or a thick volume copy. The '
|
||||
'configured rsize is %s.') % opts['rsize'])
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
if not opts['autoexpand']:
|
||||
msg = (_('You cannot set the autoexpand to disable for '
|
||||
'thin-provisioned or compressed volumes that are in data '
|
||||
'reduction pool. The configured'
|
||||
' autoexpand is %s.') % opts['autoexpand'])
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
else:
|
||||
LOG.info('You cannot specify warning, grainsize and '
|
||||
'easytier for thin-provisioned or compressed'
|
||||
' volumes that are in data reduction pools. '
|
||||
'The rsize parameter will be ignored, the '
|
||||
'autoexpand must be enabled.')
|
||||
|
||||
def is_volume_type_dr_pools(self, pool, opts, rep_type=None,
|
||||
rep_target_pool=None):
|
||||
"""Check every configured pools is data reduction pool."""
|
||||
if self.is_data_reduction_pool(pool):
|
||||
LOG.debug('The configured pool %s is a data reduction pool.', pool)
|
||||
return True
|
||||
|
||||
if opts['mirror_pool'] and self.is_data_reduction_pool(
|
||||
opts['mirror_pool']):
|
||||
LOG.debug('The mirror_pool %s is a data reduction pool.',
|
||||
opts['mirror_pool'])
|
||||
return True
|
||||
|
||||
if (opts['volume_topology'] == 'hyperswap' and
|
||||
self.is_data_reduction_pool(opts['peer_pool'])):
|
||||
LOG.debug('The peer_pool %s is a data reduction pool.',
|
||||
opts['peer_pool'])
|
||||
return True
|
||||
|
||||
if rep_type and self.is_data_reduction_pool(rep_target_pool):
|
||||
LOG.debug('The replica target pool %s is a data reduction pool.',
|
||||
rep_target_pool)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _get_vdisk_create_params(opts, add_copies=False):
|
||||
def _get_vdisk_create_params(opts, is_dr_pool, add_copies=False):
|
||||
easytier = 'on' if opts['easytier'] else 'off'
|
||||
if opts['rsize'] == -1:
|
||||
params = []
|
||||
if opts['nofmtdisk']:
|
||||
params.append('-nofmtdisk')
|
||||
else:
|
||||
params = ['-rsize', '%s%%' % str(opts['rsize']),
|
||||
'-autoexpand', '-warning',
|
||||
'%s%%' % str(opts['warning'])]
|
||||
if not opts['autoexpand']:
|
||||
params.remove('-autoexpand')
|
||||
|
||||
if opts['compression']:
|
||||
params.append('-compressed')
|
||||
if is_dr_pool:
|
||||
params = ['-rsize', '%s%%' % str(opts['rsize']), '-autoexpand']
|
||||
if opts['compression']:
|
||||
params.append('-compressed')
|
||||
else:
|
||||
params.extend(['-grainsize', str(opts['grainsize'])])
|
||||
params = ['-rsize', '%s%%' % str(opts['rsize']),
|
||||
'-autoexpand', '-warning',
|
||||
'%s%%' % str(opts['warning'])]
|
||||
if not opts['autoexpand']:
|
||||
params.remove('-autoexpand')
|
||||
|
||||
if opts['compression']:
|
||||
params.append('-compressed')
|
||||
else:
|
||||
params.extend(['-grainsize', str(opts['grainsize'])])
|
||||
|
||||
if add_copies and opts['mirror_pool']:
|
||||
params.extend(['-copies', '2'])
|
||||
|
||||
params.extend(['-easytier', easytier])
|
||||
if not is_dr_pool:
|
||||
params.extend(['-easytier', easytier])
|
||||
return params
|
||||
|
||||
def create_vdisk(self, name, size, units, pool, opts):
|
||||
@ -1517,19 +1606,31 @@ class StorwizeHelpers(object):
|
||||
# The syntax of pool SVC expects is pool:mirror_pool in
|
||||
# mdiskgrp for mirror volume
|
||||
mdiskgrp = '%s:%s' % (pool, opts['mirror_pool'])
|
||||
|
||||
is_dr_pool = False
|
||||
if opts['rsize'] != -1:
|
||||
is_dr_pool = self.is_volume_type_dr_pools(pool, opts)
|
||||
if is_dr_pool:
|
||||
self.check_data_reduction_pool_params(opts)
|
||||
params = self._get_vdisk_create_params(
|
||||
opts, add_copies=True if opts['mirror_pool'] else False)
|
||||
opts, is_dr_pool,
|
||||
add_copies=True if opts['mirror_pool'] else False)
|
||||
self.ssh.mkvdisk(name, size, units, mdiskgrp, opts, params)
|
||||
LOG.debug('Leave: _create_vdisk: volume %s.', name)
|
||||
|
||||
def _get_hyperswap_volume_create_params(self, opts):
|
||||
def _get_hyperswap_volume_create_params(self, opts, is_dr_pool):
|
||||
# Storwize/svc use cli command mkvolume to create hyperswap volume.
|
||||
# You must specify -thin with grainsize.
|
||||
# You must specify either -thin or -compressed with warning.
|
||||
params = []
|
||||
LOG.debug('The I/O groups of a hyperswap volume will be selected by '
|
||||
'storage.')
|
||||
if opts['rsize'] != -1:
|
||||
if is_dr_pool:
|
||||
if opts['compression']:
|
||||
params.append('-compressed')
|
||||
else:
|
||||
params.append('-thin')
|
||||
else:
|
||||
params.extend(['-buffersize', '%s%%' % str(opts['rsize']),
|
||||
'-warning',
|
||||
'%s%%' % six.text_type(opts['warning'])])
|
||||
@ -1544,16 +1645,23 @@ class StorwizeHelpers(object):
|
||||
|
||||
def create_hyperswap_volume(self, vol_name, size, units, pool, opts):
|
||||
vol_name = '"%s"' % vol_name
|
||||
params = self._get_hyperswap_volume_create_params(opts)
|
||||
self.ssh.mkvolume(vol_name, six.text_type(size), units, pool, params)
|
||||
params = []
|
||||
if opts['rsize'] != -1:
|
||||
is_dr_pool = self.is_volume_type_dr_pools(pool, opts)
|
||||
if is_dr_pool:
|
||||
self.check_data_reduction_pool_params(opts)
|
||||
params = self._get_hyperswap_volume_create_params(opts, is_dr_pool)
|
||||
hyperpool = '%s:%s' % (pool, opts['peer_pool'])
|
||||
self.ssh.mkvolume(vol_name, six.text_type(size), units,
|
||||
hyperpool, params)
|
||||
|
||||
def convert_volume_to_hyperswap(self, vol_name, opts, state):
|
||||
vol_name = '%s' % vol_name
|
||||
if not self.is_system_topology_hyperswap(state):
|
||||
reason = _('Convert volume to hyperswap failed, the system is '
|
||||
'below release 7.6.0.0 or it is not hyperswap '
|
||||
'topology.')
|
||||
raise exception.VolumeDriverException(reason=reason)
|
||||
msg = _('Convert volume to hyperswap failed, the system is '
|
||||
'below release 7.6.0.0 or it is not hyperswap '
|
||||
'topology.')
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
else:
|
||||
attr = self.get_vdisk_attributes(vol_name)
|
||||
if attr is None:
|
||||
@ -1564,7 +1672,10 @@ class StorwizeHelpers(object):
|
||||
pool = attr['mdisk_grp_name']
|
||||
self.check_hyperswap_pool(pool, opts['peer_pool'])
|
||||
hyper_pool = '%s' % opts['peer_pool']
|
||||
params = self._get_hyperswap_volume_create_params(opts)
|
||||
is_dr_pool = self.is_volume_type_dr_pools(pool, opts)
|
||||
if is_dr_pool and opts['rsize'] != -1:
|
||||
self.check_data_reduction_pool_params(opts)
|
||||
params = self._get_hyperswap_volume_create_params(opts, is_dr_pool)
|
||||
self.ssh.addvolumecopy(vol_name, hyper_pool, params)
|
||||
|
||||
def convert_hyperswap_volume_to_normal(self, vol_name, peer_pool):
|
||||
@ -2213,7 +2324,10 @@ class StorwizeHelpers(object):
|
||||
else:
|
||||
opts = self.get_vdisk_params(config, state, volume_type['id'],
|
||||
volume_type=volume_type)
|
||||
params = self._get_vdisk_create_params(opts)
|
||||
is_dr_pool = self.is_data_reduction_pool(dest_pool)
|
||||
if is_dr_pool and opts['rsize'] != -1:
|
||||
self.check_data_reduction_pool_params(opts)
|
||||
params = self._get_vdisk_create_params(opts, is_dr_pool)
|
||||
try:
|
||||
new_copy_id = self.ssh.addvdiskcopy(vdisk, dest_pool, params,
|
||||
auto_delete)
|
||||
@ -2904,14 +3018,12 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
'replication enabled is not supported.')
|
||||
raise exception.InvalidInput(reason=reason)
|
||||
if not opts['easytier']:
|
||||
raise exception.InvalidInput(
|
||||
reason=_('The default easytier of hyperswap volume is '
|
||||
'on, it does not support easytier off.'))
|
||||
msg = _('The default easytier of hyperswap volume is '
|
||||
'on, it does not support easytier off.')
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
self._helpers.check_hyperswap_pool(pool, opts['peer_pool'])
|
||||
hyperpool = '%s:%s' % (pool, opts['peer_pool'])
|
||||
self._helpers.create_hyperswap_volume(volume.name,
|
||||
volume.size, 'gb',
|
||||
hyperpool, opts)
|
||||
self._helpers.create_hyperswap_volume(volume.name, volume.size,
|
||||
'gb', pool, opts)
|
||||
else:
|
||||
if opts['mirror_pool'] and rep_type:
|
||||
reason = _('Create mirror volume with replication enabled is '
|
||||
@ -4293,6 +4405,21 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
resp = self._helpers.lsvdiskcopy(volume.name)
|
||||
if len(resp) > 1:
|
||||
copies = self._helpers.get_vdisk_copies(volume.name)
|
||||
src_pool = copies['primary']['mdisk_grp_name']
|
||||
mirror_pool = copies['secondary']['mdisk_grp_name']
|
||||
opts = self._get_vdisk_params(volume.volume_type_id)
|
||||
if opts['rsize'] != -1:
|
||||
if (self._helpers.is_data_reduction_pool(src_pool) or
|
||||
self._helpers.is_data_reduction_pool(mirror_pool)):
|
||||
msg = _('Unable to migrate: the thin-provisioned or '
|
||||
'compressed volume can not be migrated from a data'
|
||||
' reduction pool. ')
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
elif self._helpers.is_data_reduction_pool(dest_pool):
|
||||
msg = _('Unable to migrate: the thin-provisioned or '
|
||||
'compressed volume can not be migrated to a data '
|
||||
'reduction pool.')
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
self._helpers.migratevdisk(volume.name, dest_pool,
|
||||
copies['primary']['copy_id'])
|
||||
else:
|
||||
@ -4309,8 +4436,17 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
{'id': volume.id, 'host': host['host']})
|
||||
return (True, None)
|
||||
|
||||
def _verify_iogrp(self, rsize, pool, opts, rep_type, status):
|
||||
if rsize != -1 and self._helpers.is_volume_type_dr_pools(
|
||||
pool, opts, rep_type, rep_target_pool=self._replica_target[
|
||||
'pool_name'] if rep_type else None):
|
||||
msg = _('Unable to retype: the thin-provisioned or compressed '
|
||||
'vol in data reduction pool can not modify iogrp.')
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
|
||||
def _verify_retype_params(self, volume, new_opts, old_opts, need_copy,
|
||||
change_mirror, new_rep_type, old_rep_type):
|
||||
change_mirror, new_rep_type, old_rep_type,
|
||||
vdisk_changes, old_pool, new_pool):
|
||||
# Some volume parameters can not be changed or changed at the same
|
||||
# time during volume retype operation. This function checks the
|
||||
# retype parameters.
|
||||
@ -4320,6 +4456,16 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
'has only one copy in storage.') % volume.name)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
|
||||
is_old_type_dr_pool = self._helpers.is_volume_type_dr_pools(
|
||||
old_pool, old_opts, old_rep_type,
|
||||
rep_target_pool=self._replica_target[
|
||||
'pool_name'] if old_rep_type else None)
|
||||
is_new_type_dr_pool = self._helpers.is_volume_type_dr_pools(
|
||||
new_pool, new_opts, new_rep_type,
|
||||
rep_target_pool=self._replica_target[
|
||||
'pool_name'] if new_rep_type else None)
|
||||
need_check_dr_pool_param = False
|
||||
|
||||
if need_copy:
|
||||
# mirror volume can not add volume-copy again.
|
||||
if len(resp) > 1:
|
||||
@ -4332,6 +4478,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
'it is not allowed for mirror volume '
|
||||
'%s.') % volume.name)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
need_check_dr_pool_param = True
|
||||
|
||||
if change_mirror:
|
||||
if (new_opts['mirror_pool'] and
|
||||
@ -4340,6 +4487,16 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
msg = (_('Unable to retype: The pool %s in which mirror copy '
|
||||
'is stored is not valid') % new_opts['mirror_pool'])
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
# migrate second copy to a dr pool or from a dr pool is not allowed
|
||||
if (old_opts['mirror_pool'] and new_opts[
|
||||
'mirror_pool'] and old_opts['rsize'] != -1):
|
||||
if is_old_type_dr_pool or is_new_type_dr_pool:
|
||||
msg = _('Unable to retype: the thin-provisioned or '
|
||||
'compressed vol can not be migrated from a dr pool'
|
||||
' or to a dr pool.')
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
if not old_opts['mirror_pool'] and new_opts['mirror_pool']:
|
||||
need_check_dr_pool_param = True
|
||||
|
||||
# There are four options for rep_type: None, metro, global, gmcv
|
||||
if new_rep_type or old_rep_type:
|
||||
@ -4367,6 +4524,15 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
'new_rep_type': new_rep_type})
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
if not old_rep_type and new_rep_type:
|
||||
if new_opts['rsize'] != -1 and is_new_type_dr_pool:
|
||||
try:
|
||||
self._helpers.check_data_reduction_pool_params(
|
||||
new_opts)
|
||||
except Exception as err:
|
||||
msg = (_("Failed to retype volume, the error is "
|
||||
"%s") % err)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
elif storwize_const.GMCV == new_rep_type:
|
||||
# To gmcv, we may change cycle_period_seconds if needed
|
||||
previous_cps = old_opts.get('cycle_period_seconds')
|
||||
@ -4375,6 +4541,22 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
self._helpers.change_relationship_cycleperiod(volume.name,
|
||||
new_cps)
|
||||
|
||||
if (is_new_type_dr_pool and new_opts[
|
||||
'rsize'] != -1 and need_check_dr_pool_param == 1):
|
||||
try:
|
||||
self._helpers.check_data_reduction_pool_params(new_opts)
|
||||
except Exception as err:
|
||||
msg = (_("Failed to retype volume, the error is "
|
||||
"%s") % err)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
|
||||
if vdisk_changes and not need_copy:
|
||||
if is_old_type_dr_pool or is_new_type_dr_pool:
|
||||
msg = _('The volume specified is a thin or compressed volume '
|
||||
'in a data reduction pool. The autoexpand and warning'
|
||||
' and easytier can not be changed.')
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
|
||||
def _check_hyperswap_retype_params(self, volume, new_opts, old_opts,
|
||||
change_mirror, new_rep_type,
|
||||
old_rep_type, old_pool,
|
||||
@ -4413,13 +4595,23 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
raise exception.InvalidInput(
|
||||
reason=_('The default easytier of hyperswap volume is '
|
||||
'on, it does not support easytier off.'))
|
||||
if (old_opts['volume_topology'] != 'hyperswap' and
|
||||
self._helpers._get_vdisk_fc_mappings(volume.name)):
|
||||
msg = _('Unable to retype: it is not allowed to change a '
|
||||
'normal volume with snapshot to a hyperswap '
|
||||
'volume.')
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(message=msg)
|
||||
if old_opts['volume_topology'] != 'hyperswap':
|
||||
is_new_type_dr_pool = self._helpers.is_volume_type_dr_pools(
|
||||
new_pool, new_opts)
|
||||
if is_new_type_dr_pool and new_opts['rsize'] != -1:
|
||||
try:
|
||||
self._helpers.check_data_reduction_pool_params(
|
||||
new_opts)
|
||||
except Exception as err:
|
||||
msg = (_("Failed to retype volume, the error is "
|
||||
"%s") % err)
|
||||
raise exception.VolumeDriverException(reason=msg)
|
||||
if self._helpers._get_vdisk_fc_mappings(volume.name):
|
||||
msg = _('Unable to retype: it is not allowed to change a '
|
||||
'normal volume with snapshot to a hyperswap '
|
||||
'volume.')
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(message=msg)
|
||||
if (old_opts['volume_topology'] == 'hyperswap' and
|
||||
old_opts['peer_pool'] != new_opts['peer_pool']):
|
||||
msg = _('Unable to retype: it is not allowed to change a '
|
||||
@ -4529,7 +4721,8 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
new_opts, new_pool)
|
||||
|
||||
self._verify_retype_params(volume, new_opts, old_opts, need_copy,
|
||||
change_mirror, new_rep_type, old_rep_type)
|
||||
change_mirror, new_rep_type, old_rep_type,
|
||||
vdisk_changes, old_pool, new_pool)
|
||||
|
||||
if old_opts['volume_topology'] or new_opts['volume_topology']:
|
||||
self._check_hyperswap_retype_params(volume, new_opts, old_opts,
|
||||
@ -4540,6 +4733,11 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
old_pool, new_pool, vdisk_changes,
|
||||
need_copy, new_type)
|
||||
else:
|
||||
# hyperswap volume will select iogrp by storage. ignore iogrp here.
|
||||
if old_io_grp != new_io_grp:
|
||||
self._verify_iogrp(old_opts['rsize'], old_pool, old_opts,
|
||||
old_rep_type,
|
||||
volume.previous_status)
|
||||
if need_copy:
|
||||
self._check_volume_copy_ops()
|
||||
dest_pool = self._helpers.can_migrate_to_host(host,
|
||||
@ -4732,6 +4930,17 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
'type_cps': rep_cps})
|
||||
raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
|
||||
|
||||
pool = utils.extract_host(volume['host'], 'pool')
|
||||
if copies['primary']['mdisk_grp_name'] != pool:
|
||||
msg = (_("Failed to manage existing volume due to the "
|
||||
"pool of the volume to be managed does not "
|
||||
"match the backend pool. Pool of the "
|
||||
"volume to be managed is %(vdisk_pool)s. Pool "
|
||||
"of the backend is %(backend_pool)s.") %
|
||||
{'vdisk_pool': copies['primary']['mdisk_grp_name'],
|
||||
'backend_pool': pool})
|
||||
raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
|
||||
|
||||
if volume['volume_type_id']:
|
||||
opts = self._get_vdisk_params(volume['volume_type_id'],
|
||||
volume_metadata=
|
||||
@ -4822,17 +5031,17 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
{'vdisk_iogrp': vdisk['IO_group_name'],
|
||||
'opt_iogrp': opts['iogrp']})
|
||||
raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
|
||||
pool = utils.extract_host(volume['host'], 'pool')
|
||||
if copies['primary']['mdisk_grp_name'] != pool:
|
||||
msg = (_("Failed to manage existing volume due to the "
|
||||
"pool of the volume to be managed does not "
|
||||
"match the backend pool. Pool of the "
|
||||
"volume to be managed is %(vdisk_pool)s. Pool "
|
||||
"of the backend is %(backend_pool)s.") %
|
||||
{'vdisk_pool': copies['primary']['mdisk_grp_name'],
|
||||
'backend_pool': pool})
|
||||
raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
|
||||
|
||||
if opts['rsize'] != -1 and self._helpers.is_volume_type_dr_pools(
|
||||
pool, opts, rep_type, rep_target_pool=self._replica_target[
|
||||
'pool_name'] if rep_type else None):
|
||||
try:
|
||||
self._helpers.check_data_reduction_pool_params(opts)
|
||||
except Exception as err:
|
||||
msg = (_("Failed to manage existing volume, the error is "
|
||||
"%s") % err)
|
||||
raise exception.ManageExistingVolumeTypeMismatch(
|
||||
reason=msg)
|
||||
model_update = {'replication_status':
|
||||
fields.ReplicationStatus.NOT_CAPABLE}
|
||||
self._helpers.rename_vdisk(vdisk['name'], volume['name'])
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added data reduction pool support for thin-provisoned and compressed
|
||||
volume in Storwize cinder driver.
|
Loading…
Reference in New Issue
Block a user