From: Christian Brauner Date: Wed, 25 Aug 2021 17:20:57 +0000 (+0200) Subject: conf: port cgroup settings to new list type X-Git-Tag: lxc-5.0.0~102^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9dbb8edf972182c8b046ea6161d5e48e914cd01;p=thirdparty%2Flxc.git conf: port cgroup settings to new list type Signed-off-by: Christian Brauner --- diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 54b298910..23aef495c 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -2707,11 +2707,8 @@ __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, 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); @@ -2720,7 +2717,7 @@ __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, 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) @@ -2729,35 +2726,23 @@ __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, 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; } /* @@ -2793,9 +2778,10 @@ static int bpf_device_cgroup_prepare(struct cgroup_ops *ops, __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); @@ -2811,7 +2797,7 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops, 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)) @@ -2821,18 +2807,17 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *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"); diff --git a/src/lxc/conf.c b/src/lxc/conf.c index d048874ef..f0c6c74be 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -3379,8 +3379,8 @@ struct lxc_conf *lxc_conf_init(void) 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); @@ -4538,11 +4538,12 @@ int lxc_clear_namespace(struct lxc_conf *c) 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"; @@ -4565,21 +4566,18 @@ int lxc_clear_cgroups(struct lxc_conf *c, const char *key, int version) 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; } @@ -5817,54 +5815,25 @@ void suggest_default_idmap(void) 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; } diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 00b4a5849..e8d776cdc 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -78,6 +78,8 @@ struct lxc_cgroup { bool relative; }; }; + + struct list_head head; }; static void free_lxc_cgroup(struct lxc_cgroup *ptr) @@ -344,8 +346,8 @@ struct lxc_conf { 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; }; @@ -557,7 +559,7 @@ __hidden extern int parse_mount_attrs(struct lxc_mount_options *opts, const char __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); diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 97b822b1a..513b917d9 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -1858,8 +1858,7 @@ static int set_config_signal_stop(const char *key, const char *value, 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; @@ -1883,31 +1882,25 @@ static int __set_config_cgroup_controller(const char *key, const char *value, 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; } @@ -3842,12 +3835,13 @@ static int __get_config_cgroup_controller(const char *key, char *retv, 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; @@ -3858,10 +3852,12 @@ static int __get_config_cgroup_controller(const char *key, char *retv, 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); } @@ -3873,17 +3869,15 @@ static int __get_config_cgroup_controller(const char *key, char *retv, 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); } }