]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fix bug in rbd driver: the cloned volume size is wrong
authorwuyuting <wytdahu@gmail.com>
Sun, 18 Jan 2015 22:32:34 +0000 (06:32 +0800)
committerwuyuting <wytdahu@gmail.com>
Wed, 21 Jan 2015 18:41:26 +0000 (02:41 +0800)
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

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

index 2dabe8c4a0379aa2f673e55bbec9e754c259dc07..ea7793e58cc86ed4ae2b5c7c1a7e7fb36c5059ca 100644 (file)
@@ -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):
index 6a9e16837c39efe7f1585c4265d1ed71a1503254..7a79a8547a84b1b51003d3464bcede1590023d58 100644 (file)
@@ -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):