Skip to content

Commit c7f9472

Browse files
committed
docs: improve comments and user warnings with cgroup delegation explanation
- Add background explanation of cgroup delegation in code comments - Explain why non-systemd systems (OpenRC/elogind) need manual configuration - Update user warnings to be more helpful with actionable fix reference - Add link to Gentoo Wiki for configuring cgroup delegation Signed-off-by: xz-dev <xiangzhedev@gmail.com>
1 parent c828c25 commit c7f9472

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

distrobox-rm

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,19 @@ delete_container()
392392
# Workaround for podman rm --force timeout issue when cgroup-path is empty.
393393
# See: https://github.com/chimera-linux/cports/issues/1718
394394
#
395-
# Root cause: In rootless mode, crun may fail to create a cgroup for the
396-
# container (e.g., with cgroupfs manager or --pid host). When cgroup-path
397-
# is empty, "crun kill --all" cannot enumerate processes via cgroup, causing
398-
# podman rm --force to timeout. With systemd cgroup manager (e.g., Fedora),
399-
# cgroup delegation works and this issue doesn't occur.
395+
# Background - cgroup delegation:
396+
# In cgroup v2, only root can create sub-cgroups by default. "Delegation" means
397+
# granting a non-root user write access to a cgroup subtree, allowing them to
398+
# create child cgroups. On systemd systems, systemd-logind automatically delegates
399+
# user slices (e.g., /sys/fs/cgroup/user.slice/user-1000.slice/) to users.
400+
# On non-systemd systems (OpenRC/elogind), this delegation is NOT automatic -
401+
# users lack write permission to /sys/fs/cgroup, so rootless podman cannot create
402+
# cgroups for containers.
403+
#
404+
# Root cause: Without cgroup delegation, crun cannot create a cgroup for the
405+
# container. When cgroup-path is empty, "crun kill --all" cannot enumerate
406+
# processes via cgroup, causing podman rm --force to timeout waiting for the
407+
# container to stop.
400408
#
401409
# Solution: Check if crun's cgroup-path is empty. If so, use "podman kill"
402410
# first, which sends signal directly to the container's init process PID,
@@ -411,6 +419,10 @@ delete_container()
411419
# orphaned. Daemonized processes (setsid/double-fork) also cannot be tracked.
412420
# Use --unshare-process when creating the container for full process cleanup.
413421
# See: https://github.com/containers/podman/issues/11888
422+
#
423+
# To fix this properly on non-systemd systems, configure cgroup delegation:
424+
# https://github.com/89luca89/distrobox/issues/1939
425+
#
414426
# distrobox-rm does not call distrobox-stop by design; a similar fix exists there.
415427
if [ "${container_status}" = "running" ] && [ "${rootful}" -eq 0 ] && echo "${container_manager}" | grep -q "podman"; then
416428
container_id=$(${container_manager} inspect --format '{{.Id}}' "${container_name}" 2> /dev/null)
@@ -419,9 +431,10 @@ delete_container()
419431
cgroup_path=$(sed -n 's/.*"cgroup-path": "\([^"]*\)".*/\1/p' "${crun_status}" 2> /dev/null)
420432
if [ -z "${cgroup_path}" ]; then
421433
${container_manager} kill "${container_name}" > /dev/null 2>&1 || :
422-
printf >&2 "Warning: container was created with --pid host and cgroup is not available.\n"
434+
printf >&2 "Warning: cgroup is not available for this container.\n"
435+
printf >&2 "Warning: this is common on non-systemd systems (OpenRC/elogind) without cgroup delegation.\n"
423436
printf >&2 "Warning: some child processes may remain running (orphaned).\n"
424-
printf >&2 "Warning: use --unshare-process when creating containers for full cleanup.\n"
437+
printf >&2 "Warning: to fix: https://github.com/89luca89/distrobox/issues/1939\n"
425438
fi
426439
fi
427440
fi

distrobox-stop

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,11 +293,19 @@ case "${response}" in
293293
# Workaround for podman stop timeout issue when cgroup-path is empty.
294294
# See: https://github.com/chimera-linux/cports/issues/1718
295295
#
296-
# Root cause: In rootless mode, crun may fail to create a cgroup for the
297-
# container (e.g., with cgroupfs manager or --pid host). When cgroup-path
298-
# is empty, "crun kill --all" cannot enumerate processes via cgroup, causing
299-
# podman stop to timeout. With systemd cgroup manager (e.g., Fedora), cgroup
300-
# delegation works and this issue doesn't occur.
296+
# Background - cgroup delegation:
297+
# In cgroup v2, only root can create sub-cgroups by default. "Delegation" means
298+
# granting a non-root user write access to a cgroup subtree, allowing them to
299+
# create child cgroups. On systemd systems, systemd-logind automatically delegates
300+
# user slices (e.g., /sys/fs/cgroup/user.slice/user-1000.slice/) to users.
301+
# On non-systemd systems (OpenRC/elogind), this delegation is NOT automatic -
302+
# users lack write permission to /sys/fs/cgroup, so rootless podman cannot create
303+
# cgroups for containers.
304+
#
305+
# Root cause: Without cgroup delegation, crun cannot create a cgroup for the
306+
# container. When cgroup-path is empty, "crun kill --all" cannot enumerate
307+
# processes via cgroup, causing podman stop to timeout waiting for the container
308+
# to stop.
301309
#
302310
# Solution: Check if crun's cgroup-path is empty. If so, use "podman kill"
303311
# first, which sends signal directly to the container's init process PID,
@@ -312,16 +320,20 @@ case "${response}" in
312320
# orphaned. Daemonized processes (setsid/double-fork) also cannot be tracked.
313321
# Use --unshare-process when creating the container for full process cleanup.
314322
# See: https://github.com/containers/podman/issues/11888
323+
#
324+
# To fix this properly on non-systemd systems, configure cgroup delegation:
325+
# https://github.com/89luca89/distrobox/issues/1939
315326
if [ "${rootful}" -eq 0 ] && echo "${container_manager}" | grep -q "podman"; then
316327
container_id=$(${container_manager} inspect --format '{{.Id}}' "${container_name}" 2> /dev/null)
317328
crun_status="/run/user/$(id -u)/crun/${container_id}/status"
318329
if [ -f "${crun_status}" ]; then
319330
cgroup_path=$(sed -n 's/.*"cgroup-path": "\([^"]*\)".*/\1/p' "${crun_status}" 2> /dev/null)
320331
if [ -z "${cgroup_path}" ]; then
321332
${container_manager} kill "${container_name}" 2> /dev/null || :
322-
printf >&2 "Warning: container was created with --pid host and cgroup is not available.\n"
333+
printf >&2 "Warning: cgroup is not available for this container.\n"
334+
printf >&2 "Warning: this is common on non-systemd systems (OpenRC/elogind) without cgroup delegation.\n"
323335
printf >&2 "Warning: some child processes may remain running (orphaned).\n"
324-
printf >&2 "Warning: use --unshare-process when creating containers for full cleanup.\n"
336+
printf >&2 "Warning: to fix: https://github.com/89luca89/distrobox/issues/1939\n"
325337
fi
326338
fi
327339
fi

0 commit comments

Comments
 (0)