]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
execute: don't bind mount init.lxc.static if lxc-init is in the container
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Tue, 3 Jun 2014 03:03:58 +0000 (22:03 -0500)
committerStéphane Graber <stgraber@ubuntu.com>
Tue, 3 Jun 2014 14:11:01 +0000 (10:11 -0400)
Move choose_init into utils.c so we can re-use it.  Make it and on_path
accept an optional rootfs argument to prepend to the paths when checking
whether the file exists.

Also add lxc.init.static to .gitignore

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
.gitignore
src/lxc/conf.c
src/lxc/execute.c
src/lxc/utils.c
src/lxc/utils.h

index 8145f81c9695eea80e512ae4ef8ebbf0701a51a5..a69ffdea9d378bb4efa39622e4406960bc8a7f8f 100644 (file)
@@ -44,6 +44,7 @@ templates/lxc-ubuntu
 templates/lxc-ubuntu-cloud
 
 src/lxc/init.lxc
+src/lxc/init.lxc.static
 src/lxc/lxc-attach
 src/lxc/lxc-autostart
 src/lxc/lxc-cgroup
index 8beded29c64067d7fb5d479161099a8bf34059d2..9fa4858b906748a28964ef0c9194da500f6d8c96 100644 (file)
@@ -3246,14 +3246,14 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
        enum idtype type;
        char *buf = NULL, *pos, *cmdpath = NULL;
 
