Signed-off-by: Christian Seiler <christ...@iwakd.de>
---
 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

Reply via email to