summaryrefslogtreecommitdiffstats
path: root/src/basic/cgroup-util.c
diff options
context:
space:
mode:
authorTimo Rothenpieler <timo@rothenpieler.org>2024-04-28 16:27:06 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2024-05-14 16:12:20 +0200
commit00f1714311c38ff1de6bbb96a33cc6448920bce2 (patch)
treec86a6a423c872d9ec941d2b55176d8ec037e6f83 /src/basic/cgroup-util.c
parentlibsystemd-network: skip dhcp server test in case of EAFNOSUPPORT (diff)
downloadsystemd-00f1714311c38ff1de6bbb96a33cc6448920bce2.tar.xz
systemd-00f1714311c38ff1de6bbb96a33cc6448920bce2.zip
cgroup-util: allow cg_read_pid() to skip unmapped (zero) pids
Diffstat (limited to 'src/basic/cgroup-util.c')
-rw-r--r--src/basic/cgroup-util.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 8303b37684..c0d0fe6f14 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -95,7 +95,7 @@ int cg_enumerate_processes(const char *controller, const char *path, FILE **ret)
return cg_enumerate_items(controller, path, ret, "cgroup.procs");
}
-int cg_read_pid(FILE *f, pid_t *ret) {
+int cg_read_pid(FILE *f, pid_t *ret, CGroupFlags flags) {
unsigned long ul;
/* Note that the cgroup.procs might contain duplicates! See cgroups.txt for details. */
@@ -103,27 +103,33 @@ int cg_read_pid(FILE *f, pid_t *ret) {
assert(f);
assert(ret);
- errno = 0;
- if (fscanf(f, "%lu", &ul) != 1) {
+ for (;;) {
+ errno = 0;
+ if (fscanf(f, "%lu", &ul) != 1) {
- if (feof(f)) {
- *ret = 0;
- return 0;
+ if (feof(f)) {
+ *ret = 0;
+ return 0;
+ }
+
+ return errno_or_else(EIO);
}
- return errno_or_else(EIO);
- }
+ if (ul > PID_T_MAX)
+ return -EIO;
- if (ul <= 0)
- return -EIO;
- if (ul > PID_T_MAX)
- return -EIO;
+ /* In some circumstances (e.g. WSL), cgroups might contain unmappable PIDs from other
+ * contexts. These show up as zeros, and depending on the caller, can either be plain
+ * skipped over, or returned as-is. */
+ if (ul == 0 && !FLAGS_SET(flags, CGROUP_DONT_SKIP_UNMAPPED))
+ continue;
- *ret = (pid_t) ul;
- return 1;
+ *ret = (pid_t) ul;
+ return 1;
+ }
}
-int cg_read_pidref(FILE *f, PidRef *ret) {
+int cg_read_pidref(FILE *f, PidRef *ret, CGroupFlags flags) {
int r;
assert(f);
@@ -132,7 +138,7 @@ int cg_read_pidref(FILE *f, PidRef *ret) {
for (;;) {
pid_t pid;
- r = cg_read_pid(f, &pid);
+ r = cg_read_pid(f, &pid, flags);
if (r < 0)
return r;
if (r == 0) {
@@ -140,6 +146,9 @@ int cg_read_pidref(FILE *f, PidRef *ret) {
return 0;
}
+ if (pid == 0)
+ return -EREMOTE;
+
r = pidref_set_pid(ret, pid);
if (r >= 0)
return 1;
@@ -343,7 +352,7 @@ static int cg_kill_items(
for (;;) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
- r = cg_read_pidref(f, &pidref);
+ r = cg_read_pidref(f, &pidref, /* flags = */ 0);
if (r < 0)
return RET_GATHER(ret, r);
if (r == 0)
@@ -938,7 +947,7 @@ int cg_is_empty(const char *controller, const char *path) {
if (r < 0)
return r;
- r = cg_read_pid(f, &pid);
+ r = cg_read_pid(f, &pid, CGROUP_DONT_SKIP_UNMAPPED);
if (r < 0)
return r;