]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-daemon: Replace SO_LINGER with shutdown() + recv() 32498/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 26 Apr 2024 13:02:56 +0000 (15:02 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 26 Apr 2024 13:11:38 +0000 (15:11 +0200)
Let's shutdown the write end and wait for EOF from the other side
before continuing to make sure that the receiver has received all
data we sent on the socket.

src/libsystemd/sd-daemon/sd-daemon.c

index 20065a6a367c57475c2ede59a481ceb473440a7e..58626463a8909ba3175c1fa5262cd693038c6c87 100644 (file)
@@ -513,16 +513,6 @@ static int pid_notify_with_fds_internal(
         }
 
         if (address.sockaddr.sa.sa_family == AF_VSOCK) {
-                /* If we shut down a virtual machine the kernel might not flush the buffers of the vsock
-                 * socket before shutting down. Set SO_LINGER so that we wait until the buffers are flushed
-                 * when the socket is closed. */
-                struct linger l = {
-                        .l_onoff = true,
-                        .l_linger = 10,
-                };
-                if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
-                        log_debug_errno(errno, "Failed to set SO_LINGER on vsock notify socket, ignoring: %m");
-
                 r = vsock_bind_privileged_port(fd);
                 if (r < 0 && !ERRNO_IS_PRIVILEGE(r))
                         return log_debug_errno(r, "Failed to bind socket to privileged port: %m");
@@ -604,6 +594,19 @@ static int pid_notify_with_fds_internal(
                 }
         } while (!iovec_increment(msghdr.msg_iov, msghdr.msg_iovlen, n));
 
+        if (address.sockaddr.sa.sa_family == AF_VSOCK && IN_SET(type, SOCK_STREAM, SOCK_SEQPACKET)) {
+                /* For AF_VSOCK, we need to close the socket to signal the end of the message. */
+                if (shutdown(fd, SHUT_WR) < 0)
+                        return log_error_errno(errno, "Failed to shutdown notify socket: %m");
+
+                char buf[1];
+                n = recv(fd, buf, sizeof(buf), MSG_NOSIGNAL);
+                if (n > 0)
+                        return log_error_errno(errno, "Unexpectedly received data on notify socket: %m");
+                if (n < 0)
+                        return log_error_errno(errno, "Failed to wait for EOF on notify socket: %m");
+        }
+
         return 1;
 }