]> git.proxmox.com Git - mirror_lxc.git/commitdiff
conf: port cgroup settings to new list type
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 25 Aug 2021 17:20:57 +0000 (19:20 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 26 Aug 2021 07:47:47 +0000 (09:47 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/cgroups/cgfsng.c
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c

index 54b298910c1c16e3e81447f91fed3cac4457ef62..23aef495c4f649bf3c788ebad2d430a99b23a8ab 100644 (file)
@@ -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");
index d048874ef60828b76e8d3a899f6b7e969a025dfb..f0c6c74be364546b680644ef00915531b1e50acb 100644 (file)
@@ -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;
 }
index 00b4a58499d50cafdbb410ad4d57c8b13d58d501..e8d776cdcc14e77ef4ab850b85d7137227a6feae 100644 (file)
@@ -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);
index 97b822b1abe271d589e45095a3d1532c142e7894..513b917d986f10d21ef4c5aa020d3b515d4b56a5 100644 (file)
@@ -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);
                }
        }