From d8854ff1aca4434db0d7d6dcaf9fcf2f38105fb4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 9 Sep 2023 12:57:46 +0200 Subject: machined: port over to PidRef too --- src/machine/machine-dbus.c | 25 ++++++++++++--------- src/machine/machine.c | 55 ++++++++++++++++++++++++++------------------- src/machine/machine.h | 3 ++- src/machine/machined-dbus.c | 11 ++++++--- src/machine/machined.c | 7 +++++- 5 files changed, 62 insertions(+), 39 deletions(-) (limited to 'src/machine') diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index effee717b6..6341335c4d 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -233,7 +233,7 @@ int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd if (r < 0) return r; - p = procfs_file_alloca(m->leader, "ns/net"); + p = procfs_file_alloca(m->leader.pid, "ns/net"); r = readlink_malloc(p, &them); if (r < 0) return r; @@ -241,7 +241,7 @@ int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd if (streq(us, them)) return sd_bus_error_setf(error, BUS_ERROR_NO_PRIVATE_NETWORKING, "Machine %s does not use private networking", m->name); - r = namespace_open(m->leader, NULL, NULL, &netns_fd, NULL, NULL); + r = namespace_open(m->leader.pid, NULL, NULL, &netns_fd, NULL, NULL); if (r < 0) return r; @@ -375,7 +375,7 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s _cleanup_fclose_ FILE *f = NULL; pid_t child; - r = namespace_open(m->leader, &pidns_fd, &mntns_fd, NULL, NULL, &root_fd); + r = namespace_open(m->leader.pid, &pidns_fd, &mntns_fd, NULL, NULL, &root_fd); if (r < 0) return r; @@ -496,7 +496,7 @@ static int container_bus_new(Machine *m, sd_bus_error *error, sd_bus **ret) { if (r < 0) return r; - if (asprintf(&address, "x-machine-unix:pid=%" PID_PRI, m->leader) < 0) + if (asprintf(&address, "x-machine-unix:pid=%" PID_PRI, m->leader.pid) < 0) return -ENOMEM; bus->address = address; @@ -880,10 +880,13 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Can't bind mount on container with user namespacing applied."); propagate_directory = strjoina("/run/systemd/nspawn/propagate/", m->name); - r = bind_mount_in_namespace(m->leader, - propagate_directory, - "/run/host/incoming/", - src, dest, read_only, make_file_or_directory); + r = bind_mount_in_namespace( + m->leader.pid, + propagate_directory, + "/run/host/incoming/", + src, dest, + read_only, + make_file_or_directory); if (r < 0) return sd_bus_error_set_errnof(error, r, "Failed to mount %s on %s in machine's namespace: %m", src, dest); @@ -997,7 +1000,7 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); - q = procfs_file_alloca(m->leader, "ns/mnt"); + q = procfs_file_alloca(m->leader.pid, "ns/mnt"); mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC); if (mntfd < 0) { r = log_error_errno(errno, "Failed to open mount namespace of leader: %m"); @@ -1093,7 +1096,7 @@ int bus_machine_method_open_root_directory(sd_bus_message *message, void *userda _cleanup_close_pair_ int pair[2] = PIPE_EBADF; pid_t child; - r = namespace_open(m->leader, NULL, &mntns_fd, NULL, NULL, &root_fd); + r = namespace_open(m->leader.pid, NULL, &mntns_fd, NULL, NULL, &root_fd); if (r < 0) return r; @@ -1266,7 +1269,7 @@ static const sd_bus_vtable machine_vtable[] = { SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Machine, service), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Unit", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), - SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader.pid), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("NetworkInterfaces", "ai", property_get_netif, 0, SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/machine/machine.c b/src/machine/machine.c index acb86c1a83..6f0ef3da4a 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -49,10 +49,14 @@ int machine_new(Manager *manager, MachineClass class, const char *name, Machine * means as much as "we don't know yet", and that we'll figure * it out later when loading the state file. */ - m = new0(Machine, 1); + m = new(Machine, 1); if (!m) return -ENOMEM; + *m = (Machine) { + .leader = PIDREF_NULL, + }; + m->name = strdup(name); if (!m->name) return -ENOMEM; @@ -94,8 +98,10 @@ Machine* machine_free(Machine *m) { if (m->manager->host_machine == m) m->manager->host_machine = NULL; - if (m->leader > 0) - (void) hashmap_remove_value(m->manager->machine_leaders, PID_TO_PTR(m->leader), m); + if (pidref_is_set(&m->leader)) { + (void) hashmap_remove_value(m->manager->machine_leaders, PID_TO_PTR(m->leader.pid), m); + pidref_done(&m->leader); + } sd_bus_message_unref(m->create_message); @@ -175,8 +181,8 @@ int machine_save(Machine *m) { if (!sd_id128_is_null(m->id)) fprintf(f, "ID=" SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->id)); - if (m->leader != 0) - fprintf(f, "LEADER="PID_FMT"\n", m->leader); + if (pidref_is_set(&m->leader)) + fprintf(f, "LEADER="PID_FMT"\n", m->leader.pid); if (m->class != _MACHINE_CLASS_INVALID) fprintf(f, "CLASS=%s\n", machine_class_to_string(m->class)); @@ -272,10 +278,14 @@ int machine_load(Machine *m) { return log_error_errno(r, "Failed to read %s: %m", m->state_file); if (id) - sd_id128_from_string(id, &m->id); + (void) sd_id128_from_string(id, &m->id); - if (leader) - parse_pid(leader, &m->leader); + if (leader) { + pidref_done(&m->leader); + r = pidref_set_pidstr(&m->leader, leader); + if (r < 0) + log_debug_errno(r, "Failed to set leader PID to '%s', ignoring: %m", leader); + } if (class) { MachineClass c; @@ -337,7 +347,7 @@ static int machine_start_scope( int r; assert(machine); - assert(machine->leader > 0); + assert(pidref_is_set(&machine->leader)); assert(!machine->unit); escaped = unit_name_escape(machine->name); @@ -374,7 +384,7 @@ static int machine_start_scope( return r; r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)", - "PIDs", "au", 1, machine->leader, + "PIDs", "au", 1, machine->leader.pid, "Delegate", "b", 1, "CollectMode", "s", "inactive-or-failed", "AddRef", "b", 1, @@ -440,7 +450,7 @@ int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) { if (m->started) return 0; - r = hashmap_put(m->manager->machine_leaders, PID_TO_PTR(m->leader), m); + r = hashmap_put(m->manager->machine_leaders, PID_TO_PTR(m->leader.pid), m); if (r < 0) return r; @@ -452,7 +462,7 @@ int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) { log_struct(LOG_INFO, "MESSAGE_ID=" SD_MESSAGE_MACHINE_START_STR, "NAME=%s", m->name, - "LEADER="PID_FMT, m->leader, + "LEADER="PID_FMT, m->leader.pid, LOG_MESSAGE("New machine %s.", m->name)); if (!dual_timestamp_is_set(&m->timestamp)) @@ -503,7 +513,7 @@ int machine_finalize(Machine *m) { log_struct(LOG_INFO, "MESSAGE_ID=" SD_MESSAGE_MACHINE_STOP_STR, "NAME=%s", m->name, - "LEADER="PID_FMT, m->leader, + "LEADER="PID_FMT, m->leader.pid, LOG_MESSAGE("Machine %s terminated.", m->name)); m->stopping = true; /* The machine is supposed to be going away. Don't try to kill it. */ @@ -573,7 +583,7 @@ int machine_kill(Machine *m, KillWho who, int signo) { return -ESRCH; if (who == KILL_LEADER) /* If we shall simply kill the leader, do so directly */ - return RET_NERRNO(kill(m->leader, signo)); + return pidref_kill(&m->leader, signo); /* Otherwise, make PID 1 do it for us, for the entire cgroup */ return manager_kill_unit(m->manager, m->unit, signo, NULL); @@ -585,14 +595,13 @@ int machine_openpt(Machine *m, int flags, char **ret_slave) { switch (m->class) { case MACHINE_HOST: - return openpt_allocate(flags, ret_slave); case MACHINE_CONTAINER: - if (m->leader <= 0) + if (!pidref_is_set(&m->leader)) return -EINVAL; - return openpt_allocate_in_namespace(m->leader, flags, ret_slave); + return openpt_allocate_in_namespace(m->leader.pid, flags, ret_slave); default: return -EOPNOTSUPP; @@ -608,10 +617,10 @@ int machine_open_terminal(Machine *m, const char *path, int mode) { return open_terminal(path, mode); case MACHINE_CONTAINER: - if (m->leader <= 0) + if (!pidref_is_set(&m->leader)) return -EINVAL; - return open_terminal_in_namespace(m->leader, path, mode); + return open_terminal_in_namespace(m->leader.pid, path, mode); default: return -EOPNOTSUPP; @@ -664,7 +673,7 @@ int machine_get_uid_shift(Machine *m, uid_t *ret) { if (m->class != MACHINE_CONTAINER) return -EOPNOTSUPP; - xsprintf(p, "/proc/" PID_FMT "/uid_map", m->leader); + xsprintf(p, "/proc/" PID_FMT "/uid_map", m->leader.pid); f = fopen(p, "re"); if (!f) { if (errno == ENOENT) { @@ -702,7 +711,7 @@ int machine_get_uid_shift(Machine *m, uid_t *ret) { fclose(f); - xsprintf(p, "/proc/" PID_FMT "/gid_map", m->leader); + xsprintf(p, "/proc/" PID_FMT "/gid_map", m->leader.pid); f = fopen(p, "re"); if (!f) return -errno; @@ -756,7 +765,7 @@ static int machine_owns_uid_internal( if (machine->class != MACHINE_CONTAINER) goto negative; - p = procfs_file_alloca(machine->leader, map_file); + p = procfs_file_alloca(machine->leader.pid, map_file); f = fopen(p, "re"); if (!f) { log_debug_errno(errno, "Failed to open %s, ignoring.", p); @@ -830,7 +839,7 @@ static int machine_translate_uid_internal( /* Translates a machine UID into a host UID */ - p = procfs_file_alloca(machine->leader, map_file); + p = procfs_file_alloca(machine->leader.pid, map_file); f = fopen(p, "re"); if (!f) return -errno; diff --git a/src/machine/machine.h b/src/machine/machine.h index 54ebcb3b26..30ef93b36e 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -7,6 +7,7 @@ typedef enum KillWho KillWho; #include "list.h" #include "machined.h" #include "operation.h" +#include "pidref.h" #include "time-util.h" typedef enum MachineState { @@ -47,7 +48,7 @@ struct Machine { char *unit; char *scope_job; - pid_t leader; + PidRef leader; dual_timestamp timestamp; diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 0c157a981a..979eb3cee7 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -219,6 +219,7 @@ static int method_list_machines(sd_bus_message *message, void *userdata, sd_bus_ } static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, bool read_network, Machine **_m, sd_bus_error *error) { + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; const char *name, *service, *class, *root_directory; const int32_t *netif = NULL; MachineClass c; @@ -294,6 +295,10 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m return r; } + r = pidref_set_pid(&pidref, leader); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to pin process " PID_FMT ": %m", pidref.pid); + if (hashmap_get(manager->machines, name)) return sd_bus_error_setf(error, BUS_ERROR_MACHINE_EXISTS, "Machine '%s' already exists", name); @@ -301,7 +306,7 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m if (r < 0) return r; - m->leader = leader; + m->leader = TAKE_PIDREF(pidref); m->class = c; m->id = id; @@ -388,11 +393,11 @@ static int method_register_machine_internal(sd_bus_message *message, bool read_n if (r < 0) return r; - r = cg_pid_get_unit(m->leader, &m->unit); + r = cg_pid_get_unit(m->leader.pid, &m->unit); if (r < 0) { r = sd_bus_error_set_errnof(error, r, "Failed to determine unit of process "PID_FMT" : %m", - m->leader); + m->leader.pid); goto fail; } diff --git a/src/machine/machined.c b/src/machine/machined.c index 926a8a7f2b..58a407d451 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -107,6 +107,7 @@ static Manager* manager_unref(Manager *m) { } static int manager_add_host_machine(Manager *m) { + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; _cleanup_free_ char *rd = NULL, *unit = NULL; sd_id128_t mid; Machine *t; @@ -127,11 +128,15 @@ static int manager_add_host_machine(Manager *m) { if (!unit) return log_oom(); + r = pidref_set_pid(&pidref, 1); + if (r < 0) + return log_error_errno(r, "Failed to open reference to PID 1: %m"); + r = machine_new(m, MACHINE_HOST, ".host", &t); if (r < 0) return log_error_errno(r, "Failed to create machine: %m"); - t->leader = 1; + t->leader = TAKE_PIDREF(pidref); t->id = mid; t->root_directory = TAKE_PTR(rd); -- cgit v1.2.3