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
This commit is contained in:
Gorka Eguileor 2020-06-26 16:31:36 +02:00
parent acf411975d
commit efcec1d0ee
3 changed files with 27 additions and 2 deletions

View File

@ -253,8 +253,7 @@ def unlink_root(*links, **kwargs):
else: else:
with exc.context(catch_exception, error_msg, links): with exc.context(catch_exception, error_msg, links):
# Ignore file doesn't exist errors # Ignore file doesn't exist errors
putils.execute('rm', *links, run_as_root=True, putils.execute('rm', '-f', *links, run_as_root=True,
check_exit_code=(0, errno.ENOENT),
root_helper=ROOT_HELPER) root_helper=ROOT_HELPER)
if not no_errors and raise_at_end and exc: if not no_errors and raise_at_end and exc:

View File

@ -476,3 +476,22 @@ class TestRBDConnector(base.BaseTest):
exec_mock.assert_called_once_with( exec_mock.assert_called_once_with(
'dd', 'if=/tmp/path', 'of=/dev/null', 'bs=4096', 'count=1', 'dd', 'if=/tmp/path', 'of=/dev/null', 'bs=4096', 'count=1',
root_helper=self.connector._root_helper, run_as_root=True) 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)

View File

@ -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).