cgroups: attempt a recursive rmdir

if the cgroup cannot be deleted, then attempt to delete all its
subdirectories and try again.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano
2019-07-11 13:24:39 +02:00
parent 144567b42d
commit 1601100b3e
6 changed files with 38 additions and 9 deletions

View File

@ -37,7 +37,7 @@ func (c *blkioHandler) Create(ctr *CgroupControl) (bool, error) {
// Destroy the cgroup
func (c *blkioHandler) Destroy(ctr *CgroupControl) error {
return os.Remove(ctr.getCgroupv1Path(Blkio))
return rmDirRecursively(ctr.getCgroupv1Path(Blkio))
}
// Stat fills a metrics structure with usage stats for the controller

View File

@ -355,11 +355,40 @@ func (c *CgroupControl) Delete() error {
return c.DeleteByPath(c.path)
}
// rmDirRecursively delete recursively a cgroup directory.
// It differs from os.RemoveAll as it doesn't attempt to unlink files.
// On cgroupfs we are allowed only to rmdir empty directories.
func rmDirRecursively(path string) error {
if err := os.Remove(path); err == nil || os.IsNotExist(err) {
return nil
}
entries, err := ioutil.ReadDir(path)
if err != nil {
return errors.Wrapf(err, "read %s", path)
}
for _, i := range entries {
if i.IsDir() {
if err := rmDirRecursively(filepath.Join(path, i.Name())); err != nil {
return err
}
}
}
if os.Remove(path); err != nil {
if !os.IsNotExist(err) {
return errors.Wrapf(err, "remove %s", path)
}
}
return nil
}
// DeleteByPath deletes the specified cgroup path
func (c *CgroupControl) DeleteByPath(path string) error {
if c.systemd {
return systemdDestroy(path)
}
if c.cgroup2 {
return rmDirRecursively(filepath.Join(cgroupRoot, c.path))
}
var lastError error
for _, h := range handlers {
if err := h.Destroy(c); err != nil {
@ -368,8 +397,11 @@ func (c *CgroupControl) DeleteByPath(path string) error {
}
for _, ctr := range c.additionalControllers {
if ctr.symlink {
continue
}
p := c.getCgroupv1Path(ctr.name)
if err := os.Remove(p); err != nil {
if err := rmDirRecursively(p); err != nil {
lastError = errors.Wrapf(err, "remove %s", p)
}
}

View File

@ -68,7 +68,7 @@ func (c *cpuHandler) Create(ctr *CgroupControl) (bool, error) {
// Destroy the cgroup
func (c *cpuHandler) Destroy(ctr *CgroupControl) error {
return os.Remove(ctr.getCgroupv1Path(CPU))
return rmDirRecursively(ctr.getCgroupv1Path(CPU))
}
// Stat fills a metrics structure with usage stats for the controller

View File

@ -3,7 +3,6 @@ package cgroups
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -77,7 +76,7 @@ func (c *cpusetHandler) Create(ctr *CgroupControl) (bool, error) {
// Destroy the cgroup
func (c *cpusetHandler) Destroy(ctr *CgroupControl) error {
return os.Remove(ctr.getCgroupv1Path(CPUset))
return rmDirRecursively(ctr.getCgroupv1Path(CPUset))
}
// Stat fills a metrics structure with usage stats for the controller

View File

@ -2,7 +2,6 @@ package cgroups
import (
"fmt"
"os"
"path/filepath"
spec "github.com/opencontainers/runtime-spec/specs-go"
@ -33,7 +32,7 @@ func (c *memHandler) Create(ctr *CgroupControl) (bool, error) {
// Destroy the cgroup
func (c *memHandler) Destroy(ctr *CgroupControl) error {
return os.Remove(ctr.getCgroupv1Path(Memory))
return rmDirRecursively(ctr.getCgroupv1Path(Memory))
}
// Stat fills a metrics structure with usage stats for the controller

View File

@ -3,7 +3,6 @@ package cgroups
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
spec "github.com/opencontainers/runtime-spec/specs-go"
@ -40,7 +39,7 @@ func (c *pidHandler) Create(ctr *CgroupControl) (bool, error) {
// Destroy the cgroup
func (c *pidHandler) Destroy(ctr *CgroupControl) error {
return os.Remove(ctr.getCgroupv1Path(Pids))
return rmDirRecursively(ctr.getCgroupv1Path(Pids))
}
// Stat fills a metrics structure with usage stats for the controller