Skip to content

Commit

Permalink
Merge pull request #1884 from brauner/2017-10-28/move_tools_to_api_only
Browse files Browse the repository at this point in the history
confile: add lxc.namespace.<namespace-key> + add user namespace sharing + rework start logic
  • Loading branch information
hallyn committed Nov 5, 2017
2 parents 190f9ae + 686dd5d commit 2ed797d
Show file tree
Hide file tree
Showing 14 changed files with 338 additions and 212 deletions.
2 changes: 1 addition & 1 deletion src/lxc/commands.c
Expand Up @@ -835,7 +835,7 @@ static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,

memset(&rsp, 0, sizeof(rsp));

rsp.data = handler->name;
rsp.data = (char *)handler->name;
rsp.datalen = strlen(handler->name) + 1;
rsp.ret = 0;

Expand Down
23 changes: 13 additions & 10 deletions src/lxc/conf.c
Expand Up @@ -2461,21 +2461,19 @@ struct lxc_conf *lxc_conf_init(void)
lxc_list_init(&new->aliens);
lxc_list_init(&new->environment);
lxc_list_init(&new->limits);
for (i=0; i<NUM_LXC_HOOKS; i++)
for (i = 0; i < NUM_LXC_HOOKS; i++)
lxc_list_init(&new->hooks[i]);
lxc_list_init(&new->groups);
new->lsm_aa_profile = NULL;
new->lsm_se_context = NULL;
new->tmp_umount_proc = 0;

for (i = 0; i < LXC_NS_MAX; i++)
new->inherit_ns_fd[i] = -1;

/* if running in a new user namespace, init and COMMAND
* default to running as UID/GID 0 when using lxc-execute */
new->init_uid = 0;
new->init_gid = 0;
memset(&new->cgroup_meta, 0, sizeof(struct lxc_cgroup));
memset(&new->inherit_ns, 0, sizeof(char *) * LXC_NS_MAX);

return new;
}
Expand Down Expand Up @@ -3155,7 +3153,7 @@ int lxc_setup_child(struct lxc_handler *handler)
return -1;
}

if (lxc_conf->inherit_ns_fd[LXC_NS_UTS] == -1) {
if (handler->nsfd[LXC_NS_UTS] == -1) {
if (setup_utsname(lxc_conf->utsname)) {
ERROR("failed to setup the utsname for '%s'", name);
return -1;
Expand Down Expand Up @@ -3674,7 +3672,7 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data,
struct lxc_list *it;
struct id_map *map;
char c = '1';
int ret = -1;
int ret = -1, status = -1;
struct lxc_list *idmap = NULL, *tmplist = NULL;
struct id_map *container_root_uid = NULL, *container_root_gid = NULL,
*host_uid_map = NULL, *host_gid_map = NULL;
Expand Down Expand Up @@ -3844,10 +3842,11 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data,
goto on_error;
}

on_error:
/* Wait for child to finish. */
ret = wait_for_pid(pid);
if (pid > 0)
status = wait_for_pid(pid);

on_error:
if (idmap)
lxc_free_idmap(idmap);
if (container_root_uid)
Expand All @@ -3863,6 +3862,9 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data,
close(p[0]);
close(p[1]);

if (status < 0)
ret = -1;

return ret;
}

Expand Down Expand Up @@ -4026,10 +4028,11 @@ int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data,
goto on_error;
}

on_error:
/* Wait for child to finish. */
ret = wait_for_pid(pid);
if (pid > 0)
ret = wait_for_pid(pid);

