conf: port environment to new list type

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner 2021-08-26 14:11:48 +02:00
parent 0ef1dbb17b
commit c294a68d13
No known key found for this signature in database
GPG Key ID: 8EB056D53EECB12D
5 changed files with 73 additions and 61 deletions

View File

@ -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. */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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) {