| .. | .. |
|---|
| 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 | +} |
|---|