]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: port to notify_recv()
authorLennart Poettering <lennart@poettering.net>
Mon, 17 Feb 2025 11:00:19 +0000 (12:00 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 20 Feb 2025 17:11:31 +0000 (18:11 +0100)
src/nspawn/nspawn.c

index bcf0baaf7fb5289a7d83cc3aff6c9ed058f784f6..4ba3694280b0febb2ad2fe846414fe4e7a4aeb1d 100644 (file)
@@ -68,6 +68,7 @@
 #include "mount-util.h"
 #include "mountpoint-util.h"
 #include "namespace-util.h"
+#include "notify-recv.h"
 #include "nspawn-bind-user.h"
 #include "nspawn-cgroup.h"
 #include "nspawn-expose-ports.h"
@@ -3751,7 +3752,11 @@ static int setup_notify_child(const void *directory) {
 
         r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true);
         if (r < 0)
-                return log_error_errno(r, "SO_PASSCRED failed: %m");
+                return log_error_errno(r, "Failed to enable SO_PASSCRED: %m");
+
+        r = setsockopt_int(fd, SOL_SOCKET, SO_PASSPIDFD, true);
+        if (r < 0)
+                log_debug_errno(r, "Failed to enable SO_PASSPIDFD, ignoring: %m");
 
         return TAKE_FD(fd);
 }
@@ -4610,59 +4615,25 @@ static int setup_uid_map(
 }
 
 static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
-        char buf[NOTIFY_BUFFER_MAX+1];
-        char *p = NULL;
-        struct iovec iovec = {
-                .iov_base = buf,
-                .iov_len = sizeof(buf)-1,
-        };
-        CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) +
-                         CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)) control;
-        struct msghdr msghdr = {
-                .msg_iov = &iovec,
-                .msg_iovlen = 1,
-                .msg_control = &control,
-                .msg_controllen = sizeof(control),
-        };
-        struct ucred *ucred;
-        ssize_t n;
-        pid_t inner_child_pid;
-        _cleanup_strv_free_ char **tags = NULL;
+        pid_t inner_child_pid = PTR_TO_PID(userdata);
         int r;
 
         assert(userdata);
 
-        inner_child_pid = PTR_TO_PID(userdata);
-
-        if (revents != EPOLLIN) {
-                log_warning("Got unexpected poll event for notify fd.");
-                return 0;
-        }
-
-        n = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
-        if (ERRNO_IS_NEG_TRANSIENT(n))
-                return 0;
-        if (n == -ECHRNG) {
-                log_warning_errno(n, "Got message with truncated control data (too many fds sent?), ignoring.");
-                return 0;
-        }
-        if (n == -EXFULL) {
-                log_warning_errno(n, "Got message with truncated payload data, ignoring.");
+        _cleanup_(pidref_done) PidRef sender_pid = PIDREF_NULL;
+        _cleanup_free_ char *buf = NULL;
+        r = notify_recv(fd, &buf, /* ret_ucred= */ NULL, &sender_pid);
+        if (r == -EAGAIN)
                 return 0;
-        }
-        if (n < 0)
-                return log_warning_errno(n, "Couldn't read notification socket: %m");
-
-        cmsg_close_all(&msghdr);
+        if (r < 0)
+                return log_error_errno(r, "Failed to receive notification message: %m");
 
-        ucred = CMSG_FIND_DATA(&msghdr, SOL_SOCKET, SCM_CREDENTIALS, struct ucred);
-        if (!ucred || ucred->pid != inner_child_pid) {
+        if (sender_pid.pid != inner_child_pid) {
                 log_debug("Received notify message from process that is not the payload's PID 1. Ignoring.");
                 return 0;
         }
 
-        buf[n] = 0;
-        tags = strv_split(buf, "\n\r");
+        _cleanup_strv_free_ char **tags = strv_split(buf, "\n\r");
         if (!tags)
                 return log_oom();
 
@@ -4683,7 +4654,7 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r
                         log_warning_errno(r, "Failed to send readiness notification, ignoring: %m");
         }
 
-        p = strv_find_startswith(tags, "STATUS=");
+        char *p = strv_find_startswith(tags, "STATUS=");
         if (p)
                 (void) sd_notifyf(false, "STATUS=Container running: %s", p);