[lxc-devel] [PATCH 4/6] execute: don't bind mount init.lxc.static if lxc-init is in the container
Serge Hallyn
serge.hallyn at ubuntu.com
Tue Jun 3 03:03:58 UTC 2014
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 at ubuntu.com>
---
.gitignore | 1 +
src/lxc/conf.c | 13 +++++--
src/lxc/execute.c | 86 +-----------------------------------------
src/lxc/utils.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/lxc/utils.h | 3 +-
5 files changed, 122 insertions(+), 91 deletions(-)
diff --git a/.gitignore b/.gitignore
index 8145f81..a69ffde 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 8beded2..9fa4858 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -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) {
diff --git a/src/lxc/execute.c b/src/lxc/execute.c
index 4ebc214..b78bcbf 100644
--- a/src/lxc/execute.c
+++ b/src/lxc/execute.c
@@ -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;
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index b076ce7..173afa8 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -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;
+}
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 691e56c..050102c 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -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);
--
2.0.0
More information about the lxc-devel
mailing list