remove cgroup path recursively in cgroup v2#2412
Conversation
|
We need a test case -- create sub-cgroups, check they are actually removed. |
I add a test case in But failed in CI: the line 72-74 is: So, we can't create |
9f06248 to
2b1da44
Compare
| // Because there may be subcgroups in it. | ||
| func RemovePathUnified(path string) error { | ||
| infos, err := ioutil.ReadDir(path) | ||
| if err == nil { |
There was a problem hiding this comment.
1 nit:
if err != nil {
if os.IsNotExist(err) {
err = nil
}
return err
}so
- the rest of function will be less indented
- we won't return ENOENT.
| for _, info := range infos { | ||
| if info.IsDir() { | ||
| // We should remove subcgroups dir first | ||
| if err = RemovePathUnified(filepath.Join(path, info.Name())); err != nil && !os.IsNotExist(err) { |
There was a problem hiding this comment.
with the above suggestion, we won't have to check for IsNotExist here.
| } | ||
| } | ||
| } | ||
| if err == nil || os.IsNotExist(err) { |
| } | ||
| } | ||
| if err == nil || os.IsNotExist(err) { | ||
| return os.Remove(path) |
There was a problem hiding this comment.
I think we should avoid returning ENOENT from here as well (similar to what os.RemoveAll() does.
| // RemovePathUnified aims to remove cgroup path recursively | ||
| // Because there may be subcgroups in it. | ||
| func RemovePathUnified(path string) error { | ||
| infos, err := ioutil.ReadDir(path) |
There was a problem hiding this comment.
OK, I think we can optimize things for the common case here:
err := os.Remove(path)
if err == nil || os.IsNotExist(err) {
return nil
}
// remove subdirectories first
infos, err := ioutil.ReadDir(path)
....There was a problem hiding this comment.
I still think it's a pretty good optimization. Will follow up.
|
|
||
| // RemovePathUnified aims to remove cgroup path recursively | ||
| // Because there may be subcgroups in it. | ||
| func RemovePathUnified(path string) error { |
There was a problem hiding this comment.
Since we're only using this function from fs2, why don't we move it to fs2 and make it private.
Maybe rename to removeCgroupPath or so.
|
left an optimization suggestion for Found another problem as well -- the test case added works even without the changes. I think we need to make sure the test case fails, then make it work, otherwise it's not clear what are we fixing here. Maybe the sub-cgroup need to have some limits set? IDK. $ git fetch lifubang
...
$ git checkout removecgpath
Branch 'removecgpath' set up to track remote branch 'removecgpath' from 'lifubang'.
Switched to a new branch 'removecgpath'
$ git show libcontainer/ | patch -p1 -R # revert the "fixing" part
patching file libcontainer/cgroups/fs2/fs2.go
patching file libcontainer/cgroups/utils.go
$ sudo -s
# RUNC_USE_SYSTEMD=yes make localintegration TESTPATH=/delete.bats
go build "-mod=vendor" -buildmode=pie -tags "seccomp selinux apparmor" -ldflags "-X main.gitCommit="430a1e88c359974ba441cf75b619626cece7c261-dirty" -X main.version=1.0.0-rc10+dev " -o runc .
go build "-mod=vendor" -buildmode=pie -tags "seccomp selinux apparmor" -ldflags "-X main.gitCommit="430a1e88c359974ba441cf75b619626cece7c261-dirty" -X main.version=1.0.0-rc10+dev " -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
bats -t tests/integration/delete.bats
1..4
ok 1 runc delete
ok 2 runc delete --force
ok 3 runc delete --force ignore not exist
ok 4 runc delete --force in cgroupv2 with subcgroups |
Signed-off-by: lifubang <lifubang@acmcoder.com>
| # create subcgroups | ||
| cat <<EOF > nest.sh | ||
| cd /sys/fs/cgroup | ||
| for f in \$(cat cgroup.controllers); do echo +\$f > cgroup.subtree_control; done |
There was a problem hiding this comment.
This gives an error on my system when trying to enable io controller.
Most probably just +pids is enough (and it won't error).
|
|
||
| # create a sub process | ||
| __runc exec -d test_busybox sleep 1d | ||
| [ "$status" -eq 0 ] |
There was a problem hiding this comment.
__runc does not set $status, so this check is checking and older status.
| [ "$status" -eq 0 ] | ||
|
|
||
| # find the pid of sleep | ||
| pid=$(__runc exec test_busybox ps -a | grep 1d | awk '{print $1}') |
There was a problem hiding this comment.
busybox ps does not have -a, but fortunately it is ignored.
| cat cgroup.threads | ||
| EOF | ||
| cat nest.sh | runc exec test_busybox sh | ||
| [[ ${output} =~ [0-9]+ ]] |
There was a problem hiding this comment.
you don't check the exit status
|
|
||
| # create subcgroups | ||
| cat <<EOF > nest.sh | ||
| cd /sys/fs/cgroup |
There was a problem hiding this comment.
makes sense to add set -x -u -e
|
|
||
| # check cgroup.threads' value | ||
| runc exec test_busybox cat /sys/fs/cgroup/foo/cgroup.threads | ||
| [[ ${output} =~ [0-9]+ ]] |
There was a problem hiding this comment.
We have already checked it above (the output of nest.sh script), looks like this check is redundant.
fix #2403
If we have subcgroups in a cgroup path, we should remove it recursively.
Signed-off-by: lifubang lifubang@acmcoder.com