summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libsystemd/sd-daemon/sd-daemon.c10
-rw-r--r--src/shutdown/shutdown.c13
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;