-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcgroup.c
132 lines (119 loc) · 2.99 KB
/
cgroup.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <fcntl.h>
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "cgroup.h"
#include "sce.h"
static int echo(const char *out, const char *file) {
if (!out) return SCE_ECHO;
size_t len = strlen(out);
if (!len) return SCE_ECHO;
int fd = open(file, O_WRONLY);
if (fd == -1) {
return SCE_ECHO;
}
ssize_t r = write(fd, out, len);
if (r == -1) {
return SCE_ECHO;
}
if (r != len) {
return SCE_ECHO;
}
int ret = close(fd);
if (ret == -1) {
return SCE_ECHO;
}
return 0;
}
int _ensure_cgroup(const char *group_name_full) {
if (access(group_name_full, F_OK)) {
if (init_cgroup(group_name_full)) {
return SCE_CGIC;
}
}
return 0;
}
int init_cgroup(const char *group_name_full) {
extern int is_root;
if (!is_root) return SCE_PERM;
int ret;
mode_t perm = 0755;
if ((ret = mkdir(group_name_full, perm))) {
return SCE_PERM;
}
return 0;
}
int setup_cgroup(const char *group_name, char *sub_group, unsigned random_int) {
sprintf(sub_group, "%s/%s/%s/%u", CGFS_BASE, group_name, CGFS_NAME,
random_int);
int ret = mkdir(sub_group, 0755);
if (ret) {
return SCE_CG;
}
// no checking memory.max_usage_in_bytes equals zero here
// underlying risk
return 0;
}
int write_cgroup(const char *sub_group, const char *name, const char *content) {
char file[512] = {0};
sprintf(file, "%s/%s", sub_group, name);
int ret = echo(content, file);
if (ret) return SCE_CGCU;
return 0;
}
int flush(const char *sub_group, const char *name) {
return write_cgroup(sub_group, name, "0");
}
int add_pid_to_cg(pid_t pid, const char *sub_group) {
char file[512] = {0};
sprintf(file, "%s/tasks", sub_group);
char pid_str[32] = {0};
sprintf(pid_str, "%zd", (ssize_t)pid);
int ret = echo(pid_str, file);
if (ret) return SCE_CGAT;
return 0;
}
static int cat(const char *file, char *out, size_t len) {
if (!out || !len) return -2;
int fd = open(file, O_RDONLY);
if (fd == -1) {
return SCE_CGNOENT;
}
ssize_t r = read(fd, out, len - 1);
if (r == -1) {
return SCE_CGRST;
}
out[r] = 0;
if (close(fd)) {
return SCE_CGRST;
}
return 0;
}
int get_cg_result(const char *name, const char *sub_group, size_t *result) {
char file[512] = {0};
sprintf(file, "%s/%s", sub_group, name);
char out[32] = {0};
int ret = cat(file, out, 32);
if (ret) {
return SCE_CGRST;
}
*result = strtoul(out, 0, 10);
return 0;
}
int cleanup_cg(const char *sub_group) {
if (rmdir(sub_group)) {
return SCE_CGCU;
}
return 0;
}
int force_empty_mem(const char *sub_group) {
char file[256] = {0};
snprintf(file, 256, "%s/memory.force_empty", sub_group);
int ret = echo("0", file);
if (ret) return SCE_CGCU;
return 0;
}