diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index ff5f79a7cb..b558397418 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -5784,21 +5784,21 @@ static int run_container( bool registered_system = false, registered_runtime = false; if (arg_register != 0) { + const MachineRegistration reg = { + .name = arg_machine, + .id = arg_uuid, + .service = arg_container_service_name, + .class = "container", + .pidref = pid, + .root_directory = arg_directory, + .local_ifindex = ifi, + }; + r = register_machine_with_fallback_and_log( arg_runtime_scope == RUNTIME_SCOPE_SYSTEM ? RUNTIME_SCOPE_SYSTEM : _RUNTIME_SCOPE_INVALID, system_bus, runtime_bus, - arg_machine, - arg_uuid, - arg_container_service_name, - "container", - pid, - arg_directory, - /* cid= */ 0, - ifi, - /* address= */ NULL, - /* key_path= */ NULL, - /* allocate_unit= */ false, + ®, /* graceful= */ arg_register < 0, ®istered_system, ®istered_runtime); diff --git a/src/shared/machine-register.c b/src/shared/machine-register.c index 2f18fa8cf9..8ca2bf2f1d 100644 --- a/src/shared/machine-register.c +++ b/src/shared/machine-register.c @@ -23,28 +23,23 @@ static int register_machine_dbus_ex( sd_bus *bus, - const char *machine_name, - sd_id128_t uuid, - const char *service, - const char *class, - const PidRef *pidref, - const char *directory, - int local_ifindex, + const MachineRegistration *reg, sd_bus_error *error) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; assert(bus); - assert(machine_name); - assert(service); - assert(class); + assert(reg); + assert(reg->name); + assert(reg->service); + assert(reg->class); r = bus_message_new_method_call(bus, &m, bus_machine_mgr, "RegisterMachineEx"); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append(m, "s", machine_name); + r = sd_bus_message_append(m, "s", reg->name); if (r < 0) return bus_log_create_error(r); @@ -55,38 +50,38 @@ static int register_machine_dbus_ex( r = sd_bus_message_append( m, "(sv)(sv)(sv)", - "Id", "ay", SD_BUS_MESSAGE_APPEND_ID128(uuid), - "Service", "s", service, - "Class", "s", class); + "Id", "ay", SD_BUS_MESSAGE_APPEND_ID128(reg->id), + "Service", "s", reg->service, + "Class", "s", reg->class); if (r < 0) return bus_log_create_error(r); - if (pidref_is_set(pidref)) { - if (pidref->fd >= 0) { - r = sd_bus_message_append(m, "(sv)", "LeaderPIDFD", "h", pidref->fd); + if (pidref_is_set(reg->pidref)) { + if (reg->pidref->fd >= 0) { + r = sd_bus_message_append(m, "(sv)", "LeaderPIDFD", "h", reg->pidref->fd); if (r < 0) return bus_log_create_error(r); } - if (pidref->fd_id > 0) { - r = sd_bus_message_append(m, "(sv)", "LeaderPIDFDID", "t", pidref->fd_id); + if (reg->pidref->fd_id > 0) { + r = sd_bus_message_append(m, "(sv)", "LeaderPIDFDID", "t", reg->pidref->fd_id); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append(m, "(sv)", "LeaderPID", "u", pidref->pid); + r = sd_bus_message_append(m, "(sv)", "LeaderPID", "u", reg->pidref->pid); if (r < 0) return bus_log_create_error(r); } } - if (!isempty(directory)) { - r = sd_bus_message_append(m, "(sv)", "RootDirectory", "s", directory); + if (!isempty(reg->root_directory)) { + r = sd_bus_message_append(m, "(sv)", "RootDirectory", "s", reg->root_directory); if (r < 0) return bus_log_create_error(r); } - if (local_ifindex > 0) { - r = sd_bus_message_append(m, "(sv)", "NetworkInterfaces", "ai", 1, local_ifindex); + if (reg->local_ifindex > 0) { + r = sd_bus_message_append(m, "(sv)", "NetworkInterfaces", "ai", 1, reg->local_ifindex); if (r < 0) return bus_log_create_error(r); } @@ -100,24 +95,19 @@ static int register_machine_dbus_ex( static int register_machine_dbus( sd_bus *bus, - const char *machine_name, - sd_id128_t uuid, - const char *service, - const char *class, - const PidRef *pidref, - const char *directory, - int local_ifindex) { + const MachineRegistration *reg) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; assert(bus); - assert(machine_name); - assert(service); - assert(class); + assert(reg); + assert(reg->name); + assert(reg->service); + assert(reg->class); /* First try RegisterMachineEx which supports PIDFD-based leader tracking. */ - r = register_machine_dbus_ex(bus, machine_name, uuid, service, class, pidref, directory, local_ifindex, &error); + r = register_machine_dbus_ex(bus, reg, &error); if (r >= 0) return 0; if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) @@ -132,13 +122,13 @@ static int register_machine_dbus( &error, NULL, "sayssusai", - machine_name, - SD_BUS_MESSAGE_APPEND_ID128(uuid), - service, - class, - pidref_is_set(pidref) ? (uint32_t) pidref->pid : 0, - strempty(directory), - local_ifindex > 0 ? 1 : 0, local_ifindex); + reg->name, + SD_BUS_MESSAGE_APPEND_ID128(reg->id), + reg->service, + reg->class, + pidref_is_set(reg->pidref) ? (uint32_t) reg->pidref->pid : 0, + strempty(reg->root_directory), + reg->local_ifindex > 0 ? 1 : 0, reg->local_ifindex); if (r < 0) return log_debug_errno(r, "Failed to register machine via D-Bus: %s", bus_error_message(&error, r)); @@ -147,25 +137,16 @@ static int register_machine_dbus( int register_machine( sd_bus *bus, - const char *machine_name, - sd_id128_t uuid, - const char *service, - const char *class, - const PidRef *pidref, - const char *directory, - unsigned cid, - int local_ifindex, - const char *address, - const char *key_path, - bool allocate_unit, + const MachineRegistration *reg, RuntimeScope scope) { _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r; - assert(machine_name); - assert(service); - assert(class); + assert(reg); + assert(reg->name); + assert(reg->service); + assert(reg->class); /* First try to use varlink, as it provides more features (such as SSH support). */ _cleanup_free_ char *p = NULL; @@ -184,7 +165,7 @@ int register_machine( if (!bus) return log_debug_errno(SYNTHETIC_ERRNO(ESRCH), "Varlink connection to machined not available and no bus provided."); - return register_machine_dbus(bus, machine_name, uuid, service, class, pidref, directory, local_ifindex); + return register_machine_dbus(bus, reg); } if (r < 0) return log_debug_errno(r, "Failed to connect to machined on %s: %m", strna(p)); @@ -196,18 +177,18 @@ int register_machine( "io.systemd.Machine.Register", &reply, &error_id, - SD_JSON_BUILD_PAIR_STRING("name", machine_name), - SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(uuid), "id", SD_JSON_BUILD_ID128(uuid)), - SD_JSON_BUILD_PAIR_STRING("service", service), - SD_JSON_BUILD_PAIR_STRING("class", class), - SD_JSON_BUILD_PAIR_CONDITION(VSOCK_CID_IS_REGULAR(cid), "vSockCid", SD_JSON_BUILD_UNSIGNED(cid)), - SD_JSON_BUILD_PAIR_CONDITION(local_ifindex > 0, "ifIndices", SD_JSON_BUILD_ARRAY(SD_JSON_BUILD_INTEGER(local_ifindex))), - SD_JSON_BUILD_PAIR_CONDITION(!!directory, "rootDirectory", SD_JSON_BUILD_STRING(directory)), - 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_STRING("name", reg->name), + SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(reg->id), "id", SD_JSON_BUILD_ID128(reg->id)), + SD_JSON_BUILD_PAIR_STRING("service", reg->service), + SD_JSON_BUILD_PAIR_STRING("class", reg->class), + SD_JSON_BUILD_PAIR_CONDITION(VSOCK_CID_IS_REGULAR(reg->vsock_cid), "vSockCid", SD_JSON_BUILD_UNSIGNED(reg->vsock_cid)), + SD_JSON_BUILD_PAIR_CONDITION(reg->local_ifindex > 0, "ifIndices", SD_JSON_BUILD_ARRAY(SD_JSON_BUILD_INTEGER(reg->local_ifindex))), + SD_JSON_BUILD_PAIR_CONDITION(!!reg->root_directory, "rootDirectory", SD_JSON_BUILD_STRING(reg->root_directory)), + SD_JSON_BUILD_PAIR_CONDITION(!!reg->ssh_address, "sshAddress", SD_JSON_BUILD_STRING(reg->ssh_address)), + SD_JSON_BUILD_PAIR_CONDITION(!!reg->ssh_private_key_path, "sshPrivateKeyPath", SD_JSON_BUILD_STRING(reg->ssh_private_key_path)), SD_JSON_BUILD_PAIR_CONDITION(isatty_safe(STDIN_FILENO), "allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(true)), - SD_JSON_BUILD_PAIR_CONDITION(allocate_unit, "allocateUnit", SD_JSON_BUILD_BOOLEAN(true)), - SD_JSON_BUILD_PAIR_CONDITION(pidref_is_set(pidref), "leaderProcessId", JSON_BUILD_PIDREF(pidref))); + SD_JSON_BUILD_PAIR_CONDITION(reg->allocate_unit, "allocateUnit", SD_JSON_BUILD_BOOLEAN(true)), + SD_JSON_BUILD_PAIR_CONDITION(pidref_is_set(reg->pidref), "leaderProcessId", JSON_BUILD_PIDREF(reg->pidref))); if (r < 0) return log_debug_errno(r, "Failed to register machine via varlink: %m"); if (error_id) @@ -233,17 +214,7 @@ int register_machine_with_fallback_and_log( RuntimeScope scope, sd_bus *system_bus, sd_bus *user_bus, - const char *machine_name, - sd_id128_t uuid, - const char *service, - const char *class, - const PidRef *pidref, - const char *directory, - unsigned cid, - int local_ifindex, - const char *address, - const char *key_path, - bool allocate_unit, + const MachineRegistration *reg, bool graceful, bool *reterr_registered_system, bool *reterr_registered_user) { @@ -254,27 +225,19 @@ int register_machine_with_fallback_and_log( assert(IN_SET(scope, RUNTIME_SCOPE_SYSTEM, RUNTIME_SCOPE_USER, _RUNTIME_SCOPE_INVALID)); assert(system_bus || !IN_SET(scope, RUNTIME_SCOPE_SYSTEM, _RUNTIME_SCOPE_INVALID)); assert(user_bus || !IN_SET(scope, RUNTIME_SCOPE_USER, _RUNTIME_SCOPE_INVALID)); - assert(machine_name); - assert(service); - assert(class); + assert(reg); + assert(reg->name); + assert(reg->service); + assert(reg->class); assert(reterr_registered_system); assert(reterr_registered_user); if (IN_SET(scope, RUNTIME_SCOPE_SYSTEM, _RUNTIME_SCOPE_INVALID)) { - int q = register_machine( - system_bus, - machine_name, - uuid, - service, - class, - pidref, - directory, - cid, - local_ifindex, - address, - key_path, - scope == RUNTIME_SCOPE_SYSTEM ? allocate_unit : false, - RUNTIME_SCOPE_SYSTEM); + MachineRegistration system_reg = *reg; + if (scope != RUNTIME_SCOPE_SYSTEM) + system_reg.allocate_unit = false; + + int q = register_machine(system_bus, &system_reg, RUNTIME_SCOPE_SYSTEM); if (q < 0) RET_GATHER(r, q); else @@ -282,20 +245,7 @@ int register_machine_with_fallback_and_log( } if (IN_SET(scope, RUNTIME_SCOPE_USER, _RUNTIME_SCOPE_INVALID)) { - int q = register_machine( - user_bus, - machine_name, - uuid, - service, - class, - pidref, - directory, - cid, - local_ifindex, - address, - key_path, - allocate_unit, - RUNTIME_SCOPE_USER); + int q = register_machine(user_bus, reg, RUNTIME_SCOPE_USER); if (q < 0) RET_GATHER(r, q); else diff --git a/src/shared/machine-register.h b/src/shared/machine-register.h index e405873b5b..8fc63fd75e 100644 --- a/src/shared/machine-register.h +++ b/src/shared/machine-register.h @@ -1,37 +1,33 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include "sd-id128.h" + #include "shared-forward.h" +typedef struct MachineRegistration { + const char *name; + sd_id128_t id; + const char *service; + const char *class; + const PidRef *pidref; + const char *root_directory; + unsigned vsock_cid; + int local_ifindex; + const char *ssh_address; + const char *ssh_private_key_path; + bool allocate_unit; +} MachineRegistration; + int register_machine( sd_bus *bus, - const char *machine_name, - sd_id128_t uuid, - const char *service, - const char *class, - const PidRef *pidref, - const char *directory, - unsigned cid, - int local_ifindex, - const char *address, - const char *key_path, - bool allocate_unit, + const MachineRegistration *reg, RuntimeScope scope); int register_machine_with_fallback_and_log( RuntimeScope scope, sd_bus *system_bus, sd_bus *user_bus, - const char *machine_name, - sd_id128_t uuid, - const char *service, - const char *class, - const PidRef *pidref, - const char *directory, - unsigned cid, - int local_ifindex, - const char *address, - const char *key_path, - bool allocate_unit, + const MachineRegistration *reg, bool graceful, bool *reterr_registered_system, bool *reterr_registered_user); diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index 9610199c02..5295d4d21b 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -3601,21 +3601,25 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { if (arg_register != 0) { char vm_address[STRLEN("vsock/") + DECIMAL_STR_MAX(unsigned)]; xsprintf(vm_address, "vsock/%u", child_cid); + + const MachineRegistration reg = { + .name = arg_machine, + .id = arg_uuid, + .service = "systemd-vmspawn", + .class = "vm", + .pidref = &child_pidref, + .root_directory = arg_directory, + .vsock_cid = child_cid, + .ssh_address = child_cid != VMADDR_CID_ANY ? vm_address : NULL, + .ssh_private_key_path = ssh_private_key_path, + .allocate_unit = !arg_keep_unit, + }; + r = register_machine_with_fallback_and_log( arg_runtime_scope == RUNTIME_SCOPE_USER ? _RUNTIME_SCOPE_INVALID : RUNTIME_SCOPE_SYSTEM, system_bus, runtime_bus, - arg_machine, - arg_uuid, - "systemd-vmspawn", - "vm", - &child_pidref, - arg_directory, - child_cid, - /* local_ifindex= */ 0, - child_cid != VMADDR_CID_ANY ? vm_address : NULL, - ssh_private_key_path, - !arg_keep_unit, + ®, /* graceful= */ arg_register < 0, ®istered_system, ®istered_runtime);