From b2efeb0bb95e35e5b597b91224d07e6496d0161e Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Tue, 8 May 2018 09:43:19 -0600 Subject: [PATCH 1/3] add some TRACE/ERROR reporting The errors in execute_start are important because nothing actually prints out what error if any there was in these cases, so you're left with an empty log. The TRACE logs are simply to tell you which version of start lxc chose to invoke: exec or start. Signed-off-by: Tycho Andersen --- src/lxc/execute.c | 9 +++++++-- src/lxc/start.c | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lxc/execute.c b/src/lxc/execute.c index 79a97cf88..597233908 100644 --- a/src/lxc/execute.c +++ b/src/lxc/execute.c @@ -58,11 +58,15 @@ static int execute_start(struct lxc_handler *handler, void* data) argc_add += 2; argv = malloc((argc + argc_add) * sizeof(*argv)); - if (!argv) + if (!argv) { + SYSERROR("Allocating init args failed"); goto out1; + } - if (!my_args->init_path) + if (!my_args->init_path) { + ERROR("Init path missing"); goto out2; + } argv[i++] = my_args->init_path; @@ -139,6 +143,7 @@ int lxc_execute(const char *name, char *const argv[], int quiet, { struct execute_args args = {.argv = argv, .quiet = quiet}; + TRACE("Doing lxc_execute"); handler->conf->is_execute = 1; return __lxc_start(name, handler, &execute_start_ops, &args, lxcpath, backgrounded, error_num); diff --git a/src/lxc/start.c b/src/lxc/start.c index d7f079979..ce5cb3366 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -1971,6 +1971,7 @@ int lxc_start(const char *name, char *const argv[], struct lxc_handler *handler, .argv = argv, }; + TRACE("Doing lxc_start"); return __lxc_start(name, handler, &start_ops, &start_arg, lxcpath, backgrounded, error_num); } From 9c40b2d97829ce2afea4eed9cb4eac40ccec82e5 Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Wed, 9 May 2018 01:29:06 +0000 Subject: [PATCH 2/3] execute: account for -o path option count This always works fine... until your exec() fails and you try to go and free it, you've overwritten the allocator's metadata (and potentially other stuff) and it fails. Signed-off-by: Tycho Andersen --- src/lxc/execute.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lxc/execute.c b/src/lxc/execute.c index 597233908..b436b6a3f 100644 --- a/src/lxc/execute.c +++ b/src/lxc/execute.c @@ -57,6 +57,9 @@ static int execute_start(struct lxc_handler *handler, void* data) if (lxc_log_has_valid_level()) argc_add += 2; + if (current_config->logfd != -1 || lxc_log_fd != -1) + argc_add += 2; + argv = malloc((argc + argc_add) * sizeof(*argv)); if (!argv) { SYSERROR("Allocating init args failed"); From 410898489fb1ca8ed774ffc9ff030c64662f51a6 Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Wed, 9 May 2018 01:48:31 +0000 Subject: [PATCH 3/3] execute: set init_path when existing init is found I'm not really sure we should be looking in the rootfs for an existing init, but I'll send a much more invasive patch to correct that. For now, let's just make sure we set init_path when we find one, so that later in execute_start() we don't bail. Signed-off-by: Tycho Andersen --- src/lxc/conf.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 48c4b4ecc..253331160 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -3213,8 +3213,15 @@ static int lxc_execute_bind_init(struct lxc_handler *handler) /* If init exists in the container, don't bind mount a static one */ p = choose_init(conf->rootfs.mount); if (p) { - free(p); - return 0; + char *old = p; + + p = strdup(old + strlen(conf->rootfs.mount)); + free(old); + if (!p) + return -ENOMEM; + + INFO("Found existing init at \"%s\"", p); + goto out; } ret = snprintf(path, PATH_MAX, SBINDIR "/init.lxc.static"); @@ -3247,9 +3254,10 @@ static int lxc_execute_bind_init(struct lxc_handler *handler) 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); +out: + ((struct execute_args *)handler->data)->init_path = p; return 0; }