]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
recursively delete cgroups on container shutdown
authorSerge Hallyn <serge.hallyn@canonical.com>
Thu, 2 Feb 2012 21:52:35 +0000 (15:52 -0600)
committerDaniel Lezcano <daniel.lezcano@free.fr>
Sun, 26 Feb 2012 09:44:40 +0000 (10:44 +0100)
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>
src/lxc/cgroup.c

index 8077a8da2140853c8112163dd716a8ce0f888497..f88d556759fe203127a569255dfecb44c033f4f9 100644 (file)
@@ -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;
        }