on_error:
if (idmap)
lxc_free_idmap(idmap);
if (host_uid_map && (host_uid_map != container_root_uid))
Expand Down
4 changes: 2 additions & 2 deletions src/lxc/conf.h
Expand Up @@ -285,8 +285,6 @@ struct lxc_conf {
int loglevel; /* loglevel as specifed in config (if any) */
int logfd;

int inherit_ns_fd[LXC_NS_MAX];

unsigned int start_auto;
unsigned int start_delay;
int start_order;
Expand Down Expand Up @@ -348,6 +346,8 @@ struct lxc_conf {
* that union.
*/
struct lxc_cgroup cgroup_meta;

char *inherit_ns[LXC_NS_MAX];
};

#ifdef HAVE_TLS
Expand Down
58 changes: 58 additions & 0 deletions src/lxc/confile.c
Expand Up @@ -102,6 +102,7 @@ lxc_config_define(monitor);
lxc_config_define(mount);
lxc_config_define(mount_auto);
lxc_config_define(mount_fstab);
lxc_config_define(namespace);
lxc_config_define(net);
lxc_config_define(net_flags);
lxc_config_define(net_hwaddr);
Expand Down Expand Up @@ -178,6 +179,7 @@ static struct lxc_config_t config[] = {
{ "lxc.mount.auto", false, set_config_mount_auto, get_config_mount_auto, clr_config_mount_auto, },
{ "lxc.mount.entry", false, set_config_mount, get_config_mount, clr_config_mount, },
{ "lxc.mount.fstab", false, set_config_mount_fstab, get_config_mount_fstab, clr_config_mount_fstab, },
{ "lxc.namespace", false, set_config_namespace, get_config_namespace, clr_config_namespace, },

/* [START]: REMOVE IN LXC 3.0 */
{ "lxc.network.type", true, set_config_network_legacy_type, get_config_network_legacy_item, clr_config_network_legacy_item, },
Expand Down Expand Up @@ -1976,6 +1978,23 @@ static int set_config_uts_name(const char *key, const char *value,
return 0;
}

static int set_config_namespace(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
int ns_idx;
const char *namespace;

if (lxc_config_value_empty(value))
return clr_config_namespace(key, lxc_conf, data);

namespace = key + sizeof("lxc.namespace.") - 1;
ns_idx = lxc_namespace_2_ns_idx(namespace);
if (ns_idx < 0)
return ns_idx;

return set_config_string_item(&lxc_conf->inherit_ns[ns_idx], value);
}

struct parse_line_conf {
struct lxc_conf *conf;
bool from_include;
Expand Down Expand Up @@ -3268,6 +3287,28 @@ static int get_config_noop(const char *key, char *retv, int inlen,
return 0;
}

static int get_config_namespace(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
int len, ns_idx;
const char *namespace;
int fulllen = 0;

if (!retv)
inlen = 0;
else
memset(retv, 0, inlen);

namespace = key + sizeof("lxc.namespace.") - 1;
ns_idx = lxc_namespace_2_ns_idx(namespace);
if (ns_idx < 0)
return ns_idx;

strprint(retv, inlen, "%s", c->inherit_ns[ns_idx]);

return fulllen;
}

/* Callbacks to clear config items. */
static inline int clr_config_personality(const char *key, struct lxc_conf *c,
void *data)
Expand Down Expand Up @@ -3606,6 +3647,23 @@ static inline int clr_config_noop(const char *key, struct lxc_conf *c,
return 0;
}

static int clr_config_namespace(const char *key, struct lxc_conf *lxc_conf,
void *data)
{
int ns_idx;
const char *namespace;

namespace = key + sizeof("lxc.namespace.") - 1;
ns_idx = lxc_namespace_2_ns_idx(namespace);
if (ns_idx < 0)
return ns_idx;

free(lxc_conf->inherit_ns[ns_idx]);
lxc_conf->inherit_ns[ns_idx] = NULL;

return 0;
}

static int get_config_includefiles(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
Expand Down
77 changes: 76 additions & 1 deletion src/lxc/confile_utils.c
Expand Up @@ -29,8 +29,9 @@
#include "confile.h"
#include "confile_utils.h"
#include "error.h"
#include "log.h"
#include "list.h"
#include "log.h"
#include "lxccontainer.h"
#include "network.h"
#include "parse.h"
#include "utils.h"
Expand Down Expand Up @@ -700,3 +701,77 @@ bool parse_limit_value(const char **value, rlim_t *res)

return true;
}

static int lxc_container_name_to_pid(const char *lxcname_or_pid,
const char *lxcpath)
{
int ret;
signed long int pid;
char *err = NULL;

pid = strtol(lxcname_or_pid, &err, 10);
if (*err != '\0' || pid < 1) {
struct lxc_container *c;

c = lxc_container_new(lxcname_or_pid, lxcpath);
if (!c) {
ERROR("\"%s\" is not a valid pid nor a container name",
lxcname_or_pid);
return -1;
}

if (!c->may_control(c)) {
ERROR("Insufficient privileges to control container "
"\"%s\"", c->name);
lxc_container_put(c);
return -1;
}

pid = c->init_pid(c);
if (pid < 1) {
ERROR("Container \"%s\" is not running", c->name);
lxc_container_put(c);
return -1;
}

lxc_container_put(c);
}

ret = kill(pid, 0);
if (ret < 0) {
ERROR("%s - Failed to send signal to pid %d", strerror(errno),
(int)pid);
return -EPERM;
}

return pid;
}

int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
const char *namespace)
{
int fd, pid;
char *dup, *lastslash;

lastslash = strrchr(lxcname_or_pid, '/');
if (lastslash) {
dup = strdup(lxcname_or_pid);
if (!dup)
return -ENOMEM;

*lastslash = '\0';
pid = lxc_container_name_to_pid(lastslash, dup);
free(dup);
} else {
pid = lxc_container_name_to_pid(lxcname_or_pid, lxcpath);
}

if (pid < 0)
return -EINVAL;

fd = lxc_preserve_ns(pid, namespace);
if (fd < 0)
return -EINVAL;

return fd;
}
2 changes: 2 additions & 0 deletions src/lxc/confile_utils.h
Expand Up @@ -86,5 +86,7 @@ extern int lxc_get_conf_str(char *retv, int inlen, const char *value);
extern int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v);
extern int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64_t v);
extern bool parse_limit_value(const char **value, rlim_t *res);
extern int lxc_inherit_namespace(const char *lxcname_or_pid,
const char *lxcpath, const char *namespace);

