]> git.ipfire.org Git - pakfire.git/commitdiff
cgroup: Fix destruction function
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 9 Aug 2022 13:52:23 +0000 (13:52 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 9 Aug 2022 13:52:23 +0000 (13:52 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/cgroup.c

index 0c902d851dfd3d634189e4d888f2f0e97de10aef..873d13dae26f5eff739f3cba4fbc63caec7eee2a 100644 (file)
@@ -156,6 +156,16 @@ static void pakfire_cgroup_free(struct pakfire_cgroup* cgroup) {
        free(cgroup);
 }
 
+static int pakfire_cgroup_open_root(struct pakfire_cgroup* cgroup) {
+       int fd = open(ROOT, O_DIRECTORY|O_PATH|O_CLOEXEC);
+       if (fd < 0) {
+               ERROR(cgroup->pakfire, "Could not open %s: %m\n", ROOT);
+               return -1;
+       }
+
+       return fd;
+}
+
 static int __pakfire_cgroup_create(struct pakfire_cgroup* cgroup) {
        char path[PATH_MAX];
        int r;
@@ -179,16 +189,13 @@ static int __pakfire_cgroup_create(struct pakfire_cgroup* cgroup) {
        This function returns a negative value on error.
 */
 static int __pakfire_cgroup_open(struct pakfire_cgroup* cgroup) {
-       int rootfd = -1;
        int fd = -1;
        int r;
 
        // Open file descriptor of the cgroup root
-       rootfd = open(ROOT, O_DIRECTORY|O_PATH|O_CLOEXEC);
-       if (rootfd < 0) {
-               ERROR(cgroup->pakfire, "Could not open %s: %m\n", ROOT);
+       int rootfd = pakfire_cgroup_open_root(cgroup);
+       if (rootfd < 0)
                return -1;
-       }
 
        // Return the rootfd for the root group
        if (pakfire_cgroup_is_root(cgroup))
@@ -508,25 +515,39 @@ int pakfire_cgroup_killall(struct pakfire_cgroup* cgroup) {
 int pakfire_cgroup_destroy(struct pakfire_cgroup* cgroup) {
        int r;
 
+       // Cannot call this for the root group
+       if (pakfire_cgroup_is_root(cgroup)) {
+               errno = EPERM;
+               return 1;
+       }
+
+       DEBUG(cgroup->pakfire, "Destroying cgroup %s\n", pakfire_cgroup_name(cgroup));
+
        // Kill everything in this group
        r = pakfire_cgroup_killall(cgroup);
        if (r)
                return r;
 
-       // Delete the directory
-       r = rmdir(cgroup->path);
-       if (r) {
-               ERROR(cgroup->pakfire, "Could not destroy cgroup: %m\n");
-               return r;
-       }
-
        // Close the file descriptor
        if (cgroup->fd) {
                close(cgroup->fd);
                cgroup->fd = 0;
        }
 
-       return 0;
+       // Open the root directory
+       int fd = pakfire_cgroup_open_root(cgroup);
+       if (fd < 0)
+               return 1;
+
+       // Delete the directory
+       r = unlinkat(fd, cgroup->path, AT_REMOVEDIR);
+       if (r)
+               ERROR(cgroup->pakfire, "Could not destroy cgroup: %m\n");
+
+       // Close fd
+       close(fd);
+
+       return r;
 }
 
 int pakfire_cgroup_fd(struct pakfire_cgroup* cgroup) {