[lxc-devel] [PATCH] allow lxc-init to log when rootfs not given

Dwight Engen dwight.engen at oracle.com
Wed May 1 23:07:16 UTC 2013


On Mon, 29 Apr 2013 14:44:47 -0500
Serge Hallyn <serge.hallyn at ubuntu.com> wrote:

> Quoting Dwight Engen (dwight.engen at oracle.com):
> > So I did this, only to realize that lxc-init is passing "none" for
> > the file anyway, so it currently doesn't intend to log. This makes
> > me think that passing NULL for lxcpath is the right thing to do in
> > this patch. If you want me to make it so lxc-init can log, I can do
> > that but I think it should be in a different change :)
> 
> That actually would be very useful, but as you say that's a different
> feature - thanks.

... and here is said change.

---

fixed leak in error case in execute_start(), made lxc_log_init()
safe to call with NULL lxcpath.

Signed-off-by: Dwight Engen <dwight.engen at oracle.com>
---
 src/lxc/execute.c  | 27 ++++++++++++++++++----
 src/lxc/log.c      |  3 +++
 src/lxc/lxc_init.c | 68 +++++++++++++++++++++++++++++++++++++++---------------
 3 files changed, 75 insertions(+), 23 deletions(-)

diff --git a/src/lxc/execute.c b/src/lxc/execute.c
index c1f6526..d93e8e1 100644
--- a/src/lxc/execute.c
+++ b/src/lxc/execute.c
@@ -27,6 +27,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 
+#include "conf.h"
 #include "log.h"
 #include "start.h"
 
@@ -85,23 +86,37 @@ static int execute_start(struct lxc_handler *handler, void* data)
 	int j, i = 0;
 	struct execute_args *my_args = data;
 	char **argv;
-	int argc = 0;
+	int argc = 0, argc_add;
 	char *initpath;
 
 	while (my_args->argv[argc++]);
 
-	argv = malloc((argc + my_args->quiet ? 5 : 4) * sizeof(*argv));
+	argc_add = 4;
+	if (my_args->quiet)
+		argc_add++;
+	if (!handler->conf->rootfs.path)
+		argc_add+=6;
+
+	argv = malloc((argc + argc_add) * sizeof(*argv));
 	if (!argv)
-		return 1;
+		goto out1;
 
 	initpath = choose_init();
 	if (!initpath) {
 		ERROR("Failed to find an lxc-init");
-		return 1;
+		goto out2;
 	}
 	argv[i++] = initpath;
 	if (my_args->quiet)
 		argv[i++] = "--quiet";
+	if (!handler->conf->rootfs.path) {
+		argv[i++] = "--name";
+		argv[i++] = (char *)handler->name;
+		argv[i++] = "--lxcpath";
+		argv[i++] = (char *)handler->lxcpath;
+		argv[i++] = "--logpriority";
+		argv[i++] = (char *)lxc_log_priority_to_string(lxc_log_get_level());
+	}
 	argv[i++] = "--";
 	for (j = 0; j < argc; j++)
 		argv[i++] = my_args->argv[j];
@@ -111,6 +126,10 @@ static int execute_start(struct lxc_handler *handler, void* data)
 
 	execvp(argv[0], argv);
 	SYSERROR("failed to exec %s", argv[0]);
+	free(initpath);
+out2:
+	free(argv);
+out1:
 	return 1;
 }
 