#endif /* __LXC_CONFILE_UTILS_H */
4 changes: 2 additions & 2 deletions src/lxc/monitor.c
Expand Up @@ -105,10 +105,10 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
/* It is normal for this open() to fail with ENXIO when there is
* no monitor running, so we don't log it.
*/
if (errno == ENXIO)
if (errno == ENXIO || errno == ENOENT)
return;

WARN("Failed to open fifo to send message: %s.", strerror(errno));
WARN("%s - Failed to open fifo to send message", strerror(errno));
return;
}

Expand Down
17 changes: 14 additions & 3 deletions src/lxc/namespace.c
Expand Up @@ -96,15 +96,26 @@ const struct ns_info ns_info[LXC_NS_MAX] = {
[LXC_NS_CGROUP] = {"cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP"}
};

int lxc_namespace_2_cloneflag(char *namespace)
int lxc_namespace_2_cloneflag(const char *namespace)
{
int i;
for (i = 0; i < LXC_NS_MAX; i++)
if (!strcasecmp(ns_info[i].proc_name, namespace))
return ns_info[i].clone_flag;

ERROR("Invalid namespace name: %s.", namespace);
return -1;
ERROR("Invalid namespace name \"%s\"", namespace);
return -EINVAL;
}

int lxc_namespace_2_ns_idx(const char *namespace)
{
int i;
for (i = 0; i < LXC_NS_MAX; i++)
if (!strcmp(ns_info[i].proc_name, namespace))
return i;

ERROR("Invalid namespace name \"%s\"", namespace);
return -EINVAL;
}

int lxc_fill_namespace_flags(char *flaglist, int *flags)
Expand Down
3 changes: 2 additions & 1 deletion src/lxc/namespace.h
Expand Up @@ -81,7 +81,8 @@ int clone(int (*fn)(void *), void *child_stack,

extern pid_t lxc_clone(int (*fn)(void *), void *arg, int flags);

extern int lxc_namespace_2_cloneflag(char *namespace);
extern int lxc_namespace_2_cloneflag(const char *namespace);
extern int lxc_namespace_2_ns_idx(const char *namespace);
extern int lxc_fill_namespace_flags(char *flaglist, int *flags);

#endif

0 comments on commit 2ed797d

Please sign in to comment.