Rewrite the communication protocol
[compctl.git] / cgroup.c
blobdefeb1df767a6136c3bd5a30c863e1d5a85730cc
1 #include <limits.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/mount.h>
6 #include <sys/stat.h>
7 #include <unistd.h>
9 #include "cgroup.h"
11 void (*cgroup_perror)(const char *s) = perror;
12 static const char cgroupfs[] = "/sys/fs/cgroup/";
14 int
15 cgroup_setup(const char *chier, const char *controllers)
17 char chierdir[PATH_MAX];
18 snprintf(chierdir, sizeof(chierdir), "%s%s", cgroupfs, chier);
19 if (access(chierdir, F_OK) >= 0)
20 return 0;
22 if (mount("none", cgroupfs, "tmpfs", 0, NULL) < 0) {
23 cgroup_perror(cgroupfs);
24 return -1;
26 if (mkdir(chierdir, 0777) < 0) {
27 cgroup_perror(chierdir);
28 return -1;
30 if (mount("none", chierdir, "cgroup", 0, controllers) < 0) {
31 cgroup_perror(chierdir);
32 return -1;
34 return 1;
37 int
38 cgroup_create(const char *chier, const char *cgroup)
40 char cgroupdir[PATH_MAX];
41 snprintf(cgroupdir, sizeof(cgroupdir), "%s%s/%s", cgroupfs, chier, cgroup);
42 if (access(cgroupdir, F_OK) >= 0)
43 return 0;
44 if (mkdir(cgroupdir, 0777) < 0) {
45 cgroup_perror(cgroupdir);
46 return -1;
48 return 1;
52 int
53 cgroup_add_task(const char *chier, const char *cgroup, pid_t pid)
55 char tasksfile[PATH_MAX];
56 snprintf(tasksfile, sizeof(tasksfile), "%s%s/%s/tasks", cgroupfs, chier, cgroup);
57 FILE *tasks = fopen(tasksfile, "a");
58 if (!tasks) {
59 cgroup_perror(tasksfile);
60 return -1;
62 fprintf(tasks, "%d\n", pid);
63 fclose(tasks);
64 return 1;
67 int
68 cgroup_is_task_in_cgroup(const char *chier, const char *cgroup, pid_t pid)
70 char tasksfile[PATH_MAX];
71 snprintf(tasksfile, sizeof(tasksfile), "%s%s/%s/tasks", cgroupfs, chier, cgroup);
72 FILE *tasks = fopen(tasksfile, "r");
73 if (!tasks) {
74 cgroup_perror(tasksfile);
75 return -1;
78 bool exists = false;
79 char line[128];
80 while (fgets(line, sizeof(line), tasks)) {
81 if (atoi(line) == pid) {
82 exists = true;
83 break;
86 fclose(tasks);
87 return exists;
90 int
91 cgroup_task_list(const char *chier, const char *cgroup, pid_t **tasklist)
93 char tasksfile[PATH_MAX];
94 snprintf(tasksfile, sizeof(tasksfile), "%s%s/%s/tasks", cgroupfs, chier, cgroup);
95 FILE *tasks = fopen(tasksfile, "r");
96 if (!tasks) {
97 cgroup_perror(tasksfile);
98 return -1;
101 int ntasks = 0;
102 *tasklist = NULL;
103 char line[128];
104 while (fgets(line, sizeof(line), tasks)) {
105 if (!(ntasks % 32))
106 *tasklist = realloc(*tasklist, (ntasks + 32) * sizeof(*tasklist));
107 (*tasklist)[ntasks++] = atoi(line);
109 fclose(tasks);
110 return ntasks;
114 size_t
115 cgroup_get_mem_limit(const char *chier, const char *cgroup)
117 char limitfile[PATH_MAX];
118 snprintf(limitfile, sizeof(limitfile), "%s%s/%s/memory.limit_in_bytes", cgroupfs, chier, cgroup);
119 FILE *limit = fopen(limitfile, "r");
120 if (!limit) {
121 cgroup_perror(limitfile);
122 return -1;
124 size_t nlimit = 0;
125 fscanf(limit, "%zu", &nlimit); /* FIXME is this really unsigned? */
126 fclose(limit);
127 return nlimit;
131 cgroup_set_mem_limit(const char *chier, const char *cgroup, size_t nlimit)
133 char limitfile[PATH_MAX];
134 snprintf(limitfile, sizeof(limitfile), "%s%s/%s/memory.limit_in_bytes", cgroupfs, chier, cgroup);
135 FILE *limit = fopen(limitfile, "w");
136 if (!limit) {
137 cgroup_perror(limitfile);
138 return -1;
140 fprintf(limit, "%zu\n", nlimit);
141 fclose(limit);
142 return 1;
145 size_t
146 cgroup_get_mem_usage(const char *chier, const char *cgroup)
148 char usagefile[PATH_MAX];
149 snprintf(usagefile, sizeof(usagefile), "%s%s/%s/memory.usage_in_bytes", cgroupfs, chier, cgroup);
150 FILE *usage = fopen(usagefile, "r");
151 if (!usage) {
152 cgroup_perror(usagefile);
153 return -1;
155 size_t nusage = 0;
156 fscanf(usage, "%zu", &nusage);
157 fclose(usage);
158 return nusage;