[lxc-devel] [lxc/master] confile: list namespaced keys

brauner on Github lxc-bot at linuxcontainers.org
Tue Aug 15 23:53:11 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170815/a3a6f7d5/attachment.bin>
-------------- next part --------------
From 300df83ecfa049baf709251c22ef2b16a4a97aa0 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 16 Aug 2017 01:05:06 +0200
Subject: [PATCH 1/3] confile: lxc_getconfig() -> lxc_get_config()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/commands.c            |  2 +-
 src/lxc/confile.c             |  9 ++++++---
 src/lxc/confile.h             |  2 +-
 src/lxc/confile_legacy.c      |  2 +-
 src/lxc/lxccontainer.c        | 25 +++++++++++++++----------
 src/tests/config_jump_table.c |  2 +-
 6 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/src/lxc/commands.c b/src/lxc/commands.c
index c6ece2cc7..68fbd387c 100644
--- a/src/lxc/commands.c
+++ b/src/lxc/commands.c
@@ -516,7 +516,7 @@ static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
 	struct lxc_config_t *item;
 
 	memset(&rsp, 0, sizeof(rsp));
-	item = lxc_getconfig(req->data);
+	item = lxc_get_config(req->data);
 	if (!item)
 		goto err1;
 	cilen = item->get(req->data, NULL, 0, handler->conf, NULL);
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 4c55ad79e..f9b3cf925 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -356,13 +356,14 @@ static const struct signame signames[] = {
 
 static const size_t config_size = sizeof(config) / sizeof(struct lxc_config_t);
 
-extern struct lxc_config_t *lxc_getconfig(const char *key)
+struct lxc_config_t *lxc_get_config(const char *key)
 {
 	size_t i;
 
 	for (i = 0; i < config_size; i++)
 		if (!strncmp(config[i].name, key, strlen(config[i].name)))
 			return &config[i];
+
 	return NULL;
 }
 
@@ -2038,7 +2039,7 @@ static int parse_line(char *buffer, void *data)
 		}
 	}
 
