]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Allow specifying a container by name or pid in --share-net option.
authorMarek Majkowski <marek@cloudflare.com>
Mon, 11 Nov 2013 13:19:29 +0000 (05:19 -0800)
committerMarek Majkowski <marek@cloudflare.com>
Mon, 11 Nov 2013 13:19:29 +0000 (05:19 -0800)
src/lxc/lxc_start.c

index 69fde9a493ff719b4263ec75e93ce78c3a22f59d..395234297cb11467eb147278f4ea879ed920db3b 100644 (file)
@@ -93,6 +93,48 @@ err:
        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) {
@@ -138,7 +180,7 @@ Options :\n\
                          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,
@@ -256,23 +298,14 @@ int main(int argc, char *argv[])
        }
 
        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;
        }