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);
+ return -1;
+ }
+
+ pid = s->init_pid(s);
+ if (pid < 1) {
+ SYSERROR("Is container '%s' running?", s->name);
+ return -1;
+ }
+ }
+ 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/net", pid);
+
+ 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) {
If not specified, exit with failure instead\n\
Note: --daemon implies --close-all-fds\n\
-s, --define KEY=VAL Assign VAL to configuration variable KEY\n\
- --share-net=PID Share a network namespace with another container\n\
+ --share-net=NAME Share a network namespace with another container or pid\n\
",
.options = my_longopts,
.parser = my_parser,
}
if (my_args.share_net != NULL) {
- char *eptr;
int fd;
- int pid = strtol(my_args.share_net, &eptr, 10);
- if (*eptr != '\0') {
- SYSERROR("'%s' is not a valid pid number", my_args.share_net);
- goto out;
- }
- char path[MAXPATHLEN];
- int ret = snprintf(path, MAXPATHLEN, "/proc/%d/ns/net", pid);
- if (ret < 0 || ret >= MAXPATHLEN)
+ int pid = pid_from_lxcname(my_args.share_net, lxcpath);
+ if (pid < 1)
goto out;
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- SYSERROR("failed to open %s", path);
+ fd = open_ns(pid, "net");
+ if (fd < 0)
goto out;
- }
conf->inherit_ns_fd[LXC_NS_NET] = fd;
}