Quoting Christian Seiler (christ...@iwakd.de): > Signed-off-by: Christian Seiler <christ...@iwakd.de>
Acked-by: Serge E. Hallyn <serge.hal...@ubuntu.com> > --- > src/lxc/lxccontainer.c | 124 > ++++++++++++++++++++++++++++-------------------- > src/lxc/lxccontainer.h | 8 +++- > 2 files changed, 80 insertions(+), 52 deletions(-) > > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c > index 3affe22..1c77b63 100644 > --- a/src/lxc/lxccontainer.c > +++ b/src/lxc/lxccontainer.c > @@ -18,6 +18,7 @@ > */ > > #define _GNU_SOURCE > +#include <stdarg.h> > #include <pthread.h> > #include <unistd.h> > #include <sys/types.h> > @@ -38,6 +39,7 @@ > #include "log.h" > #include "bdev.h" > #include "utils.h" > +#include "attach.h" > #include <lxc/utils.h> > #include <lxc/monitor.h> > #include <sched.h> > @@ -583,51 +585,30 @@ reboot: > static bool lxcapi_startl(struct lxc_container *c, int useinit, ...) > { > va_list ap; > - char **inargs = NULL, **temp; > - int n_inargs = 0; > + char **inargs = NULL; > bool bret = false; > > /* container exists */ > if (!c) > return false; > > - /* build array of arguments if any */ > va_start(ap, useinit); > - while (1) { > - char *arg; > - arg = va_arg(ap, char *); > - if (!arg) > - break; > - n_inargs++; > - temp = realloc(inargs, n_inargs * sizeof(*inargs)); > - if (!temp) { > - va_end(ap); > - goto out; > - } > - inargs = temp; > - inargs[n_inargs - 1] = strdup(arg); // not sure if it's safe > not to copy > - } > + inargs = lxc_va_arg_list_to_argv(ap, 0, 1); > va_end(ap); > > - /* add trailing NULL */ > - if (n_inargs) { > - n_inargs++; > - temp = realloc(inargs, n_inargs * sizeof(*inargs)); > - if (!temp) > - goto out; > - inargs = temp; > - inargs[n_inargs - 1] = NULL; > + if (!inargs) { > + ERROR("Memory allocation error."); > + goto out; > } > > - bret = lxcapi_start(c, useinit, inargs); > + /* pass NULL if no arguments were supplied */ > + bret = lxcapi_start(c, useinit, *inargs ? inargs : NULL); > > out: > if (inargs) { > - int i; > - for (i = 0; i < n_inargs; i++) { > - if (inargs[i]) > - free(inargs[i]); > - } > + char *arg; > + for (arg = *inargs; arg; arg++) > + free(arg); > free(inargs); > } > > @@ -1133,9 +1114,8 @@ static bool lxcapi_createl(struct lxc_container *c, > const char *t, > const char *bdevtype, struct bdev_specs *specs, int flags, ...) > { > bool bret = false; > - char **args = NULL, **temp; > + char **args = NULL; > va_list ap; > - int nargs = 0; > > if (!c) > return false; > @@ -1145,29 +1125,17 @@ static bool lxcapi_createl(struct lxc_container *c, > const char *t, > * need to get a copy of the arguments. > */ > va_start(ap, flags); > - while (1) { > - char *arg; > - arg = va_arg(ap, char *); > - if (!arg) > - break; > - nargs++; > - temp = realloc(args, (nargs+1) * sizeof(*args)); > - if (!temp) { > - va_end(ap); > - goto out; > - } > - args = temp; > - args[nargs - 1] = arg; > - } > + args = lxc_va_arg_list_to_argv(ap, 0, 0); > va_end(ap); > - if (args) > - args[nargs] = NULL; > + if (!args) { > + ERROR("Memory allocation error."); > + goto out; > + } > > bret = c->create(c, t, bdevtype, specs, flags, args); > > out: > - if (args) > - free(args); > + free(args); > return bret; > } > > @@ -2000,6 +1968,57 @@ out: > return NULL; > } > > +static int lxcapi_attach(struct lxc_container *c, lxc_attach_exec_t > exec_function, void *exec_payload, lxc_attach_options_t *options, pid_t > *attached_process) > +{ > + if (!c) > + return -1; > + > + return lxc_attach(c->name, c->config_path, exec_function, exec_payload, > options, attached_process); > +} > + > +static int lxcapi_attach_run_wait(struct lxc_container *c, > lxc_attach_options_t *options, const char *program, const char * const argv[]) > +{ > + lxc_attach_command_t command; > + pid_t pid; > + int r; > + > + if (!c) > + return -1; > + > + command.program = (char*)program; > + command.argv = (char**)argv; > + r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, > &command, options, &pid); > + if (r < 0) { > + ERROR("ups"); > + return r; > + } > + return lxc_wait_for_pid_status(pid); > +} > + > +static int lxcapi_attach_run_waitl(struct lxc_container *c, > lxc_attach_options_t *options, const char *program, const char *arg, ...) > +{ > + va_list ap; > + const char **argv; > + int ret; > + > + if (!c) > + return -1; > + > + va_start(ap, arg); > + argv = lxc_va_arg_list_to_argv_const(ap, 1); > + va_end(ap); > + > + if (!argv) { > + ERROR("Memory allocation error."); > + return -1; > + } > + argv[0] = arg; > + > + ret = lxcapi_attach_run_wait(c, options, program, (const char * const > *)argv); > + free((void*)argv); > + return ret; > +} > + > struct lxc_container *lxc_container_new(const char *name, const char > *configpath) > { > struct lxc_container *c; > @@ -2086,6 +2105,9 @@ struct lxc_container *lxc_container_new(const char > *name, const char *configpath > c->set_config_path = lxcapi_set_config_path; > c->clone = lxcapi_clone; > c->get_ips = lxcapi_get_ips; > + c->attach = lxcapi_attach; > + c->attach_run_wait = lxcapi_attach_run_wait; > + c->attach_run_waitl = lxcapi_attach_run_waitl; > > /* we'll allow the caller to update these later */ > if (lxc_log_init(NULL, "none", NULL, "lxc_container", 0, > c->config_path)) { > diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h > index 3399c7f..e0c465c 100644 > --- a/src/lxc/lxccontainer.h > +++ b/src/lxc/lxccontainer.h > @@ -1,6 +1,7 @@ > #ifndef __LXC_CONTAINER_H > #define __LXC_CONTAINER_H > #include "lxclock.h" > +#include "attach_options.h" > #include <stdlib.h> > #include <malloc.h> > > @@ -150,12 +151,17 @@ struct lxc_container { > int (*console)(struct lxc_container *c, int ttynum, > int stdinfd, int stdoutfd, int stderrfd, int escape); > > + /* create subprocess and attach it to the container, run exec_function > inside */ > + int (*attach)(struct lxc_container *c, lxc_attach_exec_t exec_function, > void *exec_payload, lxc_attach_options_t *options, pid_t *attached_process); > + > + /* run program in container, wait for it to exit */ > + int (*attach_run_wait)(struct lxc_container *c, lxc_attach_options_t > *options, const char *program, const char * const argv[]); > + int (*attach_run_waitl)(struct lxc_container *c, lxc_attach_options_t > *options, const char *program, const char *arg, ...); > #if 0 > bool (*commit_cgroups)(struct lxc_container *c); > bool (*reread_cgroups)(struct lxc_container *c); > // question with clone: how do we handle non-standard config file in > orig? > struct lxc_container (*clone)(struct container *c); > - int (*ns_attach)(struct lxc_container *c, int ns_mask); > // we'll need some plumbing to support lxc-console > #endif > }; > -- > 1.7.10.4 > > > ------------------------------------------------------------------------------ > Get 100% visibility into Java/.NET code with AppDynamics Lite! > It's a free troubleshooting tool designed for production. > Get down to code-level detail for bottlenecks, with <2% overhead. > Download for free and get started troubleshooting in minutes. > http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk > _______________________________________________ > Lxc-devel mailing list > Lxc-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/lxc-devel ------------------------------------------------------------------------------ Get 100% visibility into Java/.NET code with AppDynamics Lite! It's a free troubleshooting tool designed for production. Get down to code-level detail for bottlenecks, with <2% overhead. Download for free and get started troubleshooting in minutes. http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel