conf: port sysctls to new list type

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner 2021-08-25 18:47:51 +02:00
parent 223797c313
commit ba9f93472d
No known key found for this signature in database
GPG Key ID: 8EB056D53EECB12D
3 changed files with 40 additions and 51 deletions

View File

@ -3276,29 +3276,30 @@ int setup_resource_limits(struct lxc_conf *conf, pid_t pid)
return 0;
}
int setup_sysctl_parameters(struct lxc_list *sysctls)
int setup_sysctl_parameters(struct lxc_conf *conf)
{
__do_free char *tmp = NULL;
struct lxc_list *it;
struct lxc_sysctl *elem;
int ret = 0;
char filename[PATH_MAX] = {0};
struct lxc_sysctl *sysctl, *nsysctl;
lxc_list_for_each (it, sysctls) {
elem = it->elem;
tmp = lxc_string_replace(".", "/", elem->key);
if (!list_empty(&conf->sysctls))
return 0;
list_for_each_entry_safe(sysctl, nsysctl, &conf->sysctls, head) {
tmp = lxc_string_replace(".", "/", sysctl->key);
if (!tmp)
return log_error(-1, "Failed to replace key %s", elem->key);
return log_error(-1, "Failed to replace key %s", sysctl->key);
ret = strnprintf(filename, sizeof(filename), "/proc/sys/%s", tmp);
if (ret < 0)
return log_error(-1, "Error setting up sysctl parameters path");
ret = lxc_write_to_file(filename, elem->value,
strlen(elem->value), false, 0666);
ret = lxc_write_to_file(filename, sysctl->value,
strlen(sysctl->value), false, 0666);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to setup sysctl parameters %s to %s",
elem->key, elem->value);
sysctl->key, sysctl->value);
}
return 0;
@ -3390,7 +3391,7 @@ struct lxc_conf *lxc_conf_init(void)
lxc_list_init(&new->aliens);
lxc_list_init(&new->environment);
INIT_LIST_HEAD(&new->limits);
lxc_list_init(&new->sysctls);
INIT_LIST_HEAD(&new->sysctls);
lxc_list_init(&new->procs);
new->hooks_version = 0;
for (i = 0; i < NUM_LXC_HOOKS; i++)
@ -4422,11 +4423,9 @@ int lxc_setup(struct lxc_handler *handler)
* key. For e.g. net.ipv4.ip_forward translated to
* /proc/sys/net/ipv4/ip_forward.
*/
if (!lxc_list_empty(&lxc_conf->sysctls)) {
ret = setup_sysctl_parameters(&lxc_conf->sysctls);
if (ret < 0)
return log_error(-1, "Failed to setup sysctl parameters");
}
ret = setup_sysctl_parameters(lxc_conf);
if (ret < 0)
return log_error(-1, "Failed to setup sysctl parameters");
if (!lxc_list_empty(&lxc_conf->keepcaps)) {
if (!lxc_list_empty(&lxc_conf->caps))
@ -4619,9 +4618,9 @@ int lxc_clear_limits(struct lxc_conf *c, const char *key)
int lxc_clear_sysctls(struct lxc_conf *c, const char *key)
{
struct lxc_list *it, *next;
const char *k = NULL;
bool all = false;
struct lxc_sysctl *sysctl, *nsysctl;
if (strequal(key, "lxc.sysctl"))
all = true;
@ -4630,21 +4629,18 @@ int lxc_clear_sysctls(struct lxc_conf *c, const char *key)
else
return -1;
lxc_list_for_each_safe(it, &c->sysctls, next) {
struct lxc_sysctl *elem = it->elem;
if (!all && !strequal(elem->key, k))
list_for_each_entry_safe(sysctl, nsysctl, &c->sysctls, head) {
if (!all && !strequal(sysctl->key, k))
continue;
lxc_list_del(it);
free(elem->key);
free(elem->value);
free(elem);
free(it);
list_del(&sysctl->head);
free(sysctl->key);
free(sysctl->value);
free(sysctl);
}
if (all)
lxc_list_init(&c->sysctls);
INIT_LIST_HEAD(&c->sysctls);
return 0;
}

View File

@ -132,6 +132,7 @@ enum idtype {
struct lxc_sysctl {
char *key;
char *value;
struct list_head head;
};
static void free_lxc_sysctl(struct lxc_sysctl *ptr)
@ -492,7 +493,7 @@ struct lxc_conf {
struct list_head state_clients;
/* sysctls */
struct lxc_list sysctls;
struct list_head sysctls;
/* procs */
struct lxc_list procs;
@ -572,7 +573,7 @@ static inline bool lxc_wants_cap(int cap, struct lxc_conf *conf)
return !in_caplist(cap, &conf->caps);
}
__hidden extern int setup_sysctl_parameters(struct lxc_list *sysctls);
__hidden extern int setup_sysctl_parameters(struct lxc_conf *conf);
__hidden extern int lxc_clear_sysctls(struct lxc_conf *c, const char *key);
__hidden extern int setup_proc_filesystem(struct lxc_list *procs, pid_t pid);
__hidden extern int lxc_clear_procs(struct lxc_conf *c, const char *key);

View File

@ -2132,9 +2132,8 @@ static int set_config_prlimit(const char *key, const char *value,
static int set_config_sysctl(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
__do_free struct lxc_list *sysctl_list = NULL;
call_cleaner(free_lxc_sysctl) struct lxc_sysctl *sysctl_elem = NULL;
struct lxc_list *iter;
struct lxc_sysctl *sysctl, *nsysctl;
if (lxc_config_value_empty(value))
return clr_config_sysctl(key, lxc_conf, NULL);
@ -2147,28 +2146,22 @@ static int set_config_sysctl(const char *key, const char *value,
return ret_errno(EINVAL);
/* find existing list element */
lxc_list_for_each(iter, &lxc_conf->sysctls) {
list_for_each_entry_safe(sysctl, nsysctl, &lxc_conf->sysctls, head) {
__do_free char *replace_value = NULL;
struct lxc_sysctl *cur = iter->elem;
if (!strequal(key, cur->key))
if (!strequal(key, sysctl->key))
continue;
replace_value = strdup(value);
if (!replace_value)
return ret_errno(EINVAL);
free(cur->value);
cur->value = move_ptr(replace_value);
free(sysctl->value);
sysctl->value = move_ptr(replace_value);
return 0;
}
/* allocate list element */
sysctl_list = lxc_list_new();
if (!sysctl_list)
return ret_errno(ENOMEM);
sysctl_elem = zalloc(sizeof(*sysctl_elem));
if (!sysctl_elem)
return ret_errno(ENOMEM);
@ -2181,8 +2174,8 @@ static int set_config_sysctl(const char *key, const char *value,
if (!sysctl_elem->value)
return ret_errno(ENOMEM);
lxc_list_add_elem(sysctl_list, move_ptr(sysctl_elem));
lxc_list_add_tail(&lxc_conf->sysctls, move_ptr(sysctl_list));
list_add_tail(&sysctl_elem->head, &lxc_conf->sysctls);
move_ptr(sysctl_elem);
return 0;
}
@ -4607,10 +4600,10 @@ static int get_config_prlimit(const char *key, char *retv, int inlen,
static int get_config_sysctl(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
int len;
struct lxc_list *it;
int fulllen = 0;
bool get_all = false;
int len;
struct lxc_sysctl *sysctl;
if (!retv)
inlen = 0;
@ -4624,13 +4617,12 @@ static int get_config_sysctl(const char *key, char *retv, int inlen,
else
return ret_errno(EINVAL);
lxc_list_for_each(it, &c->sysctls) {
struct lxc_sysctl *elem = it->elem;
list_for_each_entry(sysctl, &c->sysctls, head) {
if (get_all) {
strprint(retv, inlen, "lxc.sysctl.%s = %s\n", elem->key,
elem->value);
} else if (strequal(elem->key, key)) {
strprint(retv, inlen, "%s", elem->value);
strprint(retv, inlen, "lxc.sysctl.%s = %s\n", sysctl->key,
sysctl->value);
} else if (strequal(sysctl->key, key)) {
strprint(retv, inlen, "%s", sysctl->value);
}
}