]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
vmspawn: rework how we spawn qemu off
authorLennart Poettering <lennart@poettering.net>
Fri, 19 Jan 2024 17:03:49 +0000 (18:03 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 22 Jan 2024 13:03:09 +0000 (14:03 +0100)
Let's swicth to PidRef for tracking the qemu child.

let's also set a bunch of flags that ensure the child inherits less of
of context.

src/vmspawn/vmspawn.c

index e6ab63a6cdded5de6fc7929d23e17669762e8e8b..40ebe72c893908263c8e89f78ec783676eceabfa 100644 (file)
@@ -13,6 +13,7 @@
 #include "copy.h"
 #include "creds-util.h"
 #include "escape.h"
+#include "event-util.h"
 #include "fileio.h"
 #include "format-util.h"
 #include "fs-util.h"
@@ -391,12 +392,16 @@ static int setup_notify_parent(sd_event *event, int fd, int *exit_status, sd_eve
 }
 
 static int on_orderly_shutdown(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
-        pid_t pid;
+        PidRef *pidref = userdata;
+        int r;
+
+        /* TODO: actually talk to qemu and ask the guest to shutdown here */
 
-        pid = PTR_TO_PID(userdata);
-        if (pid > 0) {
-                /* TODO: actually talk to qemu and ask the guest to shutdown here */
-                if (kill(pid, SIGKILL) >= 0) {
+        if (pidref) {
+                r = pidref_kill(pidref, SIGKILL);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to kill qemu, terminating: %m");
+                else {
                         log_info("Trying to halt qemu. Send SIGTERM again to trigger vmspawn to immediately terminate.");
                         sd_event_source_set_userdata(s, NULL);
                         return 0;
@@ -663,15 +668,16 @@ static int run_virtual_machine(void) {
 
         (void) sd_event_set_watchdog(event, true);
 
-        pid_t child_pid;
-        r = safe_fork_full(
+        _cleanup_(pidref_done) PidRef child_pidref = PIDREF_NULL;
+
+        r = pidref_safe_fork_full(
                         qemu_binary,
-                        NULL,
+                        /* stdio_fds= */ NULL,
                         &child_vsock_fd, 1, /* pass the vsock fd to qemu */
-                        FORK_CLOEXEC_OFF,
-                        &child_pid);
+                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_CLOEXEC_OFF|FORK_RLIMIT_NOFILE_SAFE,
+                        &child_pidref);
         if (r < 0)
-                return log_error_errno(r, "Failed to fork off %s: %m", qemu_binary);
+                return r;
         if (r == 0) {
                 /* set TERM and LANG if they are missing */
                 if (setenv("TERM", "vt220", 0) < 0)
@@ -693,13 +699,13 @@ static int run_virtual_machine(void) {
         }
 
         /* shutdown qemu when we are shutdown */
-        (void) sd_event_add_signal(event, NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, on_orderly_shutdown, PID_TO_PTR(child_pid));
-        (void) sd_event_add_signal(event, NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, on_orderly_shutdown, PID_TO_PTR(child_pid));
+        (void) sd_event_add_signal(event, NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, on_orderly_shutdown, &child_pidref);
+        (void) sd_event_add_signal(event, NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, on_orderly_shutdown, &child_pidref);
 
         (void) sd_event_add_signal(event, NULL, (SIGRTMIN+18) | SD_EVENT_SIGNAL_PROCMASK, sigrtmin18_handler, NULL);
 
         /* Exit when the child exits */
-        (void) sd_event_add_child(event, NULL, child_pid, WEXITED, on_child_exit, NULL);
+        (void) event_add_child_pidref(event, NULL, &child_pidref, WEXITED, on_child_exit, NULL);
 
         r = sd_event_loop(event);
         if (r < 0)