This commit also gets rid of ~10 unnecessarily file descriptors that were kept
open. Before we kept open:
- A set of file descriptors that refer to the monitor's namespaces. These were
only used to reattach to the monitor's namespace in lxc_spawn() and were
never used anywhere else. So close them and don't keep them around.
- A list of inherited file descriptors.
- A list of file descriptors referring to the containers's namespaces to pass
to lxc.hook.stop. This list duplicated inherited file descriptors.
Let's simply use a single list in the handler that has all file descriptors we
need and get rid of all other ones. As an illustration. Starting a container
1. Without this patch and looking at the fds that the monitor keeps open (26):
chb@conventiont|~
> ls -al /proc/27219/fd
total 0
dr-x------ 2 root root 0 Oct 29 14:30 .
dr-xr-xr-x 9 root root 0 Oct 29 14:30 ..
lrwx------ 1 root root 64 Oct 29 14:30 0 -> /dev/null
lrwx------ 1 root root 64 Oct 29 14:30 1 -> /dev/null
lrwx------ 1 root root 64 Oct 29 14:30 10 -> anon_inode:[signalfd]
lrwx------ 1 root root 64 Oct 29 14:30 11 -> /dev/ptmx
lrwx------ 1 root root 64 Oct 29 14:30 12 -> /dev/pts/10
lr-x------ 1 root root 64 Oct 29 14:30 13 -> net:[
4026532553]
lrwx------ 1 root root 64 Oct 29 14:30 15 -> socket:[
7909181]
lrwx------ 1 root root 64 Oct 29 14:30 16 -> socket:[
7909182]
lr-x------ 1 root root 64 Oct 29 14:30 17 -> uts:[
4026531838]
lr-x------ 1 root root 64 Oct 29 14:30 18 -> ipc:[
4026531839]
lr-x------ 1 root root 64 Oct 29 14:30 19 -> net:[
4026532009]
lrwx------ 1 root root 64 Oct 29 14:30 2 -> /dev/null
lr-x------ 1 root root 64 Oct 29 14:30 20 -> mnt:[
4026532611]
lr-x------ 1 root root 64 Oct 29 14:30 21 -> pid:[
4026532612]
lr-x------ 1 root root 64 Oct 29 14:30 22 -> uts:[
4026532548]
lr-x------ 1 root root 64 Oct 29 14:30 23 -> ipc:[
4026532549]
lr-x------ 1 root root 64 Oct 29 14:30 24 -> net:[
4026532553]
l-wx------ 1 root root 64 Oct 29 14:30 3 -> /var/log/lxc/a1.log
lr-x------ 1 root root 64 Oct 29 14:30 4 -> uts:[
4026532548]
lr-x------ 1 root root 64 Oct 29 14:30 5 -> ipc:[
4026532549]
lr-x------ 1 root root 64 Oct 29 14:30 6 -> net:[
4026532553]
lrwx------ 1 root root 64 Oct 29 14:30 7 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Oct 29 14:30 9 -> socket:[
7911594]
2. With this patch and looking at the fds that the monitor keeps open (19):
chb@conventiont|~
> ls -al /proc/28465/fd
total 0
dr-x------ 2 root root 0 Oct 29 14:31 .
dr-xr-xr-x 9 root root 0 Oct 29 14:31 ..
lrwx------ 1 root root 64 Oct 29 14:31 0 -> /dev/null
lrwx------ 1 root root 64 Oct 29 14:31 1 -> /dev/null
lr-x------ 1 root root 64 Oct 29 14:31 10 -> net:[
4026532820]
lrwx------ 1 root root 64 Oct 29 14:31 12 -> socket:[
7912349]
lrwx------ 1 root root 64 Oct 29 14:31 13 -> socket:[
7912350]
lr-x------ 1 root root 64 Oct 29 14:31 14 -> mnt:[
4026532611]
lr-x------ 1 root root 64 Oct 29 14:31 15 -> pid:[
4026532813]
lr-x------ 1 root root 64 Oct 29 14:31 16 -> uts:[
4026532612]
lr-x------ 1 root root 64 Oct 29 14:31 17 -> ipc:[
4026532613]
lr-x------ 1 root root 64 Oct 29 14:31 18 -> net:[
4026532820]
lrwx------ 1 root root 64 Oct 29 14:31 2 -> /dev/null
l-wx------ 1 root root 64 Oct 29 14:31 3 -> /var/log/lxc/a1.log
lrwx------ 1 root root 64 Oct 29 14:31 4 -> anon_inode:[signalfd]
lrwx------ 1 root root 64 Oct 29 14:31 5 -> /dev/ptmx
lrwx------ 1 root root 64 Oct 29 14:31 6 -> /dev/pts/10
lrwx------ 1 root root 64 Oct 29 14:31 7 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Oct 29 14:31 9 -> socket:[
7913041]
Relates to #1881.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
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;
}
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;
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;
* that union.
*/
struct lxc_cgroup cgroup_meta;
+
+ char *inherit_ns[LXC_NS_MAX];
};
#ifdef HAVE_TLS
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);
{ "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, },
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;
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)
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)
{
#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"
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;
+}
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 */
[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)
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
*netns_path = '\0';
- if (handler->netnsfd < 0) {
+ if (handler->nsfd[LXC_NS_NET] < 0) {
DEBUG("Cannot not guarantee safe deletion of network devices. "
"Manual cleanup maybe needed");
return false;
}
ret = snprintf(netns_path, sizeof(netns_path), "/proc/%d/fd/%d",
- getpid(), handler->netnsfd);
+ getpid(), handler->nsfd[LXC_NS_NET]);
if (ret < 0 || ret >= sizeof(netns_path))
return false;
int oldfd;
char ifname[IFNAMSIZ];
struct lxc_list *iterator;
- int netnsfd = handler->netnsfd;
+ int netnsfd = handler->nsfd[LXC_NS_NET];
struct lxc_conf *conf = handler->conf;
/* We need CAP_NET_ADMIN in the parent namespace in order to setns() to
for (i = 0; i < LXC_NS_MAX; i++) {
if ((clone_flags & ns_info[i].clone_flag) == 0)
continue;
+
ns_fd[i] = lxc_preserve_ns(pid, ns_info[i].proc_name);
if (ns_fd[i] < 0)
goto error;
(i < len_fds && fd == fds_to_ignore[i]))
continue;
- if (conf) {
- for (i = 0; i < LXC_NS_MAX; i++)
- if (conf->inherit_ns_fd[i] == fd)
- break;
-
- if (i < LXC_NS_MAX)
- continue;
- }
-
if (current_config && fd == current_config->logfd)
continue;
if (closeall) {
close(fd);
closedir(dir);
- INFO("Closed inherited fd: %d.", fd);
+ INFO("Closed inherited fd %d", fd);
goto restart;
}
- WARN("Inherited fd: %d.", fd);
+ WARN("Inherited fd %d", fd);
}
/* Only enable syslog at this point to avoid the above logging function
while (namespace_count--)
free(namespaces[namespace_count]);
+
for (i = 0; i < LXC_NS_MAX; i++) {
- if (handler->nsfd[i] != -1) {
- close(handler->nsfd[i]);
- handler->nsfd[i] = -1;
- }
- }
+ if (handler->nsfd[i] < 0)
+ continue;
- if (handler->netnsfd >= 0) {
- close(handler->netnsfd);
- handler->netnsfd = -1;
+ close(handler->nsfd[i]);
+ handler->nsfd[i] = -1;
}
cgroup_destroy(handler);
if (!lxc_list_empty(&handler->conf->id_map))
handler->clone_flags |= CLONE_NEWUSER;
- if (handler->conf->inherit_ns_fd[LXC_NS_NET] == -1) {
+ if (!handler->conf->inherit_ns[LXC_NS_NET]) {
if (!lxc_requests_empty_network(handler))
handler->clone_flags |= CLONE_NEWNET;
} else {
- INFO("Inheriting a NET namespace.");
+ INFO("Inheriting net namespace");
}
- if (handler->conf->inherit_ns_fd[LXC_NS_IPC] == -1)
+ if (!handler->conf->inherit_ns[LXC_NS_IPC])
handler->clone_flags |= CLONE_NEWIPC;
else
- INFO("Inheriting an IPC namespace.");
+ INFO("Inheriting ipc namespace");
- if (handler->conf->inherit_ns_fd[LXC_NS_UTS] == -1)
+ if (!handler->conf->inherit_ns[LXC_NS_UTS])
handler->clone_flags |= CLONE_NEWUTS;
else
- INFO("Inheriting a UTS namespace.");
+ INFO("Inheriting uts namespace");
- if (handler->conf->inherit_ns_fd[LXC_NS_PID] == -1)
+ if (!handler->conf->inherit_ns[LXC_NS_PID])
handler->clone_flags |= CLONE_NEWPID;
else
- INFO("Inheriting a PID namespace.");
+ INFO("Inheriting pid namespace");
}
/* lxc_spawn() performs crucial setup tasks and clone()s the new process which
struct lxc_list *id_map;
int preserve_mask = 0;
const char *name = handler->name;
+ const char *lxcpath = handler->lxcpath;
bool cgroups_connected = false;
+ struct lxc_conf *conf = handler->conf;
- id_map = &handler->conf->id_map;
+ id_map = &conf->id_map;
wants_to_map_ids = !lxc_list_empty(id_map);
memset(saved_ns_fd, -1, sizeof(int) * LXC_NS_MAX);
- for (i = 0; i < LXC_NS_MAX; i++)
- if (handler->conf->inherit_ns_fd[i] != -1)
- preserve_mask |= ns_info[i].clone_flag;
+ for (i = 0; i < LXC_NS_MAX; i++) {
+ if (!conf->inherit_ns[i])
+ continue;
+
+ preserve_mask |= ns_info[i].clone_flag;
+
+ handler->nsfd[i] = lxc_inherit_namespace(conf->inherit_ns[i], lxcpath, ns_info[i].proc_name);
+ if (handler->nsfd[i] < 0)
+ return -1;
+ }
if (lxc_sync_init(handler))
return -1;
resolve_clone_flags(handler);
if (handler->clone_flags & CLONE_NEWNET) {
- if (!lxc_list_empty(&handler->conf->network)) {
+ if (!lxc_list_empty(&conf->network)) {
/* Find gateway addresses from the link device, which is
* no longer accessible inside the container. Do this
* If the container is unprivileged then skip rootfs pinning.
*/
if (!wants_to_map_ids) {
- handler->pinfd = pin_rootfs(handler->conf->rootfs.path);
+ handler->pinfd = pin_rootfs(conf->rootfs.path);
if (handler->pinfd == -1)
INFO("Failed to pin the rootfs for container \"%s\".", handler->name);
}
if (!preserve_ns(saved_ns_fd, preserve_mask, getpid()))
goto out_delete_net;
+ else
+ TRACE("Preserved inherited namespaces");
- if (attach_ns(handler->conf->inherit_ns_fd) < 0)
- goto out_delete_net;
+ for (i = 0; i < LXC_NS_MAX; i++) {
+ if (handler->nsfd[i] < 0)
+ continue;
+
+ ret = setns(handler->nsfd[i], 0);
+ if (ret < 0)
+ goto out_delete_net;
+ }
/* Create a process in a new set of namespaces. */
flags = handler->clone_flags;
for (i = 0; i < LXC_NS_MAX; i++)
if (flags & ns_info[i].clone_flag)
- INFO("Cloned %s.", ns_info[i].flag_name);
+ INFO("Cloned %s", ns_info[i].flag_name);
- if (!preserve_ns(handler->nsfd, handler->clone_flags | preserve_mask, handler->pid))
- INFO("Failed to preserve namespace for lxc.hook.stop.");
+ if (!preserve_ns(handler->nsfd, handler->clone_flags, handler->pid)) {
+ ERROR("Failed to preserve cloned namespaces for lxc.hook.stop");
+ goto out_delete_net;
+ }
- if (attach_ns(saved_ns_fd))
- WARN("Failed to restore saved namespaces.");
+ if (attach_ns(saved_ns_fd)) {
+ ERROR("Failed to restore saved namespaces");
+ goto out_delete_net;
+ }
lxc_sync_fini_child(handler);
if (!cgroup_chown(handler))
goto out_delete_net;
- handler->netnsfd = lxc_preserve_ns(handler->pid, "net");
- if (handler->netnsfd < 0) {
- ERROR("Failed to preserve network namespace");
- goto out_delete_net;
- }
-
/* Create the network configuration. */
if (handler->clone_flags & CLONE_NEWNET) {
if (lxc_network_move_created_netdev_priv(handler->lxcpath,
handler->name,
- &handler->conf->network,
+ &conf->network,
handler->pid)) {
ERROR("Failed to create the configured network.");
goto out_delete_net;
}
if (lxc_create_network_unpriv(handler->lxcpath, handler->name,
- &handler->conf->network,
+ &conf->network,
handler->pid)) {
ERROR("Failed to create the configured network.");
goto out_delete_net;
if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CONFIGURE))
goto out_delete_net;
- if (!lxc_list_empty(&handler->conf->limits) && setup_resource_limits(&handler->conf->limits, handler->pid)) {
+ if (!lxc_list_empty(&conf->limits) && setup_resource_limits(&conf->limits, handler->pid)) {
ERROR("failed to setup resource limits for '%s'", name);
goto out_delete_net;
}
SYSERROR("Failed to set environment variable: LXC_PID=%s.", pidstr);
/* Run any host-side start hooks */
- if (run_lxc_hooks(name, "start-host", handler->conf, handler->lxcpath, NULL)) {
+ if (run_lxc_hooks(name, "start-host", conf, handler->lxcpath, NULL)) {
ERROR("Failed to run lxc.hook.start-host for container \"%s\".", name);
return -1;
}
* been recorded. The corresponding structs have now all been filled. So
* log them for debugging purposes.
*/
- lxc_log_configured_netdevs(handler->conf);
+ lxc_log_configured_netdevs(conf);
/* Read tty fds allocated by child. */
if (lxc_recv_ttys_from_child(handler) < 0) {
handler->pinfd = -1;
}
- if (handler->netnsfd >= 0) {
- close(handler->netnsfd);
- handler->netnsfd = -1;
- }
-
return -1;
}
handler->ops = ops;
handler->data = data;
handler->backgrounded = backgrounded;
- handler->netnsfd = -1;
if (!attach_block_device(handler->conf)) {
ERROR("Failed to attach block device.");
/* The clone flags that were requested. */
int clone_flags;
- /* File descriptors referring to the network namespace of the container. */
- int netnsfd;
-
/* File descriptor to pin the rootfs for privileged containers. */
int pinfd;
return err;
}
-static int pid_from_lxcname(const char *lxcname_or_pid, const char *lxcpath) {
- char *eptr;
- int pid = strtol(lxcname_or_pid, &eptr, 10);
- if (*eptr != '\0' || pid < 1) {
- struct lxc_container *s;
- s = lxc_container_new(lxcname_or_pid, lxcpath);
- if (!s) {
- SYSERROR("'%s' is not a valid pid nor a container name", lxcname_or_pid);
- return -1;
- }
-
- if (!s->may_control(s)) {
- SYSERROR("Insufficient privileges to control container '%s'", s->name);
- lxc_container_put(s);
- return -1;
- }
-
- pid = s->init_pid(s);
- if (pid < 1) {
- SYSERROR("Is container '%s' running?", s->name);
- lxc_container_put(s);
- return -1;
- }
-
- lxc_container_put(s);
- }
- if (kill(pid, 0) < 0) {
- SYSERROR("Can't send signal to pid %d", pid);
- return -1;
- }
-
- return pid;
-}
-
-static int open_ns(int pid, const char *ns_proc_name) {
- int fd;
- char path[MAXPATHLEN];
- snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns_proc_name);
-
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- SYSERROR("failed to open %s", path);
- return -1;
- }
- return fd;
-}
-
static int my_parser(struct lxc_arguments* args, int c, char* arg)
{
switch (c) {
int main(int argc, char *argv[])
{
- int err = EXIT_FAILURE;
+ int i;
struct lxc_conf *conf;
struct lxc_log log;
+ const char *lxcpath;
char *const *args;
+ struct lxc_container *c;
+ int err = EXIT_FAILURE;
char *rcfile = NULL;
char *const default_args[] = {
"/sbin/init",
NULL,
};
- struct lxc_container *c;
lxc_list_init(&defines);
exit(err);
lxc_log_options_no_override();
- if (access(my_args.lxcpath[0], O_RDONLY) < 0) {
+ lxcpath = my_args.lxcpath[0];
+ if (access(lxcpath, O_RDONLY) < 0) {
if (!my_args.quiet)
- fprintf(stderr, "You lack access to %s\n", my_args.lxcpath[0]);
+ fprintf(stderr, "You lack access to %s\n", lxcpath);
exit(err);
}
- const char *lxcpath = my_args.lxcpath[0];
-
/* REMOVE IN LXC 3.0 */
setenv("LXC_UPDATE_CONFIG_FORMAT", "1", 0);
}
}
- int i;
for (i = 0; i < LXC_NS_MAX; i++) {
- if (my_args.share_ns[i] == NULL)
+ const char *key, *value;
+
+ value = my_args.share_ns[i];
+ if (!value)
continue;
- int pid = pid_from_lxcname(my_args.share_ns[i], lxcpath);
- if (pid < 1)
- goto out;
+ if (i == LXC_NS_NET)
+ key = "lxc.namespace.net";
+ else if (i == LXC_NS_IPC)
+ key = "lxc.namespace.ipc";
+ else if (i == LXC_NS_UTS)
+ key = "lxc.namespace.uts";
+ else if (i == LXC_NS_PID)
+ key = "lxc.namespace.pid";
+ else
+ continue;
- int fd = open_ns(pid, ns_info[i].proc_name);
- if (fd < 0)
+ if (!c->set_config_item(c, key, value))
goto out;
- conf->inherit_ns_fd[i] = fd;
}
if (!my_args.daemonize) {