struct lxc_conf *conf,
bool do_devices)
{
- __do_free struct lxc_list *sorted_cgroup_settings = NULL;
- struct lxc_list *cgroup_settings = &conf->cgroup;
- struct lxc_list *iterator, *next;
- struct lxc_cgroup *cg;
- bool ret = false;
+ struct list_head *cgroup_settings;
+ struct lxc_cgroup *cgroup;
if (!ops)
return ret_set_errno(false, ENOENT);
return ret_set_errno(false, EINVAL);
cgroup_settings = &conf->cgroup;
- if (lxc_list_empty(cgroup_settings))
+ if (list_empty(cgroup_settings))
return true;
if (!ops->hierarchies)
if (pure_unified_layout(ops))
return log_warn_errno(true, EINVAL, "Ignoring legacy cgroup limits on pure cgroup2 system");
- sorted_cgroup_settings = sort_cgroup_settings(cgroup_settings);
- if (!sorted_cgroup_settings)
- return false;
-
- lxc_list_for_each(iterator, sorted_cgroup_settings) {
- cg = iterator->elem;
-
- if (do_devices == strnequal("devices", cg->subsystem, 7)) {
- if (cg_legacy_set_data(ops, cg->subsystem, cg->value, strnequal("cpuset", cg->subsystem, 6))) {
+ sort_cgroup_settings(conf);
+ list_for_each_entry(cgroup, cgroup_settings, head) {
+ if (do_devices == strnequal("devices", cgroup->subsystem, 7)) {
+ if (cg_legacy_set_data(ops, cgroup->subsystem, cgroup->value, strnequal("cpuset", cgroup->subsystem, 6))) {
if (do_devices && (errno == EACCES || errno == EPERM)) {
- SYSWARN("Failed to set \"%s\" to \"%s\"", cg->subsystem, cg->value);
+ SYSWARN("Failed to set \"%s\" to \"%s\"", cgroup->subsystem, cgroup->value);
continue;
}
- SYSERROR("Failed to set \"%s\" to \"%s\"", cg->subsystem, cg->value);
- goto out;
+ SYSERROR("Failed to set \"%s\" to \"%s\"", cgroup->subsystem, cgroup->value);
+ return false;
}
- DEBUG("Set controller \"%s\" set to \"%s\"", cg->subsystem, cg->value);
+ DEBUG("Set controller \"%s\" set to \"%s\"", cgroup->subsystem, cgroup->value);
}
}
- ret = true;
INFO("Limits for the legacy cgroup hierarchies have been setup");
-out:
- lxc_list_for_each_safe(iterator, sorted_cgroup_settings, next) {
- lxc_list_del(iterator);
- free(iterator);
- }
-
- return ret;
+ return true;
}
/*
__cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops,
struct lxc_handler *handler)
{
- struct lxc_list *cgroup_settings, *iterator;
+ struct list_head *cgroup_settings;
struct hierarchy *h;
struct lxc_conf *conf;
+ struct lxc_cgroup *cgroup;
if (!ops)
return ret_set_errno(false, ENOENT);
conf = handler->conf;
cgroup_settings = &conf->cgroup2;
- if (lxc_list_empty(cgroup_settings))
+ if (list_empty(cgroup_settings))
return true;
if (!pure_unified_layout(ops))
return false;
h = ops->unified;
- lxc_list_for_each (iterator, cgroup_settings) {
- struct lxc_cgroup *cg = iterator->elem;
+ list_for_each_entry(cgroup, cgroup_settings, head) {
int ret;
- if (strnequal("devices", cg->subsystem, 7))
- ret = bpf_device_cgroup_prepare(ops, conf, cg->subsystem, cg->value);
+ if (strnequal("devices", cgroup->subsystem, 7))
+ ret = bpf_device_cgroup_prepare(ops, conf, cgroup->subsystem, cgroup->value);
else
- ret = lxc_write_openat(h->path_lim, cg->subsystem, cg->value, strlen(cg->value));
+ ret = lxc_write_openat(h->path_lim, cgroup->subsystem, cgroup->value, strlen(cgroup->value));
if (ret < 0)
- return log_error_errno(false, errno, "Failed to set \"%s\" to \"%s\"", cg->subsystem, cg->value);
+ return log_error_errno(false, errno, "Failed to set \"%s\" to \"%s\"", cgroup->subsystem, cgroup->value);
- TRACE("Set \"%s\" to \"%s\"", cg->subsystem, cg->value);
+ TRACE("Set \"%s\" to \"%s\"", cgroup->subsystem, cgroup->value);
}
return log_info(true, "Limits for the unified cgroup hierarchy have been setup");
new->rootfs.fd_path_pin = -EBADF;
new->rootfs.dfd_idmapped = -EBADF;
new->logfd = -1;
- lxc_list_init(&new->cgroup);
- lxc_list_init(&new->cgroup2);
+ INIT_LIST_HEAD(&new->cgroup);
+ INIT_LIST_HEAD(&new->cgroup2);
/* Block ("allowlist") all devices by default. */
new->bpf_devices.list_type = LXC_BPF_DEVICE_CGROUP_ALLOWLIST;
INIT_LIST_HEAD(&(new->bpf_devices).devices);
int lxc_clear_cgroups(struct lxc_conf *c, const char *key, int version)
{
- char *global_token, *namespaced_token;
- size_t namespaced_token_len;
- struct lxc_list *it, *next, *list;
const char *k = key;
bool all = false;
+ char *global_token, *namespaced_token;
+ size_t namespaced_token_len;
+ struct list_head *list;
+ struct lxc_cgroup *cgroup, *ncgroup;
if (version == CGROUP2_SUPER_MAGIC) {
global_token = "lxc.cgroup2";
else
return ret_errno(EINVAL);
- lxc_list_for_each_safe(it, list, next) {
- struct lxc_cgroup *cg = it->elem;
-
- if (!all && !strequal(cg->subsystem, k))
+ list_for_each_entry_safe(cgroup, ncgroup, list, head) {
+ if (!all && !strequal(cgroup->subsystem, k))
continue;
- lxc_list_del(it);
- free(cg->subsystem);
- free(cg->value);
- free(cg);
- free(it);
+ list_del(&cgroup->head);
+ free(cgroup->subsystem);
+ free(cgroup->value);
+ free(cgroup);
}
if (all)
- lxc_list_init(list);
+ INIT_LIST_HEAD(list);
return 0;
}
ERROR("lxc.idmap = g 0 %u %u", gid, grange);
}
-static void free_cgroup_settings(struct lxc_list *result)
-{
- struct lxc_list *iterator, *next;
-
- lxc_list_for_each_safe (iterator, result, next) {
- lxc_list_del(iterator);
- free_disarm(iterator);
- }
- free_disarm(result);
-}
-
/* Return the list of cgroup_settings sorted according to the following rules
* 1. Put memory.limit_in_bytes before memory.memsw.limit_in_bytes
*/
-struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings)
+void sort_cgroup_settings(struct lxc_conf *conf)
{
- struct lxc_list *result;
- struct lxc_cgroup *cg = NULL;
- struct lxc_list *it = NULL, *item = NULL, *memsw_limit = NULL;
-
- result = lxc_list_new();
- if (!result)
- return NULL;
- lxc_list_init(result);
+ struct lxc_cgroup *cgroup, *memsw_limit, *ncgroup;
/* Iterate over the cgroup settings and copy them to the output list. */
- lxc_list_for_each (it, cgroup_settings) {
- item = zalloc(sizeof(*item));
- if (!item) {
- free_cgroup_settings(result);
- return NULL;
- }
-
- item->elem = it->elem;
- cg = it->elem;
- if (strequal(cg->subsystem, "memory.memsw.limit_in_bytes")) {
+ list_for_each_entry_safe(cgroup, ncgroup, &conf->cgroup, head) {
+ if (strequal(cgroup->subsystem, "memory.memsw.limit_in_bytes")) {
/* Store the memsw_limit location */
- memsw_limit = item;
- } else if (strequal(cg->subsystem, "memory.limit_in_bytes") &&
- memsw_limit != NULL) {
- /* lxc.cgroup.memory.memsw.limit_in_bytes is found
+ memsw_limit = cgroup;
+ } else if (memsw_limit && strequal(cgroup->subsystem, "memory.limit_in_bytes")) {
+ /*
+ * lxc.cgroup.memory.memsw.limit_in_bytes is found
* before lxc.cgroup.memory.limit_in_bytes, swap these
- * two items */
- item->elem = memsw_limit->elem;
- memsw_limit->elem = it->elem;
+ * two items.
+ */
+ list_swap(&memsw_limit->head, &cgroup->head);
}
- lxc_list_add_tail(result, item);
}
-
- return result;
}
bool relative;
};
};
+
+ struct list_head head;
};
static void free_lxc_cgroup(struct lxc_cgroup *ptr)
struct utsname *utsname;
struct {
- struct lxc_list cgroup;
- struct lxc_list cgroup2;
+ struct list_head cgroup;
+ struct list_head cgroup2;
struct bpf_devices bpf_devices;
};
__hidden extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);
__hidden extern void suggest_default_idmap(void);
__hidden extern FILE *make_anonymous_mount_file(struct lxc_list *mount, bool include_nesting_helpers);
-__hidden extern struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings);
+__hidden extern void sort_cgroup_settings(struct lxc_conf *conf);
__hidden extern int run_script(const char *name, const char *section, const char *script, ...);
__hidden extern int run_script_argv(const char *name, unsigned int hook_version, const char *section,
const char *script, const char *hookname, char **argsin);
static int __set_config_cgroup_controller(const char *key, const char *value,
struct lxc_conf *lxc_conf, int version)
{
- __do_free struct lxc_list *cglist = NULL;
- call_cleaner(free_lxc_cgroup) struct lxc_cgroup *cgelem = NULL;
+ call_cleaner(free_lxc_cgroup) struct lxc_cgroup *new_cgroup = NULL;
const char *subkey, *token;
size_t token_len;
if (*subkey == '\0')
return ret_errno(EINVAL);
- cglist = lxc_list_new();
- if (!cglist)
+ new_cgroup = zalloc(sizeof(*new_cgroup));
+ if (!new_cgroup)
return ret_errno(ENOMEM);
- cgelem = zalloc(sizeof(*cgelem));
- if (!cgelem)
+ new_cgroup->subsystem = strdup(subkey);
+ if (!new_cgroup->subsystem)
return ret_errno(ENOMEM);
- cgelem->subsystem = strdup(subkey);
- if (!cgelem->subsystem)
+ new_cgroup->value = strdup(value);
+ if (!new_cgroup->value)
return ret_errno(ENOMEM);
- cgelem->value = strdup(value);
- if (!cgelem->value)
- return ret_errno(ENOMEM);
-
- cgelem->version = version;
-
- lxc_list_add_elem(cglist, move_ptr(cgelem));
+ new_cgroup->version = version;
if (version == CGROUP2_SUPER_MAGIC)
- lxc_list_add_tail(&lxc_conf->cgroup2, cglist);
+ list_add_tail(&new_cgroup->head, &lxc_conf->cgroup2);
else
- lxc_list_add_tail(&lxc_conf->cgroup, cglist);
- move_ptr(cglist);
+ list_add_tail(&new_cgroup->head, &lxc_conf->cgroup);
+ move_ptr(new_cgroup);
return 0;
}
int inlen, struct lxc_conf *c,
int version)
{
+ int fulllen = 0;
+ bool get_all = false;
int len;
size_t namespaced_token_len;
char *global_token, *namespaced_token;
- struct lxc_list *it;
- int fulllen = 0;
- bool get_all = false;
+ struct list_head *list;
+ struct lxc_cgroup *cgroup;
if (!retv)
inlen = 0;
global_token = "lxc.cgroup2";
namespaced_token = "lxc.cgroup2.";
namespaced_token_len = STRLITERALLEN("lxc.cgroup2.");
+ list = &c->cgroup2;
} else if (version == CGROUP_SUPER_MAGIC) {
global_token = "lxc.cgroup";
namespaced_token = "lxc.cgroup.";
namespaced_token_len = STRLITERALLEN("lxc.cgroup.");
+ list = &c->cgroup;
} else {
return ret_errno(EINVAL);
}
else
return ret_errno(EINVAL);
- lxc_list_for_each(it, &c->cgroup) {
- struct lxc_cgroup *cg = it->elem;
-
+ list_for_each_entry(cgroup, list, head) {
if (get_all) {
- if (version != cg->version)
+ if (version != cgroup->version)
continue;
strprint(retv, inlen, "%s.%s = %s\n", global_token,
- cg->subsystem, cg->value);
- } else if (strequal(cg->subsystem, key)) {
- strprint(retv, inlen, "%s\n", cg->value);
+ cgroup->subsystem, cgroup->value);
+ } else if (strequal(cgroup->subsystem, key)) {
+ strprint(retv, inlen, "%s\n", cgroup->value);
}
}