This commit adds a function, cgroupv2_get_subtree_control(), that will verify if a controller is enabled in the subtree control file or not.
This function will be used in the next commit - "api.c: Add function to check if a controller is enabled for a cgroup v2 cgroup" - to determine if the requested cgroup v2 controller is enabled for a cgroup. This is a required check to ensure that the cgclassify/cgexec operation will succeed. Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com> --- src/api.c | 66 ++++++++++++++++++++++++++++++++++++++++ src/libcgroup-internal.h | 3 ++ 2 files changed, 69 insertions(+) diff --git a/src/api.c b/src/api.c index 274718bbe8f4..88042f95a51c 100644 --- a/src/api.c +++ b/src/api.c @@ -1884,6 +1884,72 @@ err: return error; } +/** + * Check if the requested cgroup controller is enabled on this subtree + * + * @param path Cgroup directory + * @param ctrl_name Name of the controller to check + * @param output parameter that indicates whether the controller is enabled\ + */ +STATIC int cgroupv2_get_subtree_control(const char *path, + const char *ctrl_name, + bool * const enabled) +{ + char *path_copy = NULL, *saveptr = NULL, *token, *ret_c; + int ret, error = ECGROUPNOTMOUNTED; + char buffer[FILENAME_MAX]; + FILE *fp = NULL; + + if (!path || !ctrl_name || !enabled) + return ECGOTHER; + + *enabled = false; + + 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; + + fp = fopen(path_copy, "re"); + if (!fp) { + cgroup_warn("Warning: fopen failed\n"); + last_errno = errno; + goto out; + } + + ret_c = fgets(buffer, sizeof(buffer), fp); + if (ret_c == NULL) + /* The subtree control file is empty */ + goto out; + + /* remove the trailing newline */ + ret_c[strlen(ret_c) - 1] = '\0'; + + /* Split the enabled controllers by " " and evaluate if the requested + * controller is enabled. + */ + token = strtok_r(buffer, " ", &saveptr); + do { + if (strncmp(ctrl_name, token, FILENAME_MAX) == 0) { + error = 0; + *enabled = true; + break; + } + } while ((token = strtok_r(NULL, " ", &saveptr))); + +out: + if (path_copy) + free(path_copy); + if (fp) + fclose(fp); + + return error; +} + /** * Enable/Disable a controller in the cgroup v2 subtree_control file * diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h index 72ddc19ea6e5..b834202dcf6b 100644 --- a/src/libcgroup-internal.h +++ b/src/libcgroup-internal.h @@ -347,6 +347,9 @@ int cgroup_build_tasks_procs_path(char * const path, size_t path_sz, const char * const cg_name, const char * const ctrl_name); +int cgroupv2_get_subtree_control(const char *path, + const char *ctrl_name, + bool * const enabled); #endif /* UNIT_TEST */ __END_DECLS -- 2.25.4 _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel