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 f240960847)
This commit is contained in:
David Vallee Delisle 2019-12-18 14:11:33 -05:00
parent f52c96ede4
commit a8190cd60b
2 changed files with 21 additions and 16 deletions

View File

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

View File

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