cgroup: handle ENODEV on cg_read_pid() gracefully
The recently added test case TEST-07-PID1.subgroup-kill.sh surfaced a race: if we enumerate PIDs in a cgroup, and the cgroup is unlinked at the very same time reading will result in ENODEV. We need to handle that gracefully. Hence let's do so. Noticed while looking at: https://github.com/systemd/systemd/actions/runs/16143084441/job/45554929264?pr=38120
This commit is contained in:
committed by
Mike Yuan
parent
da412f3be2
commit
726183627b
@@ -367,6 +367,8 @@ int cg_migrate(
|
||||
if (r < 0)
|
||||
return RET_GATHER(ret, r);
|
||||
}
|
||||
if (r == -ENODEV)
|
||||
continue;
|
||||
if (r < 0)
|
||||
return RET_GATHER(ret, r);
|
||||
} while (!done);
|
||||
|
||||
@@ -107,9 +107,12 @@ static int show_cgroup_one_by_path(
|
||||
/* 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. */
|
||||
* the subtree and is not readable in the subtree proper.
|
||||
*
|
||||
* ENODEV is generated when we enumerate processes from a cgroup and the cgroup is removed
|
||||
* concurrently. */
|
||||
r = cg_read_pid(f, &pid, /* flags = */ 0);
|
||||
if (IN_SET(r, 0, -EOPNOTSUPP))
|
||||
if (IN_SET(r, 0, -EOPNOTSUPP, -ENODEV))
|
||||
break;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user