-       cmdpath = on_path("newuidmap");
+       cmdpath = on_path("newuidmap", NULL);
        if (cmdpath) {
                use_shadow = 1;
                free(cmdpath);
        }
 
        if (!use_shadow) {
-               cmdpath = on_path("newgidmap");
+               cmdpath = on_path("newgidmap", NULL);
                if (cmdpath) {
                        use_shadow = 1;
                        free(cmdpath);
@@ -3814,7 +3814,14 @@ static void remount_all_slave(void)
 void lxc_execute_bind_init(struct lxc_conf *conf)
 {
        int ret;
-       char path[PATH_MAX], destpath[PATH_MAX];
+       char path[PATH_MAX], destpath[PATH_MAX], *p;
+
+       /* If init exists in the container, don't bind mount a static one */
+       p = choose_init(conf->rootfs.mount);
+       if (p) {
+               free(p);
+               return;
+       }
 
        ret = snprintf(path, PATH_MAX, SBINDIR "/init.lxc.static");
        if (ret < 0 || ret >= PATH_MAX) {
index 4ebc214ab99824be312305a767bfc3d2e0c3d308..b78bcbfc0462c4c6ba33432e0e49f380c36e9663 100644 (file)
@@ -39,90 +39,6 @@ struct execute_args {
        int quiet;
 };
 
-/* historically lxc-init has been under /usr/lib/lxc and under
- * /usr/lib/$ARCH/lxc.  It now lives as $prefix/sbin/init.lxc.
- */
-static char *choose_init(void)
-{
-       char *retv = NULL;
-       int ret, env_set = 0;
-       struct stat mystat;
-
-       if (!getenv("PATH")) {
-               if (setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 0))
-                       SYSERROR("Failed to setenv");
-               env_set = 1;
-       }
-
-       retv = on_path("init.lxc");
-
-       if (env_set) {
-               if (unsetenv("PATH"))
-                       SYSERROR("Failed to unsetenv");
-       }
-
-       if (retv)
-               return retv;
-
-       retv = malloc(PATH_MAX);
-       if (!retv)
-               return NULL;
-
-       ret = snprintf(retv, PATH_MAX, SBINDIR "/init.lxc");
-       if (ret < 0 || ret >= PATH_MAX) {
-               ERROR("pathname too long");
-               goto out1;
-       }
-
-       ret = stat(retv, &mystat);
-       if (ret == 0)
-               return retv;
-
-       ret = snprintf(retv, PATH_MAX, LXCINITDIR "/lxc/lxc-init");
-       if (ret < 0 || ret >= PATH_MAX) {
-               ERROR("pathname too long");
-               goto out1;
-       }
-
-       ret = stat(retv, &mystat);
-       if (ret == 0)
-               return retv;
-
-       ret = snprintf(retv, PATH_MAX, "/usr/lib/lxc/lxc-init");
-       if (ret < 0 || ret >= PATH_MAX) {
-               ERROR("pathname too long");
-               goto out1;
-       }
-       ret = stat(retv, &mystat);
-       if (ret == 0)
-               return retv;
-       ret = snprintf(retv, PATH_MAX, "/sbin/lxc-init");
-       if (ret < 0 || ret >= PATH_MAX) {
-               ERROR("pathname too long");
-               goto out1;
-       }
-       ret = stat(retv, &mystat);
-       if (ret == 0)
-               return retv;
-
-       /*
-        * Last resort, look for the statically compiled init.lxc which we
-        * hopefully bind-mounted in
-        */
-       ret = snprintf(retv, PATH_MAX, "/init.lxc.static");
-       if (ret < 0 || ret >= PATH_MAX) {
-               WARN("Nonsense - name /lxc.init.static too long");
-               goto out1;
-       }
-       ret = stat(retv, &mystat);
-       if (ret == 0)
-               return retv;
-
-out1:
-       free(retv);
-       return NULL;
-}
-
 static int execute_start(struct lxc_handler *handler, void* data)
 {
        int j, i = 0;
@@ -146,7 +62,7 @@ static int execute_start(struct lxc_handler *handler, void* data)
        if (!argv)
                goto out1;
 
-       initpath = choose_init();
+       initpath = choose_init(NULL);
        if (!initpath) {
                ERROR("Failed to find an lxc-init");
                goto out2;
index b076ce741e9414933dc548ef970eb0bbf9abd0ce..173afa866e4a21857de6d69a6e783d81c6afc3ce 100644 (file)
@@ -1272,7 +1272,7 @@ int detect_ramfs_rootfs(void)
        return 0;
 }
 
-char *on_path(char *cmd) {
+char *on_path(char *cmd, const char *rootfs) {
        char *path = NULL;
        char *entry = NULL;
        char *saveptr = NULL;
@@ -1289,7 +1289,10 @@ char *on_path(char *cmd) {
 
        entry = strtok_r(path, ":", &saveptr);
        while (entry) {
-               ret = snprintf(cmdpath, MAXPATHLEN, "%s/%s", entry, cmd);
+               if (rootfs)
+                       ret = snprintf(cmdpath, MAXPATHLEN, "%s/%s/%s", rootfs, entry, cmd);
+               else
+                       ret = snprintf(cmdpath, MAXPATHLEN, "%s/%s", entry, cmd);
 
                if (ret < 0 || ret >= MAXPATHLEN)
                        goto next_loop;
@@ -1313,3 +1316,106 @@ bool file_exists(const char *f)
 
        return stat(f, &statbuf) == 0;
 }
+
+/* historically lxc-init has been under /usr/lib/lxc and under
+ * /usr/lib/$ARCH/lxc.  It now lives as $prefix/sbin/init.lxc.
+ */
+char *choose_init(const char *rootfs)
+{
+       char *retv = NULL;
+       int ret, env_set = 0;
+       struct stat mystat;
+
+       if (!getenv("PATH")) {
+               if (setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 0))
+                       SYSERROR("Failed to setenv");
+               env_set = 1;
+       }
+
+       retv = on_path("init.lxc", rootfs);
+
+       if (env_set) {
+               if (unsetenv("PATH"))
+                       SYSERROR("Failed to unsetenv");
+       }
+
+       if (retv)
+               return retv;
+
+       retv = malloc(PATH_MAX);
+       if (!retv)
+               return NULL;
+
+       if (rootfs)
+               ret = snprintf(retv, PATH_MAX, "%s/%s/init.lxc", rootfs, SBINDIR);
+       else
+               ret = snprintf(retv, PATH_MAX, SBINDIR "/init.lxc");
+       if (ret < 0 || ret >= PATH_MAX) {
+               ERROR("pathname too long");
+               goto out1;
+       }
+
+       ret = stat(retv, &mystat);
+       if (ret == 0)
+               return retv;
+
+       if (rootfs)
+               ret = snprintf(retv, PATH_MAX, "%s/%s/lxc/lxc-init", rootfs, LXCINITDIR);
+       else
+               ret = snprintf(retv, PATH_MAX, LXCINITDIR "/lxc/lxc-init");
+       if (ret < 0 || ret >= PATH_MAX) {
+               ERROR("pathname too long");
+               goto out1;
+       }
+
+       ret = stat(retv, &mystat);
+       if (ret == 0)
+               return retv;
+
+       if (rootfs)
+               ret = snprintf(retv, PATH_MAX, "%s/usr/lib/lxc/lxc-init", rootfs);
+       else
+               ret = snprintf(retv, PATH_MAX, "/usr/lib/lxc/lxc-init");
+       if (ret < 0 || ret >= PATH_MAX) {
+               ERROR("pathname too long");
+               goto out1;
+       }
+       ret = stat(retv, &mystat);
+       if (ret == 0)
+               return retv;
+
+       if (rootfs)
+               ret = snprintf(retv, PATH_MAX, "%s/sbin/lxc-init", rootfs);
+       else
+               ret = snprintf(retv, PATH_MAX, "/sbin/lxc-init");
+       if (ret < 0 || ret >= PATH_MAX) {
+               ERROR("pathname too long");
+               goto out1;
+       }
+       ret = stat(retv, &mystat);
+       if (ret == 0)
+               return retv;
+
+       /*
+        * Last resort, look for the statically compiled init.lxc which we
+        * hopefully bind-mounted in.
+        * If we are called during container setup, and we get to this point,
+        * then the init.lxc.static from the host will need to be bind-mounted
+        * in.  So we return NULL here to indicate that.
+        */
+       if (rootfs)
+               goto out1;
+
+       ret = snprintf(retv, PATH_MAX, "/init.lxc.static");
+       if (ret < 0 || ret >= PATH_MAX) {
+               WARN("Nonsense - name /lxc.init.static too long");
+               goto out1;
+       }
+       ret = stat(retv, &mystat);
+       if (ret == 0)
+               return retv;
+
+out1:
+       free(retv);
+       return NULL;
+}
index 691e56ca9118421486dfbad7d5178e2d8eba0cab..050102ce60a53de0a54665555108cc67212525b0 100644 (file)
@@ -279,5 +279,6 @@ uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval);
 
 int detect_shared_rootfs(void);
 int detect_ramfs_rootfs(void);
-char *on_path(char *cmd);
+char *on_path(char *cmd, const char *rootfs);
 bool file_exists(const char *f);
+char *choose_init(const char *rootfs);