From: Lennart Poettering Date: Thu, 15 May 2025 09:00:17 +0000 (+0200) Subject: vmspawn: use VM leader PID not vmspawn PID to register machine X-Git-Tag: v258-rc1~79^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6dc6e6459bb4dba7cd88c4f6688b1aea9159c9d2;p=thirdparty%2Fsystemd.git vmspawn: use VM leader PID not vmspawn PID to register machine Let's make vmspawn machine registration more like nspawn machine registration, and register the payload, not vmspawn/nspawn itself. --- diff --git a/src/vmspawn/vmspawn-register.c b/src/vmspawn/vmspawn-register.c index ae7edd0fdbf..d9925f171dd 100644 --- a/src/vmspawn/vmspawn-register.c +++ b/src/vmspawn/vmspawn-register.c @@ -10,7 +10,9 @@ #include "bus-error.h" #include "bus-locator.h" #include "errno-util.h" +#include "json-util.h" #include "log.h" +#include "pidref.h" #include "process-util.h" #include "socket-util.h" #include "string-util.h" @@ -23,6 +25,7 @@ int register_machine( const char *machine_name, sd_id128_t uuid, const char *service, + const PidRef *pidref, const char *directory, unsigned cid, const char *address, @@ -54,7 +57,7 @@ int register_machine( SD_BUS_MESSAGE_APPEND_ID128(uuid), service, "vm", - (uint32_t) getpid_cached(), + (uint32_t) (pidref_is_set(pidref) ? pidref->pid : 0), strempty(directory)); if (r < 0) return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r)); @@ -77,7 +80,8 @@ int register_machine( SD_JSON_BUILD_PAIR_CONDITION(!!address, "sshAddress", SD_JSON_BUILD_STRING(address)), SD_JSON_BUILD_PAIR_CONDITION(!!key_path, "sshPrivateKeyPath", SD_JSON_BUILD_STRING(key_path)), SD_JSON_BUILD_PAIR_CONDITION(isatty_safe(STDIN_FILENO), "allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(true)), - SD_JSON_BUILD_PAIR_CONDITION(!keep_unit, "allocateUnit", SD_JSON_BUILD_BOOLEAN(true))); + SD_JSON_BUILD_PAIR_CONDITION(!keep_unit, "allocateUnit", SD_JSON_BUILD_BOOLEAN(true)), + SD_JSON_BUILD_PAIR_CONDITION(pidref_is_set(pidref), "leaderProcessId", JSON_BUILD_PIDREF(pidref))); } int unregister_machine(sd_bus *bus, const char *machine_name) { diff --git a/src/vmspawn/vmspawn-register.h b/src/vmspawn/vmspawn-register.h index 58cae542ceb..2adfabdc030 100644 --- a/src/vmspawn/vmspawn-register.h +++ b/src/vmspawn/vmspawn-register.h @@ -7,6 +7,7 @@ int register_machine( const char *machine_name, sd_id128_t uuid, const char *service, + const PidRef *pidref, const char *directory, unsigned cid, const char *address, diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index 0ddc1cdb5af..bf16056b15f 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -2326,34 +2326,8 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { log_debug("Executing: %s", joined); } - if (arg_register) { - char vm_address[STRLEN("vsock/") + DECIMAL_STR_MAX(unsigned)]; - - xsprintf(vm_address, "vsock/%u", child_cid); - r = register_machine( - bus, - arg_machine, - arg_uuid, - "systemd-vmspawn", - arg_directory, - child_cid, - child_cid != VMADDR_CID_ANY ? vm_address : NULL, - ssh_private_key_path, - arg_keep_unit); - if (r < 0) - return r; - } - assert_se(sigprocmask_many(SIG_BLOCK, /* ret_old_mask=*/ NULL, SIGCHLD) >= 0); - _cleanup_(sd_event_source_unrefp) sd_event_source *notify_event_source = NULL; - _cleanup_(sd_event_unrefp) sd_event *event = NULL; - r = sd_event_new(&event); - if (r < 0) - return log_error_errno(r, "Failed to get default event source: %m"); - - (void) sd_event_set_watchdog(event, true); - _cleanup_(pidref_done) PidRef child_pidref = PIDREF_NULL; r = pidref_safe_fork_full( @@ -2386,6 +2360,32 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { child_vsock_fd = safe_close(child_vsock_fd); tap_fd = safe_close(tap_fd); + if (arg_register) { + char vm_address[STRLEN("vsock/") + DECIMAL_STR_MAX(unsigned)]; + xsprintf(vm_address, "vsock/%u", child_cid); + r = register_machine( + bus, + arg_machine, + arg_uuid, + "systemd-vmspawn", + &child_pidref, + arg_directory, + child_cid, + child_cid != VMADDR_CID_ANY ? vm_address : NULL, + ssh_private_key_path, + arg_keep_unit); + if (r < 0) + return r; + } + + _cleanup_(sd_event_source_unrefp) sd_event_source *notify_event_source = NULL; + _cleanup_(sd_event_unrefp) sd_event *event = NULL; + r = sd_event_new(&event); + if (r < 0) + return log_error_errno(r, "Failed to get default event source: %m"); + + (void) sd_event_set_watchdog(event, true); + int exit_status = INT_MAX; if (use_vsock) { r = setup_notify_parent(event, notify_sock_fd, &exit_status, ¬ify_event_source);