]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
tests/integration: use ctypes for mount instead of util-linux
authorVincent Bernat <vincent@bernat.im>
Wed, 16 Mar 2016 20:32:53 +0000 (21:32 +0100)
committerVincent Bernat <vincent@bernat.im>
Wed, 16 Mar 2016 20:32:53 +0000 (21:32 +0100)
Some versions of util-linux had a bug with respect to private/slave
mounts. The kernel doesn't expect the option to be passed during the
initial mount but only during subsequent calls (you mount the FS, you
make it private and slave). Directly use mount(2) to avoid the problem.

tests/integration/fixtures/programs.py

index 7c26710de03cc7a77e9746cb51a58c1d0738f081..46afe27aad39e106961d1379f2883e90e8bf4657 100644 (file)
@@ -10,8 +10,38 @@ import multiprocessing
 import uuid
 import time
 import platform
+import ctypes
 from collections import namedtuple
 
+libc = ctypes.CDLL('libc.so.6', use_errno=True)
+
+
+def mount_bind(source, target):
+    ret = libc.mount(source.encode('ascii'),
+                     target.encode('ascii'),
+                     None,
+                     4096,      # MS_BIND
+                     None)
+    if ret == -1:
+        e = ctypes.get_errno()
+        raise OSError(e, os.strerror(e))
+
+
+def mount_tmpfs(target, private=False):
+    flags = [0]
+    if private:
+        flags.append(1 << 18)   # MS_PRIVATE
+        flags.append(1 << 19)   # MS_SLAVE
+    for fl in flags:
+        ret = libc.mount(b"none",
+                         target.encode('ascii'),
+                         b"tmpfs",
+                         fl,
+                         None)
+        if ret == -1:
+            e = ctypes.get_errno()
+            raise OSError(e, os.strerror(e))
+
 
 def most_recent(*args):
     """Return the most recent files matching one of the provided glob
@@ -33,9 +63,8 @@ def _replace_file(tmpdir, target, content):
     tmpname = str(uuid.uuid1())
     with tmpdir.join(tmpname).open("w") as tmp:
         tmp.write(content)
-        subprocess.check_call(["mount", "-n", "--bind",
-                               str(tmpdir.join(tmpname)),
-                               target])
+        mount_bind(str(tmpdir.join(tmpname)),
+                   target)
 
 
 @pytest.fixture
@@ -128,15 +157,11 @@ class LldpdFactory(object):
             # Chroot
             chroot = self.config.lldpd.privsep.chroot
             if os.path.isdir(chroot):
-                subprocess.check_call(["mount", "-n",
-                                       "-t", "tmpfs",
-                                       "tmpfs", chroot])
+                mount_tmpfs(chroot)
             else:
                 parent = os.path.abspath(os.path.join(chroot, os.pardir))
                 assert os.path.isdir(parent)
-                subprocess.check_call(["mount", "-n",
-                                       "-t", "tmpfs",
-                                       "tmpfs", parent])
+                mount_tmpfs(parent)
             # User/group
             user = self.config.lldpd.privsep.user
             group = self.config.lldpd.privsep.group
@@ -160,13 +185,11 @@ class LldpdFactory(object):
 
         # Also setup the "namespace-dependant" directory
         tmpdir.join("ns").ensure(dir=True)
-        subprocess.check_call(["mount", "-n", "--make-slave", "--make-private",
-                               "-t", "tmpfs",
-                               "tmpfs", str(tmpdir.join("ns"))])
+        mount_tmpfs(str(tmpdir.join("ns")), private=True)
 
         # We also need a proper /etc/os-release
         _replace_file(tmpdir, "/etc/os-release",
-                     """PRETTY_NAME="Spectacular GNU/Linux 2016"
+                      """PRETTY_NAME="Spectacular GNU/Linux 2016"
 NAME="Spectacular GNU/Linux"
 ID=spectacular
 HOME_URL="https://www.example.com/spectacular"
@@ -179,13 +202,13 @@ BUG_REPORT_URL="https://www.example.com/spectacular/bugs"
 
         # And we need to ensure name resolution is sane
         _replace_file(tmpdir, "/etc/hosts",
-                     """
+                      """
 127.0.0.1 localhost.localdomain localhost
 127.0.1.1 {name}.example.com {name}
 ::1       ip6-localhost ip6-loopback
 """.format(name=name))
         _replace_file(tmpdir, "/etc/nsswitch.conf",
-                     """
+                      """
 passwd: files
 group: files
 shadow: files
@@ -201,8 +224,7 @@ services: files
             _replace_file(tmpdir, path, "")
         path = os.path.join(self.config.lldpd.confdir, "lldpd.d")
         if os.path.isdir(path):
-            subprocess.check_call(["mount", "-n", "-t", "tmpfs",
-                                   "tmpfs", path])
+            mount_tmpfs(path)
 
 
 @pytest.fixture()