NetApp E-series: Fix provisioned_capacity_gb

Currently, NetApp E-series drivers (iSCSI and FC) are incorrectly
reporting the total physical used size as the provisioned_capacity_gb.
This patch fixes the calculation of this attribute by summing the
user-visible capacity of all the volumes present in the backend and
reporting the result as the provisioning_capacity_gb.

Change-Id: I1471ecfffe340dafb1c95bac5eaff79cde650955
Closes-Bug: #1718739
This commit is contained in:
Adriano Rosso 2017-09-29 10:29:48 -03:00 committed by Adriano Freires Rosso
parent ddf00aa70c
commit f905253b94
4 changed files with 26 additions and 3 deletions

View File

@ -319,7 +319,7 @@ VOLUMES = [
}, },
"volumeRef": "0200000060080E50002998A00000945355C37C19", "volumeRef": "0200000060080E50002998A00000945355C37C19",
"status": "optimal", "status": "optimal",
"volumeGroupRef": "0400000060080E50002998A00000945255C37C14", "volumeGroupRef": "fakevolgroupref",
"currentManager": "070000000000000000000001", "currentManager": "070000000000000000000001",
"preferredManager": "070000000000000000000001", "preferredManager": "070000000000000000000001",
"perms": { "perms": {

View File

@ -491,6 +491,7 @@ class NetAppEseriesLibraryTestCase(test.TestCase):
def test_update_volume_stats_provisioning(self): def test_update_volume_stats_provisioning(self):
"""Validate pool capacity calculations""" """Validate pool capacity calculations"""
fake_pool = copy.deepcopy(eseries_fake.STORAGE_POOL) fake_pool = copy.deepcopy(eseries_fake.STORAGE_POOL)
fake_eseries_volume = copy.deepcopy(eseries_fake.VOLUME)
self.library._get_storage_pools = mock.Mock(return_value=[fake_pool]) self.library._get_storage_pools = mock.Mock(return_value=[fake_pool])
self.mock_object(self.library, '_ssc_stats', self.mock_object(self.library, '_ssc_stats',
{fake_pool["volumeGroupRef"]: { {fake_pool["volumeGroupRef"]: {
@ -504,6 +505,11 @@ class NetAppEseriesLibraryTestCase(test.TestCase):
total_gb = int(fake_pool['totalRaidedSpace']) / units.Gi total_gb = int(fake_pool['totalRaidedSpace']) / units.Gi
used_gb = int(fake_pool['usedSpace']) / units.Gi used_gb = int(fake_pool['usedSpace']) / units.Gi
free_gb = total_gb - used_gb free_gb = total_gb - used_gb
provisioned_gb = int(fake_eseries_volume['capacity']) * 10 / units.Gi
# Testing with 10 fake volumes
self.library._client.list_volumes = mock.Mock(
return_value=[eseries_fake.VOLUME for _ in range(10)])
self.library._update_volume_stats() self.library._update_volume_stats()
@ -514,7 +520,8 @@ class NetAppEseriesLibraryTestCase(test.TestCase):
self.assertEqual(over_subscription_ratio, self.assertEqual(over_subscription_ratio,
pool_stats['max_over_subscription_ratio']) pool_stats['max_over_subscription_ratio'])
self.assertEqual(total_gb, pool_stats.get('total_capacity_gb')) self.assertEqual(total_gb, pool_stats.get('total_capacity_gb'))
self.assertEqual(used_gb, pool_stats.get('provisioned_capacity_gb')) self.assertEqual(provisioned_gb,
pool_stats.get('provisioned_capacity_gb'))
self.assertEqual(free_gb, pool_stats.get('free_capacity_gb')) self.assertEqual(free_gb, pool_stats.get('free_capacity_gb'))
@ddt.data(False, True) @ddt.data(False, True)

View File

@ -1452,6 +1452,7 @@ class NetAppESeriesLibrary(object):
data["driver_version"] = self.VERSION data["driver_version"] = self.VERSION
data["storage_protocol"] = self.driver_protocol data["storage_protocol"] = self.driver_protocol
data["pools"] = [] data["pools"] = []
storage_volumes = self._client.list_volumes()
for storage_pool in self._get_storage_pools(): for storage_pool in self._get_storage_pools():
cinder_pool = {} cinder_pool = {}
@ -1463,7 +1464,15 @@ class NetAppESeriesLibrary(object):
self.configuration.max_over_subscription_ratio) self.configuration.max_over_subscription_ratio)
tot_bytes = int(storage_pool.get("totalRaidedSpace", 0)) tot_bytes = int(storage_pool.get("totalRaidedSpace", 0))
used_bytes = int(storage_pool.get("usedSpace", 0)) used_bytes = int(storage_pool.get("usedSpace", 0))
cinder_pool["provisioned_capacity_gb"] = used_bytes / units.Gi
provisioned_capacity = 0
for volume in storage_volumes:
if (volume["volumeGroupRef"] == storage_pool.get('id') and
not volume['label'].startswith('repos_')):
provisioned_capacity += float(volume["capacity"])
cinder_pool["provisioned_capacity_gb"] = (provisioned_capacity /
units.Gi)
cinder_pool["free_capacity_gb"] = ((tot_bytes - used_bytes) / cinder_pool["free_capacity_gb"] = ((tot_bytes - used_bytes) /
units.Gi) units.Gi)
cinder_pool["total_capacity_gb"] = tot_bytes / units.Gi cinder_pool["total_capacity_gb"] = tot_bytes / units.Gi

View File

@ -0,0 +1,7 @@
---
fixes:
- The NetApp E-series driver has been fixed to correctly report
the "provisioned_capacity_gb". Now it sums the capacity of all
the volumes in the configured backend to get the correct value.
This bug fix affects all the protocols supported by the driver
(FC and iSCSI).