summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-09-09 12:57:46 +0200
committerLennart Poettering <lennart@poettering.net>2023-09-09 14:11:03 +0200
commitd8854ff1aca4434db0d7d6dcaf9fcf2f38105fb4 (patch)
treef8e302eaf73aa0d6ea561b5a7fe40606d3511b74
parentlogind: also port session leader tracking over to PidRef (diff)
downloadsystemd-d8854ff1aca4434db0d7d6dcaf9fcf2f38105fb4.tar.xz
systemd-d8854ff1aca4434db0d7d6dcaf9fcf2f38105fb4.zip
machined: port over to PidRef too
-rw-r--r--src/machine/machine-dbus.c25
-rw-r--r--src/machine/machine.c55
-rw-r--r--src/machine/machine.h3
-rw-r--r--src/machine/machined-dbus.c11
-rw-r--r--src/machine/machined.c7
5 files changed, 62 insertions, 39 deletions
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);