mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-13 20:03:19 +00:00
conf: port cgroup settings to new list type
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
parent
91d04bf9db
commit
c9dbb8edf9
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user