This patch allows to create application containers with liblxc.so directly.
Some code cleanups on the way:
- separate ops for lxc_execute() and lxc_start(): the factorisation is wrong
here as we may have specific things to do if we're running an application
container. It deserves separate ops.
- lxc_arguments_dup() is merged in the pre-exec operation: this is a first
use for the execute op introduced just above. It's better to build the
arguments to execvp() where they're really used.
Signed-off-by: Greg Kurz <gkurz@fr.ibm.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Cc: Cedric Le Goater <clg@fr.ibm.com>
commands.c commands.h \
start.c start.h \
stop.c \
+ execute.c \
monitor.c monitor.h \
console.c \
freezer.c \
return ret;
}
-extern char **lxc_arguments_dup(const char *file, struct lxc_arguments *args)
-{
- char **argv;
- int opt, nbargs = args->argc + 2;
-
- if (args->quiet)
- nbargs += 1;
-
- argv = malloc((nbargs + 1) * sizeof(*argv));
- if (!argv)
- return NULL;
-
- nbargs = 0;
-
- argv[nbargs] = strdup(file);
- if (!argv[nbargs])
- return NULL;
- nbargs++;
-
- if (args->quiet)
- argv[nbargs++] = "--quiet";
-
- argv[nbargs++] = "--";
-
- for (opt = 0; opt < args->argc; opt++) {
- argv[nbargs] = strdup(args->argv[opt]);
- if (!argv[nbargs])
- return NULL;
- nbargs++;
- }
-
- argv[nbargs] = NULL;
-
- return argv;
-}
-
int lxc_arguments_str_to_int(struct lxc_arguments *args, const char *str)
{
long val;
extern int lxc_arguments_parse(struct lxc_arguments *args,
int argc, char *const argv[]);
-extern char **lxc_arguments_dup(const char *file, struct lxc_arguments *args);
extern int lxc_arguments_str_to_int(struct lxc_arguments *args, const char *str);
extern const char *lxc_strerror(int errnum);
--- /dev/null
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "log.h"
+#include "start.h"
+
+lxc_log_define(lxc_execute, lxc_start);
+
+struct execute_args {
+ char *const *argv;
+ int quiet;
+};
+
+static int execute_start(struct lxc_handler *handler, void* data)
+{
+ int j, i = 0;
+ struct execute_args *my_args = data;
+ char **argv;
+ int argc = 0;
+
+ while (my_args->argv[argc++]);
+
+ argv = malloc((argc + my_args->quiet ? 5 : 4) * sizeof(*argv));
+ if (!argv)
+ return 1;
+
+ argv[i++] = LXCINITDIR "/lxc-init";
+ if (my_args->quiet)
+ argv[i++] = "--quiet";
+ argv[i++] = "--";
+ for (j = 0; j < argc; j++)
+ argv[i++] = my_args->argv[j];
+ argv[i++] = NULL;
+
+ NOTICE("exec'ing '%s'", my_args->argv[0]);
+
+ execvp(argv[0], argv);
+ SYSERROR("failed to exec %s", argv[0]);
+ return 1;
+}
+
+static int execute_post_start(struct lxc_handler *handler, void* data)
+{
+ struct execute_args *my_args = data;
+ NOTICE("'%s' started with pid '%d'", my_args->argv[0], handler->pid);
+ return 0;
+}
+
+static struct lxc_operations execute_start_ops = {
+ .start = execute_start,
+ .post_start = execute_post_start
+};
+
+int lxc_execute(const char *name, char *const argv[], int quiet,
+ struct lxc_conf *conf)
+{
+ struct execute_args args = {
+ .argv = argv,
+ .quiet = quiet
+ };
+
+ if (lxc_check_inherited(-1))
+ return -1;
+
+ return __lxc_start(name, conf, &execute_start_ops, &args);
+}
struct lxc_msg;
struct lxc_conf;
+struct lxc_arguments;
/**
Following code is for liblxc.
**/
/*
- * Start the specified command inside a container
+ * Start the specified command inside a system container
* @name : the name of the container
* @argv : an array of char * corresponding to the commande line
* @conf : configuration
*/
extern int lxc_stop(const char *name);
+/*
+ * Start the specified command inside an application container
+ * @name : the name of the container
+ * @argv : an array of char * corresponding to the commande line
+ * @quiet : if != 0 then lxc-init won't produce any output
+ * @conf : configuration
+ * Returns 0 on sucess, < 0 otherwise
+ */
+extern int lxc_execute(const char *name, char *const argv[], int quiet,
+ struct lxc_conf *conf);
+
/*
* Open the monitoring mechanism for a specific container
* The function will return an fd corresponding to the events
#include "confile.h"
#include "arguments.h"
#include "config.h"
+#include "start.h"
-lxc_log_define(lxc_execute_ui, lxc_start);
+lxc_log_define(lxc_execute_ui, lxc_execute);
static struct lxc_list defines;
int main(int argc, char *argv[])
{
- static char **args;
char *rcfile;
struct lxc_conf *conf;
my_args.progname, my_args.quiet))
return -1;
- args = lxc_arguments_dup(LXCINITDIR "/lxc-init", &my_args);
- if (!args)
- return -1;
-
/* rcfile is specified in the cli option */
if (my_args.rcfile)
rcfile = (char *)my_args.rcfile;
if (lxc_config_define_load(&defines, conf))
return -1;
- return lxc_start(my_args.name, args, conf);
+ return lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf);
}
-