diff --git a/src/lxc/log.c b/src/lxc/log.c
index 8d87a51..d49a544 100644
--- a/src/lxc/log.c
+++ b/src/lxc/log.c
@@ -318,6 +318,9 @@ extern int lxc_log_init(const char *name, const char *file,
 	} else {
 		ret = -1;
 
+		if (!lxcpath)
+			lxcpath = LOGPATH;
+
 		/* try LOGPATH if lxcpath is the default */
 		if (strcmp(lxcpath, default_lxc_path()) == 0)
 			ret = _lxc_log_set_file(name, NULL, 0);
diff --git a/src/lxc/lxc_init.c b/src/lxc/lxc_init.c
index 663875b..f772f0d 100644
--- a/src/lxc/lxc_init.c
+++ b/src/lxc/lxc_init.c
@@ -43,7 +43,10 @@ lxc_log_define(lxc_init, lxc);
 static int quiet;
 
 static struct option options[] = {
-	{ "quiet", no_argument, &quiet, 1 },
+	{ "name",        required_argument, NULL, 'n' },
+	{ "logpriority", required_argument, NULL, 'l' },
+	{ "quiet",       no_argument,       NULL, 'q' },
+	{ "lxcpath",     required_argument, NULL, 'P' },
 	{ 0, 0, 0, 0 },
 };
 
@@ -55,39 +58,66 @@ static void interrupt_handler(int sig)
 		was_interrupted = sig;
 }
 
+static void usage(void) {
+	fprintf(stderr, "Usage: lxc-init [OPTION]...\n\n"
+		"Common options :\n"
+		"  -n, --name=NAME          NAME for name of the container\n"
+		"  -l, --logpriority=LEVEL  Set log priority to LEVEL\n"
+		"  -q, --quiet              Don't produce any output\n"
+		"  -P, --lxcpath=PATH       Use specified container path\n"
+		"  -?, --help               Give this help list\n"
+		"\n"
+		"Mandatory or optional arguments to long options are also mandatory or optional\n"
+		"for any corresponding short options.\n"
+		"\n"
+		"NOTE: lxc-init is intended for use by lxc internally\n"
+		"      and does not need to be run by hand\n\n");
+}
+
 int main(int argc, char *argv[])
 {
 	pid_t pid;
-	int nbargs = 0;
-	int err = -1;
+	int err;
 	char **aargv;
 	sigset_t mask, omask;
 	int i, have_status = 0, shutdown = 0;
+	int opt;
+	char *lxcpath = NULL, *name = NULL, *logpriority = NULL;
 
-	while (1) {
-		int ret = getopt_long_only(argc, argv, "", options, NULL);
-		if (ret == -1) {
+	while ((opt = getopt_long(argc, argv, "n:l:qP:", options, NULL)) != -1) {
+		switch(opt) {
+		case 'n':
+			name = optarg;
+			break;
+		case 'l':
+			logpriority = optarg;
 			break;
+		case 'q':
+			quiet = 1;
+ 			break;
+		case 'P':
+			lxcpath = optarg;
+			break;
+		default: /* '?' */
+			usage();
+			exit(EXIT_FAILURE);
 		}
-		if  (ret == '?')
-			exit(err);
-
-		nbargs++;
 	}
 
 	if (lxc_caps_init())
-		exit(err);
+		exit(EXIT_FAILURE);
 
-	if (lxc_log_init(NULL, "none", 0, basename(argv[0]), quiet, NULL))
-		exit(err);
+	err = lxc_log_init(name, name ? NULL : "none", logpriority,
+			   basename(argv[0]), quiet, lxcpath);
+	if (err < 0)
+		exit(EXIT_FAILURE);
 
 	if (!argv[optind]) {
 		ERROR("missing command to launch");
-		exit(err);
+		exit(EXIT_FAILURE);
 	}
 
 	aargv = &argv[optind];
-	argc -= nbargs;
 
         /*
 	 * mask all the signals so we are safe to install a
@@ -125,15 +155,15 @@ int main(int argc, char *argv[])
 	}
 
 	if (lxc_setup_fs())
-		exit(err);
+		exit(EXIT_FAILURE);
 
 	if (lxc_caps_reset())
-		exit(err);
+		exit(EXIT_FAILURE);
 
 	pid = fork();
 
 	if (pid < 0)
-		exit(err);
+		exit(EXIT_FAILURE);
 
 	if (!pid) {
 
@@ -158,7 +188,7 @@ int main(int argc, char *argv[])
 	close(fileno(stdin));
 	close(fileno(stdout));
 
-	err = 0;
+	err = EXIT_SUCCESS;
 	for (;;) {
 		int status;
 		pid_t waited_pid;
-- 
1.8.1.4





More information about the lxc-devel mailing list