The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/1750
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Signed-off-by: Christian Brauner <[email protected]>
From 300df83ecfa049baf709251c22ef2b16a4a97aa0 Mon Sep 17 00:00:00 2001 From: Christian Brauner <[email protected]> Date: Wed, 16 Aug 2017 01:05:06 +0200 Subject: [PATCH 1/3] confile: lxc_getconfig() -> lxc_get_config() Signed-off-by: Christian Brauner <[email protected]> --- 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 <[email protected]> Date: Wed, 16 Aug 2017 01:24:20 +0200 Subject: [PATCH 2/3] confile: list namespaced keys Signed-off-by: Christian Brauner <[email protected]> --- 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 <[email protected]> Date: Wed, 16 Aug 2017 01:51:31 +0200 Subject: [PATCH 3/3] test: add test to get subkeys Signed-off-by: Christian Brauner <[email protected]> --- 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:
_______________________________________________ lxc-devel mailing list [email protected] http://lists.linuxcontainers.org/listinfo/lxc-devel
