[lxc-devel] [lxc/master] Make lxc-config use the lxc parser

brauner on Github lxc-bot at linuxcontainers.org
Sat Feb 13 13:23:02 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 883 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160213/76fb0440/attachment.bin>
-------------- next part --------------
From 33944e6a3166f2a1e40772557676c998936876f7 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at mailbox.org>
Date: Sat, 13 Feb 2016 13:59:16 +0100
Subject: [PATCH 1/2] Make lxc-config use the lxc parser

For this to work we need to change one command line flag:
	-l becomes -L/--list
-l is used by the lxc parser to specify a log file.

Signed-off-by: Christian Brauner <christian.brauner at mailbox.org>
---
 src/lxc/arguments.h  |  2 +-
 src/lxc/lxc_config.c | 93 ++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 73 insertions(+), 22 deletions(-)

diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h
index 861437e..70f0e38 100644
--- a/src/lxc/arguments.h
+++ b/src/lxc/arguments.h
@@ -99,7 +99,7 @@ struct lxc_arguments {
 	/* auto-start */
 	int all;
 	int ignore_auto;
-	int list;
+	int list; /* also used by lxc-config */
 	char *groups; /* also used by lxc-ls */
 
 	/* lxc-snapshot and lxc-clone */
diff --git a/src/lxc/lxc_config.c b/src/lxc/lxc_config.c
index d146ad8..2c8e1a6 100644
--- a/src/lxc/lxc_config.c
+++ b/src/lxc/lxc_config.c
@@ -23,7 +23,30 @@
 
 #include <lxc/lxccontainer.h>
 
+#include "arguments.h"
 #include "config.h"
+#include "log.h"
+
+static int my_parser(struct lxc_arguments* args, int c, char* arg);
+
+static const struct option my_longopts[] = {
+	{"list", no_argument, 0, 'L'},
+	LXC_COMMON_OPTIONS
+};
+
+static struct lxc_arguments my_args = {
+	.progname = "lxc-config",
+	.help     = "\
+--list\n\
+ITEM\n\
+\n\
+lxc-config queries the lxc system configuration\n\
+\n\
+Options :\n\
+  -L, --list	list all supported keys\n",
+	.options  = my_longopts,
+	.parser   = my_parser,
+};
 
 struct lxc_config_items {
 	char *name;
@@ -41,20 +64,12 @@ static struct lxc_config_items items[] =
 	{ .name = NULL, },
 };
 
-static void usage(char *me)
-{
-	printf("Usage: %s -l: list all available configuration items\n", me);
-	printf("       %s item: print configuration item\n", me);
-	exit(1);
-}
-
 static void list_config_items(void)
 {
 	struct lxc_config_items *i;
 
 	for (i = &items[0]; i->name; i++)
 		printf("%s\n", i->name);
-	exit(0);
 }
 
 int main(int argc, char *argv[])
@@ -62,20 +77,56 @@ int main(int argc, char *argv[])
 	struct lxc_config_items *i;
 	const char *value;
 
-	if (argc < 2)
-		usage(argv[0]);
-	if (strcmp(argv[1], "-l") == 0)
+	/*
+	 * The lxc parser requires that my_args.name is set. So let's satisfy
+	 * that condition by setting a dummy name which is never used.
+	 */
+	my_args.name  = "";
+	if (lxc_arguments_parse(&my_args, argc, argv))
+		exit(EXIT_FAILURE);
+
+	if (!my_args.log_file)
+		my_args.log_file = "none";
+
+	/*
+	 * We set the first argument that usually takes my_args.name to NULL so
+	 * that the log is only used when the user specifies a file.
+	 */
+	if (lxc_log_init(NULL, my_args.log_file, my_args.log_priority,
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
+		exit(EXIT_FAILURE);
+	lxc_log_options_no_override();
+
+	if (my_args.list) {
 		list_config_items();
-	for (i = &items[0]; i->name; i++) {
-		if (strcmp(argv[1], i->name) == 0) {
-			value = lxc_get_global_config_item(i->name);
-			if (value)
-				printf("%s\n", value);
-			else
-				printf("%s is not set.\n", argv[1]);
-			exit(0);
+	} else if (my_args.argc == 1) {
+		for (i = &items[0]; i->name; i++) {
+			if (strcmp(my_args.argv[0], i->name) == 0) {
+				value = lxc_get_global_config_item(i->name);
+				if (value)
+					printf("%s\n", value);
+				else if (!my_args.quiet)
+					printf("%s is not set.\n", my_args.argv[0]);
+				break; /* avoid pointless work */
+			}
 		}
+		if (!i->name && !my_args.quiet)
+			printf("Unknown configuration item: %s\n", my_args.argv[0]);
 	}
-	printf("Unknown configuration item: %s\n", argv[1]);
-	exit(1);
+
+	exit(EXIT_SUCCESS);
 }
+
+static int my_parser(struct lxc_arguments *args, int c, char *arg)
+{
+	switch (c) {
+	case 'L':
+		args->list = 1;
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+

From 27983081a1b93f4cd131c20c73b9a9e2c94996d1 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at mailbox.org>
Date: Sat, 13 Feb 2016 14:11:35 +0100
Subject: [PATCH 2/2] Minor printing and function changes

Signed-off-by: Christian Brauner <christian.brauner at mailbox.org>
---
 src/lxc/lxc_unshare.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/src/lxc/lxc_unshare.c b/src/lxc/lxc_unshare.c
index e629525..bccfe28 100644
--- a/src/lxc/lxc_unshare.c
+++ b/src/lxc/lxc_unshare.c
@@ -69,15 +69,15 @@ struct my_iflist
 static void usage(char *cmd)
 {
 	fprintf(stderr, "%s <options> command [command_arguments]\n", basename(cmd));
-	fprintf(stderr, "Options are:\n");
-	fprintf(stderr, "\t -s flags   : ORed list of flags to unshare:\n" \
-			"\t           MOUNT, PID, UTSNAME, IPC, USER, NETWORK\n");
-	fprintf(stderr, "\t -u <id>      : new id to be set if -s USER is specified\n");
-	fprintf(stderr, "\t -i <iface>   : Interface name to be moved into container (presumably with NETWORK unsharing set)\n");
-	fprintf(stderr, "\t -H <hostname>: Set the hostname in the container\n");
-	fprintf(stderr, "\t -d           : Daemonize (do not wait for container to exit)\n");
-	fprintf(stderr, "\t -M           : reMount default fs inside container (/proc /dev/shm /dev/mqueue)\n");
-	_exit(1);
+	fprintf(stderr, "Options are\n");
+	fprintf(stderr, "\t -s flags      : ORed list of flags to unshare:\n" \
+			"\t                 MOUNT, PID, UTSNAME, IPC, USER, NETWORK\n");
+	fprintf(stderr, "\t -u <id>       : new id to be set if -s USER is specified\n");
+	fprintf(stderr, "\t -i <iface>    : Interface name to be moved into container (presumably with NETWORK unsharing set)\n");
+	fprintf(stderr, "\t -H <hostname> : Set the hostname in the container\n");
+	fprintf(stderr, "\t -d            : Daemonize (do not wait for container to exit)\n");
+	fprintf(stderr, "\t -M            : remount default fs inside container (/proc /dev/shm /dev/mqueue)\n");
+	_exit(EXIT_FAILURE);
 }
 
 static bool lookup_user(const char *optarg, uid_t *uid)
@@ -109,7 +109,6 @@ static bool lookup_user(const char *optarg, uid_t *uid)
 	return true;
 }
 
-
 struct start_arg {
 	char ***args;
 	int *flags;
@@ -134,19 +133,19 @@ static int do_start(void *arg)
 	if ((flags & CLONE_NEWUTS) && want_hostname)
 		if (sethostname(want_hostname, strlen(want_hostname)) < 0) {
 			ERROR("failed to set hostname %s: %s", want_hostname, strerror(errno));
-			exit(1);
+			exit(EXIT_FAILURE);
 		}
 
 	// Setuid is useful even without a new user id space
 	if (start_arg->setuid && setuid(uid)) {
 		ERROR("failed to set uid %d: %s", uid, strerror(errno));
-		exit(1);
+		exit(EXIT_FAILURE);
 	}
 
 	execvp(args[0], args);
 
 	ERROR("failed to exec: '%s': %s", args[0], strerror(errno));
-	return 1;
+	exit(EXIT_FAILURE);
 }
 
 int main(int argc, char *argv[])
@@ -177,7 +176,7 @@ int main(int argc, char *argv[])
 		case 'i':
 			if (!(tmpif = malloc(sizeof(*tmpif)))) {
 				perror("malloc");
-				exit(1);
+				exit(EXIT_FAILURE);
 			}
 			tmpif->mi_ifname = optarg;
 			tmpif->mi_next = my_iflist;
@@ -246,7 +245,7 @@ int main(int argc, char *argv[])
 	}
 
 	if (daemonize)
-		exit(0);
+		exit(EXIT_SUCCESS);
 
 	if (waitpid(pid, &status, 0) < 0) {
 		ERROR("failed to wait for '%d'", pid);


More information about the lxc-devel mailing list