summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-10-16 23:18:37 +0200
committerLennart Poettering <lennart@poettering.net>2023-10-18 14:39:33 +0200
commitd57d521caec3a135c71b500ada51bd29649870c4 (patch)
tree55502e264fd8dc99a7299bf460037273b6616a20
parentprocess-util: add pidref_is_kernel_thread() (diff)
downloadsystemd-d57d521caec3a135c71b500ada51bd29649870c4.tar.xz
systemd-d57d521caec3a135c71b500ada51bd29649870c4.zip
dbus-unit: make sure GetProcesses() D-Bus call internally uses pidfd
This way we can be sure to provide an atomic view of the process tree of a unit.
-rw-r--r--src/core/dbus-unit.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 501055c10b..91660cf3aa 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -1232,21 +1232,21 @@ static int property_get_cgroup(
return sd_bus_message_append(reply, "s", t);
}
-static int append_process(sd_bus_message *reply, const char *p, pid_t pid, Set *pids) {
+static int append_process(sd_bus_message *reply, const char *p, PidRef *pid, Set *pids) {
_cleanup_free_ char *buf = NULL, *cmdline = NULL;
int r;
assert(reply);
- assert(pid > 0);
+ assert(pidref_is_set(pid));
- r = set_put(pids, PID_TO_PTR(pid));
+ r = set_put(pids, PID_TO_PTR(pid->pid));
if (IN_SET(r, 0, -EEXIST))
return 0;
if (r < 0)
return r;
if (!p) {
- r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &buf);
+ r = cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &buf);
if (r == -ESRCH)
return 0;
if (r < 0)
@@ -1255,7 +1255,7 @@ static int append_process(sd_bus_message *reply, const char *p, pid_t pid, Set *
p = buf;
}
- (void) pid_get_cmdline(
+ (void) pidref_get_cmdline(
pid,
SIZE_MAX,
PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE,
@@ -1264,7 +1264,7 @@ static int append_process(sd_bus_message *reply, const char *p, pid_t pid, Set *
return sd_bus_message_append(reply,
"(sus)",
p,
- (uint32_t) pid,
+ (uint32_t) pid->pid,
cmdline);
}
@@ -1283,22 +1283,28 @@ static int append_cgroup(sd_bus_message *reply, const char *p, Set *pids) {
return r;
for (;;) {
- pid_t pid;
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
/* libvirt / qemu uses threaded mode and cgroup.procs cannot be read at the lower levels.
- * From https://docs.kernel.org/admin-guide/cgroup-v2.html#threads,
- * “cgroup.procs” in a threaded domain cgroup contains the PIDs of all processes in
- * the subtree and is not readable in the subtree proper. */
- r = cg_read_pid(f, &pid);
+ * From https://docs.kernel.org/admin-guide/cgroup-v2.html#threads, “cgroup.procs” in a
+ * threaded domain cgroup contains the PIDs of all processes in the subtree and is not
+ * readable in the subtree proper. */
+
+ r = cg_read_pidref(f, &pidref);
if (IN_SET(r, 0, -EOPNOTSUPP))
break;
if (r < 0)
return r;
- if (pid_is_kernel_thread(pid) > 0)
+ r = pidref_is_kernel_thread(&pidref);
+ if (r == -ESRCH) /* gone by now */
+ continue;
+ if (r < 0)
+ log_debug_errno(r, "Failed to determine if " PID_FMT " is a kernel thread, assuming not: %m", pidref.pid);
+ if (r > 0)
continue;
- r = append_process(reply, p, pid, pids);
+ r = append_process(reply, p, &pidref, pids);
if (r < 0)
return r;
}
@@ -1363,14 +1369,14 @@ int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bu
/* The main and control pids might live outside of the cgroup, hence fetch them separately */
PidRef *pid = unit_main_pid(u);
if (pidref_is_set(pid)) {
- r = append_process(reply, NULL, pid->pid, pids);
+ r = append_process(reply, NULL, pid, pids);
if (r < 0)
return r;
}
pid = unit_control_pid(u);
if (pidref_is_set(pid)) {
- r = append_process(reply, NULL, pid->pid, pids);
+ r = append_process(reply, NULL, pid, pids);
if (r < 0)
return r;
}