]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/namespace.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / core / namespace.c
index 045321e1d44e8468ac6530f809948366767de4b5..6806fc27e6c8813921aa282b3e4ee99cada627a0 100644 (file)
 ***/
 
 #include <errno.h>
-#include <sys/mount.h>
-#include <string.h>
+#include <sched.h>
 #include <stdio.h>
-#include <unistd.h>
+#include <string.h>
+#include <sys/mount.h>
 #include <sys/stat.h>
-#include <sched.h>
+#include <unistd.h>
 #include <linux/fs.h>
 
-#include "strv.h"
-#include "util.h"
-#include "path-util.h"
-#include "missing.h"
-#include "loopback-setup.h"
 #include "dev-setup.h"
+#include "loopback-setup.h"
+#include "missing.h"
+#include "mkdir.h"
+#include "path-util.h"
 #include "selinux-util.h"
+#include "string-util.h"
+#include "strv.h"
+#include "util.h"
 #include "namespace.h"
-#include "mkdir.h"
 
 typedef enum MountMode {
         /* This is ordered by priority! */
@@ -288,22 +289,21 @@ static int mount_kdbus(BindMount *m) {
         /* create a new /dev/null dev node copy so we have some fodder to
          * bind-mount the custom endpoint over. */
         if (stat("/dev/null", &st) < 0) {
-                log_error_errno(errno, "Failed to stat /dev/null: %m");
-                r = -errno;
+                r = log_error_errno(errno, "Failed to stat /dev/null: %m");
                 goto fail;
         }
 
         busnode = strjoina(root, "/bus");
         if (mknod(busnode, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) {
-                log_error_errno(errno, "mknod() for %s failed: %m", busnode);
-                r = -errno;
+                r = log_error_errno(errno, "mknod() for %s failed: %m",
+                                    busnode);
                 goto fail;
         }
 
         r = mount(m->path, busnode, NULL, MS_BIND, NULL);
         if (r < 0) {
-                log_error_errno(errno, "bind mount of %s failed: %m", m->path);
-                r = -errno;
+                r = log_error_errno(errno, "bind mount of %s failed: %m",
+                                    m->path);
                 goto fail;
         }
 
@@ -314,8 +314,8 @@ static int mount_kdbus(BindMount *m) {
         }
 
         if (mount(root, basepath, NULL, MS_MOVE, NULL) < 0) {
-                log_error_errno(errno, "bind mount of %s failed: %m", basepath);
-                r = -errno;
+                r = log_error_errno(errno, "bind mount of %s failed: %m",
+                                    basepath);
                 goto fail;
         }
 
@@ -556,10 +556,9 @@ int setup_namespace(
         /* Remount / as the desired mode. Not that this will not
          * reestablish propagation from our side to the host, since
          * what's disconnected is disconnected. */
-        if (mount(NULL, "/", NULL, mount_flags | MS_REC, NULL) < 0) {
+        if (mount(NULL, "/", NULL, mount_flags | MS_REC, NULL) < 0)
                 /* at this point, we cannot rollback */
                 return -errno;
-        }
 
         return 0;
 
@@ -645,16 +644,7 @@ int setup_tmp_dirs(const char *id, char **tmp_dir, char **var_tmp_dir) {
 
 int setup_netns(int netns_storage_socket[2]) {
         _cleanup_close_ int netns = -1;
-        union {
-                struct cmsghdr cmsghdr;
-                uint8_t buf[CMSG_SPACE(sizeof(int))];
-        } control = {};
-        struct msghdr mh = {
-                .msg_control = &control,
-                .msg_controllen = sizeof(control),
-        };
-        struct cmsghdr *cmsg;
-        int r;
+        int r, q;
 
         assert(netns_storage_socket);
         assert(netns_storage_socket[0] >= 0);
@@ -671,12 +661,8 @@ int setup_netns(int netns_storage_socket[2]) {
         if (lockf(netns_storage_socket[0], F_LOCK, 0) < 0)
                 return -errno;
 
-        if (recvmsg(netns_storage_socket[0], &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC) < 0) {
-                if (errno != EAGAIN) {
-                        r = -errno;
-                        goto fail;
-                }
-
+        netns = receive_one_fd(netns_storage_socket[0], MSG_DONTWAIT);
+        if (netns == -EAGAIN) {
                 /* Nothing stored yet, so let's create a new namespace */
 
                 if (unshare(CLONE_NEWNET) < 0) {
@@ -693,15 +679,13 @@ int setup_netns(int netns_storage_socket[2]) {
                 }
 
                 r = 1;
-        } else {
-                /* Yay, found something, so let's join the namespace */
 
-                CMSG_FOREACH(cmsg, &mh)
-                        if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
-                                assert(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
-                                netns = *(int*) CMSG_DATA(cmsg);
-                        }
+        } else if (netns < 0) {
+                r = netns;
+                goto fail;
 
+        } else {
+                /* Yay, found something, so let's join the namespace */
                 if (setns(netns, CLONE_NEWNET) < 0) {
                         r = -errno;
                         goto fail;
@@ -710,21 +694,14 @@ int setup_netns(int netns_storage_socket[2]) {
                 r = 0;
         }
 
-        cmsg = CMSG_FIRSTHDR(&mh);
-        cmsg->cmsg_level = SOL_SOCKET;
-        cmsg->cmsg_type = SCM_RIGHTS;
-        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
-        memcpy(CMSG_DATA(cmsg), &netns, sizeof(int));
-        mh.msg_controllen = cmsg->cmsg_len;
-
-        if (sendmsg(netns_storage_socket[1], &mh, MSG_DONTWAIT|MSG_NOSIGNAL) < 0) {
-                r = -errno;
+        q = send_one_fd(netns_storage_socket[1], netns, MSG_DONTWAIT);
+        if (q < 0) {
+                r = q;
                 goto fail;
         }
 
 fail:
         lockf(netns_storage_socket[0], F_ULOCK, 0);
-
         return r;
 }