From 3411bbcc0787d7ae062c91b7c7aa7fafb4e1596d Mon Sep 17 00:00:00 2001 From: Kurt Martin Date: Wed, 12 Aug 2015 11:18:44 -0700 Subject: [PATCH] Over subscription for HP 3PAR drivers Add support for over subscription in the HP 3PAR drivers. Also, fixed the reporting of capacity related stats at the pool level in the unit tests. DocImpact Change-Id: I182c67d864c6094e738c20436e42e4fa2d876613 Implements: blueprint over-subscription-3par --- cinder/tests/unit/test_hp3par.py | 46 +++++++++++-------- .../volume/drivers/san/hp/hp_3par_common.py | 19 +++++--- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/cinder/tests/unit/test_hp3par.py b/cinder/tests/unit/test_hp3par.py index 18434a3672b..83177c92555 100644 --- a/cinder/tests/unit/test_hp3par.py +++ b/cinder/tests/unit/test_hp3par.py @@ -3458,8 +3458,10 @@ def test_get_volume_stats1(self): stats = self.driver.get_volume_stats(True) const = 0.0009765625 self.assertEqual('FC', stats['storage_protocol']) - self.assertEqual(0, stats['total_capacity_gb']) - self.assertEqual(0, stats['free_capacity_gb']) + self.assertTrue(stats['pools'][0]['thin_provisioning_support']) + self.assertTrue(stats['pools'][0]['thick_provisioning_support']) + self.assertEqual(86.0, + stats['pools'][0]['provisioned_capacity_gb']) self.assertEqual(24.0, stats['pools'][0]['total_capacity_gb']) self.assertEqual(3.0, stats['pools'][0]['free_capacity_gb']) self.assertEqual(87.5, stats['pools'][0]['capacity_utilization']) @@ -3496,8 +3498,10 @@ def test_get_volume_stats1(self): self.standard_logout) stats = self.driver.get_volume_stats(True) self.assertEqual('FC', stats['storage_protocol']) - self.assertEqual(0, stats['total_capacity_gb']) - self.assertEqual(0, stats['free_capacity_gb']) + self.assertTrue(stats['pools'][0]['thin_provisioning_support']) + self.assertTrue(stats['pools'][0]['thick_provisioning_support']) + self.assertEqual(86.0, + stats['pools'][0]['provisioned_capacity_gb']) self.assertEqual(24.0, stats['pools'][0]['total_capacity_gb']) self.assertEqual(3.0, stats['pools'][0]['free_capacity_gb']) self.assertEqual(87.5, stats['pools'][0]['capacity_utilization']) @@ -3525,16 +3529,22 @@ def test_get_volume_stats1(self): stats = self.driver.get_volume_stats(True) self.assertEqual('FC', stats['storage_protocol']) + self.assertTrue(stats['pools'][0]['thin_provisioning_support']) + self.assertTrue(stats['pools'][0]['thick_provisioning_support']) total_capacity_gb = 8192 * const - self.assertEqual(0, stats['total_capacity_gb']) self.assertEqual(total_capacity_gb, stats['pools'][0]['total_capacity_gb']) free_capacity_gb = int( (8192 - (self.cpgs[0]['UsrUsage']['usedMiB'] + self.cpgs[0]['SDUsage']['usedMiB'])) * const) - self.assertEqual(0, stats['free_capacity_gb']) self.assertEqual(free_capacity_gb, stats['pools'][0]['free_capacity_gb']) + provisioned_capacity_gb = int( + (self.cpgs[0]['UsrUsage']['totalMiB'] + + self.cpgs[0]['SAUsage']['totalMiB'] + + self.cpgs[0]['SDUsage']['totalMiB']) * const) + self.assertEqual(provisioned_capacity_gb, + stats['pools'][0]['provisioned_capacity_gb']) cap_util = (float(total_capacity_gb - free_capacity_gb) / float(total_capacity_gb)) * 100 self.assertEqual(cap_util, @@ -3588,8 +3598,6 @@ def test_get_volume_stats2(self): stats = self.driver.get_volume_stats(True) self.assertEqual('FC', stats['storage_protocol']) - self.assertEqual(0, stats['total_capacity_gb']) - self.assertEqual(0, stats['free_capacity_gb']) self.assertEqual(24.0, stats['pools'][0]['total_capacity_gb']) self.assertEqual(3.0, stats['pools'][0]['free_capacity_gb']) self.assertEqual(87.5, stats['pools'][0]['capacity_utilization']) @@ -3645,8 +3653,6 @@ def test_get_volume_stats3(self): stats = self.driver.get_volume_stats(True) self.assertEqual('FC', stats['storage_protocol']) - self.assertEqual(0, stats['total_capacity_gb']) - self.assertEqual(0, stats['free_capacity_gb']) self.assertEqual(24.0, stats['pools'][0]['total_capacity_gb']) self.assertEqual(3.0, stats['pools'][0]['free_capacity_gb']) self.assertEqual(87.5, stats['pools'][0]['capacity_utilization']) @@ -4192,10 +4198,12 @@ def test_get_volume_stats(self): stats = self.driver.get_volume_stats(True) const = 0.0009765625 self.assertEqual('iSCSI', stats['storage_protocol']) - self.assertEqual(0, stats['total_capacity_gb']) - self.assertEqual(0, stats['free_capacity_gb']) + self.assertTrue(stats['pools'][0]['thin_provisioning_support']) + self.assertTrue(stats['pools'][0]['thick_provisioning_support']) self.assertEqual(24.0, stats['pools'][0]['total_capacity_gb']) self.assertEqual(3.0, stats['pools'][0]['free_capacity_gb']) + self.assertEqual(86.0, + stats['pools'][0]['provisioned_capacity_gb']) self.assertEqual(87.5, stats['pools'][0]['capacity_utilization']) self.assertEqual(3, stats['pools'][0]['total_volumes']) self.assertEqual(GOODNESS_FUNCTION, @@ -4235,20 +4243,26 @@ def test_get_volume_stats(self): stats = self.driver.get_volume_stats(True) self.assertEqual('iSCSI', stats['storage_protocol']) + self.assertTrue(stats['pools'][0]['thin_provisioning_support']) + self.assertTrue(stats['pools'][0]['thick_provisioning_support']) total_capacity_gb = 8192 * const - self.assertEqual(0, stats['total_capacity_gb']) self.assertEqual(total_capacity_gb, stats['pools'][0]['total_capacity_gb']) free_capacity_gb = int( (8192 - (self.cpgs[0]['UsrUsage']['usedMiB'] + self.cpgs[0]['SDUsage']['usedMiB'])) * const) - self.assertEqual(0, stats['free_capacity_gb']) self.assertEqual(free_capacity_gb, stats['pools'][0]['free_capacity_gb']) cap_util = (float(total_capacity_gb - free_capacity_gb) / float(total_capacity_gb)) * 100 self.assertEqual(cap_util, stats['pools'][0]['capacity_utilization']) + provisioned_capacity_gb = int( + (self.cpgs[0]['UsrUsage']['totalMiB'] + + self.cpgs[0]['SAUsage']['totalMiB'] + + self.cpgs[0]['SDUsage']['totalMiB']) * const) + self.assertEqual(provisioned_capacity_gb, + stats['pools'][0]['provisioned_capacity_gb']) self.assertEqual(3, stats['pools'][0]['total_volumes']) self.assertEqual(GOODNESS_FUNCTION, stats['pools'][0]['goodness_function']) @@ -4296,8 +4310,6 @@ def test_get_volume_stats2(self): stats = self.driver.get_volume_stats(True) self.assertEqual('iSCSI', stats['storage_protocol']) - self.assertEqual(0, stats['total_capacity_gb']) - self.assertEqual(0, stats['free_capacity_gb']) self.assertEqual(24.0, stats['pools'][0]['total_capacity_gb']) self.assertEqual(3.0, stats['pools'][0]['free_capacity_gb']) self.assertEqual(87.5, stats['pools'][0]['capacity_utilization']) @@ -4353,8 +4365,6 @@ def test_get_volume_stats3(self): stats = self.driver.get_volume_stats(True) self.assertEqual('iSCSI', stats['storage_protocol']) - self.assertEqual(0, stats['total_capacity_gb']) - self.assertEqual(0, stats['free_capacity_gb']) self.assertEqual(24.0, stats['pools'][0]['total_capacity_gb']) self.assertEqual(3.0, stats['pools'][0]['free_capacity_gb']) self.assertEqual(87.5, stats['pools'][0]['capacity_utilization']) diff --git a/cinder/volume/drivers/san/hp/hp_3par_common.py b/cinder/volume/drivers/san/hp/hp_3par_common.py index 84ec963f26d..04b8e257d3a 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_common.py +++ b/cinder/volume/drivers/san/hp/hp_3par_common.py @@ -197,10 +197,11 @@ class HP3PARCommon(object): 2.0.47 - Changed initialize_connection to use getHostVLUNs. #1475064 2.0.48 - Adding changes to support 3PAR iSCSI multipath. 2.0.49 - Added client CPG stats to driver volume stats. bug #1482741 + 2.0.50 - Add over subscription support """ - VERSION = "2.0.49" + VERSION = "2.0.50" stats = {} @@ -778,6 +779,10 @@ def _update_volume_stats(self, capacity_utilization = ( (float(total_capacity - free_capacity) / float(total_capacity)) * 100) + provisioned_capacity = int((cpg['UsrUsage']['totalMiB'] + + cpg['SAUsage']['totalMiB'] + + cpg['SDUsage']['totalMiB']) * + const) except hpexceptions.HTTPNotFound: err = (_("CPG (%s) doesn't exist on array") @@ -788,8 +793,14 @@ def _update_volume_stats(self, pool = {'pool_name': cpg_name, 'total_capacity_gb': total_capacity, 'free_capacity_gb': free_capacity, + 'provisioned_capacity_gb': provisioned_capacity, 'QoS_support': True, - 'reserved_percentage': 0, + 'thin_provisioning_support': True, + 'thick_provisioning_support': True, + 'max_over_subscription_ratio': ( + self.config.safe_get('max_over_subscription_ratio')), + 'reserved_percentage': ( + self.config.safe_get('reserved_percentage')), 'location_info': ('HP3PARDriver:%(sys_id)s:%(dest_cpg)s' % {'sys_id': info['serialNumber'], 'dest_cpg': cpg_name}), @@ -812,10 +823,6 @@ def _update_volume_stats(self, 'storage_protocol': None, 'vendor_name': 'Hewlett-Packard', 'volume_backend_name': None, - # Use zero capacities here so we always use a pool. - 'total_capacity_gb': 0, - 'free_capacity_gb': 0, - 'reserved_percentage': 0, 'pools': pools} def _get_vlun(self, volume_name, hostname, lun_id=None, nsp=None):