summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwuyuting <wytdahu@gmail.com>2015-03-20 18:41:11 +0800
committerDuncan Thomas <duncan.thomas@hp.com>2015-04-07 12:33:40 +0300
commitac219d5dd93c5c637336a9c79389fc260af65d36 (patch)
tree265f26ef8b62de28c77eb0876455dca954cd725d
parent73f2c6f329ce1073a4ac27ce430d05ee05ac85fa (diff)
downloadcinder-ac219d5dd93c5c637336a9c79389fc260af65d36.tar.gz
Rbd update volume stats in wrong way
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
-rw-r--r--cinder/tests/test_rbd.py26
-rw-r--r--cinder/volume/drivers/rbd.py17
2 files changed, 30 insertions, 13 deletions
diff --git a/cinder/tests/test_rbd.py b/cinder/tests/test_rbd.py
index b30735293..fcd3bcc63 100644
--- a/cinder/tests/test_rbd.py
+++ b/cinder/tests/test_rbd.py
@@ -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
diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py
index d9e939b5e..7dae2ec20 100644
--- a/cinder/volume/drivers/rbd.py
+++ b/cinder/volume/drivers/rbd.py
@@ -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'))