]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Rbd update volume stats in wrong way
authorwuyuting <wytdahu@gmail.com>
Fri, 20 Mar 2015 10:41:11 +0000 (18:41 +0800)
committerDuncan Thomas <duncan.thomas@hp.com>
Tue, 7 Apr 2015 09:33:40 +0000 (12:33 +0300)
Cinder volume uses a RADOS pool to store volumes and
update storage stats periodically. However, rbd driver
reports the whole cluster stats but not the pool's. This
is wrong. The right way is to report the pool stats but
not the whole cluster.

Change-Id: Ie18324ebd8b85f7b63dc034ba20857ae9e470804
Closes-Bug: #1434441

cinder/tests/test_rbd.py
cinder/volume/drivers/rbd.py

index b30735293e520d553ef2e9233c0e2a3c4a1dffcc..fcd3bcc6303a4174a1ea1e2c89f7d38a318b8206 100644 (file)
@@ -662,10 +662,14 @@ class RBDTestCase(test.TestCase):
         client.__enter__.return_value = client
 
         client.cluster = mock.Mock()
-        client.cluster.get_cluster_stats = mock.Mock()
-        client.cluster.get_cluster_stats.return_value = {'kb': 1024 ** 3,
-                                                         'kb_avail': 1024 ** 2}
-
+        client.cluster.mon_command = mock.Mock()
+        client.cluster.mon_command.return_value = (
+            0, '{"stats":{"total_bytes":64385286144,'
+            '"total_used_bytes":3289628672,"total_avail_bytes":61095657472},'
+            '"pools":[{"name":"rbd","id":2,"stats":{"kb_used":1510197,'
+            '"bytes_used":1546440971,"max_avail":28987613184,"objects":412}},'
+            '{"name":"volumes","id":3,"stats":{"kb_used":0,"bytes_used":0,'
+            '"max_avail":28987613184,"objects":0}}]}\n', '')
         self.driver.configuration.safe_get = mock.Mock()
         self.driver.configuration.safe_get.return_value = 'RBD'
 
@@ -674,12 +678,13 @@ class RBDTestCase(test.TestCase):
             vendor_name='Open Source',
             driver_version=self.driver.VERSION,
             storage_protocol='ceph',
-            total_capacity_gb=1024,
-            free_capacity_gb=1,
+            total_capacity_gb=27,
+            free_capacity_gb=26,
             reserved_percentage=0)
 
         actual = self.driver.get_volume_stats(True)
-        client.cluster.get_cluster_stats.assert_called_once_with()
+        client.cluster.mon_command.assert_called_once_with(
+            '{"prefix":"df", "format":"json"}', '')
         self.assertDictMatch(expected, actual)
 
     @common_mocks
@@ -688,8 +693,8 @@ class RBDTestCase(test.TestCase):
         client.__enter__.return_value = client
 
         client.cluster = mock.Mock()
-        client.cluster.get_cluster_stats = mock.Mock()
-        client.cluster.get_cluster_stats.side_effect = Exception
+        client.cluster.mon_command = mock.Mock()
+        client.cluster.mon_command.return_value = (22, '', '')
 
         self.driver.configuration.safe_get = mock.Mock()
         self.driver.configuration.safe_get.return_value = 'RBD'
@@ -703,7 +708,8 @@ class RBDTestCase(test.TestCase):
                         reserved_percentage=0)
 
         actual = self.driver.get_volume_stats(True)
-        client.cluster.get_cluster_stats.assert_called_once_with()
+        client.cluster.mon_command.assert_called_once_with(
+            '{"prefix":"df", "format":"json"}', '')
         self.assertDictMatch(expected, actual)
 
     @common_mocks
index d9e939b5e2992e85509540c1fc37a206a26dcbb4..7dae2ec2044465c6ce0206577a1ec7d868c5411c 100644 (file)
@@ -371,9 +371,20 @@ class RBDDriver(driver.VolumeDriver):
 
         try:
             with RADOSClient(self) as client:
-                new_stats = client.cluster.get_cluster_stats()
-            stats['total_capacity_gb'] = new_stats['kb'] / units.Mi
-            stats['free_capacity_gb'] = new_stats['kb_avail'] / units.Mi
+                ret, outbuf, _outs = client.cluster.mon_command(
+                    '{"prefix":"df", "format":"json"}', '')
+                if ret != 0:
+                    LOG.warning(_LW('Unable to get rados pool stats.'))
+                else:
+                    outbuf = json.loads(outbuf)
+                    pool_stats = [pool for pool in outbuf['pools'] if
+                                  pool['name'] ==
+                                  self.configuration.rbd_pool][0]['stats']
+                    stats['free_capacity_gb'] = (
+                        pool_stats['max_avail'] / units.Gi)
+                    used_capacity_gb = pool_stats['bytes_used'] / units.Gi
+                    stats['total_capacity_gb'] = (stats['free_capacity_gb']
+                                                  + used_capacity_gb)
         except self.rados.Error:
             # just log and return unknown capacities
             LOG.exception(_LE('error refreshing volume stats'))