[lxc-devel] [PATCH 1/1] create: add a quiet flag

Serge Hallyn serge.hallyn at ubuntu.com
Fri Jul 12 14:44:41 UTC 2013


If set, then fds 0,1,2 will be redirected while the creation
template is executed.

Note, as Dwight has pointed out, if fd 0 is redirected, then if
templates ask for input there will be a problem.  We could simply
not redirect fd 0, or we could require that templates work without
interaction.  I'm assuming here that we want to do the latter, but
I'm open to changing that.

Reported-by: "S.Çağlar Onur" <caglar at 10ur.org>
Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 src/lua-lxc/core.c       |    2 +-
 src/lxc/lxc_create.c     |    5 ++++-
 src/lxc/lxccontainer.c   |   20 ++++++++++++++------
 src/lxc/lxccontainer.h   |    7 +++++--
 src/python-lxc/lxc.c     |    2 +-
 src/tests/cgpath.c       |    2 +-
 src/tests/clonetest.c    |    2 +-
 src/tests/console.c      |    2 +-
 src/tests/createtest.c   |    2 +-
 src/tests/get_item.c     |    2 +-
 src/tests/shutdowntest.c |    2 +-
 11 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/src/lua-lxc/core.c b/src/lua-lxc/core.c
index 778ef99..642dbfc 100644
--- a/src/lua-lxc/core.c
+++ b/src/lua-lxc/core.c
@@ -111,7 +111,7 @@ static int container_create(lua_State *L)
 	argv[i] = strdupa(luaL_checkstring(L, i+3));
     argv[i] = NULL;
 
-    lua_pushboolean(L, !!c->create(c, template_name, NULL, NULL, argv));
+    lua_pushboolean(L, !!c->create(c, template_name, NULL, NULL, 0, argv));
     return 1;
 }
 
