From 6a6db9ede90cd0e2ee4ade38d19e74c9cb3dda42 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 13 Oct 2026 18:01:57 -0700 Subject: [PATCH] fs: initialize subsystems lazily Package init calls IsCgroup2HybridMode, which does statfs(2) on /sys/fs/cgroup/unified. This happens on every start of any program which imports this package (e.g. runc, including runc init), even when the fs cgroup manager is never used (as it is the case on cgroup v2 hosts). Make subsystems a sync.OnceValue to only do this when needed. Signed-off-by: Kir Kolyshkin --- fs/fs.go | 54 ++++++++++++++++++++++++++++------------------------- fs/paths.go | 2 +- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/fs/fs.go b/fs/fs.go index d14179d..e5efeaa 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -14,33 +14,37 @@ import ( "github.com/opencontainers/cgroups/fscommon" ) -var subsystems = []subsystem{ - &CpusetGroup{}, - &DevicesGroup{}, - &MemoryGroup{}, - &CpuGroup{}, - &CpuacctGroup{}, - &PidsGroup{}, - &BlkioGroup{}, - &HugetlbGroup{}, - &NetClsGroup{}, - &NetPrioGroup{}, - &PerfEventGroup{}, - &FreezerGroup{}, - &RdmaGroup{}, - &NameGroup{GroupName: "name=systemd", Join: true}, - &NameGroup{GroupName: "misc", Join: true, GroupID: cgroups.Misc}, -} - -var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist") +// subsystems returns the list of supported subsystems. It is initialized +// lazily to avoid doing any filesystem access during package initialization. +var subsystems = sync.OnceValue(func() []subsystem { + ss := []subsystem{ + &CpusetGroup{}, + &DevicesGroup{}, + &MemoryGroup{}, + &CpuGroup{}, + &CpuacctGroup{}, + &PidsGroup{}, + &BlkioGroup{}, + &HugetlbGroup{}, + &NetClsGroup{}, + &NetPrioGroup{}, + &PerfEventGroup{}, + &FreezerGroup{}, + &RdmaGroup{}, + &NameGroup{GroupName: "name=systemd", Join: true}, + &NameGroup{GroupName: "misc", Join: true, GroupID: cgroups.Misc}, + } -func init() { // If using cgroups-hybrid mode then add a "" controller indicating // it should join the cgroups v2. if cgroups.IsCgroup2HybridMode() { - subsystems = append(subsystems, &NameGroup{GroupName: "", Join: true}) + ss = append(ss, &NameGroup{GroupName: "", Join: true}) } -} + + return ss +}) + +var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist") type subsystem interface { // Name returns the name of the subsystem. @@ -114,7 +118,7 @@ func (m *Manager) Apply(pid int) (retErr error) { c := m.cgroups - for _, sys := range subsystems { + for _, sys := range subsystems() { name := sys.Name() p, ok := m.paths[name] if !ok { @@ -199,7 +203,7 @@ func (m *Manager) Stats(opts *cgroups.StatsOptions) (*cgroups.Stats, error) { } stats := cgroups.NewStats() - for _, sys := range subsystems { + for _, sys := range subsystems() { path := m.paths[sys.Name()] if path == "" { continue @@ -228,7 +232,7 @@ func (m *Manager) Set(r *cgroups.Resources) error { m.mu.Lock() defer m.mu.Unlock() - for _, sys := range subsystems { + for _, sys := range subsystems() { path := m.paths[sys.Name()] if err := sys.Set(path, r); err != nil { // When rootless is true, errors from the device subsystem diff --git a/fs/paths.go b/fs/paths.go index edbe041..68768a7 100644 --- a/fs/paths.go +++ b/fs/paths.go @@ -32,7 +32,7 @@ func initPaths(cg *cgroups.Cgroup) (map[string]string, error) { } paths := make(map[string]string) - for _, sys := range subsystems { + for _, sys := range subsystems() { name := sys.Name() path, err := subsysPath(root, inner, name) if err != nil {