Commit dc23c1c8 by Serge Hallyn

create: add a quiet flag

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 avatar"S.Çağlar Onur" <caglar@10ur.org> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com> Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com>
parent ae13ae08
...@@ -111,7 +111,7 @@ static int container_create(lua_State *L) ...@@ -111,7 +111,7 @@ static int container_create(lua_State *L)
argv[i] = strdupa(luaL_checkstring(L, i+3)); argv[i] = strdupa(luaL_checkstring(L, i+3));
argv[i] = NULL; 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; return 1;
} }
......
...@@ -169,6 +169,7 @@ int main(int argc, char *argv[]) ...@@ -169,6 +169,7 @@ int main(int argc, char *argv[])
{ {
struct lxc_container *c; struct lxc_container *c;
struct bdev_specs spec; struct bdev_specs spec;
int flags = 0;
/* this is a short term test. We'll probably want to check for /* this is a short term test. We'll probably want to check for
* write access to lxcpath instead */ * write access to lxcpath instead */
...@@ -228,7 +229,9 @@ int main(int argc, char *argv[]) ...@@ -228,7 +229,9 @@ int main(int argc, char *argv[])
if (strcmp(my_args.bdevtype, "_unset") == 0) if (strcmp(my_args.bdevtype, "_unset") == 0)
my_args.bdevtype = NULL; 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); ERROR("Error creating container %s", c->name);
lxc_container_put(c); lxc_container_put(c);
exit(1); exit(1);
......
...@@ -752,7 +752,7 @@ static char *lxcbasename(char *path) ...@@ -752,7 +752,7 @@ static char *lxcbasename(char *path)
return p; 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[]) char *const argv[])
{ {
pid_t pid; pid_t pid;
...@@ -773,6 +773,14 @@ static bool create_run_template(struct lxc_container *c, char *tpath, ...@@ -773,6 +773,14 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
int ret, len, nargs = 0; int ret, len, nargs = 0;
char **newargv; 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) { if (unshare(CLONE_NEWNS) < 0) {
ERROR("error unsharing mounts"); ERROR("error unsharing mounts");
exit(1); exit(1);
...@@ -878,7 +886,7 @@ static bool lxcapi_destroy(struct lxc_container *c); ...@@ -878,7 +886,7 @@ static bool lxcapi_destroy(struct lxc_container *c);
* arguments, you can just pass NULL. * arguments, you can just pass NULL.
*/ */
static bool lxcapi_create(struct lxc_container *c, const char *t, 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[]) char *const argv[])
{ {
bool bret = false; bool bret = false;
...@@ -951,7 +959,7 @@ static bool lxcapi_create(struct lxc_container *c, const char *t, ...@@ -951,7 +959,7 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
if (!load_config_locked(c, c->configfile)) if (!load_config_locked(c, c->configfile))
goto out; goto out;
if (!create_run_template(c, tpath, argv)) if (!create_run_template(c, tpath, !!(flags & LXC_CREATE_QUIET), argv))
goto out_unlock; goto out_unlock;
// now clear out the lxc_conf we have, reload from the created // now clear out the lxc_conf we have, reload from the created
...@@ -1014,7 +1022,7 @@ static bool lxcapi_shutdown(struct lxc_container *c, int timeout) ...@@ -1014,7 +1022,7 @@ static bool lxcapi_shutdown(struct lxc_container *c, int timeout)
} }
static bool lxcapi_createl(struct lxc_container *c, const char *t, 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; bool bret = false;
char **args = NULL, **temp; char **args = NULL, **temp;
...@@ -1028,7 +1036,7 @@ static bool lxcapi_createl(struct lxc_container *c, const char *t, ...@@ -1028,7 +1036,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 * since we're going to wait for create to finish, I don't think we
* need to get a copy of the arguments. * need to get a copy of the arguments.
*/ */
va_start(ap, specs); va_start(ap, flags);
while (1) { while (1) {
char *arg; char *arg;
arg = va_arg(ap, char *); arg = va_arg(ap, char *);
...@@ -1047,7 +1055,7 @@ static bool lxcapi_createl(struct lxc_container *c, const char *t, ...@@ -1047,7 +1055,7 @@ static bool lxcapi_createl(struct lxc_container *c, const char *t,
if (args) if (args)
args[nargs] = NULL; args[nargs] = NULL;
bret = c->create(c, t, bdevtype, specs, args); bret = c->create(c, t, bdevtype, specs, flags, args);
out: out:
if (args) if (args)
......
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
#define LXC_CLONE_SNAPSHOT (1 << 3) #define LXC_CLONE_SNAPSHOT (1 << 3)
#define LXC_CLONE_MAXFLAGS (1 << 4) #define LXC_CLONE_MAXFLAGS (1 << 4)
#define LXC_CREATE_QUIET (1 << 0)
#define LXC_CREATE_MAXFLAGS (1 << 1)
struct bdev_specs; struct bdev_specs;
struct lxc_container { struct lxc_container {
...@@ -51,9 +54,9 @@ struct lxc_container { ...@@ -51,9 +54,9 @@ struct lxc_container {
bool (*destroy)(struct lxc_container *c); bool (*destroy)(struct lxc_container *c);
bool (*save_config)(struct lxc_container *c, const char *alt_file); bool (*save_config)(struct lxc_container *c, const char *alt_file);
bool (*create)(struct lxc_container *c, const char *t, const char *bdevtype, 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, 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 */ /* send SIGINT to ask container to reboot */
bool (*reboot)(struct lxc_container *c); bool (*reboot)(struct lxc_container *c);
/* send SIGPWR. if timeout is not 0 or -1, do a hard stop after timeout seconds */ /* send SIGPWR. if timeout is not 0 or -1, do a hard stop after timeout seconds */
......
...@@ -249,7 +249,7 @@ Container_create(Container *self, PyObject *args, PyObject *kwds) ...@@ -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; retval = Py_True;
else else
retval = Py_False; retval = Py_False;
......
...@@ -279,7 +279,7 @@ static int test_container(const char *lxcpath, ...@@ -279,7 +279,7 @@ static int test_container(const char *lxcpath,
c = lxc_container_new(name, lxcpath); c = lxc_container_new(name, lxcpath);
} }
c->set_config_item(c, "lxc.network.type", "empty"); 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); TSTERR("creating container %s", name);
goto out2; goto out2;
} }
......
...@@ -53,7 +53,7 @@ int main(int argc, char *argv[]) ...@@ -53,7 +53,7 @@ int main(int argc, char *argv[])
goto out; goto out;
} }
c->save_config(c, NULL); 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__); fprintf(stderr, "%d: failed to create a container\n", __LINE__);
goto out; goto out;
} }
......
...@@ -137,7 +137,7 @@ static int test_console(const char *lxcpath, ...@@ -137,7 +137,7 @@ static int test_console(const char *lxcpath,
c->destroy(c); c->destroy(c);
c = lxc_container_new(name, lxcpath); 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); TSTERR("creating container %s", name);
goto out2; goto out2;
} }
......
...@@ -50,7 +50,7 @@ int main(int argc, char *argv[]) ...@@ -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.link", "lxcbr0");
c->set_config_item(c, "lxc.network.flags", "up"); 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__); fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__);
goto out; goto out;
} }
......
...@@ -170,7 +170,7 @@ int main(int argc, char *argv[]) ...@@ -170,7 +170,7 @@ int main(int argc, char *argv[])
ret = 1; ret = 1;
goto out; 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__); fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__);
ret = 1; ret = 1;
goto out; goto out;
......
...@@ -51,7 +51,7 @@ int main(int argc, char *argv[]) ...@@ -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.link", "lxcbr0");
c->set_config_item(c, "lxc.network.flags", "up"); 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__); fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__);
goto out; goto out;
} }
......
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