Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 108 additions & 16 deletions src/rt-app_taskgroups.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
#include "rt-app_taskgroups.h"

#define PIN "[tg] "
#define SUBTREE_CONTROL "cgroup.subtree_control"
#define TYPE "cgroup.type"
#define CONTROLLERS "cgroup.controllers"

typedef struct _taskgroup_ctrl_t
{
char *mount_point;
taskgroup_data_t *tg_array;
unsigned int nr_tgs;
char version;
} taskgroup_ctrl_t;

static taskgroup_ctrl_t ctrl;
Expand Down Expand Up @@ -143,6 +147,31 @@ static int cgroup_check_cpu_controller(void)
return ret;
}

static int cgroup_check_cpu_controller_v2(char* mnt_dir)
{
size_t size = strlen(mnt_dir) + strlen(CONTROLLERS) + 2;
char* path = malloc(size);
char buf[256];
FILE *file;
snprintf(path, size, "%s/%s", mnt_dir, CONTROLLERS);
file = fopen(path, "r");
if (!file) {
perror("fopen");
goto error;
}
while (fscanf(file, "%s", buf) != EOF) {
if (!strcmp(buf, "cpu")) {
return 0;
}
}
if (fclose(file)) {
perror("fclose");
goto error;
}
error:
return -1;
}

static int cgroup_get_cpu_controller_mount_point(void)
{
struct mntent *ent;
Expand All @@ -157,23 +186,38 @@ static int cgroup_get_cpu_controller_mount_point(void)
}

while (ent = getmntent(mounts)) {
if (strcmp(ent->mnt_type, "cgroup"))
continue;
if (!strcmp(ent->mnt_type, "cgroup")) {
if (!hasmntopt(ent, "cpu"))
continue;

if (!hasmntopt(ent, "cpu"))
continue;
ctrl.mount_point = malloc(strlen(ent->mnt_dir) + 1);
if (!ctrl.mount_point) {
perror("malloc");
break;
}
ctrl.version = 1;

ctrl.mount_point = malloc(strlen(ent->mnt_dir) + 1);
if (!ctrl.mount_point) {
perror("malloc");
strcpy(ctrl.mount_point, ent->mnt_dir);
log_debug(PIN "cgroup cpu controller mountpoint [%s] found", ent->mnt_dir);
ret = 0;
break;
}
} else if (!strcmp(ent->mnt_type, "cgroup2")) {
if (cgroup_check_cpu_controller_v2(ent->mnt_dir) == -1) {
continue;
}

strcpy(ctrl.mount_point, ent->mnt_dir);
ctrl.mount_point = malloc(strlen(ent->mnt_dir) + 1);
if (!ctrl.mount_point) {
perror("malloc");
break;
}
ctrl.version = 2;

log_debug(PIN "cgroup cpu controller mountpoint [%s] found", ent->mnt_dir);
ret = 0;
break;
strcpy(ctrl.mount_point, ent->mnt_dir);
log_debug(PIN "cgroup cpu controller mountpoint [%s] found", ent->mnt_dir);
ret = 0;
break;
}
}

endmntent(mounts);
Expand Down Expand Up @@ -253,6 +297,24 @@ static int cgroup_mkdir(const char *name, int *offset)
} else if (*offset == -1) {
*offset = y;
}

if (ctrl.version == 2) {
size_t path_size = strlen(path) + strlen(SUBTREE_CONTROL) + 2;
char* cgroup_path = malloc(path_size);
FILE *cgroup_file;
snprintf(cgroup_path, path_size, "%s/%s", path, SUBTREE_CONTROL);
cgroup_file = fopen(cgroup_path, "we");
if (!cgroup_file) {
perror("fopen");
goto error;
}
fprintf(cgroup_file, "+cpu");
if (fclose(cgroup_file)) {
perror("fclose");
goto error;
}
free(cgroup_path);
}
next:
dir[i] = del;
} while (dir[i]);
Expand Down Expand Up @@ -373,7 +435,35 @@ static int cgroup_attach_task(char *name)
FILE *tasks;
size_t size;

file = strcmp(name, "/") ? "/tasks" : "tasks";
if (ctrl.version == 1) {
file = strcmp(name, "/") ? "/tasks" : "tasks";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder it this special casing for root cgrp is worth it (here and other places).

-sprintf(path, "%s%s%s", ctrl.mount_point, name, file);
+sprintf(path, "%s%s/%s", ctrl.mount_point, name, file);

with possibly double // being resolved by open.

}

if (ctrl.version == 2) {
if (strcmp(name, "/")) {
size_t path_size = strlen(ctrl.mount_point) + strlen(name) + strlen(TYPE) + 3;
char* cgroup_path = malloc(path_size);
FILE* cgroup_file;

snprintf(cgroup_path, path_size, "%s/%s/%s", ctrl.mount_point, name, TYPE);
cgroup_file = fopen(cgroup_path, "we");
if (!cgroup_file) {
perror("open");
goto error;
}
if (fprintf(cgroup_file, "threaded") < 0) {
perror("fprintf");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cgroup_file not closed here

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also some better message may ease future debugging, like cgroup.type <- threaded failed.

goto error;
}
if (fclose(cgroup_file)) {
perror("fclose");
goto error;
}
free(cgroup_path);
}
file = strcmp(name, "/") ? "/cgroup.threads" : "cgroup.threads";
}

size = strlen(ctrl.mount_point) + strlen(name) + strlen(file) + 1;
path = malloc(size);
if (!path) {
Expand All @@ -393,9 +483,11 @@ static int cgroup_attach_task(char *name)
goto error;
}

if (fclose(tasks)) {
perror("fclose");
goto error;
if (ctrl.version == 1) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v2 file deserves to be closed here too, no?

if (fclose(tasks)) {
perror("fclose");
goto error;
}
}

ret = 0;
Expand Down