*/
static bool string_in_list(char **list, const char *entry)
{
- int i;
-
if (!list)
return false;
- for (i = 0; list[i]; i++)
+ for (int i = 0; list[i]; i++)
if (strcmp(list[i], entry) == 0)
return true;
*/
struct hierarchy *get_hierarchy(struct cgroup_ops *ops, const char *controller)
{
- int i;
-
- errno = ENOENT;
-
- if (!ops->hierarchies) {
- TRACE("There are no useable cgroup controllers");
- return NULL;
- }
+ if (!ops->hierarchies)
+ return log_trace_errno(NULL, errno, "There are no useable cgroup controllers");
- for (i = 0; ops->hierarchies[i]; i++) {
+ for (int i = 0; ops->hierarchies[i]; i++) {
if (!controller) {
/* This is the empty unified hierarchy. */
if (ops->hierarchies[i]->controllers &&
else
WARN("There is no empty unified cgroup hierarchy");
- return NULL;
+ return ret_set_errno(NULL, ENOENT);
}
#define BATCH_SIZE 50
int newbatches = (newlen / BATCH_SIZE) + 1;
int oldbatches = (oldlen / BATCH_SIZE) + 1;
- if (!*mem || newbatches > oldbatches) {
+ if (!*mem || newbatches > oldbatches)
*mem = must_realloc(*mem, newbatches * BATCH_SIZE);
- }
}
static void append_line(char **dest, size_t oldlen, char *new, size_t newlen)
/* Slurp in a whole file */
static char *read_file(const char *fnam)
{
- __do_free char *line = NULL;
+ __do_free char *buf = NULL, *line = NULL;
__do_fclose FILE *f = NULL;
- int linelen;
- char *buf = NULL;
size_t len = 0, fulllen = 0;
+ int linelen;
f = fopen(fnam, "re");
if (!f)
return NULL;
+
while ((linelen = getline(&line, &len, f)) != -1) {
append_line(&buf, fulllen, line, linelen);
fulllen += linelen;
}
- return buf;
+
+ return move_ptr(buf);
}
/* Taken over modified from the kernel sources. */
*/
static uint32_t *lxc_cpumask(char *buf, size_t nbits)
{
+ __do_free uint32_t *bitarr = NULL;
char *token;
size_t arrlen;
- __do_free uint32_t *bitarr = NULL;
arrlen = BITS_TO_LONGS(nbits);
bitarr = calloc(arrlen, sizeof(uint32_t));
static char *lxc_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits)
{
__do_free_string_list char **cpulist = NULL;
- int ret;
- size_t i;
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))
continue;
parent_file = must_make_path(parent_cgroup, file, NULL);
len = lxc_read_from_file(parent_file, NULL, 0);
if (len <= 0)
- return log_error_errno(false, errno,
- "Failed to determine buffer size");
+ return log_error_errno(false, errno, "Failed to determine buffer size");
value = must_realloc(NULL, len + 1);
value[len] = '\0';
ret = lxc_read_from_file(parent_file, value, len);
if (ret != len)
- return log_error_errno(false, errno,
- "Failed to read from parent file \"%s\"",
- parent_file);
+ return log_error_errno(false, errno, "Failed to read from parent file \"%s\"", parent_file);
ret = lxc_write_openat(child_cgroup, file, value, len);
if (ret < 0 && errno != EACCES)
- return log_error_errno(false,
- errno, "Failed to write \"%s\" to file \"%s/%s\"",
+ return log_error_errno(false, errno, "Failed to write \"%s\" to file \"%s/%s\"",
value, child_cgroup, file);
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;
}
*/
static bool controller_lists_intersect(char **l1, char **l2)
{
- int i;
-
if (!l1 || !l2)
return false;
- for (i = 0; l1[i]; i++) {
+ for (int i = 0; l1[i]; i++)
if (string_in_list(l2, l1[i]))
return true;
- }
return false;
}
*/
static bool controller_list_is_dup(struct hierarchy **hlist, char **clist)
{
- int i;
-
if (!hlist)
return false;
- for (i = 0; hlist[i]; i++)
+ for (int i = 0; hlist[i]; i++)
if (controller_lists_intersect(hlist[i]->controllers, clist))
return true;
*/
static bool controller_found(struct hierarchy **hlist, char *entry)
{
- int i;
-
if (!hlist)
return false;
- for (i = 0; hlist[i]; i++)
+ for (int i = 0; hlist[i]; i++)
if (string_in_list(hlist[i]->controllers, entry))
return true;
*/
static bool all_controllers_found(struct cgroup_ops *ops)
{
- char **cur;
- struct hierarchy **hlist = ops->hierarchies;
+ struct hierarchy **hlist;
if (!ops->cgroup_use)
return true;
- for (cur = ops->cgroup_use; cur && *cur; cur++)
- if (!controller_found(hlist, *cur)) {
- ERROR("No %s controller mountpoint found", *cur);
- return false;
- }
+ hlist = ops->hierarchies;
+ for (char **cur = ops->cgroup_use; cur && *cur; cur++)
+ if (!controller_found(hlist, *cur))
+ return log_error(false, "No %s controller mountpoint found", *cur);
return true;
}
/* Note, if we change how mountinfo works, then our caller will need to
* verify /sys/fs/cgroup/ in this field.
*/
- if (strncmp(p, DEFAULT_CGROUP_MOUNTPOINT "/", 15) != 0) {
- ERROR("Found hierarchy not under " DEFAULT_CGROUP_MOUNTPOINT ": \"%s\"", p);
- return NULL;
- }
+ if (strncmp(p, DEFAULT_CGROUP_MOUNTPOINT "/", 15) != 0)
+ return log_error(NULL, "Found hierarchy not under " DEFAULT_CGROUP_MOUNTPOINT ": \"%s\"", p);
p += 15;
p2 = strchr(p, ' ');
- if (!p2) {
- ERROR("Corrupt mountinfo");
- return NULL;
- }
+ if (!p2)
+ return log_error(NULL, "Corrupt mountinfo");
*p2 = '\0';
if (type == CGROUP_SUPER_MAGIC) {
*/
static char *cg_hybrid_get_mountpoint(char *line)
{
- int i;
+ char *p = line, *sret = NULL;
size_t len;
char *p2;
- char *p = line, *sret = NULL;
- for (i = 0; i < 4; i++) {
+ for (int i = 0; i < 4; i++) {
p = strchr(p, ' ');
if (!p)
return NULL;
sret = must_realloc(NULL, len + 1);
memcpy(sret, p, len);
sret[len] = '\0';
+
return sret;
}
/* Given a multi-line string, return a null-terminated copy of the current line. */
static char *copy_to_eol(char *p)
{
- char *p2 = strchr(p, '\n'), *sret;
+ char *p2, *sret;
size_t len;
+ p2 = strchr(p, '\n');
if (!p2)
return NULL;
sret = must_realloc(NULL, len + 1);
memcpy(sret, p, len);
sret[len] = '\0';
+
return sret;
}
return 0;
for (int i = 0; hierarchies[i]; i++) {
- int ret;
struct hierarchy *h = hierarchies[i];
+ int ret;
if (!h->container_full_path)
continue;
if (ret < 0)
WARN("Failed to destroy \"%s\"", h->container_full_path);
- free(h->container_full_path);
- h->container_full_path = NULL;
+ free_disarm(h->container_full_path);
}
return 0;
ret = setresgid(nsgid, nsgid, nsgid);
if (ret < 0)
- return log_error_errno(-1, errno,
- "Failed to setresgid(%d, %d, %d)",
+ return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)",
(int)nsgid, (int)nsgid, (int)nsgid);
ret = setresuid(nsuid, nsuid, nsuid);
if (ret < 0)
- return log_error_errno(-1, errno,
- "Failed to setresuid(%d, %d, %d)",
+ return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)",
(int)nsuid, (int)nsuid, (int)nsuid);
return cgroup_rmdir(arg->hierarchies, arg->container_cgroup);
if (handler->conf && !lxc_list_empty(&handler->conf->id_map)) {
struct generic_userns_exec_data wrap = {
- .origuid = 0,
- .container_cgroup = ops->container_cgroup,
- .hierarchies = ops->hierarchies,
- .conf = handler->conf,
+ .conf = handler->conf,
+ .container_cgroup = ops->container_cgroup,
+ .hierarchies = ops->hierarchies,
+ .origuid = 0,
};
ret = userns_exec_1(handler->conf, cgroup_rmdir_wrapper, &wrap,
"cgroup_rmdir_wrapper");
dir = tmp + strspn(tmp, "/");
tmp = dir + strcspn(dir, "/");
- errno = ENOMEM;
cur_len = dir - orig;
makeme = strndup(orig, cur_len);
if (!makeme)
- return -1;
+ return ret_set_errno(-1, ENOMEM);
ret = mkdir(makeme, mode);
- if (ret < 0) {
- if ((errno != EEXIST) || (orig_len == cur_len)) {
- SYSERROR("Failed to create directory \"%s\"", makeme);
- return -1;
- }
- }
+ if (ret < 0 && ((errno != EEXIST) || (orig_len == cur_len)))
+ return log_error_errno(-1, errno, "Failed to create directory \"%s\"", makeme);
} while (tmp != dir);
return 0;
ret = setresgid(nsgid, nsgid, nsgid);
if (ret < 0)
- return log_error_errno(-1, errno,
- "Failed to setresgid(%d, %d, %d)",
+ return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)",
(int)nsgid, (int)nsgid, (int)nsgid);
ret = setresuid(nsuid, nsuid, nsuid);
if (ret < 0)
- return log_error_errno(-1, errno,
- "Failed to setresuid(%d, %d, %d)",
+ return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)",
(int)nsuid, (int)nsuid, (int)nsuid);
destuid = get_ns_uid(arg->origuid);
}
/* 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 false;
-
- return true;
+ return !(type >= LXC_AUTO_CGROUP_FULL_RO);
}
/* After $rootfs/sys/fs/container/controller/the/cg/path has been created,
if (type == LXC_AUTO_CGROUP_RO || type == LXC_AUTO_CGROUP_MIXED) {
ret = mount(controllerpath, controllerpath, "cgroup", MS_BIND, NULL);
- if (ret < 0) {
- SYSERROR("Failed to bind mount \"%s\" onto \"%s\"",
- controllerpath, controllerpath);
- return -1;
- }
+ if (ret < 0)
+ return log_error_errno(-1, errno, "Failed to bind mount \"%s\" onto \"%s\"",
+ controllerpath, controllerpath);
remount_flags = add_required_remount_flags(controllerpath,
controllerpath,
ret = mount(controllerpath, controllerpath, "cgroup",
remount_flags | MS_REMOUNT | MS_BIND | MS_RDONLY,
NULL);
- if (ret < 0) {
- SYSERROR("Failed to remount \"%s\" ro", controllerpath);
- return -1;
- }
+ if (ret < 0)
+ return log_error_errno(-1, errno, "Failed to remount \"%s\" ro", controllerpath);
INFO("Remounted %s read-only", controllerpath);
}
flags |= MS_RDONLY;
ret = mount(sourcepath, cgpath, "cgroup", flags, NULL);
- if (ret < 0) {
- SYSERROR("Failed to mount \"%s\" onto \"%s\"", h->controllers[0], cgpath);
- return -1;
- }
+ if (ret < 0)
+ return log_error_errno(-1, errno, "Failed to mount \"%s\" onto \"%s\"",
+ h->controllers[0], cgpath);
INFO("Mounted \"%s\" onto \"%s\"", h->controllers[0], cgpath);
if (flags & MS_RDONLY) {
remount_flags = add_required_remount_flags(sourcepath, cgpath,
flags | MS_REMOUNT);
ret = mount(sourcepath, cgpath, "cgroup", remount_flags, NULL);
- if (ret < 0) {
- SYSERROR("Failed to remount \"%s\" ro", cgpath);
- return -1;
- }
+ if (ret < 0)
+ return log_error_errno(-1, errno, "Failed to remount \"%s\" ro", cgpath);
INFO("Remounted %s read-only", cgpath);
}
}
ret = mount("cgroup", controllerpath, fstype, flags, controllers);
- if (ret < 0) {
- SYSERROR("Failed to mount \"%s\" with cgroup filesystem type %s", controllerpath, fstype);
- return -1;
- }
+ if (ret < 0)
+ return log_error_errno(-1, errno, "Failed to mount \"%s\" with cgroup filesystem type %s",
+ controllerpath, fstype);
DEBUG("Mounted \"%s\" with cgroup filesystem type %s", controllerpath, fstype);
return 0;
"cgroup.procs", NULL);
ret = lxc_write_to_file(fullpath, "0", 2, false, 0666);
if (ret != 0)
- return log_error_errno(false,
- errno, "Failed to escape to cgroup \"%s\"",
- fullpath);
+ return log_error_errno(false, errno, "Failed to escape to cgroup \"%s\"", fullpath);
}
return true;
return ret_set_errno(false, ENOENT);
if (!ops->hierarchies)
- return false;
+ return ret_set_errno(false, ENOENT);
/* sanity check n */
for (i = 0; i < n; i++)
h = get_hierarchy(ops, controller);
if (!h)
- return log_warn_errno(NULL,
- ENOENT, "Failed to find hierarchy for controller \"%s\"",
+ return log_warn_errno(NULL, ENOENT, "Failed to find hierarchy for controller \"%s\"",
controller ? controller : "(null)");
return h->container_full_path
fullpath = build_full_cgpath_from_monitorpath(h, path, "cgroup.procs");
ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666);
if (ret < 0)
- return log_error_errno(false, errno,
- "Failed to attach %d to %s",
+ return log_error_errno(false, errno, "Failed to attach %d to %s",
(int)pid, fullpath);
}
: LXC_BPF_DEVICE_CGROUP_WHITELIST;
device->allow = -1;
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) {
case 'a':
__fallthrough;
device->type = 'c';
break;
default:
- return log_error_errno(-1, EINVAL,
- "Unsupported device type %i for \"%s\"",
- m, path);
+ return log_error_errno(-1, EINVAL, "Unsupported device type %i for \"%s\"", m, path);
}
device->major = MAJOR(sb.st_rdev);
ret = snprintf(dest, 50, "%c %d:%d %s", device.type, device.major,
device.minor, device.access);
if (ret < 0 || ret >= 50)
- return log_error_errno(-1,
- ENAMETOOLONG, "Error on configuration value \"%c %d:%d %s\" (max 50 chars)",
- device.type, device.major, device.minor,
- device.access);
+ return log_error_errno(-1, ENAMETOOLONG, "Error on configuration value \"%c %d:%d %s\" (max 50 chars)",
+ device.type, device.major, device.minor, device.access);
return 0;
}
}
h = get_hierarchy(ops, controller);
- if (!h) {
- ERROR("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);
- errno = ENOENT;
- return -ENOENT;
- }
+ if (!h)
+ 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);
return lxc_write_openat(h->container_full_path, filename, value, strlen(value));
}
if (do_devices == !strncmp("devices", cg->subsystem, 7)) {
if (cg_legacy_set_data(ops, cg->subsystem, cg->value)) {
if (do_devices && (errno == EACCES || errno == EPERM))
- log_warn_errno(continue,
- errno, "Failed to set \"%s\" to \"%s\"",
+ log_warn_errno(continue, errno, "Failed to set \"%s\" to \"%s\"",
cg->subsystem, cg->value);
- log_warn_errno(goto out, errno,
- "Failed to set \"%s\" to \"%s\"",
+ log_warn_errno(goto out, errno, "Failed to set \"%s\" to \"%s\"",
cg->subsystem, cg->value);
}
- DEBUG("Set controller \"%s\" set to \"%s\"",
- cg->subsystem, cg->value);
+ DEBUG("Set controller \"%s\" set to \"%s\"", cg->subsystem, cg->value);
}
}
else
ret = device_cgroup_rule_parse(&device_item, key, val);
if (ret < 0)
- return log_error_errno(-1, EINVAL,
- "Failed to parse device string %s=%s",
- key, val);
+ return log_error_errno(-1, EINVAL, "Failed to parse device string %s=%s", key, val);
ret = bpf_list_add_device(conf, &device_item);
if (ret < 0)
cg->subsystem, cg->value,
strlen(cg->value));
if (ret < 0)
- return log_error_errno(false,
- errno, "Failed to set \"%s\" to \"%s\"",
+ return log_error_errno(false, errno, "Failed to set \"%s\" to \"%s\"",
cg->subsystem, cg->value);
}
TRACE("Set \"%s\" to \"%s\"", cg->subsystem, cg->value);
devices = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE);
if (!devices)
- return log_error_errno(false, ENOMEM,
- "Failed to create new bpf program");
+ return log_error_errno(false, ENOMEM, "Failed to create new bpf program");
ret = bpf_program_init(devices);
if (ret)
- return log_error_errno(false, ENOMEM,
- "Failed to initialize bpf program");
+ return log_error_errno(false, ENOMEM, "Failed to initialize bpf program");
lxc_list_for_each(it, &conf->devices) {
struct device_item *cur = it->elem;
ret = bpf_program_append_device(devices, cur);
if (ret)
- 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",
- cur->type, cur->major,
- cur->minor, cur->access,
- cur->allow, cur->global_rule);
+ 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",
+ cur->type,
+ cur->major,
+ cur->minor,
+ 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",
- cur->type, cur->major, cur->minor, cur->access,
- cur->allow, cur->global_rule);
+ cur->type,
+ cur->major,
+ cur->minor,
+ cur->access,
+ cur->allow,
+ cur->global_rule);
}
ret = bpf_program_finalize(devices);
if (ret)
- return log_error_errno(false, ENOMEM,
- "Failed to finalize bpf program");
+ return log_error_errno(false, ENOMEM, "Failed to finalize bpf program");
ret = bpf_program_cgroup_attach(devices, BPF_CGROUP_DEVICE,
unified->container_full_path,
BPF_F_ALLOW_MULTI);
if (ret)
- return log_error_errno(false, ENOMEM,
- "Failed to attach bpf program");
+ return log_error_errno(false, ENOMEM, "Failed to attach bpf program");
/* Replace old bpf program. */
devices_old = move_ptr(conf->cgroup2_devices);
ops->cgroup_layout = CGROUP_LAYOUT_UNIFIED;
ops->unified = new;
+
return CGROUP2_SUPER_MAGIC;
}