From 341a9bd8aca9c404d0d59f7036d81d47de0d6f5a Mon Sep 17 00:00:00 2001 From: Serge Hallyn Date: Thu, 2 Feb 2012 15:52:35 -0600 Subject: recursively delete cgroups on container shutdown If a container has created its own cgroups, i.e. by running libvirtd, then if we don't delete all child cgroups, then the rmdir will fail. Signed-off-by: Serge Hallyn Signed-off-by: Daniel Lezcano --- src/lxc/cgroup.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c index 8077a8d..f88d556 100644 --- a/src/lxc/cgroup.c +++ b/src/lxc/cgroup.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -419,6 +420,48 @@ out: return err; } +int recursive_rmdir(char *dirname) +{ + struct dirent dirent, *direntp; + int fddir; + DIR *dir; + int ret; + char pathname[MAXPATHLEN]; + + dir = opendir(dirname); + if (!dir) { + WARN("failed to open directory: %m"); + return -1; + } + + fddir = dirfd(dir); + + while (!readdir_r(dir, &dirent, &direntp)) { + struct stat mystat; + + if (!direntp) + break; + + if (!strcmp(direntp->d_name, ".") || + !strcmp(direntp->d_name, "..")) + continue; + + snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name); + ret = stat(pathname, &mystat); + if (ret) + continue; + if (S_ISDIR(mystat.st_mode)) + recursive_rmdir(pathname); + } + + ret = rmdir(dirname); + + if (closedir(dir)) + ERROR("failed to close directory"); + return ret; + + +} int lxc_one_cgroup_destroy(struct mntent *mntent, const char *name) { @@ -428,7 +471,7 @@ int lxc_one_cgroup_destroy(struct mntent *mntent, const char *name) snprintf(cgname, MAXPATHLEN, "%s%s/lxc/%s", cgmnt, get_init_cgroup(NULL, mntent, initcgroup), name); DEBUG("destroying %s\n", cgname); - if (rmdir(cgname)) { + if (recursive_rmdir(cgname)) { SYSERROR("failed to remove cgroup '%s'", cgname); return -1; } -- cgit v1.2.3-65-gdbad