cgroups: cleanup

parent f761d24d
...@@ -77,12 +77,10 @@ static int append_null_to_list(void ***list) ...@@ -77,12 +77,10 @@ static int append_null_to_list(void ***list)
*/ */
static bool string_in_list(char **list, const char *entry) static bool string_in_list(char **list, const char *entry)
{ {
int i;
if (!list) if (!list)
return false; return false;
for (i = 0; list[i]; i++) for (int i = 0; list[i]; i++)
if (strcmp(list[i], entry) == 0) if (strcmp(list[i], entry) == 0)
return true; return true;
...@@ -147,16 +145,10 @@ static void must_append_controller(char **klist, char **nlist, char ***clist, ...@@ -147,16 +145,10 @@ static void must_append_controller(char **klist, char **nlist, char ***clist,
*/ */
struct hierarchy *get_hierarchy(struct cgroup_ops *ops, const char *controller) struct hierarchy *get_hierarchy(struct cgroup_ops *ops, const char *controller)
{ {
int i; if (!ops->hierarchies)
return log_trace_errno(NULL, errno, "There are no useable cgroup controllers");
errno = ENOENT;
if (!ops->hierarchies) {
TRACE("There are no useable cgroup controllers");
return NULL;
}
for (i = 0; ops->hierarchies[i]; i++) { for (int i = 0; ops->hierarchies[i]; i++) {
if (!controller) { if (!controller) {
/* This is the empty unified hierarchy. */ /* This is the empty unified hierarchy. */
if (ops->hierarchies[i]->controllers && if (ops->hierarchies[i]->controllers &&
...@@ -179,7 +171,7 @@ struct hierarchy *get_hierarchy(struct cgroup_ops *ops, const char *controller) ...@@ -179,7 +171,7 @@ struct hierarchy *get_hierarchy(struct cgroup_ops *ops, const char *controller)
else else
WARN("There is no empty unified cgroup hierarchy"); WARN("There is no empty unified cgroup hierarchy");
return NULL; return ret_set_errno(NULL, ENOENT);
} }
#define BATCH_SIZE 50 #define BATCH_SIZE 50
...@@ -188,9 +180,8 @@ static void batch_realloc(char **mem, size_t oldlen, size_t newlen) ...@@ -188,9 +180,8 @@ static void batch_realloc(char **mem, size_t oldlen, size_t newlen)
int newbatches = (newlen / BATCH_SIZE) + 1; int newbatches = (newlen / BATCH_SIZE) + 1;
int oldbatches = (oldlen / BATCH_SIZE) + 1; int oldbatches = (oldlen / BATCH_SIZE) + 1;
if (!*mem || newbatches > oldbatches) { if (!*mem || newbatches > oldbatches)
*mem = must_realloc(*mem, newbatches * BATCH_SIZE); *mem = must_realloc(*mem, newbatches * BATCH_SIZE);
}
} }
static void append_line(char **dest, size_t oldlen, char *new, size_t newlen) static void append_line(char **dest, size_t oldlen, char *new, size_t newlen)
...@@ -205,20 +196,21 @@ static void append_line(char **dest, size_t oldlen, char *new, size_t newlen) ...@@ -205,20 +196,21 @@ static void append_line(char **dest, size_t oldlen, char *new, size_t newlen)
/* Slurp in a whole file */ /* Slurp in a whole file */
static char *read_file(const char *fnam) static char *read_file(const char *fnam)
{ {
__do_free char *line = NULL; __do_free char *buf = NULL, *line = NULL;
__do_fclose FILE *f = NULL; __do_fclose FILE *f = NULL;
int linelen;
char *buf = NULL;
size_t len = 0, fulllen = 0; size_t len = 0, fulllen = 0;
int linelen;
f = fopen(fnam, "re"); f = fopen(fnam, "re");
if (!f) if (!f)
return NULL; return NULL;
while ((linelen = getline(&line, &len, f)) != -1) { while ((linelen = getline(&line, &len, f)) != -1) {
append_line(&buf, fulllen, line, linelen); append_line(&buf, fulllen, line, linelen);
fulllen += linelen; fulllen += linelen;
} }
return buf;
return move_ptr(buf);
} }
/* Taken over modified from the kernel sources. */ /* Taken over modified from the kernel sources. */
...@@ -251,9 +243,9 @@ static bool is_set(unsigned bit, uint32_t *bitarr) ...@@ -251,9 +243,9 @@ static bool is_set(unsigned bit, uint32_t *bitarr)
*/ */
static uint32_t *lxc_cpumask(char *buf, size_t nbits) static uint32_t *lxc_cpumask(char *buf, size_t nbits)
{ {
__do_free uint32_t *bitarr = NULL;
char *token; char *token;
size_t arrlen; size_t arrlen;
__do_free uint32_t *bitarr = NULL;
arrlen = BITS_TO_LONGS(nbits); arrlen = BITS_TO_LONGS(nbits);
bitarr = calloc(arrlen, sizeof(uint32_t)); bitarr = calloc(arrlen, sizeof(uint32_t));
...@@ -288,11 +280,10 @@ static uint32_t *lxc_cpumask(char *buf, size_t nbits) ...@@ -288,11 +280,10 @@ static uint32_t *lxc_cpumask(char *buf, size_t nbits)
static char *lxc_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits) static char *lxc_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits)
{ {
__do_free_string_list char **cpulist = NULL; __do_free_string_list char **cpulist = NULL;
int ret;
size_t i;
char numstr[INTTYPE_TO_STRLEN(size_t)] = {0}; char numstr[INTTYPE_TO_STRLEN(size_t)] = {0};
int ret;
for (i = 0; i <= nbits; i++) { for (size_t i = 0; i <= nbits; i++) {
if (!is_set(i, bitarr)) if (!is_set(i, bitarr))
continue; continue;
...@@ -470,26 +461,22 @@ static bool copy_parent_file(const char *parent_cgroup, ...@@ -470,26 +461,22 @@ static bool copy_parent_file(const char *parent_cgroup,
parent_file = must_make_path(parent_cgroup, file, NULL); parent_file = must_make_path(parent_cgroup, file, NULL);
len = lxc_read_from_file(parent_file, NULL, 0); len = lxc_read_from_file(parent_file, NULL, 0);
if (len <= 0) if (len <= 0)
return log_error_errno(false, errno, return log_error_errno(false, errno, "Failed to determine buffer size");
"Failed to determine buffer size");
value = must_realloc(NULL, len + 1); value = must_realloc(NULL, len + 1);
value[len] = '\0'; value[len] = '\0';
ret = lxc_read_from_file(parent_file, value, len); ret = lxc_read_from_file(parent_file, value, len);
if (ret != len) if (ret != len)
return log_error_errno(false, errno, return log_error_errno(false, errno, "Failed to read from parent file \"%s\"", parent_file);
"Failed to read from parent file \"%s\"",
parent_file);
ret = lxc_write_openat(child_cgroup, file, value, len); ret = lxc_write_openat(child_cgroup, file, value, len);
if (ret < 0 && errno != EACCES) if (ret < 0 && errno != EACCES)
return log_error_errno(false, return log_error_errno(false, errno, "Failed to write \"%s\" to file \"%s/%s\"",
errno, "Failed to write \"%s\" to file \"%s/%s\"",
value, child_cgroup, file); value, child_cgroup, file);
return true; return true;
} }
static bool is_unified_hierarchy(const struct hierarchy *h) static inline bool is_unified_hierarchy(const struct hierarchy *h)
{ {
return h->version == CGROUP2_SUPER_MAGIC; return h->version == CGROUP2_SUPER_MAGIC;
} }
...@@ -579,15 +566,12 @@ static int cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, ...@@ -579,15 +566,12 @@ static int cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h,
*/ */
static bool controller_lists_intersect(char **l1, char **l2) static bool controller_lists_intersect(char **l1, char **l2)
{ {
int i;
if (!l1 || !l2) if (!l1 || !l2)
return false; return false;
for (i = 0; l1[i]; i++) { for (int i = 0; l1[i]; i++)
if (string_in_list(l2, l1[i])) if (string_in_list(l2, l1[i]))
return true; return true;
}
return false; return false;
} }
...@@ -598,12 +582,10 @@ static bool controller_lists_intersect(char **l1, char **l2) ...@@ -598,12 +582,10 @@ static bool controller_lists_intersect(char **l1, char **l2)
*/ */
static bool controller_list_is_dup(struct hierarchy **hlist, char **clist) static bool controller_list_is_dup(struct hierarchy **hlist, char **clist)
{ {
int i;
if (!hlist) if (!hlist)
return false; return false;
for (i = 0; hlist[i]; i++) for (int i = 0; hlist[i]; i++)
if (controller_lists_intersect(hlist[i]->controllers, clist)) if (controller_lists_intersect(hlist[i]->controllers, clist))
return true; return true;
...@@ -615,12 +597,10 @@ static bool controller_list_is_dup(struct hierarchy **hlist, char **clist) ...@@ -615,12 +597,10 @@ static bool controller_list_is_dup(struct hierarchy **hlist, char **clist)
*/ */
static bool controller_found(struct hierarchy **hlist, char *entry) static bool controller_found(struct hierarchy **hlist, char *entry)
{ {
int i;
if (!hlist) if (!hlist)
return false; return false;
for (i = 0; hlist[i]; i++) for (int i = 0; hlist[i]; i++)
if (string_in_list(hlist[i]->controllers, entry)) if (string_in_list(hlist[i]->controllers, entry))
return true; return true;
...@@ -632,17 +612,15 @@ static bool controller_found(struct hierarchy **hlist, char *entry) ...@@ -632,17 +612,15 @@ static bool controller_found(struct hierarchy **hlist, char *entry)
*/ */
static bool all_controllers_found(struct cgroup_ops *ops) static bool all_controllers_found(struct cgroup_ops *ops)
{ {
char **cur; struct hierarchy **hlist;
struct hierarchy **hlist = ops->hierarchies;
if (!ops->cgroup_use) if (!ops->cgroup_use)
return true; return true;
for (cur = ops->cgroup_use; cur && *cur; cur++) hlist = ops->hierarchies;
if (!controller_found(hlist, *cur)) { for (char **cur = ops->cgroup_use; cur && *cur; cur++)
ERROR("No %s controller mountpoint found", *cur); if (!controller_found(hlist, *cur))
return false; return log_error(false, "No %s controller mountpoint found", *cur);
}
return true; return true;
} }
...@@ -673,17 +651,13 @@ static char **cg_hybrid_get_controllers(char **klist, char **nlist, char *line, ...@@ -673,17 +651,13 @@ static char **cg_hybrid_get_controllers(char **klist, char **nlist, char *line,
/* Note, if we change how mountinfo works, then our caller will need to /* Note, if we change how mountinfo works, then our caller will need to
* verify /sys/fs/cgroup/ in this field. * verify /sys/fs/cgroup/ in this field.
*/ */
if (strncmp(p, DEFAULT_CGROUP_MOUNTPOINT "/", 15) != 0) { if (strncmp(p, DEFAULT_CGROUP_MOUNTPOINT "/", 15) != 0)
ERROR("Found hierarchy not under " DEFAULT_CGROUP_MOUNTPOINT ": \"%s\"", p); return log_error(NULL, "Found hierarchy not under " DEFAULT_CGROUP_MOUNTPOINT ": \"%s\"", p);
return NULL;
}
p += 15; p += 15;
p2 = strchr(p, ' '); p2 = strchr(p, ' ');
if (!p2) { if (!p2)
ERROR("Corrupt mountinfo"); return log_error(NULL, "Corrupt mountinfo");
return NULL;
}
*p2 = '\0'; *p2 = '\0';
if (type == CGROUP_SUPER_MAGIC) { if (type == CGROUP_SUPER_MAGIC) {
...@@ -762,12 +736,11 @@ static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char ...@@ -762,12 +736,11 @@ static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char
*/ */
static char *cg_hybrid_get_mountpoint(char *line) static char *cg_hybrid_get_mountpoint(char *line)
{ {
int i; char *p = line, *sret = NULL;
size_t len; size_t len;
char *p2; char *p2;
char *p = line, *sret = NULL;
for (i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
p = strchr(p, ' '); p = strchr(p, ' ');
if (!p) if (!p)
return NULL; return NULL;
...@@ -786,15 +759,17 @@ static char *cg_hybrid_get_mountpoint(char *line) ...@@ -786,15 +759,17 @@ static char *cg_hybrid_get_mountpoint(char *line)
sret = must_realloc(NULL, len + 1); sret = must_realloc(NULL, len + 1);
memcpy(sret, p, len); memcpy(sret, p, len);
sret[len] = '\0'; sret[len] = '\0';
return sret; return sret;
} }
/* Given a multi-line string, return a null-terminated copy of the current line. */ /* Given a multi-line string, return a null-terminated copy of the current line. */
static char *copy_to_eol(char *p) static char *copy_to_eol(char *p)
{ {
char *p2 = strchr(p, '\n'), *sret; char *p2, *sret;
size_t len; size_t len;
p2 = strchr(p, '\n');
if (!p2) if (!p2)
return NULL; return NULL;
...@@ -802,6 +777,7 @@ static char *copy_to_eol(char *p) ...@@ -802,6 +777,7 @@ static char *copy_to_eol(char *p)
sret = must_realloc(NULL, len + 1); sret = must_realloc(NULL, len + 1);
memcpy(sret, p, len); memcpy(sret, p, len);
sret[len] = '\0'; sret[len] = '\0';
return sret; return sret;
} }
...@@ -974,8 +950,8 @@ static int cgroup_rmdir(struct hierarchy **hierarchies, ...@@ -974,8 +950,8 @@ static int cgroup_rmdir(struct hierarchy **hierarchies,
return 0; return 0;
for (int i = 0; hierarchies[i]; i++) { for (int i = 0; hierarchies[i]; i++) {
int ret;
struct hierarchy *h = hierarchies[i]; struct hierarchy *h = hierarchies[i];
int ret;
if (!h->container_full_path) if (!h->container_full_path)
continue; continue;
...@@ -984,8 +960,7 @@ static int cgroup_rmdir(struct hierarchy **hierarchies, ...@@ -984,8 +960,7 @@ static int cgroup_rmdir(struct hierarchy **hierarchies,
if (ret < 0) if (ret < 0)
WARN("Failed to destroy \"%s\"", h->container_full_path); WARN("Failed to destroy \"%s\"", h->container_full_path);
free(h->container_full_path); free_disarm(h->container_full_path);
h->container_full_path = NULL;
} }
return 0; return 0;
...@@ -1011,14 +986,12 @@ static int cgroup_rmdir_wrapper(void *data) ...@@ -1011,14 +986,12 @@ static int cgroup_rmdir_wrapper(void *data)
ret = setresgid(nsgid, nsgid, nsgid); ret = setresgid(nsgid, nsgid, nsgid);
if (ret < 0) if (ret < 0)
return log_error_errno(-1, errno, return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)",
"Failed to setresgid(%d, %d, %d)",
(int)nsgid, (int)nsgid, (int)nsgid); (int)nsgid, (int)nsgid, (int)nsgid);
ret = setresuid(nsuid, nsuid, nsuid); ret = setresuid(nsuid, nsuid, nsuid);
if (ret < 0) if (ret < 0)
return log_error_errno(-1, errno, return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)",
"Failed to setresuid(%d, %d, %d)",
(int)nsuid, (int)nsuid, (int)nsuid); (int)nsuid, (int)nsuid, (int)nsuid);
return cgroup_rmdir(arg->hierarchies, arg->container_cgroup); return cgroup_rmdir(arg->hierarchies, arg->container_cgroup);
...@@ -1049,10 +1022,10 @@ __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, ...@@ -1049,10 +1022,10 @@ __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops,
if (handler->conf && !lxc_list_empty(&handler->conf->id_map)) { if (handler->conf && !lxc_list_empty(&handler->conf->id_map)) {
struct generic_userns_exec_data wrap = { struct generic_userns_exec_data wrap = {
.origuid = 0, .conf = handler->conf,
.container_cgroup = ops->container_cgroup, .container_cgroup = ops->container_cgroup,
.hierarchies = ops->hierarchies, .hierarchies = ops->hierarchies,
.conf = handler->conf, .origuid = 0,
}; };
ret = userns_exec_1(handler->conf, cgroup_rmdir_wrapper, &wrap, ret = userns_exec_1(handler->conf, cgroup_rmdir_wrapper, &wrap,
"cgroup_rmdir_wrapper"); "cgroup_rmdir_wrapper");
...@@ -1138,19 +1111,14 @@ static int mkdir_eexist_on_last(const char *dir, mode_t mode) ...@@ -1138,19 +1111,14 @@ static int mkdir_eexist_on_last(const char *dir, mode_t mode)
dir = tmp + strspn(tmp, "/"); dir = tmp + strspn(tmp, "/");
tmp = dir + strcspn(dir, "/"); tmp = dir + strcspn(dir, "/");
errno = ENOMEM;
cur_len = dir - orig; cur_len = dir - orig;
makeme = strndup(orig, cur_len); makeme = strndup(orig, cur_len);
if (!makeme) if (!makeme)
return -1; return ret_set_errno(-1, ENOMEM);
ret = mkdir(makeme, mode); ret = mkdir(makeme, mode);
if (ret < 0) { if (ret < 0 && ((errno != EEXIST) || (orig_len == cur_len)))
if ((errno != EEXIST) || (orig_len == cur_len)) { return log_error_errno(-1, errno, "Failed to create directory \"%s\"", makeme);
SYSERROR("Failed to create directory \"%s\"", makeme);
return -1;
}
}
} while (tmp != dir); } while (tmp != dir);
return 0; return 0;
...@@ -1492,14 +1460,12 @@ static int chown_cgroup_wrapper(void *data) ...@@ -1492,14 +1460,12 @@ static int chown_cgroup_wrapper(void *data)
ret = setresgid(nsgid, nsgid, nsgid); ret = setresgid(nsgid, nsgid, nsgid);
if (ret < 0) if (ret < 0)
return log_error_errno(-1, errno, return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)",
"Failed to setresgid(%d, %d, %d)",
(int)nsgid, (int)nsgid, (int)nsgid); (int)nsgid, (int)nsgid, (int)nsgid);
ret = setresuid(nsuid, nsuid, nsuid); ret = setresuid(nsuid, nsuid, nsuid);
if (ret < 0) if (ret < 0)
return log_error_errno(-1, errno, return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)",
"Failed to setresuid(%d, %d, %d)",
(int)nsuid, (int)nsuid, (int)nsuid); (int)nsuid, (int)nsuid, (int)nsuid);
destuid = get_ns_uid(arg->origuid); destuid = get_ns_uid(arg->origuid);
...@@ -1587,12 +1553,9 @@ __cgfsng_ops void cgfsng_payload_finalize(struct cgroup_ops *ops) ...@@ -1587,12 +1553,9 @@ __cgfsng_ops void cgfsng_payload_finalize(struct cgroup_ops *ops)
} }
/* cgroup-full:* is done, no need to create subdirs */ /* cgroup-full:* is done, no need to create subdirs */
static bool cg_mount_needs_subdirs(int type) static inline bool cg_mount_needs_subdirs(int type)
{ {
if (type >= LXC_AUTO_CGROUP_FULL_RO) return !(type >= LXC_AUTO_CGROUP_FULL_RO);
return false;
return true;
} }
/* After $rootfs/sys/fs/container/controller/the/cg/path has been created, /* After $rootfs/sys/fs/container/controller/the/cg/path has been created,
...@@ -1609,11 +1572,9 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h, ...@@ -1609,11 +1572,9 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h,
if (type == LXC_AUTO_CGROUP_RO || type == LXC_AUTO_CGROUP_MIXED) { if (type == LXC_AUTO_CGROUP_RO || type == LXC_AUTO_CGROUP_MIXED) {
ret = mount(controllerpath, controllerpath, "cgroup", MS_BIND, NULL); ret = mount(controllerpath, controllerpath, "cgroup", MS_BIND, NULL);
if (ret < 0) { if (ret < 0)
SYSERROR("Failed to bind mount \"%s\" onto \"%s\"", return log_error_errno(-1, errno, "Failed to bind mount \"%s\" onto \"%s\"",
controllerpath, controllerpath); controllerpath, controllerpath);
return -1;
}
remount_flags = add_required_remount_flags(controllerpath, remount_flags = add_required_remount_flags(controllerpath,
controllerpath, controllerpath,
...@@ -1621,10 +1582,8 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h, ...@@ -1621,10 +1582,8 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h,
ret = mount(controllerpath, controllerpath, "cgroup", ret = mount(controllerpath, controllerpath, "cgroup",
remount_flags | MS_REMOUNT | MS_BIND | MS_RDONLY, remount_flags | MS_REMOUNT | MS_BIND | MS_RDONLY,
NULL); NULL);
if (ret < 0) { if (ret < 0)
SYSERROR("Failed to remount \"%s\" ro", controllerpath); return log_error_errno(-1, errno, "Failed to remount \"%s\" ro", controllerpath);
return -1;
}
INFO("Remounted %s read-only", controllerpath); INFO("Remounted %s read-only", controllerpath);
} }
...@@ -1635,20 +1594,17 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h, ...@@ -1635,20 +1594,17 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h,
flags |= MS_RDONLY; flags |= MS_RDONLY;
ret = mount(sourcepath, cgpath, "cgroup", flags, NULL); ret = mount(sourcepath, cgpath, "cgroup", flags, NULL);
if (ret < 0) { if (ret < 0)
SYSERROR("Failed to mount \"%s\" onto \"%s\"", h->controllers[0], cgpath); return log_error_errno(-1, errno, "Failed to mount \"%s\" onto \"%s\"",
return -1; h->controllers[0], cgpath);
}
INFO("Mounted \"%s\" onto \"%s\"", h->controllers[0], cgpath); INFO("Mounted \"%s\" onto \"%s\"", h->controllers[0], cgpath);
if (flags & MS_RDONLY) { if (flags & MS_RDONLY) {
remount_flags = add_required_remount_flags(sourcepath, cgpath, remount_flags = add_required_remount_flags(sourcepath, cgpath,
flags | MS_REMOUNT); flags | MS_REMOUNT);
ret = mount(sourcepath, cgpath, "cgroup", remount_flags, NULL); ret = mount(sourcepath, cgpath, "cgroup", remount_flags, NULL);
if (ret < 0) { if (ret < 0)
SYSERROR("Failed to remount \"%s\" ro", cgpath); return log_error_errno(-1, errno, "Failed to remount \"%s\" ro", cgpath);
return -1;
}
INFO("Remounted %s read-only", cgpath); INFO("Remounted %s read-only", cgpath);
} }
...@@ -1686,10 +1642,9 @@ static int __cg_mount_direct(int type, struct hierarchy *h, ...@@ -1686,10 +1642,9 @@ static int __cg_mount_direct(int type, struct hierarchy *h,
} }
ret = mount("cgroup", controllerpath, fstype, flags, controllers); ret = mount("cgroup", controllerpath, fstype, flags, controllers);
if (ret < 0) { if (ret < 0)
SYSERROR("Failed to mount \"%s\" with cgroup filesystem type %s", controllerpath, fstype); return log_error_errno(-1, errno, "Failed to mount \"%s\" with cgroup filesystem type %s",
return -1; controllerpath, fstype);
}
DEBUG("Mounted \"%s\" with cgroup filesystem type %s", controllerpath, fstype); DEBUG("Mounted \"%s\" with cgroup filesystem type %s", controllerpath, fstype);
return 0; return 0;
...@@ -1853,9 +1808,7 @@ __cgfsng_ops static bool cgfsng_escape(const struct cgroup_ops *ops, ...@@ -1853,9 +1808,7 @@ __cgfsng_ops static bool cgfsng_escape(const struct cgroup_ops *ops,
"cgroup.procs", NULL); "cgroup.procs", NULL);
ret = lxc_write_to_file(fullpath, "0", 2, false, 0666); ret = lxc_write_to_file(fullpath, "0", 2, false, 0666);
if (ret != 0) if (ret != 0)
return log_error_errno(false, return log_error_errno(false, errno, "Failed to escape to cgroup \"%s\"", fullpath);
errno, "Failed to escape to cgroup \"%s\"",
fullpath);
} }
return true; return true;
...@@ -1886,7 +1839,7 @@ __cgfsng_ops static bool cgfsng_get_hierarchies(struct cgroup_ops *ops, int n, ...@@ -1886,7 +1839,7 @@ __cgfsng_ops static bool cgfsng_get_hierarchies(struct cgroup_ops *ops, int n,
return ret_set_errno(false, ENOENT); return ret_set_errno(false, ENOENT);
if (!ops->hierarchies) if (!ops->hierarchies)
return false; return ret_set_errno(false, ENOENT);
/* sanity check n */ /* sanity check n */
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
...@@ -2075,8 +2028,7 @@ __cgfsng_ops static const char *cgfsng_get_cgroup(struct cgroup_ops *ops, ...@@ -2075,8 +2028,7 @@ __cgfsng_ops static const char *cgfsng_get_cgroup(struct cgroup_ops *ops,
h = get_hierarchy(ops, controller); h = get_hierarchy(ops, controller);
if (!h) if (!h)
return log_warn_errno(NULL, return log_warn_errno(NULL, ENOENT, "Failed to find hierarchy for controller \"%s\"",
ENOENT, "Failed to find hierarchy for controller \"%s\"",
controller ? controller : "(null)"); controller ? controller : "(null)");
return h->container_full_path return h->container_full_path
...@@ -2227,8 +2179,7 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name, ...@@ -2227,8 +2179,7 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name,
fullpath = build_full_cgpath_from_monitorpath(h, path, "cgroup.procs"); fullpath = build_full_cgpath_from_monitorpath(h, path, "cgroup.procs");
ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666); ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666);
if (ret < 0) if (ret < 0)
return log_error_errno(false, errno, return log_error_errno(false, errno, "Failed to attach %d to %s",
"Failed to attach %d to %s",
(int)pid, fullpath); (int)pid, fullpath);
} }
...@@ -2319,10 +2270,11 @@ static int device_cgroup_rule_parse(struct device_item *device, const char *key, ...@@ -2319,10 +2270,11 @@ static int device_cgroup_rule_parse(struct device_item *device, const char *key,
: LXC_BPF_DEVICE_CGROUP_WHITELIST; : LXC_BPF_DEVICE_CGROUP_WHITELIST;
device->allow = -1; device->allow = -1;
return 0; return 0;
} else {
device->global_rule = LXC_BPF_DEVICE_CGROUP_LOCAL_RULE;
} }
/* local rule */
device->global_rule = LXC_BPF_DEVICE_CGROUP_LOCAL_RULE;
switch (*val) { switch (*val) {
case 'a': case 'a':
__fallthrough; __fallthrough;
...@@ -2498,9 +2450,7 @@ static int device_cgroup_rule_parse_devpath(struct device_item *device, ...@@ -2498,9 +2450,7 @@ static int device_cgroup_rule_parse_devpath(struct device_item *device,
device->type = 'c'; device->type = 'c';
break; break;
default: default:
return log_error_errno(-1, EINVAL, return log_error_errno(-1, EINVAL, "Unsupported device type %i for \"%s\"", m, path);
"Unsupported device type %i for \"%s\"",
m, path);
} }
device->major = MAJOR(sb.st_rdev); device->major = MAJOR(sb.st_rdev);
...@@ -2523,10 +2473,8 @@ static int convert_devpath(const char *invalue, char *dest) ...@@ -2523,10 +2473,8 @@ static int convert_devpath(const char *invalue, char *dest)
ret = snprintf(dest, 50, "%c %d:%d %s", device.type, device.major, ret = snprintf(dest, 50, "%c %d:%d %s", device.type, device.major,
device.minor, device.access); device.minor, device.access);
if (ret < 0 || ret >= 50) if (ret < 0 || ret >= 50)
return log_error_errno(-1, return log_error_errno(-1, ENAMETOOLONG, "Error on configuration value \"%c %d:%d %s\" (max 50 chars)",
ENAMETOOLONG, "Error on configuration value \"%c %d:%d %s\" (max 50 chars)", device.type, device.major, device.minor, device.access);
device.type, device.major, device.minor,
device.access);
return 0; return 0;
} }
...@@ -2558,14 +2506,8 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, ...@@ -2558,14 +2506,8 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
} }
h = get_hierarchy(ops, controller); h = get_hierarchy(ops, controller);
if (!h) { if (!h)
ERROR("Failed to setup limits for the \"%s\" controller. " return log_error_errno(-ENOENT, ENOENT, "Failed to setup limits for the \"%s\" controller. The controller seems to be unused by \"cgfsng\" cgroup driver or not enabled on the cgroup hierarchy", controller);
"The controller seems to be unused by \"cgfsng\" cgroup "
"driver or not enabled on the cgroup hierarchy",
controller);
errno = ENOENT;
return -ENOENT;
}
return lxc_write_openat(h->container_full_path, filename, value, strlen(value)); return lxc_write_openat(h->container_full_path, filename, value, strlen(value));
} }
...@@ -2603,15 +2545,12 @@ __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, ...@@ -2603,15 +2545,12 @@ __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops,
if (do_devices == !strncmp("devices", cg->subsystem, 7)) { if (do_devices == !strncmp("devices", cg->subsystem, 7)) {
if (cg_legacy_set_data(ops, cg->subsystem, cg->value)) { if (cg_legacy_set_data(ops, cg->subsystem, cg->value)) {
if (do_devices && (errno == EACCES || errno == EPERM)) if (do_devices && (errno == EACCES || errno == EPERM))
log_warn_errno(continue, log_warn_errno(continue, errno, "Failed to set \"%s\" to \"%s\"",
errno, "Failed to set \"%s\" to \"%s\"",
cg->subsystem, cg->value); cg->subsystem, cg->value);
log_warn_errno(goto out, errno, log_warn_errno(goto out, errno, "Failed to set \"%s\" to \"%s\"",
"Failed to set \"%s\" to \"%s\"",
cg->subsystem, cg->value); cg->subsystem, cg->value);
} }
DEBUG("Set controller \"%s\" set to \"%s\"", DEBUG("Set controller \"%s\" set to \"%s\"", cg->subsystem, cg->value);
cg->subsystem, cg->value);
} }
} }
...@@ -2643,9 +2582,7 @@ static int bpf_device_cgroup_prepare(struct cgroup_ops *ops, ...@@ -2643,9 +2582,7 @@ static int bpf_device_cgroup_prepare(struct cgroup_ops *ops,
else else
ret = device_cgroup_rule_parse(&device_item, key, val); ret = device_cgroup_rule_parse(&device_item, key, val);
if (ret < 0) if (ret < 0)
return log_error_errno(-1, EINVAL, return log_error_errno(-1, EINVAL, "Failed to parse device string %s=%s", key, val);
"Failed to parse device string %s=%s",
key, val);
ret = bpf_list_add_device(conf, &device_item); ret = bpf_list_add_device(conf, &device_item);
if (ret < 0) if (ret < 0)
...@@ -2694,8 +2631,7 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops, ...@@ -2694,8 +2631,7 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops,
cg->subsystem, cg->value, cg->subsystem, cg->value,
strlen(cg->value)); strlen(cg->value));
if (ret < 0) if (ret < 0)
return log_error_errno(false, return log_error_errno(false, errno, "Failed to set \"%s\" to \"%s\"",
errno, "Failed to set \"%s\" to \"%s\"",
cg->subsystem, cg->value); cg->subsystem, cg->value);
} }
TRACE("Set \"%s\" to \"%s\"", cg->subsystem, cg->value); TRACE("Set \"%s\" to \"%s\"", cg->subsystem, cg->value);
...@@ -2735,40 +2671,42 @@ __cgfsng_ops bool cgfsng_devices_activate(struct cgroup_ops *ops, ...@@ -2735,40 +2671,42 @@ __cgfsng_ops bool cgfsng_devices_activate(struct cgroup_ops *ops,
devices = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE); devices = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE);
if (!devices) if (!devices)
return log_error_errno(false, ENOMEM, return log_error_errno(false, ENOMEM, "Failed to create new bpf program");
"Failed to create new bpf program");
ret = bpf_program_init(devices); ret = bpf_program_init(devices);
if (ret) if (ret)
return log_error_errno(false, ENOMEM, return log_error_errno(false, ENOMEM, "Failed to initialize bpf program");
"Failed to initialize bpf program");
lxc_list_for_each(it, &conf->devices) { lxc_list_for_each(it, &conf->devices) {
struct device_item *cur = it->elem; struct device_item *cur = it->elem;
ret = bpf_program_append_device(devices, cur); ret = bpf_program_append_device(devices, cur);
if (ret) if (ret)
return log_error_errno(false, return log_error_errno(false, ENOMEM, "Failed to add new rule to bpf device program: type %c, major %d, minor %d, access %s, allow %d, global_rule %d",
ENOMEM, "Failed to add new rule to bpf device program: type %c, major %d, minor %d, access %s, allow %d, global_rule %d", cur->type,
cur->type, cur->major, cur->major,
cur->minor, cur->access, cur->minor,
cur->allow, cur->global_rule); cur->access,
cur->allow,
cur->global_rule);
TRACE("Added rule to bpf device program: type %c, major %d, minor %d, access %s, allow %d, global_rule %d", TRACE("Added rule to bpf device program: type %c, major %d, minor %d, access %s, allow %d, global_rule %d",
cur->type, cur->major, cur->minor, cur->access, cur->type,
cur->allow, cur->global_rule); cur->major,
cur->minor,
cur->access,
cur->allow,
cur->global_rule);
} }
ret = bpf_program_finalize(devices); ret = bpf_program_finalize(devices);
if (ret) if (ret)
return log_error_errno(false, ENOMEM, return log_error_errno(false, ENOMEM, "Failed to finalize bpf program");
"Failed to finalize bpf program");
ret = bpf_program_cgroup_attach(devices, BPF_CGROUP_DEVICE, ret = bpf_program_cgroup_attach(devices, BPF_CGROUP_DEVICE,
unified->container_full_path, unified->container_full_path,
BPF_F_ALLOW_MULTI); BPF_F_ALLOW_MULTI);
if (ret) if (ret)
return log_error_errno(false, ENOMEM, return log_error_errno(false, ENOMEM, "Failed to attach bpf program");
"Failed to attach bpf program");
/* Replace old bpf program. */ /* Replace old bpf program. */
devices_old = move_ptr(conf->cgroup2_devices); devices_old = move_ptr(conf->cgroup2_devices);
...@@ -3116,6 +3054,7 @@ static int cg_unified_init(struct cgroup_ops *ops, bool relative, ...@@ -3116,6 +3054,7 @@ static int cg_unified_init(struct cgroup_ops *ops, bool relative,
ops->cgroup_layout = CGROUP_LAYOUT_UNIFIED; ops->cgroup_layout = CGROUP_LAYOUT_UNIFIED;
ops->unified = new; ops->unified = new;
return CGROUP2_SUPER_MAGIC; return CGROUP2_SUPER_MAGIC;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment