From c294a68d1364c874521404fdcf82c53a6ab9e8db Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 26 Aug 2021 14:11:48 +0200 Subject: [PATCH] conf: port environment to new list type Signed-off-by: Christian Brauner --- src/lxc/attach.c | 15 +++------------ src/lxc/conf.c | 32 +++++++++++++++++++++++++------- src/lxc/conf.h | 10 +++++++++- src/lxc/confile.c | 45 +++++++++++++++++++++++++-------------------- src/lxc/start.c | 32 +++++++++++--------------------- 5 files changed, 73 insertions(+), 61 deletions(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c index 396001963..5668fd035 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -782,7 +782,6 @@ static int lxc_attach_set_environment(struct attach_context *ctx, char **extra_env, char **extra_keep) { int ret; - struct lxc_list *iterator; if (policy == LXC_ATTACH_CLEAR_ENV) { int path_kept = 0; @@ -863,17 +862,9 @@ static int lxc_attach_set_environment(struct attach_context *ctx, /* Set container environment variables.*/ if (ctx->container->lxc_conf) { - lxc_list_for_each(iterator, &ctx->container->lxc_conf->environment) { - char *env_tmp; - - env_tmp = strdup((char *)iterator->elem); - if (!env_tmp) - return -1; - - ret = putenv(env_tmp); - if (ret < 0) - return log_error_errno(-1, errno, "Failed to set environment variable: %s", (char *)iterator->elem); - } + ret = lxc_set_environment(ctx->container->lxc_conf); + if (ret < 0) + return -1; } /* Set extra environment variables. */ diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 8070a32b1..fa1777699 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -3390,7 +3390,7 @@ struct lxc_conf *lxc_conf_init(void) INIT_LIST_HEAD(&new->id_map); new->root_nsuid_map = NULL; new->root_nsgid_map = NULL; - lxc_list_init(&new->environment); + INIT_LIST_HEAD(&new->environment); INIT_LIST_HEAD(&new->limits); INIT_LIST_HEAD(&new->sysctls); INIT_LIST_HEAD(&new->procs); @@ -4677,15 +4677,16 @@ int lxc_clear_groups(struct lxc_conf *c) int lxc_clear_environment(struct lxc_conf *c) { - struct lxc_list *it, *next; + struct environment_entry *env, *nenv; - lxc_list_for_each_safe (it, &c->environment, next) { - lxc_list_del(it); - free(it->elem); - free(it); + list_for_each_entry_safe(env, nenv, &c->environment, head) { + list_del(&env->head); + free(env->key); + free(env->val); + free(env); } - lxc_list_init(&c->environment); + INIT_LIST_HEAD(&c->environment); return 0; } @@ -5726,3 +5727,20 @@ void sort_cgroup_settings(struct lxc_conf *conf) } } } + +int lxc_set_environment(const struct lxc_conf *conf) +{ + struct environment_entry *env; + + list_for_each_entry(env, &conf->environment, head) { + int ret; + + ret = setenv(env->key, env->val, 1); + if (ret < 0) + return syserror("Failed to set environment variable: %s=%s", + env->key, env->val); + TRACE("Set environment variable: %s=%s", env->key, env->val); + } + + return 0; +} diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 1449774e4..0ec423458 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -337,6 +337,12 @@ struct timens_offsets { int64_t ns_monotonic; }; +struct environment_entry { + char *key; + char *val; + struct list_head head; +}; + struct lxc_conf { /* Pointer to the name of the container. Do not free! */ const char *name; @@ -438,7 +444,7 @@ struct lxc_conf { /* list of environment variables we'll add to the container when * started */ - struct lxc_list environment; + struct list_head environment; /* text representation of the config file */ char *unexpanded_config; @@ -643,4 +649,6 @@ static inline int lxc_personality(personality_t persona) return personality(persona); } +__hidden extern int lxc_set_environment(const struct lxc_conf *conf); + #endif /* __LXC_CONF_H */ diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 6c05838a2..e9c241f56 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -1539,35 +1539,40 @@ static int set_config_group(const char *key, const char *value, static int set_config_environment(const char *key, const char *value, struct lxc_conf *lxc_conf, void *data) { - __do_free struct lxc_list *list_item = NULL; + __do_free char *dup = NULL, *val = NULL; + __do_free struct environment_entry *new_env = NULL; + char *env_val; if (lxc_config_value_empty(value)) return lxc_clear_environment(lxc_conf); - list_item = lxc_list_new(); - if (!list_item) + new_env = zalloc(sizeof(struct environment_entry)); + if (!new_env) return ret_errno(ENOMEM); - if (!strchr(value, '=')) { - const char *env_val; - const char *env_key = value; - const char *env_var[3] = {0}; + dup = strdup(value); + if (!dup) + return ret_errno(ENOMEM); - env_val = getenv(env_key); - if (!env_val) - return ret_errno(ENOENT); - - env_var[0] = env_key; - env_var[1] = env_val; - list_item->elem = lxc_string_join("=", env_var, false); + env_val = strchr(dup, '='); + if (!env_val) { + env_val = getenv(dup); } else { - list_item->elem = strdup(value); + *env_val = '\0'; + env_val++; } + if (!env_val) + return ret_errno(ENOENT); - if (!list_item->elem) + val = strdup(env_val); + if (!val) return ret_errno(ENOMEM); - lxc_list_add_tail(&lxc_conf->environment, move_ptr(list_item)); + new_env->key = move_ptr(dup); + new_env->val = move_ptr(val); + + list_add_tail(&new_env->head, &lxc_conf->environment); + move_ptr(new_env); return 0; } @@ -4442,15 +4447,15 @@ static int get_config_environment(const char *key, char *retv, int inlen, struct lxc_conf *c, void *data) { int len, fulllen = 0; - struct lxc_list *it; + struct environment_entry *env; if (!retv) inlen = 0; else memset(retv, 0, inlen); - lxc_list_for_each(it, &c->environment) { - strprint(retv, inlen, "%s\n", (char *)it->elem); + list_for_each_entry(env, &c->environment, head) { + strprint(retv, inlen, "%s=%s\n", env->key, env->val); } return fulllen; diff --git a/src/lxc/start.c b/src/lxc/start.c index 7041a913c..7f0903f1b 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -1052,12 +1052,11 @@ static int do_start(void *data) { struct lxc_handler *handler = data; __lxc_unused __do_close int data_sock0 = handler->data_sock[0], - data_sock1 = handler->data_sock[1]; + data_sock1 = handler->data_sock[1]; __do_close int devnull_fd = -EBADF, status_fd = -EBADF; int ret; uid_t new_uid; gid_t new_gid; - struct lxc_list *iterator; uid_t nsuid = 0; gid_t nsgid = 0; @@ -1257,18 +1256,14 @@ static int do_start(void *data) } } - /* Add the requested environment variables to the current environment to - * allow them to be used by the various hooks, such as the start hook - * below. + /* + * Add the requested environment variables to the current environment + * to allow them to be used by the various hooks, such as the start + * hook below. */ - lxc_list_for_each(iterator, &handler->conf->environment) { - ret = putenv((char *)iterator->elem); - if (ret < 0) { - SYSERROR("Failed to set environment variable: %s", - (char *)iterator->elem); - goto out_warn_father; - } - } + ret = lxc_set_environment(handler->conf); + if (ret < 0) + goto out_warn_father; if (!lxc_sync_wait_parent(handler, START_SYNC_POST_CONFIGURE)) goto out_warn_father; @@ -1361,14 +1356,9 @@ static int do_start(void *data) if (ret < 0) SYSERROR("Failed to clear environment."); - lxc_list_for_each(iterator, &handler->conf->environment) { - ret = putenv((char *)iterator->elem); - if (ret < 0) { - SYSERROR("Failed to set environment variable: %s", - (char *)iterator->elem); - goto out_warn_father; - } - } + ret = lxc_set_environment(handler->conf); + if (ret < 0) + goto out_warn_father; ret = putenv("container=lxc"); if (ret < 0) {