Skip to content

cgroupfs: drop registry entries on filesystem release#13215

Open
ibondarenko1 wants to merge 1 commit into
google:masterfrom
ibondarenko1:cgroupfs-release-removecgroup
Open

cgroupfs: drop registry entries on filesystem release#13215
ibondarenko1 wants to merge 1 commit into
google:masterfrom
ibondarenko1:cgroupfs-release-removecgroup

Conversation

@ibondarenko1
Copy link
Copy Markdown

Summary

Follow-up to commit 26ef5174081be0b4b1f750a97e75ee6bad5d5a53 (cgroupfs: remove cgroup from CgroupRegistry on rmdir). Walk the cgroupfs dentry subtree in (*filesystem).Release and call CgroupRegistry.RemoveCgroup for every cgroupInode.id in the tree.

Why

The rmdir fix covers cgroups removed via rmdir(2). Two release paths still leak entries:

  1. FilesystemType.GetFilesystem error window at cgroupfs.go:376-398. newCgroupInode at base.go:190 calls r.AddCgroup for the root cgroup before prepareInitialCgroup and r.Register run. On either failure the code does rootD.DecRef(ctx); fs.VFSFilesystem().DecRef(ctx). Release then runs but currently skips ReleaseCgroupHierarchy and Unregister because fs.hierarchyID is still InvalidCgroupHierarchyID. The root cgroup id stays in CgroupRegistry.cgroups forever. Repeated mount-failures accumulate unbounded entries that get serialized on every checkpoint, same class as the rmdir leak.

  2. prepareInitialCgroup at cgroupfs.go:440-447 creates intermediate cgroup directories via newDirWithOwner, each of which calls AddCgroup. If the path walk later fails, the partially created children leak.

Approach

Add a helper removeCgroupsFromRegistryLocked that walks fs.root via the existing dir.forEachChildDir and calls RemoveCgroup for each cgroupInode.id. RemoveCgroup is documented as a no-op for ids that are not present (cgroup.go:556-558), so cgroups already removed by RmDir cost nothing. RmDir stays the primary owner of the live-cgroup case; this walk is the safety net for the release-time residue.

Test

  • bazel test //pkg/sentry/fsimpl/cgroupfs/... //test/syscalls:cgroup_test

CLA

Signed via individual Google CLA on sactransport2000@gmail.com.

Commit 26ef517 added
CgroupRegistry.RemoveCgroup and called it from dir.RmDir so that
destroyed cgroup directories do not stay in
kernel.CgroupRegistry.cgroups across save/restore. That fix covers
rmdir but two release paths still leak:

1. GetFilesystem error window. newCgroupInode at base.go:190 calls
   r.AddCgroup for the root cgroup before prepareInitialCgroup and
   r.Register run. On either failure the code calls rootD.DecRef and
   fs.VFSFilesystem().DecRef. Release then runs but currently skips
   ReleaseCgroupHierarchy and Unregister because fs.hierarchyID is
   still InvalidCgroupHierarchyID. The root cgroup id stays in the
   registry forever. Repeated mount-failures accumulate unbounded
   entries.

2. prepareInitialCgroup creates intermediate cgroup directories via
   newDirWithOwner, each of which calls AddCgroup. If
   prepareInitialCgroup fails partway, the same residue applies.

Walk fs.root in Release and call RemoveCgroup for each cgroupInode in
the subtree. RemoveCgroup is documented as a no-op for ids not in the
map (cgroup.go:556-558), so cgroups that RmDir already removed cost
nothing and the rmdir path stays the primary owner.

Signed-off-by: Ievgen Bondarenko <sactransport2000@gmail.com>
@ayushr2
Copy link
Copy Markdown
Collaborator

ayushr2 commented May 20, 2026

@xiangbin-hu could you help review this, as this is supposed to be a follow-up from your commit in #12909

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.

3 participants