Merge pull request #2272 from brauner/2018-04-12/bugfixes

conf: ret-try devpts mount without gid=5 on error
This commit is contained in:
Serge Hallyn 2018-04-12 11:31:05 -05:00 committed by GitHub
commit 465c891a7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 32 deletions

View File

@ -99,6 +99,7 @@
#include "network.h" #include "network.h"
#include "parse.h" #include "parse.h"
#include "ringbuf.h" #include "ringbuf.h"
#include "start.h"
#include "storage.h" #include "storage.h"
#include "storage/overlay.h" #include "storage/overlay.h"
#include "terminal.h" #include "terminal.h"
@ -1523,7 +1524,7 @@ static struct id_map *find_mapped_nsid_entry(struct lxc_conf *conf, unsigned id,
static int lxc_setup_devpts(struct lxc_conf *conf) static int lxc_setup_devpts(struct lxc_conf *conf)
{ {
int ret; int ret;
const char *default_devpts_mntopts; const char *default_devpts_mntopts = "gid=5,newinstance,ptmxmode=0666,mode=0620";
char devpts_mntopts[256]; char devpts_mntopts[256];
if (conf->pts <= 0) { if (conf->pts <= 0) {
@ -1532,11 +1533,6 @@ static int lxc_setup_devpts(struct lxc_conf *conf)
return 0; return 0;
} }
if (!find_mapped_nsid_entry(conf, 5, ID_TYPE_GID))
default_devpts_mntopts = "newinstance,ptmxmode=0666,mode=0620";
else
default_devpts_mntopts = "newinstance,ptmxmode=0666,mode=0620,gid=5";
ret = snprintf(devpts_mntopts, sizeof(devpts_mntopts), "%s,max=%d", ret = snprintf(devpts_mntopts, sizeof(devpts_mntopts), "%s,max=%d",
default_devpts_mntopts, conf->pts); default_devpts_mntopts, conf->pts);
if (ret < 0 || (size_t)ret >= sizeof(devpts_mntopts)) if (ret < 0 || (size_t)ret >= sizeof(devpts_mntopts))
@ -1560,12 +1556,17 @@ static int lxc_setup_devpts(struct lxc_conf *conf)
return -1; return -1;
} }
/* Mount new devpts instance. */ /* mount new devpts instance */
ret = mount("devpts", "/dev/pts", "devpts", MS_NOSUID | MS_NOEXEC, devpts_mntopts); ret = mount("devpts", "/dev/pts", "devpts", MS_NOSUID | MS_NOEXEC, devpts_mntopts);
if (ret < 0) {
/* try mounting without gid=5 */
ret = mount("devpts", "/dev/pts", "devpts",
MS_NOSUID | MS_NOEXEC, devpts_mntopts + sizeof("gid=5"));
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to mount new devpts instance"); SYSERROR("Failed to mount new devpts instance");
return -1; return -1;
} }
}
DEBUG("Mount new devpts instance with options \"%s\"", devpts_mntopts); DEBUG("Mount new devpts instance with options \"%s\"", devpts_mntopts);
/* Remove any pre-existing /dev/ptmx file. */ /* Remove any pre-existing /dev/ptmx file. */
@ -3206,10 +3207,12 @@ void remount_all_slave(void)
free(line); free(line);
} }
static int lxc_execute_bind_init(struct lxc_conf *conf) static int lxc_execute_bind_init(struct lxc_handler *handler)
{ {
int ret; int ret;
char path[PATH_MAX], destpath[PATH_MAX], *p; char *p;
char path[PATH_MAX], destpath[PATH_MAX];
struct lxc_conf *conf = handler->conf;
/* If init exists in the container, don't bind mount a static one */ /* If init exists in the container, don't bind mount a static one */
p = choose_init(conf->rootfs.mount); p = choose_init(conf->rootfs.mount);
@ -3227,20 +3230,16 @@ static int lxc_execute_bind_init(struct lxc_conf *conf)
return -1; return -1;
} }
ret = snprintf(destpath, PATH_MAX, "%s%s", conf->rootfs.mount, "/init.lxc.static"); ret = snprintf(destpath, PATH_MAX, "%s" P_tmpdir "%s", conf->rootfs.mount, "/.lxc-init");
if (ret < 0 || ret >= PATH_MAX) if (ret < 0 || ret >= PATH_MAX)
return -1; return -1;
if (!file_exists(destpath)) { if (!file_exists(destpath)) {
FILE *pathfile; ret = mknod(destpath, S_IFREG | 0000, 0);
if (ret < 0 && errno != EEXIST) {
pathfile = fopen(destpath, "wb"); SYSERROR("Failed to create dummy \"%s\" file as bind mount target", destpath);
if (!pathfile) {
SYSERROR("Failed to create mount target \"%s\"", destpath);
return -1; return -1;
} }
fclose(pathfile);
} }
ret = safe_mount(path, destpath, "none", MS_BIND, NULL, conf->rootfs.mount); ret = safe_mount(path, destpath, "none", MS_BIND, NULL, conf->rootfs.mount);
@ -3249,6 +3248,11 @@ static int lxc_execute_bind_init(struct lxc_conf *conf)
return -1; return -1;
} }
p = strdup(destpath + strlen(conf->rootfs.mount));
if (!p)
return -ENOMEM;
((struct execute_args *)handler->data)->init_path = p;
INFO("Bind mounted lxc.init.static into container at \"%s\"", path); INFO("Bind mounted lxc.init.static into container at \"%s\"", path);
return 0; return 0;
} }
@ -3383,7 +3387,7 @@ int lxc_setup(struct lxc_handler *handler)
return -1; return -1;
if (lxc_conf->is_execute) { if (lxc_conf->is_execute) {
ret = lxc_execute_bind_init(lxc_conf); ret = lxc_execute_bind_init(handler);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to bind-mount the lxc init system"); ERROR("Failed to bind-mount the lxc init system");
return -1; return -1;

View File

@ -34,18 +34,12 @@
lxc_log_define(lxc_execute, lxc_start); lxc_log_define(lxc_execute, lxc_start);
struct execute_args {
char *const *argv;
int quiet;
};
static int execute_start(struct lxc_handler *handler, void* data) static int execute_start(struct lxc_handler *handler, void* data)
{ {
int j, i = 0; int j, i = 0;
struct execute_args *my_args = data; struct execute_args *my_args = data;
char **argv; char **argv;
int argc = 0, argc_add; int argc = 0, argc_add;
char *initpath;
while (my_args->argv[argc++]); while (my_args->argv[argc++]);
@ -62,12 +56,10 @@ static int execute_start(struct lxc_handler *handler, void* data)
if (!argv) if (!argv)
goto out1; goto out1;
initpath = choose_init(NULL); if (!my_args->init_path)
if (!initpath) {
ERROR("Failed to find an init.lxc or init.lxc.static");
goto out2; goto out2;
}
argv[i++] = initpath; argv[i++] = my_args->init_path;
argv[i++] = "-n"; argv[i++] = "-n";
argv[i++] = (char *)handler->name; argv[i++] = (char *)handler->name;
@ -99,7 +91,7 @@ static int execute_start(struct lxc_handler *handler, void* data)
execvp(argv[0], argv); execvp(argv[0], argv);
SYSERROR("Failed to exec %s", argv[0]); SYSERROR("Failed to exec %s", argv[0]);
free(initpath);
out2: out2:
free(argv); free(argv);
out1: out1:

View File

@ -134,6 +134,12 @@ struct lxc_handler {
int exit_status; int exit_status;
}; };
struct execute_args {
char *init_path;
char *const *argv;
int quiet;
};
struct lxc_operations { struct lxc_operations {
int (*start)(struct lxc_handler *, void *); int (*start)(struct lxc_handler *, void *);
int (*post_start)(struct lxc_handler *, void *); int (*post_start)(struct lxc_handler *, void *);