]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
machined: port over to PidRef too
authorLennart Poettering <lennart@poettering.net>
Sat, 9 Sep 2023 10:57:46 +0000 (12:57 +0200)
committerLennart Poettering <lennart@poettering.net>
Sat, 9 Sep 2023 12:11:03 +0000 (14:11 +0200)
src/machine/machine-dbus.c
src/machine/machine.c
src/machine/machine.h
src/machine/machined-dbus.c
src/machine/machined.c

index effee717b658f603e100b5ce46e1efe0ae1ced8a..6341335c4dd46789b7a9a0e4806fa51a8e8ff86d 100644 (file)
@@ -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),
index acb86c1a83f9dfe6e734dea5f465675ca30f1862..6f0ef3da4a66ee8d093a579dc8c3ae5b01f6ba46 100644 (file)
@@ -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;
index 54ebcb3b26cf5b0d989da3f2dd410f912b4a0efe..30ef93b36e76db4ee3f4e66ac7cc474b04b756a6 100644 (file)
@@ -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;
 
index 0c157a981aff495bf716715bfc98489e25dd0cf6..979eb3cee78685e08252b89d48aba84c12b38264 100644 (file)
@@ -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;
         }
 
index 926a8a7f2b69f94ad28a84879caa672deb853163..58a407d4513f0d5f215ea50009c718828806ac10 100644 (file)
@@ -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);