From a8190cd60b59dedb11a8ed27d236d81adee3255d Mon Sep 17 00:00:00 2001 From: David Vallee Delisle Date: Wed, 18 Dec 2019 14:11:33 -0500 Subject: [PATCH] Read mounts from /proc/mounts instead of running mount When creating multiple concurrent volumes, there's a lock that prevents mount from returning quickly. Reading /proc/mounts is way faster. Change-Id: If31d120955eb216823a55005fdd3d24870aa6b9a Closes-Bug: #1856889 (cherry picked from commit f2409608473c06892b087e44e0041c9ade3f9924) --- os_brick/remotefs/remotefs.py | 23 +++++++++++++---------- os_brick/tests/remotefs/test_remotefs.py | 14 ++++++++------ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/os_brick/remotefs/remotefs.py b/os_brick/remotefs/remotefs.py index 76c7f8fd6..7262f922f 100644 --- a/os_brick/remotefs/remotefs.py +++ b/os_brick/remotefs/remotefs.py @@ -81,16 +81,19 @@ class RemoteFsClient(executor.Executor): self._get_hash_str(device_name)) def _read_mounts(self): - (out, _err) = self._execute('mount', check_exit_code=0) - lines = out.split('\n') - mounts = {} - for line in lines: - tokens = line.split() - if 2 < len(tokens): - device = tokens[0] - mnt_point = tokens[2] - mounts[mnt_point] = device - return mounts + """Returns a dict of mounts and their mountpoint + + Format reference: + http://man7.org/linux/man-pages/man5/fstab.5.html + """ + with open("/proc/mounts", "r") as mounts: + # Remove empty lines and split lines by whitespace + lines = [l.split() for l in mounts.read().splitlines() + if l.strip()] + + # Return {mountpoint: mountdevice}. Fields 2nd and 1st as per + # http://man7.org/linux/man-pages/man5/fstab.5.html + return {line[1]: line[0] for line in lines if line[0] != '#'} def mount(self, share, flags=None): """Mount given share.""" diff --git a/os_brick/tests/remotefs/test_remotefs.py b/os_brick/tests/remotefs/test_remotefs.py index 27762153f..bcfbcdf48 100644 --- a/os_brick/tests/remotefs/test_remotefs.py +++ b/os_brick/tests/remotefs/test_remotefs.py @@ -59,15 +59,17 @@ class RemoteFsClientTestCase(base.TestCase): self.mock_execute.assert_has_calls(calls) def test_read_mounts(self): - mounts = """device1 on mnt_point1 - device2 on mnt_point2 type ext4 opts""" - with mock.patch.object(priv_rootwrap, 'execute', - return_value=[mounts, '']): + mounts = """device1 mnt_point1 ext4 rw,seclabel,relatime 0 0 + device2 mnt_point2 ext4 rw,seclabel,relatime 0 0""" + mockopen = mock.mock_open(read_data=mounts) + mockopen.return_value.__iter__ = lambda self: iter(self.readline, '') + with mock.patch.object(six.moves.builtins, "open", mockopen, + create=True): client = remotefs.RemoteFsClient("cifs", root_helper='true', smbfs_mount_point_base='/mnt') ret = client._read_mounts() - self.assertEqual(ret, {'mnt_point1': 'device1', - 'mnt_point2': 'device2'}) + self.assertEqual(ret, {'mnt_point1': 'device1', + 'mnt_point2': 'device2'}) @mock.patch.object(priv_rootwrap, 'execute') @mock.patch.object(remotefs.RemoteFsClient, '_do_mount')