13 #define MEMSW ".memsw"
18 void (*cgroup_perror
)(const char *s
) = perror
;
19 static const char cgroupfs
[] = "/sys/fs/cgroup/";
22 cgroup_setup(const char *chier
, const char *controllers
)
24 char chierdir
[PATH_MAX
];
25 snprintf(chierdir
, sizeof(chierdir
), "%s%s", cgroupfs
, chier
);
26 if (access(chierdir
, F_OK
) >= 0)
29 if (mount("none", cgroupfs
, "tmpfs", 0, NULL
) < 0) {
30 cgroup_perror(cgroupfs
);
33 if (mkdir(chierdir
, 0777) < 0) {
34 cgroup_perror(chierdir
);
37 if (mount("none", chierdir
, "cgroup", 0, controllers
) < 0) {
38 cgroup_perror(chierdir
);
45 cgroup_create(const char *chier
, const char *cgroup
)
47 char cgroupdir
[PATH_MAX
];
48 snprintf(cgroupdir
, sizeof(cgroupdir
), "%s%s/%s", cgroupfs
, chier
, cgroup
);
49 if (access(cgroupdir
, F_OK
) >= 0)
51 if (mkdir(cgroupdir
, 0777) < 0) {
52 cgroup_perror(cgroupdir
);
59 cgroup_available(const char *chier
, const char *cgroup
)
61 char cgroupdir
[PATH_MAX
];
62 snprintf(cgroupdir
, sizeof(cgroupdir
), "%s%s/%s", cgroupfs
, chier
, cgroup
);
63 return (access(cgroupdir
, F_OK
) >= 0);
68 cgroup_add_task(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
, "a");
74 cgroup_perror(tasksfile
);
77 if (fprintf(tasks
, "%d\n", pid
) < 0) {
78 cgroup_perror(tasksfile
);
82 if (fclose(tasks
) < 0) {
83 cgroup_perror(tasksfile
);
90 cgroup_is_task_in_cgroup(const char *chier
, const char *cgroup
, pid_t pid
)
92 char tasksfile
[PATH_MAX
];
93 snprintf(tasksfile
, sizeof(tasksfile
), "%s%s/%s/tasks", cgroupfs
, chier
, cgroup
);
94 FILE *tasks
= fopen(tasksfile
, "r");
96 cgroup_perror(tasksfile
);
102 while (fgets(line
, sizeof(line
), tasks
)) {
103 if (atoi(line
) == pid
) {
113 cgroup_task_list(const char *chier
, const char *cgroup
, pid_t
**tasklist
)
115 char tasksfile
[PATH_MAX
];
116 snprintf(tasksfile
, sizeof(tasksfile
), "%s%s/%s/tasks", cgroupfs
, chier
, cgroup
);
117 FILE *tasks
= fopen(tasksfile
, "r");
119 cgroup_perror(tasksfile
);
126 while (fgets(line
, sizeof(line
), tasks
)) {
128 *tasklist
= realloc(*tasklist
, (ntasks
+ 32) * sizeof(*tasklist
));
129 (*tasklist
)[ntasks
++] = atoi(line
);
137 cgroup_get_mem_limit(const char *chier
, const char *cgroup
)
139 char limitfile
[PATH_MAX
];
140 snprintf(limitfile
, sizeof(limitfile
), "%s%s/%s/memory"MEMSW
".limit_in_bytes", cgroupfs
, chier
, cgroup
);
141 FILE *limit
= fopen(limitfile
, "r");
143 cgroup_perror(limitfile
);
147 fscanf(limit
, "%zu", &nlimit
);
153 cgroup_set_mem_limit_do(const char *chier
, const char *cgroup
, size_t nlimit
, char *memsw
)
155 char limitfile
[PATH_MAX
];
156 snprintf(limitfile
, sizeof(limitfile
), "%s%s/%s/memory%s.limit_in_bytes", cgroupfs
, chier
, cgroup
, memsw
);
157 FILE *limit
= fopen(limitfile
, "w");
159 cgroup_perror(limitfile
);
162 if (fprintf(limit
, "%zu\n", nlimit
) < 0) {
163 cgroup_perror(limitfile
);
167 if (fclose(limit
) < 0) {
168 cgroup_perror(limitfile
);
175 cgroup_set_mem_limit_twice(const char *chier
, const char *cgroup
, size_t nlimit
, char *memsw1
, char *memsw2
)
177 int ret
= cgroup_set_mem_limit_do(chier
, cgroup
, nlimit
, memsw1
);
179 int ret2
= cgroup_set_mem_limit_do(chier
, cgroup
, nlimit
, memsw2
);
180 ret
= ret2
< 0 ? ret2
: (ret
|| ret2
);
186 cgroup_set_mem_limit(const char *chier
, const char *cgroup
, size_t nlimit
)
189 /* We need to set both the "normal" and memsw limits, but in such
190 * order that normal <= memsw always holds. */
191 size_t curlimit
= cgroup_get_mem_limit(chier
, cgroup
);
192 if (nlimit
< curlimit
)
193 return cgroup_set_mem_limit_twice(chier
, cgroup
, nlimit
, "", MEMSW
);
195 return cgroup_set_mem_limit_twice(chier
, cgroup
, nlimit
, MEMSW
, "");
197 return cgroup_set_mem_limit_do(chier
, cgroup
, nlimit
, "");
202 cgroup_get_mem_usage(const char *chier
, const char *cgroup
)
204 char usagefile
[PATH_MAX
];
205 snprintf(usagefile
, sizeof(usagefile
), "%s%s/%s/memory"MEMSW
".usage_in_bytes", cgroupfs
, chier
, cgroup
);
206 FILE *usage
= fopen(usagefile
, "r");
208 cgroup_perror(usagefile
);
212 fscanf(usage
, "%zu", &nusage
);