From 55fd2ec7ca167f0c79937ee613b800e973321652 Mon Sep 17 00:00:00 2001 From: Silvan Kaiser Date: Tue, 19 Jul 2016 12:17:45 +0200 Subject: [PATCH] Correct Quobyte driver capacity reporting Current capacity reporting is based on logical values which can differ significantly from real usage with e.g. sparse files. This change switches to using physical values and includes free space correction based on a Quobyte volumes internal replication factor. Closes-Bug: #1603434 Change-Id: I74ae2974709a13697412f43a448582be56c21e63 --- manila/share/drivers/quobyte/quobyte.py | 19 ++++++++--- .../share/drivers/quobyte/test_quobyte.py | 32 +++++++++++++++++-- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/manila/share/drivers/quobyte/quobyte.py b/manila/share/drivers/quobyte/quobyte.py index ac926f4dc2..000997206a 100644 --- a/manila/share/drivers/quobyte/quobyte.py +++ b/manila/share/drivers/quobyte/quobyte.py @@ -76,9 +76,10 @@ class QuobyteShareDriver(driver.ExecuteMixin, driver.ShareDriver,): 1.0.1 - Adds ensure_share() implementation. 1.1 - Adds extend_share() and shrink_share() implementation. 1.2 - Adds update_access() implementation and related methods + 1.2.1 - Improved capacity calculation """ - DRIVER_VERSION = '1.2' + DRIVER_VERSION = '1.2.1' def __init__(self, *args, **kwargs): super(QuobyteShareDriver, self).__init__(False, *args, **kwargs) @@ -141,18 +142,28 @@ class QuobyteShareDriver(driver.ExecuteMixin, driver.ShareDriver,): def _get_capacities(self): result = self.rpc.call('getSystemStatistics', {}) - total = float(result['total_logical_capacity']) - used = float(result['total_logical_usage']) + total = float(result['total_physical_capacity']) + used = float(result['total_physical_usage']) LOG.info(_LI('Read capacity of %(cap)s bytes and ' 'usage of %(use)s bytes from backend. '), {'cap': total, 'use': used}) free = total - used + if free < 0: + free = 0 # no space available + free_replicated = free / self._get_qb_replication_factor() # floor numbers to nine digits (bytes) total = math.floor((total / units.Gi) * units.G) / units.G - free = math.floor((free / units.Gi) * units.G) / units.G + free = math.floor((free_replicated / units.Gi) * units.G) / units.G return total, free + def _get_qb_replication_factor(self): + result = self.rpc.call('getEffectiveVolumeConfiguration', + {'configuration_name': self. + configuration.quobyte_volume_configuration}) + return int(result['configuration']['volume_metadata_configuration'] + ['replication_factor']) + def check_for_setup_error(self): pass diff --git a/manila/tests/share/drivers/quobyte/test_quobyte.py b/manila/tests/share/drivers/quobyte/test_quobyte.py index f71785323c..8f73f0bcc1 100644 --- a/manila/tests/share/drivers/quobyte/test_quobyte.py +++ b/manila/tests/share/drivers/quobyte/test_quobyte.py @@ -318,13 +318,39 @@ class QuobyteShareDriverTestCase(test.TestCase): def test_get_capacities_gb(self): capval = 42115548133 useval = 19695128917 + replfact = 3 + self._driver._get_qb_replication_factor = mock.Mock( + return_value=replfact) self._driver.rpc.call = mock.Mock( - return_value={'total_logical_capacity': six.text_type(capval), - 'total_logical_usage': six.text_type(useval)}) + return_value={'total_physical_capacity': six.text_type(capval), + 'total_physical_usage': six.text_type(useval)}) - self.assertEqual((39.223160718, 20.880642548), + self.assertEqual((39.223160718, 6.960214182), self._driver._get_capacities()) + def test_get_capacities_gb_full(self): + capval = 1024 * 1024 * 1024 * 3 + useval = 1024 * 1024 * 1024 * 3 + 1 + replfact = 1 + self._driver._get_qb_replication_factor = mock.Mock( + return_value=replfact) + self._driver.rpc.call = mock.Mock( + return_value={'total_physical_capacity': six.text_type(capval), + 'total_physical_usage': six.text_type(useval)}) + + self.assertEqual((3.0, 0), self._driver._get_capacities()) + + def test_get_replication(self): + fakerepl = 42 + self._driver.configuration.quobyte_volume_configuration = 'fakeVolConf' + self._driver.rpc.call = mock.Mock( + return_value={'configuration': + {'volume_metadata_configuration': + {'replication_factor': + six.text_type(fakerepl)}}}) + + self.assertEqual(fakerepl, self._driver._get_qb_replication_factor()) + @mock.patch.object(quobyte.QuobyteShareDriver, "_resolve_volume_name", return_value="fake_uuid")