Commit 9d9c111c by Serge Hallyn Committed by Stéphane Graber

execute: don't bind mount init.lxc.static if lxc-init is in the container

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: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 041cb499
......@@ -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
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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;
}
......@@ -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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment