diff --git a/pkg/selfcontain/init.go b/pkg/selfcontain/init.go index 8b94bf65518006334b3ed5971c9b04bbef5f377b..eeb2a64780eb417146aea51236218cd1e7de5d5e 100644 --- a/pkg/selfcontain/init.go +++ b/pkg/selfcontain/init.go @@ -25,24 +25,11 @@ func init() { // Do not start the full featured runtime runtime.GOMAXPROCS(1) runtime.LockOSThread() - // Evacuate cgroups, which is required for many in-container cgroup - // use cases, since we are now at the root cgroup - // Libcontainer cgroup manager is not designed for evacuation and will - // fail in such a case, so we are using cgroupfs directly, which is - // explicitely available due to defaults, and simple since we are - // the only running process at the moment - err := os.Mkdir("/sys/fs/cgroup/selfcontain", 0o755) - if err != nil { - logrus.Fatal("could not create evacuation cgroup: ", err) - } - err = os.WriteFile("/sys/fs/cgroup/selfcon/cgroup.procs", []byte("0"), 0o755) - if err != nil { - logrus.Fatal("could not evacuate self: ", err) - } // Run libcontainer initialization, which will fork/exec to the // provided process executable, a.k.a ourselves + logrus.Debug("initializing self-contained app") factory, _ := libcontainer.New("") - err = factory.StartInitialization() + err := factory.StartInitialization() if err != nil { logrus.Fatal("could not run self-contained app: ", err) } diff --git a/pkg/selfcontain/utils.go b/pkg/selfcontain/utils.go index 6a6eb149a7fd9780ebfa5072747683b392f26541..6c2a132f28b3d855f07a2b2dbb983ba42f17c871 100644 --- a/pkg/selfcontain/utils.go +++ b/pkg/selfcontain/utils.go @@ -16,6 +16,7 @@ func RunFun(config *Config, f runnable) error { for _, arg := range os.Args { if arg == argRunFun { logrus.Debug("we are running inside the container...") + Evacuate() f() return nil } @@ -44,3 +45,21 @@ func RunFun(config *Config, f runnable) error { }() return c.Run() } + +// Evacuate cgroups, which is required for many in-container use cases +// Remaining in the root cgroup would prevent creating any domain sub-cgroup +func Evacuate() { + // Libcontainer cgroup manager is not designed for evacuation and will + // fail in such a case, so we are using cgroupfs directly, which is + // explicitely available due to defaults, and simple since we are + // the only running process at the moment + logrus.Debug("evacuating self to /selfcontain") + err := os.Mkdir("/sys/fs/cgroup/selfcontain", 0o755) + if err != nil && !os.IsExist(err) { + logrus.Fatal("could not create evacuation cgroup: ", err) + } + err = os.WriteFile("/sys/fs/cgroup/selfcontain/cgroup.procs", []byte("0"), 0o755) + if err != nil { + logrus.Fatal("could not evacuate self: ", err) + } +}