From efcec1d0ee7c892059519ad21791fce4943ac569 Mon Sep 17 00:00:00 2001 From: Gorka Eguileor Date: Fri, 26 Jun 2020 16:31:36 +0200 Subject: [PATCH] RBD: Fix error on disconnect On the RBD driver, when doing a disconnect call inside a container, when the "rbd_common" package is installed on the host, we can get a "No such file or directory" error if the udev rule from the host removes the symlink before we do. This error is caused by the rm command returning 1 for different type of errors, so we'll now use -f to ensure we don't fail if the file is missing, which is what we intended before when passing the check_exit_code parameter to the execute call. Trivial-Fix Closes-Bug: #1885293 Change-Id: Id1655614a8a60fba8ed225c6cea53ae1ed4b694a --- cinderlib/nos_brick.py | 3 +-- cinderlib/tests/unit/test_nos_brick.py | 19 +++++++++++++++++++ ...ng-file-or-directory-c835abac22f6b32e.yaml | 7 +++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/rbd-missing-file-or-directory-c835abac22f6b32e.yaml diff --git a/cinderlib/nos_brick.py b/cinderlib/nos_brick.py index ade8958..0e91ca4 100644 --- a/cinderlib/nos_brick.py +++ b/cinderlib/nos_brick.py @@ -253,8 +253,7 @@ def unlink_root(*links, **kwargs): else: with exc.context(catch_exception, error_msg, links): # Ignore file doesn't exist errors - putils.execute('rm', *links, run_as_root=True, - check_exit_code=(0, errno.ENOENT), + putils.execute('rm', '-f', *links, run_as_root=True, root_helper=ROOT_HELPER) if not no_errors and raise_at_end and exc: diff --git a/cinderlib/tests/unit/test_nos_brick.py b/cinderlib/tests/unit/test_nos_brick.py index 4e0b744..6a526ad 100644 --- a/cinderlib/tests/unit/test_nos_brick.py +++ b/cinderlib/tests/unit/test_nos_brick.py @@ -476,3 +476,22 @@ class TestRBDConnector(base.BaseTest): exec_mock.assert_called_once_with( 'dd', 'if=/tmp/path', 'of=/dev/null', 'bs=4096', 'count=1', root_helper=self.connector._root_helper, run_as_root=True) + + @mock.patch.object(nos_brick.os, 'unlink') + @mock.patch.object(nos_brick.os, 'getuid', return_value=0) + def test_unlink_root_being_root(self, mock_getuid, mock_unlink): + mock_unlink.side_effect = [None, OSError(errno.ENOENT, '')] + nos_brick.unlink_root(mock.sentinel.file1, mock.sentinel.file2) + mock_getuid.assert_called_once() + mock_unlink.assert_has_calls([mock.call(mock.sentinel.file1), + mock.call(mock.sentinel.file2)]) + + @mock.patch.object(nos_brick.putils, 'execute') + @mock.patch.object(nos_brick.os, 'getuid', return_value=1000) + def test_unlink_root_non_root(self, mock_getuid, mock_exec): + nos_brick.unlink_root(mock.sentinel.file1, mock.sentinel.file2) + mock_getuid.assert_called_once() + mock_exec.assert_called_once_with('rm', '-f', mock.sentinel.file1, + mock.sentinel.file2, + run_as_root=True, + root_helper=nos_brick.ROOT_HELPER) diff --git a/releasenotes/notes/rbd-missing-file-or-directory-c835abac22f6b32e.yaml b/releasenotes/notes/rbd-missing-file-or-directory-c835abac22f6b32e.yaml new file mode 100644 index 0000000..3453e60 --- /dev/null +++ b/releasenotes/notes/rbd-missing-file-or-directory-c835abac22f6b32e.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fix issue where disconnecting an RBD volume inside a container when the + host had the ceph-common package installed could lead to failure due to a + "No such file or directory" error. + (Bug #1885293).