diff --git a/libcontainer/cgroups/fs2/fs2.go b/libcontainer/cgroups/fs2/fs2.go index 7be26211..0975064f 100644 --- a/libcontainer/cgroups/fs2/fs2.go +++ b/libcontainer/cgroups/fs2/fs2.go @@ -4,14 +4,12 @@ package fs2 import ( "io/ioutil" - "os" "path/filepath" "strings" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" "github.com/pkg/errors" - "golang.org/x/sys/unix" ) type manager struct { @@ -157,45 +155,8 @@ func (m *manager) Freeze(state configs.FreezerState) error { return nil } -func rmdir(path string) error { - err := unix.Rmdir(path) - if err == nil || err == unix.ENOENT { - return nil - } - return &os.PathError{Op: "rmdir", Path: path, Err: err} -} - -// removeCgroupPath aims to remove cgroup path recursively -// Because there may be subcgroups in it. -func removeCgroupPath(path string) error { - // try the fast path first - if err := rmdir(path); err == nil { - return nil - } - - infos, err := ioutil.ReadDir(path) - if err != nil { - if os.IsNotExist(err) { - err = nil - } - return err - } - for _, info := range infos { - if info.IsDir() { - // We should remove subcgroups dir first - if err = removeCgroupPath(filepath.Join(path, info.Name())); err != nil { - break - } - } - } - if err == nil { - err = rmdir(path) - } - return err -} - func (m *manager) Destroy() error { - return removeCgroupPath(m.dirPath) + return cgroups.RemovePath(m.dirPath) } func (m *manager) Path(_ string) string { diff --git a/libcontainer/cgroups/utils.go b/libcontainer/cgroups/utils.go index 222a513e..dc6aa683 100644 --- a/libcontainer/cgroups/utils.go +++ b/libcontainer/cgroups/utils.go @@ -207,6 +207,43 @@ func EnterPid(cgroupPaths map[string]string, pid int) error { return nil } +func rmdir(path string) error { + err := unix.Rmdir(path) + if err == nil || err == unix.ENOENT { + return nil + } + return &os.PathError{Op: "rmdir", Path: path, Err: err} +} + +// RemovePath aims to remove cgroup path. It does so recursively, +// by removing any subdirectories (sub-cgroups) first. +func RemovePath(path string) error { + // try the fast path first + if err := rmdir(path); err == nil { + return nil + } + + infos, err := ioutil.ReadDir(path) + if err != nil { + if os.IsNotExist(err) { + err = nil + } + return err + } + for _, info := range infos { + if info.IsDir() { + // We should remove subcgroups dir first + if err = RemovePath(filepath.Join(path, info.Name())); err != nil { + break + } + } + } + if err == nil { + err = rmdir(path) + } + return err +} + // RemovePaths iterates over the provided paths removing them. // We trying to remove all paths five times with increasing delay between tries. // If after all there are not removed cgroups - appropriate error will be