diff options
-rw-r--r-- | src/libsystemd/sd-daemon/sd-daemon.c | 10 | ||||
-rw-r--r-- | src/shutdown/shutdown.c | 13 |
2 files changed, 14 insertions, 9 deletions
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index 2ff9537a6d..20065a6a36 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -513,6 +513,16 @@ 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"); diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c index 1ddda00941..67f44e16e9 100644 --- a/src/shutdown/shutdown.c +++ b/src/shutdown/shutdown.c @@ -344,13 +344,15 @@ static void notify_supervisor(void) { if (reboot_parameter) (void) sd_notifyf(/* unset_environment= */ false, + "EXIT_STATUS=%i\n" "X_SYSTEMD_SHUTDOWN=%s\n" "X_SYSTEMD_REBOOT_PARAMETER=%s", - arg_verb, reboot_parameter); + arg_exit_code, arg_verb, reboot_parameter); else (void) sd_notifyf(/* unset_environment= */ false, + "EXIT_STATUS=%i\n" "X_SYSTEMD_SHUTDOWN=%s", - arg_verb); + arg_exit_code, arg_verb); } int main(int argc, char *argv[]) { @@ -407,13 +409,6 @@ int main(int argc, char *argv[]) { goto error; } - /* This is primarily useful when running systemd in a VM, as it provides the user running the VM with - * a mechanism to pick up systemd's exit status in the VM. Note that we execute this as early as - * possible since otherwise we might shut down the VM before the AF_VSOCK buffers have been flushed. - * While this doesn't guarantee the message will arrive, in practice we do enough work after this - * that the message should always arrive on the host */ - (void) sd_notifyf(0, "EXIT_STATUS=%i", arg_exit_code); - (void) cg_get_root_path(&cgroup); bool in_container = detect_container() > 0; |