.. | .. |
---|
34 | 34 | CGROUP_WORK_DIR, path) |
---|
35 | 35 | |
---|
36 | 36 | /** |
---|
| 37 | + * enable_all_controllers() - Enable all available cgroup v2 controllers |
---|
| 38 | + * |
---|
| 39 | + * Enable all available cgroup v2 controllers in order to increase |
---|
| 40 | + * the code coverage. |
---|
| 41 | + * |
---|
| 42 | + * If successful, 0 is returned. |
---|
| 43 | + */ |
---|
| 44 | +static int enable_all_controllers(char *cgroup_path) |
---|
| 45 | +{ |
---|
| 46 | + char path[PATH_MAX + 1]; |
---|
| 47 | + char buf[PATH_MAX]; |
---|
| 48 | + char *c, *c2; |
---|
| 49 | + int fd, cfd; |
---|
| 50 | + ssize_t len; |
---|
| 51 | + |
---|
| 52 | + snprintf(path, sizeof(path), "%s/cgroup.controllers", cgroup_path); |
---|
| 53 | + fd = open(path, O_RDONLY); |
---|
| 54 | + if (fd < 0) { |
---|
| 55 | + log_err("Opening cgroup.controllers: %s", path); |
---|
| 56 | + return 1; |
---|
| 57 | + } |
---|
| 58 | + |
---|
| 59 | + len = read(fd, buf, sizeof(buf) - 1); |
---|
| 60 | + if (len < 0) { |
---|
| 61 | + close(fd); |
---|
| 62 | + log_err("Reading cgroup.controllers: %s", path); |
---|
| 63 | + return 1; |
---|
| 64 | + } |
---|
| 65 | + buf[len] = 0; |
---|
| 66 | + close(fd); |
---|
| 67 | + |
---|
| 68 | + /* No controllers available? We're probably on cgroup v1. */ |
---|
| 69 | + if (len == 0) |
---|
| 70 | + return 0; |
---|
| 71 | + |
---|
| 72 | + snprintf(path, sizeof(path), "%s/cgroup.subtree_control", cgroup_path); |
---|
| 73 | + cfd = open(path, O_RDWR); |
---|
| 74 | + if (cfd < 0) { |
---|
| 75 | + log_err("Opening cgroup.subtree_control: %s", path); |
---|
| 76 | + return 1; |
---|
| 77 | + } |
---|
| 78 | + |
---|
| 79 | + for (c = strtok_r(buf, " ", &c2); c; c = strtok_r(NULL, " ", &c2)) { |
---|
| 80 | + if (dprintf(cfd, "+%s\n", c) <= 0) { |
---|
| 81 | + log_err("Enabling controller %s: %s", c, path); |
---|
| 82 | + close(cfd); |
---|
| 83 | + return 1; |
---|
| 84 | + } |
---|
| 85 | + } |
---|
| 86 | + close(cfd); |
---|
| 87 | + return 0; |
---|
| 88 | +} |
---|
| 89 | + |
---|
| 90 | +/** |
---|
37 | 91 | * setup_cgroup_environment() - Setup the cgroup environment |
---|
38 | 92 | * |
---|
39 | 93 | * After calling this function, cleanup_cgroup_environment should be called |
---|
.. | .. |
---|
70 | 124 | log_err("mkdir cgroup work dir"); |
---|
71 | 125 | return 1; |
---|
72 | 126 | } |
---|
| 127 | + |
---|
| 128 | + if (enable_all_controllers(cgroup_workdir)) |
---|
| 129 | + return 1; |
---|
73 | 130 | |
---|
74 | 131 | return 0; |
---|
75 | 132 | } |
---|
.. | .. |
---|
155 | 212 | * This function creates a cgroup under the top level workdir and returns the |
---|
156 | 213 | * file descriptor. It is idempotent. |
---|
157 | 214 | * |
---|
158 | | - * On success, it returns the file descriptor. On failure it returns 0. |
---|
| 215 | + * On success, it returns the file descriptor. On failure it returns -1. |
---|
159 | 216 | * If there is a failure, it prints the error to stderr. |
---|
160 | 217 | */ |
---|
161 | 218 | int create_and_get_cgroup(const char *path) |
---|
.. | .. |
---|
166 | 223 | format_cgroup_path(cgroup_path, path); |
---|
167 | 224 | if (mkdir(cgroup_path, 0777) && errno != EEXIST) { |
---|
168 | 225 | log_err("mkdiring cgroup %s .. %s", path, cgroup_path); |
---|
169 | | - return 0; |
---|
| 226 | + return -1; |
---|
170 | 227 | } |
---|
171 | 228 | |
---|
172 | 229 | fd = open(cgroup_path, O_RDONLY); |
---|
173 | 230 | if (fd < 0) { |
---|
174 | 231 | log_err("Opening Cgroup"); |
---|
175 | | - return 0; |
---|
| 232 | + return -1; |
---|
176 | 233 | } |
---|
177 | 234 | |
---|
178 | 235 | return fd; |
---|
.. | .. |
---|
233 | 290 | free(fhp); |
---|
234 | 291 | return ret; |
---|
235 | 292 | } |
---|
| 293 | + |
---|
| 294 | +int cgroup_setup_and_join(const char *path) { |
---|
| 295 | + int cg_fd; |
---|
| 296 | + |
---|
| 297 | + if (setup_cgroup_environment()) { |
---|
| 298 | + fprintf(stderr, "Failed to setup cgroup environment\n"); |
---|
| 299 | + return -EINVAL; |
---|
| 300 | + } |
---|
| 301 | + |
---|
| 302 | + cg_fd = create_and_get_cgroup(path); |
---|
| 303 | + if (cg_fd < 0) { |
---|
| 304 | + fprintf(stderr, "Failed to create test cgroup\n"); |
---|
| 305 | + cleanup_cgroup_environment(); |
---|
| 306 | + return cg_fd; |
---|
| 307 | + } |
---|
| 308 | + |
---|
| 309 | + if (join_cgroup(path)) { |
---|
| 310 | + fprintf(stderr, "Failed to join cgroup\n"); |
---|
| 311 | + cleanup_cgroup_environment(); |
---|
| 312 | + return -EINVAL; |
---|
| 313 | + } |
---|
| 314 | + return cg_fd; |
---|
| 315 | +} |
---|