From: Daan De Meyer Date: Fri, 26 Apr 2024 13:02:56 +0000 (+0200) Subject: sd-daemon: Replace SO_LINGER with shutdown() + recv() X-Git-Tag: v256-rc2~192^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F32498%2Fhead;p=thirdparty%2Fsystemd.git sd-daemon: Replace SO_LINGER with shutdown() + recv() 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. --- diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index 20065a6a367..58626463a89 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -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; }