]> git.ipfire.org Git - pakfire.git/commitdiff
cgroups: Keep bitmap of enabled controllers
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 14 Dec 2024 13:21:06 +0000 (13:21 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 14 Dec 2024 13:21:06 +0000 (13:21 +0000)
This helps us to perform fewer operations when we create a cgroup.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/cgroup.c
src/libpakfire/include/pakfire/cgroup.h

index 5b490097399cb56504450adcf49533855d260f5b..b318eaf8860a0ee089f6200a23945b3710102758 100644 (file)
@@ -71,6 +71,9 @@ struct pakfire_cgroup {
        char name[NAME_MAX];
        char path[PATH_MAX];
 
+       // Controllers
+       unsigned int controllers;
+
        // File descriptor to cgroup
        int fd;
 
@@ -263,19 +266,87 @@ ERROR:
        return r;
 }
 
+static int pakfire_cgroup_controller_from_string(const char* name) {
+       if (!name)
+               return 0;
+
+       if (strcmp(name, "cpu") == 0)
+               return PAKFIRE_CGROUP_CONTROLLER_CPU;
+
+       else if (strcmp(name, "memory") == 0)
+               return PAKFIRE_CGROUP_CONTROLLER_MEMORY;
+
+       else if (strcmp(name, "pids") == 0)
+               return PAKFIRE_CGROUP_CONTROLLER_PIDS;
+
+       else if (strcmp(name, "io") == 0)
+               return PAKFIRE_CGROUP_CONTROLLER_IO;
+
+       return 0;
+}
+
+static const char* pakfire_cgroup_controller_name(int controller) {
+       switch (controller) {
+               case PAKFIRE_CGROUP_CONTROLLER_CPU:
+                       return "cpu";
+
+               case PAKFIRE_CGROUP_CONTROLLER_MEMORY:
+                       return "memory";
+
+               case PAKFIRE_CGROUP_CONTROLLER_PIDS:
+                       return "pids";
+
+               case PAKFIRE_CGROUP_CONTROLLER_IO:
+                       return "io";
+       }
+
+       return NULL;
+}
+
+static int pakfire_cgroup_read_controllers(struct pakfire_cgroup* cgroup) {
+       char buffer[4096];
+       char* p = NULL;
+       int r;
+
+       // Read the data into a buffer
+       r = pakfire_cgroup_read(cgroup, "cgroup.subtree_control", buffer, sizeof(buffer));
+       if (r < 0)
+               return r;
+
+       // Tokenize the string
+       char* token = strtok_r(buffer, " ", &p);
+
+       while (token) {
+               cgroup->controllers |= pakfire_cgroup_controller_from_string(token);
+
+               // Move on to the next token
+               token = strtok_r(NULL, " ", &p);
+       }
+
+       return 0;
+}
+
 /*
        Enables a cgroup controller.
 */
-static int pakfire_cgroup_enable_controller(struct pakfire_cgroup* cgroup, const char* name) {
+static int pakfire_cgroup_enable_controller(struct pakfire_cgroup* cgroup, int controller) {
        int r;
 
        // Ensure this controller is enabled on the parent, too
        if (cgroup->parent) {
-               r = pakfire_cgroup_enable_controller(cgroup->parent, name);
+               r = pakfire_cgroup_enable_controller(cgroup->parent, controller);
                if (r < 0)
                        return r;
        }
 
+       const char* name = pakfire_cgroup_controller_name(controller);
+
+       // Check if we know this controller
+       if (!name) {
+               ERROR(cgroup->ctx, "Cannot enable unknown controller\n");
+               return -ENOTSUP;
+       }
+
        // Try to enable the controller
        r = pakfire_cgroup_write(cgroup, "cgroup.subtree_control", "+%s", name);
        if (r < 0) {
@@ -291,13 +362,17 @@ static int pakfire_cgroup_enable_controller(struct pakfire_cgroup* cgroup, const
        Enables all controllers that we need.
 */
 static int pakfire_cgroup_enable_controllers(struct pakfire_cgroup* cgroup) {
-       static const char* controllers[] = {
-               "cpu", "memory", "pids", "io", NULL,
+       static const int controllers[] = {
+               PAKFIRE_CGROUP_CONTROLLER_CPU,
+               PAKFIRE_CGROUP_CONTROLLER_MEMORY,
+               PAKFIRE_CGROUP_CONTROLLER_PIDS,
+               PAKFIRE_CGROUP_CONTROLLER_IO,
+               0,
        };
        int r;
 
        // Enable all controllers
-       for (const char** controller = controllers; *controller; controller++) {
+       for (int* controller = controllers; *controller; controller++) {
                r = pakfire_cgroup_enable_controller(cgroup, *controller);
                if (r < 0)
                        return r;
@@ -354,6 +429,11 @@ static int pakfire_cgroup_open(struct pakfire_cgroup** cgroup,
        if (r < 0)
                goto ERROR;
 
+       // Read controllers
+       r = pakfire_cgroup_read_controllers(c);
+       if (r < 0)
+               goto ERROR;
+
        // Enable all controllers
        r = pakfire_cgroup_enable_controllers(c);
        if (r < 0)
index b4100a48ba115492686e2bace2e6cc7e0648649d..6f86fbdcac2ca0864f48cc5d64768bb07dba3cbc 100644 (file)
 
 #include <pakfire/ctx.h>
 
+enum pakfire_cgroup_controllers {
+       PAKFIRE_CGROUP_CONTROLLER_CPU     = (1 << 0),
+       PAKFIRE_CGROUP_CONTROLLER_MEMORY  = (1 << 1),
+       PAKFIRE_CGROUP_CONTROLLER_PIDS    = (1 << 2),
+       PAKFIRE_CGROUP_CONTROLLER_IO      = (1 << 3),
+};
+
 struct pakfire_cgroup;
 
 struct pakfire_cgroup_stats {