From: Adriaan Schmidt Date: Tue, 27 Feb 2024 12:37:17 +0000 (+0100) Subject: feat: add cgroup_get_threads() X-Git-Tag: v3.2.0~124 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84ff288c1b95a2060558011d0878037adcbf7660;p=thirdparty%2Flibcgroup.git feat: add cgroup_get_threads() In the same way `cgroup_get_procs()` reads the cgroup.procs file of a cgroup, the new function reads cgroup.threads, which is useful to interact with threaded cgroups. Signed-off-by: Adriaan Schmidt Reviewed-by: Kamalesh Babulal Signed-off-by: Tom Hromatka --- diff --git a/include/libcgroup/groups.h b/include/libcgroup/groups.h index a79e8244..4fd3169f 100644 --- a/include/libcgroup/groups.h +++ b/include/libcgroup/groups.h @@ -588,6 +588,17 @@ char *cgroup_get_value_name(struct cgroup_controller *controller, int index); */ int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size); +/** + * Get the list of threads in a cgroup. This list is guaranteed to + * be sorted. It is not necessary that it is unique. + * @param name The name of the cgroup + * @param controller The name of the controller + * @param pids The list of pids. Should be uninitialized when passed + * to the API. Should be freed by the caller using free. + * @param size The size of the pids array returned by the API. + */ +int cgroup_get_threads(char *name, char *controller, pid_t **pids, int *size); + /** * Change permission of files and directories of given group * @param cgroup The cgroup which permissions should be changed diff --git a/src/api.c b/src/api.c index 645e9a62..526bda8a 100644 --- a/src/api.c +++ b/src/api.c @@ -6140,20 +6140,16 @@ static int pid_compare(const void *a, const void *b) * * Caller must free up pids. */ -int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size) +static int read_pids(char *path, pid_t **pids, int *size) { - char cgroup_path[FILENAME_MAX]; - int tot_procs = 16; + int tot_pids = 16; pid_t *tmp_list; - FILE *procs; + FILE *pid_file; int n = 0; int err; - cg_build_path(name, cgroup_path, controller); - strncat(cgroup_path, "/cgroup.procs", FILENAME_MAX-strlen(cgroup_path)); - - procs = fopen(cgroup_path, "r"); - if (!procs) { + pid_file = fopen(path, "r"); + if (!pid_file) { last_errno = errno; *pids = NULL; *size = 0; @@ -6164,31 +6160,31 @@ int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size) } /* Keep doubling the memory allocated if needed */ - tmp_list = malloc(sizeof(pid_t) * tot_procs); + tmp_list = malloc(sizeof(pid_t) * tot_pids); if (!tmp_list) { last_errno = errno; - fclose(procs); + fclose(pid_file); return ECGOTHER; } - while (!feof(procs)) { - while (!feof(procs) && n < tot_procs) { + while (!feof(pid_file)) { + while (!feof(pid_file) && n < tot_pids) { pid_t pid; - err = fscanf(procs, "%u", &pid); + err = fscanf(pid_file, "%u", &pid); if (err == EOF) break; tmp_list[n] = pid; n++; } - if (!feof(procs)) { + if (!feof(pid_file)) { pid_t *orig_list = tmp_list; - tot_procs *= 2; - tmp_list = realloc(tmp_list, sizeof(pid_t) * tot_procs); + tot_pids *= 2; + tmp_list = realloc(tmp_list, sizeof(pid_t) * tot_pids); if (!tmp_list) { last_errno = errno; - fclose(procs); + fclose(pid_file); free(orig_list); *pids = NULL; *size = 0; @@ -6196,7 +6192,7 @@ int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size) } } } - fclose(procs); + fclose(pid_file); *size = n; qsort(tmp_list, n, sizeof(pid_t), &pid_compare); @@ -6205,6 +6201,26 @@ int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size) return 0; } +int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size) +{ + char cgroup_path[FILENAME_MAX]; + + cg_build_path(name, cgroup_path, controller); + strncat(cgroup_path, "/cgroup.procs", FILENAME_MAX-strlen(cgroup_path)); + + return read_pids(cgroup_path, pids, size); +} + +int cgroup_get_threads(char *name, char *controller, pid_t **pids, int *size) +{ + char cgroup_path[FILENAME_MAX]; + + cg_build_path(name, cgroup_path, controller); + strncat(cgroup_path, "/cgroup.threads", FILENAME_MAX-strlen(cgroup_path)); + + return read_pids(cgroup_path, pids, size); +} + int cgroup_dictionary_create(struct cgroup_dictionary **dict, int flags) { diff --git a/src/libcgroup.map b/src/libcgroup.map index 31780656..5e504719 100644 --- a/src/libcgroup.map +++ b/src/libcgroup.map @@ -164,3 +164,7 @@ CGROUP_3.0 { cgroup_is_systemd_enabled; cgroup_attach_thread_tid; } CGROUP_2.0; + +CGROUP_3.2 { + cgroup_get_threads; +} CGROUP_3.0;