diff options
author | 2012-02-02 15:52:35 -0600 | |
---|---|---|
committer | 2012-02-26 10:44:40 +0100 | |
commit | 341a9bd8aca9c404d0d59f7036d81d47de0d6f5a (patch) | |
tree | 6ae40f864fbaff28256c37571398d1c367c88112 | |
parent | fix lxc-netstat for nested cgroups (diff) | |
download | lxc-341a9bd8aca9c404d0d59f7036d81d47de0d6f5a.tar.gz lxc-341a9bd8aca9c404d0d59f7036d81d47de0d6f5a.tar.bz2 lxc-341a9bd8aca9c404d0d59f7036d81d47de0d6f5a.zip |
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 <serge.hallyn@canonical.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
-rw-r--r-- | src/lxc/cgroup.c | 45 |
1 files changed, 44 insertions, 1 deletions
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 <mntent.h> #include <unistd.h> #include <string.h> +#include <dirent.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> @@ -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; } |