diff --git a/src/lxc/lxc_create.c b/src/lxc/lxc_create.c
index 6d8ca01..bd08ea2 100644
--- a/src/lxc/lxc_create.c
+++ b/src/lxc/lxc_create.c
@@ -169,6 +169,7 @@ int main(int argc, char *argv[])
 {
 	struct lxc_container *c;
 	struct bdev_specs spec;
+	int flags = 0;
 
 	/* this is a short term test.  We'll probably want to check for
 	 * write access to lxcpath instead */
@@ -228,7 +229,9 @@ int main(int argc, char *argv[])
 
 	if (strcmp(my_args.bdevtype, "_unset") == 0)
 		my_args.bdevtype = NULL;
-	if (!c->create(c, my_args.template, my_args.bdevtype, &spec, &argv[optind])) {
+	if (my_args.quiet)
+		flags = LXC_CREATE_QUIET;
+	if (!c->create(c, my_args.template, my_args.bdevtype, &spec, flags, &argv[optind])) {
 		ERROR("Error creating container %s", c->name);
 		lxc_container_put(c);
 		exit(1);
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 4b26051..3da23b7 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -752,7 +752,7 @@ static char *lxcbasename(char *path)
 	return p;
 }
 
-static bool create_run_template(struct lxc_container *c, char *tpath,
+static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet,
 				char *const argv[])
 {
 	pid_t pid;
@@ -773,6 +773,14 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
 		int ret, len, nargs = 0;
 		char **newargv;
 
+		if (quiet) {
+			close(0);
+			close(1);
+			close(2);
+			open("/dev/zero", O_RDONLY);
+			open("/dev/null", O_RDWR);
+			open("/dev/null", O_RDWR);
+		}
 		if (unshare(CLONE_NEWNS) < 0) {
 			ERROR("error unsharing mounts");
 			exit(1);
@@ -974,7 +982,7 @@ static bool lxcapi_destroy(struct lxc_container *c);
  * arguments, you can just pass NULL.
  */
 static bool lxcapi_create(struct lxc_container *c, const char *t,
-		const char *bdevtype, struct bdev_specs *specs,
+		const char *bdevtype, struct bdev_specs *specs, int flags,
 		char *const argv[])
 {
 	bool bret = false;
@@ -1047,7 +1055,7 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
 	if (!load_config_locked(c, c->configfile))
 		goto out;
 
-	if (!create_run_template(c, tpath, argv))
+	if (!create_run_template(c, tpath, !!(flags & LXC_CREATE_QUIET), argv))
 		goto out_unlock;
 
 	// now clear out the lxc_conf we have, reload from the created
@@ -1115,7 +1123,7 @@ static bool lxcapi_shutdown(struct lxc_container *c, int timeout)
 }
 
 static bool lxcapi_createl(struct lxc_container *c, const char *t,
-		const char *bdevtype, struct bdev_specs *specs, ...)
+		const char *bdevtype, struct bdev_specs *specs, int flags, ...)
 {
 	bool bret = false;
 	char **args = NULL, **temp;
@@ -1129,7 +1137,7 @@ static bool lxcapi_createl(struct lxc_container *c, const char *t,
 	 * since we're going to wait for create to finish, I don't think we
 	 * need to get a copy of the arguments.
 	 */
-	va_start(ap, specs);
+	va_start(ap, flags);
 	while (1) {
 		char *arg;
 		arg = va_arg(ap, char *);
@@ -1148,7 +1156,7 @@ static bool lxcapi_createl(struct lxc_container *c, const char *t,
 	if (args)
 		args[nargs] = NULL;
 
-	bret = c->create(c, t, bdevtype, specs, args);
+	bret = c->create(c, t, bdevtype, specs, flags, args);
 
 out:
 	if (args)
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index 5449a46..3399c7f 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -12,6 +12,9 @@
 #define LXC_CLONE_SNAPSHOT        (1 << 3)
 #define LXC_CLONE_MAXFLAGS        (1 << 4)
 
+#define LXC_CREATE_QUIET	  (1 << 0)
+#define LXC_CREATE_MAXFLAGS       (1 << 1)
+
 struct bdev_specs;
 
 struct lxc_container {
@@ -51,9 +54,9 @@ struct lxc_container {
 	bool (*destroy)(struct lxc_container *c);
 	bool (*save_config)(struct lxc_container *c, const char *alt_file);
 	bool (*create)(struct lxc_container *c, const char *t, const char *bdevtype,
-			struct bdev_specs *specs, char *const argv[]);
+			struct bdev_specs *specs, int flags, char *const argv[]);
 	bool (*createl)(struct lxc_container *c, const char *t, const char *bdevtype,
-			struct bdev_specs *specs, ...);
+			struct bdev_specs *specs, int flags, ...);
 	/* send SIGINT to ask container to reboot */
 	bool (*reboot)(struct lxc_container *c);
 	/* send SIGPWR.  if timeout is not 0 or -1, do a hard stop after timeout seconds */
diff --git a/src/python-lxc/lxc.c b/src/python-lxc/lxc.c
index 02428d4..18f2224 100644
--- a/src/python-lxc/lxc.c
+++ b/src/python-lxc/lxc.c
@@ -249,7 +249,7 @@ Container_create(Container *self, PyObject *args, PyObject *kwds)
         }
     }
 
-    if (self->container->create(self->container, template_name, NULL, NULL, create_args))
+    if (self->container->create(self->container, template_name, NULL, NULL, 0, create_args))
         retval = Py_True;
     else
         retval = Py_False;
diff --git a/src/tests/cgpath.c b/src/tests/cgpath.c
index 55c6664..944769c 100644
--- a/src/tests/cgpath.c
+++ b/src/tests/cgpath.c
@@ -279,7 +279,7 @@ static int test_container(const char *lxcpath,
 		c = lxc_container_new(name, lxcpath);
 	}
 	c->set_config_item(c, "lxc.network.type", "empty");
-	if (!c->createl(c, template, NULL, NULL, NULL)) {
+	if (!c->createl(c, template, NULL, NULL, 0, NULL)) {
 		TSTERR("creating container %s", name);
 		goto out2;
 	}
diff --git a/src/tests/clonetest.c b/src/tests/clonetest.c
index f15f400..da3ce75 100644
--- a/src/tests/clonetest.c
+++ b/src/tests/clonetest.c
@@ -53,7 +53,7 @@ int main(int argc, char *argv[])
 		goto out;
 	}
 	c->save_config(c, NULL);
-	if (!c->createl(c, "ubuntu", NULL, NULL, NULL)) {
+	if (!c->createl(c, "ubuntu", NULL, NULL, 0, NULL)) {
 		fprintf(stderr, "%d: failed to create a container\n", __LINE__);
 		goto out;
 	}
diff --git a/src/tests/console.c b/src/tests/console.c
index 434f7f2..cd63981 100644
--- a/src/tests/console.c
+++ b/src/tests/console.c
@@ -137,7 +137,7 @@ static int test_console(const char *lxcpath,
 		c->destroy(c);
 		c = lxc_container_new(name, lxcpath);
 	}
-	if (!c->createl(c, template, NULL, NULL, NULL)) {
+	if (!c->createl(c, template, NULL, NULL, 0, NULL)) {
 		TSTERR("creating container %s", name);
 		goto out2;
 	}
diff --git a/src/tests/createtest.c b/src/tests/createtest.c
index f33f59b..879d0a1 100644
--- a/src/tests/createtest.c
+++ b/src/tests/createtest.c
@@ -50,7 +50,7 @@ int main(int argc, char *argv[])
 	}
 	c->set_config_item(c, "lxc.network.link", "lxcbr0");
 	c->set_config_item(c, "lxc.network.flags", "up");
-	if (!c->createl(c, "ubuntu", NULL, NULL, "-r", "lucid", NULL)) {
+	if (!c->createl(c, "ubuntu", NULL, NULL, 0, "-r", "lucid", NULL)) {
 		fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__);
 		goto out;
 	}
diff --git a/src/tests/get_item.c b/src/tests/get_item.c
index 9511899..c4c95cb 100644
--- a/src/tests/get_item.c
+++ b/src/tests/get_item.c
@@ -170,7 +170,7 @@ int main(int argc, char *argv[])
 		ret = 1;
 		goto out;
 	}
-	if (!c->createl(c, "ubuntu", NULL, NULL, "-r", "lucid", NULL)) {
+	if (!c->createl(c, "ubuntu", NULL, NULL, 0, "-r", "lucid", NULL)) {
 		fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__);
 		ret = 1;
 		goto out;
diff --git a/src/tests/shutdowntest.c b/src/tests/shutdowntest.c
index 6e50cb0..f67995e 100644
--- a/src/tests/shutdowntest.c
+++ b/src/tests/shutdowntest.c
@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
 	}
 	c->set_config_item(c, "lxc.network.link", "lxcbr0");
 	c->set_config_item(c, "lxc.network.flags", "up");
-	if (!c->createl(c, "ubuntu", NULL, NULL, "-r", "lucid", NULL)) {
+	if (!c->createl(c, "ubuntu", NULL, NULL, 0, "-r", "lucid", NULL)) {
 		fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__);
 		goto out;
 	}
-- 
1.7.9.5





More information about the lxc-devel mailing list