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

Reply via email to