[lxc-devel] [PATCH] lxc: introduce lxc_execute()

Greg Kurz gkurz at fr.ibm.com
Mon Oct 17 18:47:50 UTC 2011


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 at fr.ibm.com>
Cc: Cedric Le Goater <clg at fr.ibm.com>
---

 src/lxc/Makefile.am   |    1 +
 src/lxc/arguments.c   |   36 --------------------
 src/lxc/arguments.h   |    1 -
 src/lxc/execute.c     |   90 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/lxc.h         |   14 +++++++-
 src/lxc/lxc_execute.c |   11 ++----
 6 files changed, 107 insertions(+), 46 deletions(-)
 create mode 100644 src/lxc/execute.c

diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
index d2c4720..2654675 100644
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -22,6 +22,7 @@ liblxc_so_SOURCES = \
 	commands.c commands.h \
 	start.c start.h \
 	stop.c \
+	execute.c \
 	monitor.c monitor.h \
 	console.c \
 	freezer.c \
diff --git a/src/lxc/arguments.c b/src/lxc/arguments.c
index 51ebadb..76d8366 100644
--- a/src/lxc/arguments.c
+++ b/src/lxc/arguments.c
@@ -206,42 +206,6 @@ error:
 	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;
diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h
index a2c35c4..d5ccaef 100644
--- a/src/lxc/arguments.h
+++ b/src/lxc/arguments.h
@@ -78,7 +78,6 @@ struct lxc_arguments {
 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);
diff --git a/src/lxc/execute.c b/src/lxc/execute.c
new file mode 100644
index 0000000..43210e2
--- /dev/null
+++ b/src/lxc/execute.c
@@ -0,0 +1,90 @@
+/*
+ * 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);
+}
diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h
index e6af295..ae8a3f7 100644
--- a/src/lxc/lxc.h
+++ b/src/lxc/lxc.h
@@ -32,6 +32,7 @@ extern "C" {
 
 struct lxc_msg;
 struct lxc_conf;
+struct lxc_arguments;
 
 /**
  Following code is for liblxc.
@@ -40,7 +41,7 @@ struct lxc_conf;
  **/
 
 /*
- * 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
@@ -57,6 +58,17 @@ extern int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf
 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
  * Returns a file descriptor on success, < 0 otherwise
diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c
index f480859..1eb25a7 100644
--- a/src/lxc/lxc_execute.c
+++ b/src/lxc/lxc_execute.c
@@ -38,8 +38,9 @@
 #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;
 
@@ -87,7 +88,6 @@ Options :\n\
 
 int main(int argc, char *argv[])
 {
-	static char **args;
 	char *rcfile;
 	struct lxc_conf *conf;
 
@@ -103,10 +103,6 @@ int main(int argc, char *argv[])
 			 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;
@@ -140,6 +136,5 @@ int main(int argc, char *argv[])
 	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);
 }
-





More information about the lxc-devel mailing list