RBD Thin Provisioning stats

Allow the RBD driver to work with max_over_subscription_ratio.

This should be expanded to use rbd diff_iterate2() when
Infernalis and newer deployments are widespread.

Co-Authored-By: Ivan Kolodyazhny <e0ne@e0ne.info>
Change-Id: Ida7654545ae46d106908b991c91bab989b998484
This commit is contained in:
Eric Harney 2016-01-18 16:47:51 -05:00 committed by Ivan Kolodyazhny
parent 2c0eea799c
commit d4fd566073
3 changed files with 40 additions and 5 deletions

View File

@ -79,12 +79,13 @@ def common_mocks(f):
def _common_inner_inner1(inst, *args, **kwargs):
@mock.patch('retrying.Retrying', _FakeRetrying)
@mock.patch.object(driver.RBDDriver, '_get_usage_info')
@mock.patch('cinder.volume.drivers.rbd.RBDVolumeProxy')
@mock.patch('cinder.volume.drivers.rbd.RADOSClient')
@mock.patch('cinder.backup.drivers.ceph.rbd')
@mock.patch('cinder.backup.drivers.ceph.rados')
def _common_inner_inner2(mock_rados, mock_rbd, mock_client,
mock_proxy):
mock_proxy, mock_usage_info):
inst.mock_rbd = mock_rbd
inst.mock_rados = mock_rados
inst.mock_client = mock_client
@ -821,7 +822,10 @@ class RBDTestCase(test.TestCase):
storage_protocol='ceph',
total_capacity_gb=28.44,
free_capacity_gb=27.0,
reserved_percentage=0,
reserved_percentage='RBD',
thin_provisioning_support=True,
provisioned_capacity_gb=0.0,
max_over_subscription_ratio='RBD',
multiattach=False)
actual = self.driver.get_volume_stats(True)
@ -847,8 +851,11 @@ class RBDTestCase(test.TestCase):
storage_protocol='ceph',
total_capacity_gb='unknown',
free_capacity_gb='unknown',
reserved_percentage=0,
multiattach=False)
reserved_percentage='RBD',
multiattach=False,
provisioned_capacity_gb=0.0,
max_over_subscription_ratio='RBD',
thin_provisioning_support=True)
actual = self.driver.get_volume_stats(True)
client.cluster.mon_command.assert_called_once_with(

View File

@ -389,6 +389,20 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
ports.append(port)
return hosts, ports
def _iterate_cb(self, offset, length, exists):
if exists:
self._total_usage += length
def _get_usage_info(self):
with RADOSClient(self) as client:
for t in self.RBDProxy().list(client.ioctx):
if t.startswith('volume'):
# Only check for "volume" to allow some flexibility with
# non-default volume_name_template settings. Template
# must start with "volume".
with RBDVolumeProxy(self, t, read_only=True) as v:
v.diff_iterate(0, v.size(), None, self._iterate_cb)
def _update_volume_stats(self):
stats = {
'vendor_name': 'Open Source',
@ -396,8 +410,14 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
'storage_protocol': 'ceph',
'total_capacity_gb': 'unknown',
'free_capacity_gb': 'unknown',
'reserved_percentage': 0,
'provisioned_capacity_gb': 0,
'reserved_percentage': (
self.configuration.safe_get('reserved_percentage')),
'multiattach': False,
'thin_provisioning_support': True,
'max_over_subscription_ratio': (
self.configuration.safe_get('max_over_subscription_ratio'))
}
backend_name = self.configuration.safe_get('volume_backend_name')
stats['volume_backend_name'] = backend_name or 'RBD'
@ -419,6 +439,11 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
pool_stats['bytes_used']) / units.Gi
stats['total_capacity_gb'] = round(
(stats['free_capacity_gb'] + used_capacity_gb), 2)
self._total_usage = 0
self._get_usage_info()
total_usage_gb = math.ceil(float(self._total_usage) / units.Gi)
stats['provisioned_capacity_gb'] = total_usage_gb
except self.rados.Error:
# just log and return unknown capacities
LOG.exception(_LE('error refreshing volume stats'))

View File

@ -0,0 +1,3 @@
---
features:
- Allow the RBD driver to work with max_over_subscription_ratio.