]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
namespace-util: introduce helper for combining unshare() + MS_SLAVE remount
authorLennart Poettering <lennart@poettering.net>
Sun, 2 Feb 2020 17:56:12 +0000 (18:56 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 7 Jul 2020 09:20:42 +0000 (11:20 +0200)
We have multiple places we do these two non-trivial operations together,
let's introduce a unified helper for doing both at once.

src/basic/namespace-util.c
src/basic/namespace-util.h
src/core/machine-id-setup.c
src/shared/tests.c
src/test/test-udev.c

index b0168ae227caf2fee9344867e05b92f8cc119f60..b34c532604a5fe85b88e6fae3b49f32300d13de6 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#include <sys/mount.h>
 
 #include "fd-util.h"
 #include "missing_fs.h"
@@ -169,3 +170,16 @@ int fd_is_network_ns(int fd) {
 
         return r == CLONE_NEWNET;
 }
+
+int detach_mount_namespace(void) {
+
+        /* Detaches the mount namespace, disabling propagation from our namespace to the host */
+
+        if (unshare(CLONE_NEWNS) < 0)
+                return -errno;
+
+        if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
+                return -errno;
+
+        return 0;
+}
index 8c17ce91b21ca4aa781a7c46239734c4e9be870f..99d9b977edf118614406faa34f23381040a9acf1 100644 (file)
@@ -7,3 +7,5 @@ int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *
 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
 
 int fd_is_network_ns(int fd);
+
+int detach_mount_namespace(void);
index 284b77c1fcce9d11b4ca0bbb03d13a4c156f96de..f76b82a8a45a18eb7a1981dcc50e1a1e232810db 100644 (file)
@@ -223,11 +223,9 @@ int machine_id_commit(const char *root) {
                 return log_error_errno(r, "Can't fetch current mount namespace: %m");
 
         /* Switch to a new mount namespace, isolate ourself and unmount etc_machine_id in our new namespace */
-        if (unshare(CLONE_NEWNS) < 0)
-                return log_error_errno(errno, "Failed to enter new namespace: %m");
-
-        if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
-                return log_error_errno(errno, "Couldn't make-rslave / mountpoint in our private namespace: %m");
+        r = detach_mount_namespace();
+        if (r < 0)
+                return log_error_errno(r, "Failed to set up new mount namespace: %m");
 
         if (umount(etc_machine_id) < 0)
                 return log_error_errno(errno, "Failed to unmount transient %s file in our private namespace: %m", etc_machine_id);
index ecf8e8f623720f14231d69f0de378d90f848ba31..ff662ecfe0cdc27393234470e82da99ae8b2cf4c 100644 (file)
@@ -21,6 +21,7 @@
 #include "env-util.h"
 #include "fs-util.h"
 #include "log.h"
+#include "namespace-util.h"
 #include "path-util.h"
 #include "random-util.h"
 #include "strv.h"
@@ -137,10 +138,7 @@ bool have_namespaces(void) {
 
         if (pid == 0) {
                 /* child */
-                if (unshare(CLONE_NEWNS) < 0)
-                        _exit(EXIT_FAILURE);
-
-                if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
+                if (detach_mount_namespace() < 0)
                         _exit(EXIT_FAILURE);
 
                 _exit(EXIT_SUCCESS);
index 208e7a0e96a7d6e0bb0fde3fbcd62642fb717303..c0b215dadc4020dc262cee426b56286e73651ca3 100644 (file)
@@ -17,6 +17,7 @@
 #include "log.h"
 #include "main-func.h"
 #include "mkdir.h"
+#include "namespace-util.h"
 #include "selinux-util.h"
 #include "signal-util.h"
 #include "string-util.h"
@@ -36,15 +37,13 @@ static int fake_filesystems(void) {
                 { "test/run",       "/etc/udev/rules.d",       "Failed to mount empty /etc/udev/rules.d",          true },
                 { "test/run",       UDEVLIBEXECDIR "/rules.d", "Failed to mount empty " UDEVLIBEXECDIR "/rules.d", true },
         };
-        unsigned i;
-
-        if (unshare(CLONE_NEWNS) < 0)
-                return log_error_errno(errno, "Failed to call unshare(): %m");
+        int r;
 
-        if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
-                return log_error_errno(errno, "Failed to mount / as private: %m");
+        r = detach_mount_namespace();
+        if (r < 0)
+                return log_error_errno(r, "Failed to detach mount namespace: %m");
 
-        for (i = 0; i < ELEMENTSOF(fakefss); i++)
+        for (size_t i = 0; i < ELEMENTSOF(fakefss); i++)
                 if (mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL) < 0) {
                         log_full_errno(fakefss[i].ignore_mount_error ? LOG_DEBUG : LOG_ERR, errno, "%s: %m", fakefss[i].error);
                         if (!fakefss[i].ignore_mount_error)