[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