-	config = lxc_getconfig(key);
+	config = lxc_get_config(key);
 	if (!config) {
 		ERROR("unknown key %s", key);
 		goto out;
@@ -3607,7 +3608,7 @@ static struct lxc_config_t *get_network_config_ops(const char *key,
 		memmove(copy + 8, idx_end + 1, strlen(idx_end + 1));
 		copy[strlen(key) - numstrlen + 1] = '\0';
 
-		config = lxc_getconfig(copy);
+		config = lxc_get_config(copy);
 		if (!config) {
 			ERROR("unknown network configuration key %s", key);
 			goto on_error;
@@ -4442,8 +4443,10 @@ int lxc_list_config_items(char *retv, int inlen)
 
 	for (i = 0; i < config_size; i++) {
 		char *s = config[i].name;
+
 		if (s[strlen(s) - 1] == '.')
 			continue;
+
 		strprint(retv, inlen, "%s\n", s);
 	}
 
diff --git a/src/lxc/confile.h b/src/lxc/confile.h
index ef0343945..88a98cfb2 100644
--- a/src/lxc/confile.h
+++ b/src/lxc/confile.h
@@ -47,7 +47,7 @@ struct lxc_config_t {
 	config_clr_cb clr;
 };
 
-extern struct lxc_config_t *lxc_getconfig(const char *key);
+extern struct lxc_config_t *lxc_get_config(const char *key);
 
 /* List all configuration items associated with a given network. For example
  * pass "lxc.net.[i]" to retrieve all configuration items associated with
diff --git a/src/lxc/confile_legacy.c b/src/lxc/confile_legacy.c
index 5dddfe139..f3bd8fbaf 100644
--- a/src/lxc/confile_legacy.c
+++ b/src/lxc/confile_legacy.c
@@ -91,7 +91,7 @@ int set_config_network_legacy_nic(const char *key, const char *value,
 		goto out;
 
 	strcpy(copy + 12, p + 1);
-	config = lxc_getconfig(copy);
+	config = lxc_get_config(copy);
 	if (!config) {
 		ERROR("unknown key %s", key);
 		goto out;
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 34696069c..564d3aa7e 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1902,7 +1902,7 @@ static bool do_lxcapi_clear_config_item(struct lxc_container *c,
 	if (container_mem_lock(c))
 		return false;
 
-	config = lxc_getconfig(key);
+	config = lxc_get_config(key);
 	/* Verify that the config key exists and that it has a callback
 	 * implemented.
 	 */
@@ -2218,7 +2218,7 @@ static int do_lxcapi_get_config_item(struct lxc_container *c, const char *key, c
 	if (container_mem_lock(c))
 		return -1;
 
-	config = lxc_getconfig(key);
+	config = lxc_get_config(key);
 	/* Verify that the config key exists and that it has a callback
 	 * implemented.
 	 */
@@ -2248,22 +2248,27 @@ WRAP_API_1(char *, lxcapi_get_running_config_item, const char *)
 
 static int do_lxcapi_get_keys(struct lxc_container *c, const char *key, char *retv, int inlen)
 {
+	int ret = -1;
+
+	/* List all config items. */
 	if (!key)
 		return lxc_list_config_items(retv, inlen);
-	/*
-	 * Support 'lxc.net.<idx>', i.e. 'lxc.net.0'
-	 * This is an intelligent result to show which keys are valid given
-	 * the type of nic it is
-	 */
+
 	if (!c || !c->lxc_conf)
 		return -1;
+
 	if (container_mem_lock(c))
 		return -1;
-	int ret = -1;
+
+	/* Support 'lxc.net.<idx>', i.e. 'lxc.net.0'
+	 * This is an intelligent result to show which keys are valid given the
+	 * type of nic it is.
+	 */
 	if (!strncmp(key, "lxc.net.", 8))
 		ret = lxc_list_net(c->lxc_conf, key, retv, inlen);
 	else if (strncmp(key, "lxc.network.", 12) == 0)
 		ret = lxc_list_nicconfigs_legacy(c->lxc_conf, key, retv, inlen);
+
 	container_mem_unlock(c);
 	return ret;
 }
@@ -2755,7 +2760,7 @@ static bool set_config_item_locked(struct lxc_container *c, const char *key, con
 	if (!c->lxc_conf)
 		return false;
 
-	config = lxc_getconfig(key);
+	config = lxc_get_config(key);
 	if (!config)
 		return false;
 
@@ -4867,5 +4872,5 @@ int list_all_containers(const char *lxcpath, char ***nret,
 
 bool lxc_config_item_is_supported(const char *key)
 {
-	return !!lxc_getconfig(key);
+	return !!lxc_get_config(key);
 }
diff --git a/src/tests/config_jump_table.c b/src/tests/config_jump_table.c
index 1fb244d42..8e86c48e4 100644
--- a/src/tests/config_jump_table.c
+++ b/src/tests/config_jump_table.c
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])
 	for (key = strtok_r(keys, "\n", &saveptr); key != NULL;
 	     key = strtok_r(NULL, "\n", &saveptr)) {
 		struct lxc_config_t *config;
-		config = lxc_getconfig(key);
+		config = lxc_get_config(key);
 		if (!config) {
 			lxc_error("configuration key \"%s\" not implemented in "
 				  "jump table",

From fe9b7349dde985300436c85b234b03cff839b92b Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 16 Aug 2017 01:24:20 +0200
Subject: [PATCH 2/3] confile: list namespaced keys

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/confile.c      | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/confile.h      | 46 ++++++++++++++++++++++++++++++++-----
 src/lxc/lxccontainer.c |  2 ++
 3 files changed, 103 insertions(+), 6 deletions(-)

diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index f9b3cf925..7bd71e366 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -4453,6 +4453,67 @@ int lxc_list_config_items(char *retv, int inlen)
 	return fulllen;
 }
 
+int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv,
+		     int inlen)
+{
+	int len;
+	int fulllen = 0;
+
+	if (!retv)
+		inlen = 0;
+	else
+		memset(retv, 0, inlen);
+
+	if (!strcmp(key, "lxc.apparmor")) {
+		strprint(retv, inlen, "allow_incomplete\n");
+		strprint(retv, inlen, "profile\n");
+	} else if (!strcmp(key, "lxc.selinux")) {
+		strprint(retv, inlen, "context\n");
+	} else if (!strcmp(key, "lxc.mount")) {
+		strprint(retv, inlen, "auto\n");
+		strprint(retv, inlen, "entry\n");
+		strprint(retv, inlen, "fstab\n");
+	} else if (!strcmp(key, "lxc.rootfs")) {
+		strprint(retv, inlen, "mount\n");
+		strprint(retv, inlen, "options\n");
+		strprint(retv, inlen, "path\n");
+	} else if (!strcmp(key, "lxc.uts")) {
+		strprint(retv, inlen, "name\n");
+	} else if (!strcmp(key, "lxc.hook")) {
+		strprint(retv, inlen, "autodev\n");
+		strprint(retv, inlen, "clone\n");
+		strprint(retv, inlen, "destroy\n");
+		strprint(retv, inlen, "mount\n");
+		strprint(retv, inlen, "post-stop\n");
+		strprint(retv, inlen, "pre-mount\n");
+		strprint(retv, inlen, "pre-start\n");
+		strprint(retv, inlen, "start\n");
+		strprint(retv, inlen, "stop\n");
+	} else if (!strcmp(key, "lxc.cap")) {
+		strprint(retv, inlen, "drop\n");
+		strprint(retv, inlen, "keep\n");
+	} else if (!strcmp(key, "lxc.console")) {
+		strprint(retv, inlen, "logfile\n");
+		strprint(retv, inlen, "path\n");
+	} else if (!strcmp(key, "lxc.seccomp")) {
+		strprint(retv, inlen, "profile\n");
+	} else if (!strcmp(key, "lxc.signal")) {
+		strprint(retv, inlen, "halt\n");
+		strprint(retv, inlen, "reboot\n");
+		strprint(retv, inlen, "stop\n");
+	} else if (!strcmp(key, "lxc.start")) {
+		strprint(retv, inlen, "auto\n");
+		strprint(retv, inlen, "delay\n");
+		strprint(retv, inlen, "order\n");
+	} else if (!strcmp(key, "lxc.monitor")) {
+		strprint(retv, inlen, "unshare\n");
+	} else {
+		fulllen = -1;
+	}
+
+	return fulllen;
+}
+
 int lxc_list_net(struct lxc_conf *c, const char *key, char *retv, int inlen)
 {
 	int len;
diff --git a/src/lxc/confile.h b/src/lxc/confile.h
index 88a98cfb2..50c09ba29 100644
--- a/src/lxc/confile.h
+++ b/src/lxc/confile.h
@@ -33,10 +33,21 @@
 struct lxc_conf;
 struct lxc_list;
 
+/* Callback prototype to set a configuration item.
+ * Must be implemented when adding a new configuration key.
+ */
 typedef int (*config_set_cb)(const char *key, const char *value,
 			     struct lxc_conf *conf, void *data);
+
+/* Callback prototype to get a configuration item.
+ * Must be implemented when adding a new configuration key.
+ */
 typedef int (*config_get_cb)(const char *key, char *value, int inlen,
 			     struct lxc_conf *conf, void *data);
+
+/* Callback prototype to clear a configuration item.
+ * Must be implemented when adding a new configuration key.
+ */
 typedef int (*config_clr_cb)(const char *key, struct lxc_conf *conf,
 			     void *data);
 
@@ -47,37 +58,60 @@ struct lxc_config_t {
 	config_clr_cb clr;
 };
 
+/* Get the jump table entry for the given configuration key. */
 extern struct lxc_config_t *lxc_get_config(const char *key);
 
+/* List all available config items. */
+extern int lxc_list_config_items(char *retv, int inlen);
+
+/* Given a configuration key namespace (e.g. lxc.apparmor) list all associated
+ * subkeys for that namespace.
+ * Must be implemented when adding a new configuration key.
+ */
+extern int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv,
+			    int inlen);
+
 /* List all configuration items associated with a given network. For example
  * pass "lxc.net.[i]" to retrieve all configuration items associated with
  * the network associated with index [i].
  */
 extern int lxc_list_net(struct lxc_conf *c, const char *key, char *retv,
 			int inlen);
-extern int lxc_list_config_items(char *retv, int inlen);
-extern int lxc_config_read(const char *file, struct lxc_conf *conf, bool from_include);
+
+extern int lxc_config_read(const char *file, struct lxc_conf *conf,
+			   bool from_include);
+
 extern int append_unexp_config_line(const char *line, struct lxc_conf *conf);
 
 extern int lxc_config_define_add(struct lxc_list *defines, char* arg);
+
 extern int lxc_config_define_load(struct lxc_list *defines,
 				  struct lxc_conf *conf);
 
 /* needed for lxc-attach */
 extern signed long lxc_config_parse_arch(const char *arch);
+
 extern int lxc_fill_elevated_privileges(char *flaglist, int *flags);
 
 extern int lxc_clear_config_item(struct lxc_conf *c, const char *key);
+
 extern void write_config(FILE *fout, struct lxc_conf *c);
 
-extern bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key, const char *v);
+extern bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key,
+					const char *v);
 
 /* These are used when cloning a container */
-extern void clear_unexp_config_line(struct lxc_conf *conf, const char *key, bool rm_subkeys);
+extern void clear_unexp_config_line(struct lxc_conf *conf, const char *key,
+				    bool rm_subkeys);
+
 extern bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
-	const char *newpath, const char *oldname, const char *newmame);
+				     const char *newpath, const char *oldname,
+				     const char *newmame);
+
 bool clone_update_unexp_ovl_paths(struct lxc_conf *conf, const char *oldpath,
 				  const char *newpath, const char *oldname,
 				  const char *newname, const char *ovldir);
+
 extern bool network_new_hwaddrs(struct lxc_conf *conf);
-#endif
+
+#endif /* __LXC_CONFILE_H */
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 564d3aa7e..1f15ee1df 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -2268,6 +2268,8 @@ static int do_lxcapi_get_keys(struct lxc_container *c, const char *key, char *re
 		ret = lxc_list_net(c->lxc_conf, key, retv, inlen);
 	else if (strncmp(key, "lxc.network.", 12) == 0)
 		ret = lxc_list_nicconfigs_legacy(c->lxc_conf, key, retv, inlen);
+	else
+		ret = lxc_list_subkeys(c->lxc_conf, key, retv, inlen);
 
 	container_mem_unlock(c);
 	return ret;

From c8313003e8c305c519576a8534c9171beee292ae Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 16 Aug 2017 01:51:31 +0200
Subject: [PATCH 3/3] test: add test to get subkeys

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/tests/getkeys.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 103 insertions(+), 4 deletions(-)

diff --git a/src/tests/getkeys.c b/src/tests/getkeys.c
index ed68440b7..6055d9179 100644
--- a/src/tests/getkeys.c
+++ b/src/tests/getkeys.c
@@ -16,15 +16,17 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-#include <lxc/lxccontainer.h>
 
-#include <unistd.h>
+#include <errno.h>
 #include <signal.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
-#include <stdlib.h>
-#include <errno.h>
+#include <lxc/lxccontainer.h>
+
 #include "lxc/state.h"
 
 #define MYNAME "lxctest1"
@@ -64,6 +66,103 @@ int main(int argc, char *argv[])
 		goto out;
 	}
 	printf("get_keys for nic 1 returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.apparmor", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.selinux", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.mount", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.rootfs", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.uts", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.hook", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.cap", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.console", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.seccomp", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.signal", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.start", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
+	ret = c->get_keys(c, "lxc.monitor", v3, 2000);
+	if (ret < 0) {
+		fprintf(stderr, "%d: failed to get keys(%d)\n", __LINE__, ret);
+		ret = 1;
+		goto out;
+	}
+	printf("get_keys returned %d\n%s", ret, v3);
+
 	ret = 0;
 
 out:


More information about the lxc-devel mailing list