]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
namespace: Modernize shareable namespace functions 26749/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 8 Mar 2023 14:30:19 +0000 (15:30 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 13 Mar 2023 12:07:32 +0000 (13:07 +0100)
src/core/namespace.c
src/core/namespace.h

index 252f5c9d2ce01b2f2478b297da9a73f3bb5375b4..b4bb01bb742fa36cef0b476faf24c5d9bcc64094 100644 (file)
@@ -24,6 +24,7 @@
 #include "glyph-util.h"
 #include "label.h"
 #include "list.h"
+#include "lock-util.h"
 #include "loop-util.h"
 #include "loopback-setup.h"
 #include "missing_syscall.h"
@@ -2847,9 +2848,9 @@ int setup_tmp_dirs(const char *id, char **tmp_dir, char **var_tmp_dir) {
         return 0;
 }
 
-int setup_shareable_ns(const int ns_storage_socket[static 2], unsigned long nsflag) {
+int setup_shareable_ns(int ns_storage_socket[static 2], unsigned long nsflag) {
         _cleanup_close_ int ns = -EBADF;
-        int r, q;
+        int r;
         const char *ns_name, *ns_path;
 
         assert(ns_storage_socket);
@@ -2867,57 +2868,47 @@ int setup_shareable_ns(const int ns_storage_socket[static 2], unsigned long nsfl
          *
          * It's a bit crazy, but hey, works great! */
 
-        if (lockf(ns_storage_socket[0], F_LOCK, 0) < 0)
-                return -errno;
+        r = posix_lock(ns_storage_socket[0], LOCK_EX);
+        if (r < 0)
+                return r;
 
-        ns = receive_one_fd(ns_storage_socket[0], MSG_DONTWAIT);
-        if (ns == -EAGAIN) {
-                /* Nothing stored yet, so let's create a new namespace. */
+        CLEANUP_POSIX_UNLOCK(ns_storage_socket[0]);
 
-                if (unshare(nsflag) < 0) {
-                        r = -errno;
-                        goto fail;
-                }
+        ns = receive_one_fd(ns_storage_socket[0], MSG_PEEK|MSG_DONTWAIT);
+        if (ns >= 0) {
+                /* Yay, found something, so let's join the namespace */
+                r = RET_NERRNO(setns(ns, nsflag));
+                if (r < 0)
+                        return r;
 
-                (void) loopback_setup();
+                return 0;
+        }
 
-                ns_path = strjoina("/proc/self/ns/", ns_name);
-                ns = open(ns_path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                if (ns < 0) {
-                        r = -errno;
-                        goto fail;
-                }
+        if (ns != -EAGAIN)
+                return ns;
 
-                r = 1;
+        /* Nothing stored yet, so let's create a new namespace. */
 
-        } else if (ns < 0) {
-                r = ns;
-                goto fail;
+        if (unshare(nsflag) < 0)
+                return -errno;
 
-        } else {
-                /* Yay, found something, so let's join the namespace */
-                if (setns(ns, nsflag) < 0) {
-                        r = -errno;
-                        goto fail;
-                }
+        (void) loopback_setup();
 
-                r = 0;
-        }
+        ns_path = strjoina("/proc/self/ns/", ns_name);
+        ns = open(ns_path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (ns < 0)
+                return -errno;
 
-        q = send_one_fd(ns_storage_socket[1], ns, MSG_DONTWAIT);
-        if (q < 0) {
-                r = q;
-                goto fail;
-        }
+        r = send_one_fd(ns_storage_socket[1], ns, MSG_DONTWAIT);
+        if (r < 0)
+                return r;
 
-fail:
-        (void) lockf(ns_storage_socket[0], F_ULOCK, 0);
-        return r;
+        return 1;
 }
 
-int open_shareable_ns_path(const int ns_storage_socket[static 2], const char *path, unsigned long nsflag) {
+int open_shareable_ns_path(int ns_storage_socket[static 2], const char *path, unsigned long nsflag) {
         _cleanup_close_ int ns = -EBADF;
-        int q, r;
+        int r;
 
         assert(ns_storage_socket);
         assert(ns_storage_socket[0] >= 0);
@@ -2928,44 +2919,35 @@ int open_shareable_ns_path(const int ns_storage_socket[static 2], const char *pa
          * it. This is supposed to be called ahead of time, i.e. before setup_shareable_ns() which will
          * allocate a new anonymous ns if needed. */
 
-        if (lockf(ns_storage_socket[0], F_LOCK, 0) < 0)
-                return -errno;
+        r = posix_lock(ns_storage_socket[0], LOCK_EX);
+        if (r < 0)
+                return r;
 
-        ns = receive_one_fd(ns_storage_socket[0], MSG_DONTWAIT);
-        if (ns == -EAGAIN) {
-                /* Nothing stored yet. Open the file from the file system. */
+        CLEANUP_POSIX_UNLOCK(ns_storage_socket[0]);
 
-                ns = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-                if (ns < 0) {
-                        r = -errno;
-                        goto fail;
-                }
+        ns = receive_one_fd(ns_storage_socket[0], MSG_PEEK|MSG_DONTWAIT);
+        if (ns >= 0)
+                return 0;
+        if (ns != -EAGAIN)
+                return ns;
 
-                r = fd_is_ns(ns, nsflag);
-                if (r == 0) { /* Not a ns of our type? Refuse early. */
-                        r = -EINVAL;
-                        goto fail;
-                }
-                if (r < 0 && r != -EUCLEAN) /* EUCLEAN: we don't know */
-                        goto fail;
+        /* Nothing stored yet. Open the file from the file system. */
 
-                r = 1;
+        ns = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
+        if (ns < 0)
+                return -errno;
 
-        } else if (ns < 0) {
-                r = ns;
-                goto fail;
-        } else
-                r = 0; /* Already allocated */
+        r = fd_is_ns(ns, nsflag);
+        if (r == 0)
+                return -EINVAL;
+        if (r < 0 && r != -EUCLEAN) /* EUCLEAN: we don't know */
+                return r;
 
-        q = send_one_fd(ns_storage_socket[1], ns, MSG_DONTWAIT);
-        if (q < 0) {
-                r = q;
-                goto fail;
-        }
+        r = send_one_fd(ns_storage_socket[1], ns, MSG_DONTWAIT);
+        if (r < 0)
+                return r;
 
-fail:
-        (void) lockf(ns_storage_socket[0], F_ULOCK, 0);
-        return r;
+        return 1;
 }
 
 bool ns_type_supported(NamespaceType type) {
index 74f78784b6805636b4ae36f9ed73ba210a699235..52ab6c4f2fb9201f7fac7aabb1406d8994e4c7db 100644 (file)
@@ -153,8 +153,8 @@ int setup_tmp_dirs(
                 char **tmp_dir,
                 char **var_tmp_dir);
 
-int setup_shareable_ns(const int ns_storage_socket[static 2], unsigned long nsflag);
-int open_shareable_ns_path(const int netns_storage_socket[static 2], const char *path, unsigned long nsflag);
+int setup_shareable_ns(int ns_storage_socket[static 2], unsigned long nsflag);
+int open_shareable_ns_path(int netns_storage_socket[static 2], const char *path, unsigned long nsflag);
 
 const char* protect_home_to_string(ProtectHome p) _const_;
 ProtectHome protect_home_from_string(const char *s) _pure_;