POOL_PROPERTY_W_FASTCACHE_CMD = ('storagepool', '-list', '-name',
'unit_test_pool', '-availableCap',
- '-userCap', '-fastcache', '-state')
+ '-userCap', '-fastcache', '-state',
+ '-subscribedCap')
def POOL_GET_ALL_CMD(self, withfastcache=False):
if withfastcache:
return ('storagepool', '-list', '-availableCap',
- '-userCap', '-fastcache', '-state')
+ '-userCap', '-fastcache', '-state', '-subscribedCap')
else:
return ('storagepool', '-list', '-availableCap',
- '-userCap', '-state')
+ '-userCap', '-state', '-subscribedCap')
def POOL_GET_ALL_RESULT(self, withfastcache=False):
if withfastcache:
"User Capacity (GBs): 3281.146\n"
"Available Capacity (Blocks): 6512292864\n"
"Available Capacity (GBs): 3105.303\n"
+ "Total Subscribed Capacity (GBs): 536.140\n"
"FAST Cache: Enabled\n"
"State: Ready\n"
"\n"
"User Capacity (GBs): 4099.992\n"
"Available Capacity (Blocks): 8356663296\n"
"Available Capacity (GBs): 3984.768\n"
+ "Total Subscribed Capacity (GBs): 636.240\n"
"FAST Cache: Disabled\n"
"State: Ready\n", 0)
else:
"User Capacity (GBs): 3281.146\n"
"Available Capacity (Blocks): 6512292864\n"
"Available Capacity (GBs): 3105.303\n"
+ "Total Subscribed Capacity (GBs): 536.140\n"
"State: Ready\n"
"\n"
"Pool Name: unit test pool 2\n"
"User Capacity (GBs): 4099.992\n"
"Available Capacity (Blocks): 8356663296\n"
"Available Capacity (GBs): 3984.768\n"
+ "Total Subscribed Capacity (GBs): 636.240\n"
"State: Ready\n", 0)
def POOL_GET_ALL_STATES_TEST(self, states=['Ready']):
"User Capacity (GBs): 3281.146\n"
"Available Capacity (Blocks): 6832207872\n"
"Available Capacity (GBs): 3257.851\n"
+ "Total Subscribed Capacity (GBs): 636.240\n"
"FAST Cache: Enabled\n"
"State: Ready\n\n", 0)
1))]
fake_cli.assert_has_calls(expect_cmd)
+ @mock.patch(
+ 'cinder.openstack.common.loopingcall.FixedIntervalLoopingCall',
+ new=utils.ZeroIntervalLoopingCall)
+ @mock.patch(
+ "cinder.volume.volume_types."
+ "get_volume_type_extra_specs",
+ mock.Mock(return_value={'provisioning:type': 'thin',
+ 'storagetype:provisioning': 'thick'}))
+ def test_create_volume_thin(self):
+ commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'),
+ self.testData.NDU_LIST_CMD]
+ results = [self.testData.LUN_PROPERTY('vol_with_type', True),
+ self.testData.NDU_LIST_RESULT]
+ fake_cli = self.driverSetup(commands, results)
+ self.driver.cli.enablers = ['-Compression',
+ '-Deduplication',
+ '-ThinProvisioning',
+ '-FAST']
+ # case
+ self.driver.create_volume(self.testData.test_volume_with_type)
+ # verification
+ expect_cmd = [
+ mock.call(*self.testData.LUN_CREATION_CMD(
+ 'vol_with_type', 1,
+ 'unit_test_pool',
+ 'thin', None, False)),
+ mock.call(*self.testData.LUN_PROPERTY_ALL_CMD(
+ 'vol_with_type'), poll=False)]
+ fake_cli.assert_has_calls(expect_cmd)
+
+ @mock.patch(
+ 'cinder.openstack.common.loopingcall.FixedIntervalLoopingCall',
+ new=utils.ZeroIntervalLoopingCall)
+ @mock.patch(
+ "cinder.volume.volume_types."
+ "get_volume_type_extra_specs",
+ mock.Mock(return_value={'provisioning:type': 'thick'}))
+ def test_create_volume_thick(self):
+ commands = [self.testData.LUN_PROPERTY_ALL_CMD('vol_with_type'),
+ self.testData.NDU_LIST_CMD]
+ results = [self.testData.LUN_PROPERTY('vol_with_type', False),
+ self.testData.NDU_LIST_RESULT]
+ fake_cli = self.driverSetup(commands, results)
+ self.driver.cli.enablers = ['-Compression',
+ '-Deduplication',
+ '-ThinProvisioning',
+ '-FAST']
+ # case
+ self.driver.create_volume(self.testData.test_volume_with_type)
+ # verification
+ expect_cmd = [
+ mock.call(*self.testData.LUN_CREATION_CMD(
+ 'vol_with_type', 1,
+ 'unit_test_pool',
+ 'thick', None, False)),
+ mock.call(*self.testData.LUN_PROPERTY_ALL_CMD(
+ 'vol_with_type'), poll=False)]
+ fake_cli.assert_has_calls(expect_cmd)
+
@mock.patch(
"eventlet.event.Event.wait",
mock.Mock(return_value=None))
'reserved_percentage': 3,
'location_info': 'unit_test_pool|fakeSerial',
'total_capacity_gb': 3281.146,
+ 'provisioned_capacity_gb': 636.240,
'compression_support': 'True',
'deduplication_support': 'True',
- 'thinprovisioning_support': 'True',
+ 'thin_provisioning_support': True,
+ 'thick_provisioning_support': True,
+ 'max_over_subscription_ratio': 20.0,
'consistencygroup_support': 'True',
'pool_name': 'unit_test_pool',
'fast_cache_enabled': 'True',
'lun_nums': 1000,
'total_capacity_gb': 10,
'free_capacity_gb': 5,
+ 'provisioned_capacity_gb': 8,
'pool_name': "unit_test_pool",
'fast_cache_enabled': 'True',
'state': 'Ready'})
'reserved_percentage': 2,
'location_info': 'unit_test_pool1|fakeSerial',
'total_capacity_gb': 3281.146,
+ 'provisioned_capacity_gb': 536.140,
'compression_support': 'True',
'deduplication_support': 'True',
- 'thinprovisioning_support': 'True',
+ 'thin_provisioning_support': True,
+ 'thick_provisioning_support': True,
'consistencygroup_support': 'True',
'pool_name': 'unit_test_pool1',
+ 'max_over_subscription_ratio': 20.0,
'fast_cache_enabled': 'True',
'fast_support': 'True'}
self.assertEqual(expected_pool_stats1, pool_stats1)
'reserved_percentage': 2,
'location_info': 'unit test pool 2|fakeSerial',
'total_capacity_gb': 4099.992,
+ 'provisioned_capacity_gb': 636.240,
'compression_support': 'True',
'deduplication_support': 'True',
- 'thinprovisioning_support': 'True',
+ 'thin_provisioning_support': True,
+ 'thick_provisioning_support': True,
'consistencygroup_support': 'True',
'pool_name': 'unit test pool 2',
+ 'max_over_subscription_ratio': 20.0,
'fast_cache_enabled': 'False',
'fast_support': 'True'}
self.assertEqual(expected_pool_stats2, pool_stats2)
'reserved_percentage': 2,
'location_info': 'unit_test_pool1|fakeSerial',
'total_capacity_gb': 3281.146,
+ 'provisioned_capacity_gb': 536.140,
'compression_support': 'False',
'deduplication_support': 'False',
- 'thinprovisioning_support': 'False',
+ 'thin_provisioning_support': False,
+ 'thick_provisioning_support': True,
'consistencygroup_support': 'False',
'pool_name': 'unit_test_pool1',
+ 'max_over_subscription_ratio': 20.0,
'fast_cache_enabled': 'False',
'fast_support': 'False'}
self.assertEqual(expected_pool_stats1, pool_stats1)
'reserved_percentage': 2,
'location_info': 'unit test pool 2|fakeSerial',
'total_capacity_gb': 4099.992,
+ 'provisioned_capacity_gb': 636.240,
'compression_support': 'False',
'deduplication_support': 'False',
- 'thinprovisioning_support': 'False',
+ 'thin_provisioning_support': False,
+ 'thick_provisioning_support': True,
'consistencygroup_support': 'False',
'pool_name': 'unit test pool 2',
+ 'max_over_subscription_ratio': 20.0,
'fast_cache_enabled': 'False',
'fast_support': 'False'}
self.assertEqual(expected_pool_stats2, pool_stats2)
'reserved_percentage': 3,
'location_info': 'unit_test_pool|fakeSerial',
'total_capacity_gb': 3281.146,
+ 'provisioned_capacity_gb': 636.24,
'compression_support': 'True',
'deduplication_support': 'True',
- 'thinprovisioning_support': 'True',
+ 'thin_provisioning_support': True,
+ 'thick_provisioning_support': True,
+ 'max_over_subscription_ratio': 20.0,
'consistencygroup_support': 'True',
'pool_name': 'unit_test_pool',
'fast_cache_enabled': 'True',
'-name',
'Pool Name:\s*(.*)\s*',
'pool_name')
+ POOL_SUBSCRIBED_CAPACITY = PropertyDescriptor(
+ '-subscribedCap',
+ 'Total Subscribed Capacity *\(GBs\) *:\s*(.*)\s*',
+ 'provisioned_capacity_gb',
+ float)
POOL_ALL = [POOL_TOTAL_CAPACITY, POOL_FREE_CAPACITY, POOL_STATE]
# extra spec constants
self.tiering_spec = 'storagetype:tiering'
- self.provisioning_spec = 'storagetype:provisioning'
+ self.provisioning_specs = [
+ 'provisioning:type',
+ 'storagetype:provisioning']
self.provisioning_values = {
'thin': ['-type', 'Thin'],
'thick': ['-type', 'NonThin'],
class EMCVnxCliBase(object):
"""This class defines the functions to use the native CLI functionality."""
- VERSION = '05.03.07'
+ VERSION = '06.00.00'
stats = {'driver_version': VERSION,
'storage_protocol': None,
'vendor_name': 'EMC',
'compression_support': 'False',
'fast_support': 'False',
'deduplication_support': 'False',
- 'thinprovisioning_support': 'False'}
+ 'thin_provisioning_support': False,
+ 'thick_provisioning_support': True}
enablers = []
def __init__(self, prtcl, configuration=None):
self.configuration.force_delete_lun_in_storagegroup)
if self.force_delete_lun_in_sg:
LOG.warning(_LW("force_delete_lun_in_storagegroup=True"))
+ self.max_over_subscription_ratio = (
+ self.configuration.max_over_subscription_ratio)
def get_target_storagepool(self, volume, source_volume=None):
raise NotImplementedError
provisioning = 'thick'
tiering = None
- if self._client.provisioning_spec in extra_specs:
- provisioning = extra_specs[self._client.provisioning_spec].lower()
+ if self._client.provisioning_specs[0] in extra_specs:
+ provisioning = (
+ extra_specs[self._client.provisioning_specs[0]].lower())
+ if self._client.provisioning_specs[1] in extra_specs:
+ LOG.warning(_LW("Both 'storagetype:prvosioning' and "
+ "'provisioning:type' are set in the "
+ "extra specs, the value of "
+ "'provisioning:type' will be used. The "
+ "key 'storagetype:provisioning' may be "
+ "deprecated in the next release."))
+ elif self._client.provisioning_specs[1] in extra_specs:
+ provisioning = (
+ extra_specs[self._client.provisioning_specs[1]].lower())
+ LOG.warning(_LW("Extra spec key 'storagetype:provisioning' may "
+ "be deprecated in the next release. It is "
+ "recommended to use extra spec key "
+ "'provisioning:type' instead."))
if self._client.tiering_spec in extra_specs:
tiering = extra_specs[self._client.tiering_spec].lower()
pool_stats = {}
pool_stats['pool_name'] = pool['pool_name']
pool_stats['total_capacity_gb'] = pool['total_capacity_gb']
+ pool_stats['provisioned_capacity_gb'] = (
+ pool['provisioned_capacity_gb'])
pool_stats['reserved_percentage'] = 0
# Handle pool state Initializing, Ready, Faulted, Offline or Deleting.
pool_stats['fast_support'] = self.stats['fast_support']
pool_stats['deduplication_support'] = (
self.stats['deduplication_support'])
- pool_stats['thinprovisioning_support'] = (
- self.stats['thinprovisioning_support'])
+ # Thin provisioning is supported on VNX pools only when
+ # ThinProvisioning Enabler software is installed on VNX,
+ # and thick provisioning is always supported on VNX pools.
+ pool_stats['thin_provisioning_support'] = (
+ self.stats['thin_provisioning_support'])
+ pool_stats['thick_provisioning_support'] = True
pool_stats['consistencygroup_support'] = (
self.stats['consistencygroup_support'])
+ pool_stats['max_over_subscription_ratio'] = (
+ self.max_over_subscription_ratio)
return pool_stats
self.stats['deduplication_support'] = (
'True' if '-Deduplication' in self.enablers else 'False')
- self.stats['thinprovisioning_support'] = (
- 'True' if '-ThinProvisioning' in self.enablers else 'False')
+ self.stats['thin_provisioning_support'] = (
+ True if '-ThinProvisioning' in self.enablers else False)
self.stats['consistencygroup_support'] = (
'True' if '-VNXSnapshots' in self.enablers else 'False')
properties = [self._client.POOL_FREE_CAPACITY,
self._client.POOL_TOTAL_CAPACITY,
self._client.POOL_FAST_CACHE,
- self._client.POOL_STATE]
+ self._client.POOL_STATE,
+ self._client.POOL_SUBSCRIBED_CAPACITY]
else:
properties = [self._client.POOL_FREE_CAPACITY,
self._client.POOL_TOTAL_CAPACITY,
- self._client.POOL_STATE]
+ self._client.POOL_STATE,
+ self._client.POOL_SUBSCRIBED_CAPACITY]
pool = self._client.get_pool(self.storage_pool,
properties=properties,
properties = [self._client.POOL_FREE_CAPACITY,
self._client.POOL_TOTAL_CAPACITY,
self._client.POOL_FAST_CACHE,
- self._client.POOL_STATE]
+ self._client.POOL_STATE,
+ self._client.POOL_SUBSCRIBED_CAPACITY]
else:
properties = [self._client.POOL_FREE_CAPACITY,
self._client.POOL_TOTAL_CAPACITY,
- self._client.POOL_STATE]
+ self._client.POOL_STATE,
+ self._client.POOL_SUBSCRIBED_CAPACITY]
pool_list = self._client.get_pool_list(properties, False)
self.stats['pools'] = map(lambda pool: self._build_pool_stats(pool),