summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2020-04-30 22:20:12 +0000
committerGerrit Code Review <review@openstack.org>2020-04-30 22:20:12 +0000
commit05f87142c5b81c53e6200c6bf1936df3d5a9e991 (patch)
tree4ae39ee38e1a11d168d5adf6fd3e46aa441631a2
parent5da6530592b9c0292cf2f1705793502a5dd420c9 (diff)
parent63ed20b7e9d9a3856c7f2444473504ae6e634e4c (diff)
downloadcinder-05f87142c5b81c53e6200c6bf1936df3d5a9e991.tar.gz
Merge "RBD: fix volume reference handling in clone logic" into stable/queens
-rw-r--r--cinder/tests/unit/volume/drivers/test_rbd.py11
-rw-r--r--cinder/volume/drivers/rbd.py3
2 files changed, 8 insertions, 6 deletions
diff --git a/cinder/tests/unit/volume/drivers/test_rbd.py b/cinder/tests/unit/volume/drivers/test_rbd.py
index 3b50840e8..58f35b594 100644
--- a/cinder/tests/unit/volume/drivers/test_rbd.py
+++ b/cinder/tests/unit/volume/drivers/test_rbd.py
@@ -923,10 +923,13 @@ class RBDTestCase(test.TestCase):
(self.mock_rbd.Image.return_value.protect_snap
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
+ # We expect clone() to be called exactly once.
self.assertEqual(
1, self.mock_rbd.RBD.return_value.clone.call_count)
+ # Without flattening, only the source volume is opened,
+ # so only one call to close() should occur.
self.assertEqual(
- 2, self.mock_rbd.Image.return_value.close.call_count)
+ 1, self.mock_rbd.Image.return_value.close.call_count)
self.assertTrue(mock_get_clone_depth.called)
mock_resize.assert_not_called()
mock_enable_repl.assert_not_called()
@@ -962,7 +965,7 @@ class RBDTestCase(test.TestCase):
image.protect_snap.assert_called_once_with(name + '.clone_snap')
self.assertEqual(1, self.mock_rbd.RBD.return_value.clone.call_count)
self.assertEqual(
- 2, self.mock_rbd.Image.return_value.close.call_count)
+ 1, self.mock_rbd.Image.return_value.close.call_count)
mock_get_clone_depth.assert_called_once_with(
self.mock_client().__enter__(), self.volume_a.name)
mock_resize.assert_not_called()
@@ -992,7 +995,7 @@ class RBDTestCase(test.TestCase):
self.assertEqual(
1, self.mock_rbd.RBD.return_value.clone.call_count)
self.assertEqual(
- 2, self.mock_rbd.Image.return_value.close.call_count)
+ 1, self.mock_rbd.Image.return_value.close.call_count)
self.assertTrue(mock_get_clone_depth.called)
self.assertEqual(
1, mock_resize.call_count)
@@ -1049,7 +1052,7 @@ class RBDTestCase(test.TestCase):
# We expect the driver to close both volumes, so 2 is expected
self.assertEqual(
- 3, self.mock_rbd.Image.return_value.close.call_count)
+ 2, self.mock_rbd.Image.return_value.close.call_count)
self.assertTrue(mock_get_clone_depth.called)
mock_enable_repl.assert_not_called()
diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py
index dcdb8ee6d..cf063c50a 100644
--- a/cinder/volume/drivers/rbd.py
+++ b/cinder/volume/drivers/rbd.py
@@ -595,6 +595,7 @@ class RBDDriver(driver.CloneableImageVD,
except Exception as e:
src_volume.unprotect_snap(clone_snap)
src_volume.remove_snap(clone_snap)
+ src_volume.close()
msg = (_("Failed to clone '%(src_vol)s@%(src_snap)s' to "
"'%(dest)s', error: %(error)s") %
{'src_vol': src_name,
@@ -603,8 +604,6 @@ class RBDDriver(driver.CloneableImageVD,
'error': e})
LOG.exception(msg)
raise exception.VolumeBackendAPIException(data=msg)
- finally:
- src_volume.close()
depth = self._get_clone_depth(client, src_name)
# If dest volume is a clone and rbd_max_clone_depth reached,