From: wuyuting Date: Sun, 18 Jan 2015 22:32:34 +0000 (+0800) Subject: Fix bug in rbd driver: the cloned volume size is wrong X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=ae375ebb9d64f67767838d91c5d007fee93f4f63;p=openstack-build%2Fcinder-build.git Fix bug in rbd driver: the cloned volume size is wrong The cloned volume size is wrong when the size is different from source volume. This is because rbd driver doesn't resize the volume when clone has completed. Change-Id: If953441b2c24dee46bd64e6d4b8f4d3ab116f0fa Closes-Bug: #1412317 --- diff --git a/cinder/tests/test_rbd.py b/cinder/tests/test_rbd.py index 2dabe8c4a..ea7793e58 100644 --- a/cinder/tests/test_rbd.py +++ b/cinder/tests/test_rbd.py @@ -472,7 +472,7 @@ class RBDTestCase(test.TestCase): volume.parent_info.assert_called_once_with() @common_mocks - def test_create_cloned_volume(self): + def test_create_cloned_volume_same_size(self): src_name = u'volume-00000001' dst_name = u'volume-00000002' @@ -481,19 +481,59 @@ class RBDTestCase(test.TestCase): with mock.patch.object(self.driver, '_get_clone_depth') as \ mock_get_clone_depth: # Try with no flatten required - mock_get_clone_depth.return_value = 1 + with mock.patch.object(self.driver, '_resize') as mock_resize: + mock_get_clone_depth.return_value = 1 + + self.driver.create_cloned_volume({'name': dst_name, + 'size': 10}, + {'name': src_name, + 'size': 10}) + + (self.mock_rbd.Image.return_value.create_snap + .assert_called_once_with('.'.join((dst_name, + 'clone_snap')))) + (self.mock_rbd.Image.return_value.protect_snap + .assert_called_once_with('.'.join((dst_name, + 'clone_snap')))) + self.assertEqual( + 1, self.mock_rbd.RBD.return_value.clone.call_count) + self.mock_rbd.Image.return_value.close \ + .assert_called_once_with() + self.assertTrue(mock_get_clone_depth.called) + self.assertEqual( + 0, mock_resize.call_count) - self.driver.create_cloned_volume({'name': dst_name}, - {'name': src_name}) + @common_mocks + def test_create_cloned_volume_different_size(self): + src_name = u'volume-00000001' + dst_name = u'volume-00000002' - (self.mock_rbd.Image.return_value.create_snap - .assert_called_once_with('.'.join((dst_name, 'clone_snap')))) - (self.mock_rbd.Image.return_value.protect_snap - .assert_called_once_with('.'.join((dst_name, 'clone_snap')))) - self.assertEqual( - 1, self.mock_rbd.RBD.return_value.clone.call_count) - self.mock_rbd.Image.return_value.close.assert_called_once_with() - self.assertTrue(mock_get_clone_depth.called) + self.cfg.rbd_max_clone_depth = 2 + + with mock.patch.object(self.driver, '_get_clone_depth') as \ + mock_get_clone_depth: + # Try with no flatten required + with mock.patch.object(self.driver, '_resize') as mock_resize: + mock_get_clone_depth.return_value = 1 + + self.driver.create_cloned_volume({'name': dst_name, + 'size': 20}, + {'name': src_name, + 'size': 10}) + + (self.mock_rbd.Image.return_value.create_snap + .assert_called_once_with('.'.join((dst_name, + 'clone_snap')))) + (self.mock_rbd.Image.return_value.protect_snap + .assert_called_once_with('.'.join((dst_name, + 'clone_snap')))) + self.assertEqual( + 1, self.mock_rbd.RBD.return_value.clone.call_count) + self.mock_rbd.Image.return_value.close \ + .assert_called_once_with() + self.assertTrue(mock_get_clone_depth.called) + self.assertEqual( + 1, mock_resize.call_count) @common_mocks def test_create_cloned_volume_w_flatten(self): diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py index 6a9e16837..7a79a8547 100644 --- a/cinder/volume/drivers/rbd.py +++ b/cinder/volume/drivers/rbd.py @@ -482,6 +482,13 @@ class RBDDriver(driver.VolumeDriver): finally: src_volume.close() + if volume['size'] != src_vref['size']: + LOG.debug("resize volume '%(dst_vol)s' from %(src_size)d to " + "%(dst_size)d" % + {'dst_vol': volume['name'], 'src_size': src_vref['size'], + 'dst_size': volume['size']}) + self._resize(volume) + LOG.debug("clone created successfully") def create_volume(self, volume):