This commit adds the function cgroupv2_subtree_control().
cgroupv2_subtree_control() can be used to enable or disable a
controller in the subtree_control file.  The equivalent command
line is:
        echo +{ctrl_name} > {path}/cgroup.subtree_control
        echo -{ctrl_name} > {path}/cgroup.subtree_control

Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com>
---
 src/api.c                | 52 +++++++++++++++++++++++++++++++++++++++-
 src/libcgroup-internal.h |  3 +++
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/src/api.c b/src/api.c
index c4870046e8c2..d16b79c8e8e1 100644
--- a/src/api.c
+++ b/src/api.c
@@ -63,8 +63,9 @@ static __thread char errtext[MAXLEN];
 /* Task command name length */
 #define TASK_COMM_LEN 16
 
-/* cgroup v2 controllers file */
+/* cgroup v2 files */
 #define CGV2_CONTROLLERS_FILE "cgroup.controllers"
+#define CGV2_SUBTREE_CTRL_FILE "cgroup.subtree_control"
 
 /* maximum line length when reading the cgroup.controllers file */
 #define LL_MAX                 100
@@ -1835,6 +1836,55 @@ err:
        return error;
 }
 
+/**
+ * Enable/Disable a controller in the cgroup v2 subtree_control file
+ *
+ * @param path Directory that contains the subtree_control file
+ * @param ctrl_name Name of the controller to be enabled/disabled
+ * @param enable Enable/Disable the given controller
+ */
+STATIC int cgroupv2_subtree_control(const char *path, const char *ctrl_name,
+                                   bool enable)
+{
+       char *path_copy = NULL;
+       char *value = NULL;
+       int ret, error = ECGOTHER;
+
+       if (!path || !ctrl_name)
+               return ECGOTHER;
+
+       value = (char *)malloc(FILENAME_MAX);
+       if (!value)
+               goto out;
+
+       path_copy = (char *)malloc(FILENAME_MAX);
+       if (!path_copy)
+               goto out;
+
+       ret = snprintf(path_copy, FILENAME_MAX, "%s/%s", path,
+                      CGV2_SUBTREE_CTRL_FILE);
+       if (ret < 0)
+               goto out;
+
+       if (enable)
+               ret = snprintf(value, FILENAME_MAX, "+%s", ctrl_name);
+       else
+               ret = snprintf(value, FILENAME_MAX, "-%s", ctrl_name);
+       if (ret < 0)
+               goto out;
+
+       error = cg_set_control_value(path_copy, value);
+       if (error)
+               goto out;
+
+out:
+       if (value)
+               free(value);
+       if (path_copy)
+               free(path_copy);
+       return error;
+}
+
 /** cgroup_modify_cgroup modifies the cgroup control files.
  * struct cgroup *cgroup: The name will be the cgroup to be modified.
  * The values will be the values to be modified, those not mentioned
diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
index 57c870a8c41f..38a17e0ab251 100644
--- a/src/libcgroup-internal.h
+++ b/src/libcgroup-internal.h
@@ -340,6 +340,9 @@ int cgroup_set_values_recursive(const char * const base,
 int cgroup_chown_chmod_tasks(const char * const cg_path,
                             uid_t uid, gid_t gid, mode_t fperm);
 
+int cgroupv2_subtree_control(const char *path, const char *ctrl_name,
+                            bool enable);
+
 #endif /* UNIT_TEST */
 
 __END_DECLS
-- 
2.25.3



_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to