Skip to content

fix: only remount /sys/fs/cgroup when rooted at a nested path#173

Merged
geokat merged 2 commits into
mainfrom
george/plat-383/fix-ebusy-on-unconditional-cgroupfs-remount
Jul 21, 2026
Merged

fix: only remount /sys/fs/cgroup when rooted at a nested path#173
geokat merged 2 commits into
mainfrom
george/plat-383/fix-ebusy-on-unconditional-cgroupfs-remount

Conversation

@geokat

@geokat geokat commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

The cgroup-v2 nesting setup in wrap_dockerd.sh unconditionally unmounted and remounted /sys/fs/cgroup after unsharing the cgroup namespace to ensure inner container cgroups land under the envbox container's cgroup on the host (see #169).

On some runtimes, /sys/fs/cgroup is already rooted at "/" once the cgroup namespace is unshared, and remounting a live cgroupfs there can fail with EBUSY, aborting dockerd startup. This can break envbox startup in affected environments, including the README Hacking example.

Read the mount root from /proc/self/mountinfo and skip the umount/remount when it's already "/", only remounting when the mount still points at a nested path from the inherited environment. Update the inline script copy and assertions in the docker tests to match.

Refs: https://linear.app/codercom/issue/PLAT-383

The cgroup-v2 nesting setup in wrap_dockerd.sh unconditionally
unmounted and remounted /sys/fs/cgroup after unsharing the cgroup
namespace to ensure inner container cgroups land under the envbox
container's cgroup on the host (see #169).

On some runtimes, /sys/fs/cgroup is already rooted at "/" once the
cgroup namespace is unshared, and remounting a live cgroupfs there can
fail with EBUSY, aborting dockerd startup. This can break envbox
startup in affected environments, including the README Hacking
example.

Read the mount root from /proc/self/mountinfo and skip the
umount/remount when it's already "/", only remounting when the mount
still points at a nested path from the inherited environment. Update
the inline script copy and assertions in the docker tests to match.

Refs: https://linear.app/codercom/issue/PLAT-383
@linear-code

linear-code Bot commented Jul 20, 2026

Copy link
Copy Markdown

PLAT-383

@geokat
geokat marked this pull request as ready for review July 20, 2026 06:49
@geokat
geokat requested a review from johnstcn July 20, 2026 06:49
Comment thread cli/wrap_dockerd.sh Outdated
@geokat
geokat requested a review from johnstcn July 20, 2026 18:24
Comment thread cli/docker_test.go
Comment on lines +194 to +210
# Some runtimes already root /sys/fs/cgroup at "/" after unsharing the
# cgroup namespace; remounting it again fails with EBUSY. Only remount
# when it's still rooted at a nested host path.
# When mounts are stacked at /sys/fs/cgroup, the visible mount is the
# one whose ID is not another same-location mount's parent (see
# proc_pid_mountinfo(5)).
cgroup_mount_root=$(awk '
$5 == "/sys/fs/cgroup" { root[$1] = $4; isparent[$2] = 1 }
END { for (id in root) if (!(id in isparent)) print root[id] }
' /proc/self/mountinfo)
if [ "$cgroup_mount_root" != "/" ]; then
# Remount /sys/fs/cgroup so the new cgroup namespace's view becomes the
# fs root; inner container cgroups end up under the envbox container's
# cgroup on the host.
umount /sys/fs/cgroup || { echo "envbox: failed to umount /sys/fs/cgroup" >&2; exit 1; }
mount -t cgroup2 cgroup /sys/fs/cgroup || { echo "envbox: failed to mount cgroup2 on /sys/fs/cgroup" >&2; exit 1; }
fi

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, non-blocking: We now have this logic duplicated verbatim. Might be worth de-duping? Not a blocker though and more of a follow-up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! More than that, we're effectively triplicating this logic between this
test, TestWrapDockerdCmd, and the production script itself. It would be nice to
replace most of that with a black-box test of the wrapper's behavior, but that
would need a bit of dedicated harness/setup (good for a follow-up PR).

@geokat
geokat merged commit 7f301fa into main Jul 21, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants