]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
feat: add cgroup_get_threads()
authorAdriaan Schmidt <adriaan.schmidt@siemens.com>
Tue, 27 Feb 2024 12:37:17 +0000 (13:37 +0100)
committerTom Hromatka <tom.hromatka@oracle.com>
Wed, 20 Mar 2024 21:38:04 +0000 (15:38 -0600)
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 <adriaan.schmidt@siemens.com>
Reviewed-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
include/libcgroup/groups.h
src/api.c
src/libcgroup.map

index a79e8244a3b4fa757ee14f08d18f0f4541110b42..4fd3169ff1517f592434ac0d5550c1eb091ee8da 100644 (file)
@@ -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
index 645e9a622066655900e12a2964858f2e2840fc24..526bda8ac322486ffd3fd2e62def883bfe705eda 100644 (file)
--- 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)
 {
index 317806568dec86393cca96562ed877c3fb6beb21..5e504719d5a9d26074942b731bee1a7a49cdcb11 100644 (file)
@@ -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;