[lxc-devel] [lxc/master] unit test idmap parser
brauner on Github
lxc-bot at linuxcontainers.org
Thu Jun 1 21:44:22 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/20170601/950b3671/attachment.bin>
-------------- next part --------------
From 9d03851990dccf216c2b40afe0ecaea2e71ad301 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 1 Jun 2017 23:43:16 +0200
Subject: [PATCH 1/2] confile: move idmap parser to separate helper
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/confile.c | 178 +++++++++++++++++++++++++++++++-----------------------
1 file changed, 101 insertions(+), 77 deletions(-)
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 4186d6347..ee15690e7 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -1979,131 +1979,156 @@ static int set_config_limit(const char *key, const char *value,
return -1;
}
-static int set_config_idmaps(const char *key, const char *value,
- struct lxc_conf *lxc_conf)
+static int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
+ unsigned long *hostid, unsigned long *range)
{
- unsigned long hostid, nsid, range;
- char type;
+ int ret = -1;
+ unsigned long tmp_hostid, tmp_nsid, tmp_range;
+ char tmp_type;
char *window, *slide;
char *dup = NULL;
- struct lxc_list *idmaplist = NULL;
- struct id_map *idmap = NULL;
-
- if (config_value_empty(value))
- return lxc_clear_idmaps(lxc_conf);
-
- idmaplist = malloc(sizeof(*idmaplist));
- if (!idmaplist)
- goto on_error;
-
- idmap = malloc(sizeof(*idmap));
- if (!idmap)
- goto on_error;
- memset(idmap, 0, sizeof(*idmap));
/* Duplicate string. */
- dup = strdup(value);
+ dup = strdup(idmap);
if (!dup)
goto on_error;
/* A prototypical idmap entry would be: "u 1000 1000000 65536" */
/* align */
- slide = window = dup;
- /* skip whitespace */
- slide += strspn(slide, " \t\r");
- if (slide != window && *slide == '\0')
- goto on_error;
+ slide = window = dup;
+ /* skip whitespace */
+ slide += strspn(slide, " \t\r");
+ if (slide != window && *slide == '\0')
+ goto on_error;
/* Validate type. */
- if (*slide != 'u' && *slide != 'g')
- goto on_error;
- /* Assign type. */
- type = *slide;
+ if (*slide != 'u' && *slide != 'g')
+ goto on_error;
+ /* Assign type. */
+ tmp_type = *slide;
/* move beyond type */
- slide++;
+ slide++;
/* align */
- window = slide;
- /* Validate that only whitespace follows. */
- slide += strspn(slide, " \t\r");
+ window = slide;
+ /* Validate that only whitespace follows. */
+ slide += strspn(slide, " \t\r");
/* There must be whitespace. */
- if (slide == window)
- goto on_error;
+ if (slide == window)
+ goto on_error;
- /* Mark beginning of nsuid. */
- window = slide;
+ /* Mark beginning of nsuid. */
+ window = slide;
/* Validate that non-whitespace follows. */
- slide += strcspn(slide, " \t\r");
+ slide += strcspn(slide, " \t\r");
/* There must be non-whitespace. */
- if (slide == window || *slide == '\0')
- goto on_error;
- /* Mark end of nsuid. */
- *slide = '\0';
+ if (slide == window || *slide == '\0')
+ goto on_error;
+ /* Mark end of nsuid. */
+ *slide = '\0';
- /* Parse nsuid. */
- if (lxc_safe_ulong(window, &nsid) < 0)
- goto on_error;
+ /* Parse nsuid. */
+ if (lxc_safe_ulong(window, &tmp_nsid) < 0)
+ goto on_error;
/* Move beyond \0. */
- slide++;
+ slide++;
/* align */
- window = slide;
- /* Validate that only whitespace follows. */
- slide += strspn(slide, " \t\r");
+ window = slide;
+ /* Validate that only whitespace follows. */
+ slide += strspn(slide, " \t\r");
/* If there was only one whitespace then we whiped it with our \0 above.
* So only ensure that we're not at the end of the string.
*/
if (*slide == '\0')
- goto on_error;
+ goto on_error;
- /* Mark beginning of hostid. */
- window = slide;
+ /* Mark beginning of hostid. */
+ window = slide;
/* Validate that non-whitespace follows. */
- slide += strcspn(slide, " \t\r");
+ slide += strcspn(slide, " \t\r");
/* There must be non-whitespace. */
- if (slide == window || *slide == '\0')
- goto on_error;
- /* Mark end of nsuid. */
- *slide = '\0';
+ if (slide == window || *slide == '\0')
+ goto on_error;
+ /* Mark end of nsuid. */
+ *slide = '\0';
- /* Parse hostid. */
- if (lxc_safe_ulong(window, &hostid) < 0)
- goto on_error;
+ /* Parse hostid. */
+ if (lxc_safe_ulong(window, &tmp_hostid) < 0)
+ goto on_error;
/* Move beyond \0. */
- slide++;
+ slide++;
/* align */
- window = slide;
- /* Validate that only whitespace follows. */
- slide += strspn(slide, " \t\r");
+ window = slide;
+ /* Validate that only whitespace follows. */
+ slide += strspn(slide, " \t\r");
/* If there was only one whitespace then we whiped it with our \0 above.
* So only ensure that we're not at the end of the string.
*/
- if (*slide == '\0')
- goto on_error;
+ if (*slide == '\0')
+ goto on_error;
- /* Mark beginning of range. */
- window = slide;
+ /* Mark beginning of range. */
+ window = slide;
/* Validate that non-whitespace follows. */
- slide += strcspn(slide, " \t\r");
+ slide += strcspn(slide, " \t\r");
/* There must be non-whitespace. */
- if (slide == window)
- goto on_error;
+ if (slide == window)
+ goto on_error;
/* The range is the last valid entry we expect. So make sure that there
* is not trailing garbage and if there is, error out.
*/
if (*(slide + strspn(slide, " \t\r\n")) != '\0')
- goto on_error;
- /* Mark end of range. */
- *slide = '\0';
+ goto on_error;
+ /* Mark end of range. */
+ *slide = '\0';
+
+ /* Parse range. */
+ if (lxc_safe_ulong(window, &tmp_range) < 0)
+ goto on_error;
- /* Parse range. */
- if (lxc_safe_ulong(window, &range) < 0)
- goto on_error;
+ *type = tmp_type;
+ *nsid = tmp_nsid;
+ *hostid = tmp_hostid;
+ *range = tmp_range;
/* Yay, we survived. */
+ ret = 0;
+
+on_error:
+ free(dup);
+
+ return ret;
+}
+
+static int set_config_idmaps(const char *key, const char *value,
+ struct lxc_conf *lxc_conf)
+{
+ unsigned long hostid, nsid, range;
+ char type;
+ int ret;
+ struct lxc_list *idmaplist = NULL;
+ struct id_map *idmap = NULL;
+
+ if (config_value_empty(value))
+ return lxc_clear_idmaps(lxc_conf);
+
+ idmaplist = malloc(sizeof(*idmaplist));
+ if (!idmaplist)
+ goto on_error;
+
+ idmap = malloc(sizeof(*idmap));
+ if (!idmap)
+ goto on_error;
+ memset(idmap, 0, sizeof(*idmap));
+
+ ret = parse_idmaps(value, &type, &nsid, &hostid, &range);
+ if (ret < 0)
+ goto on_error;
+
INFO("read uid map: type %c nsid %lu hostid %lu range %lu", type, nsid, hostid, range);
if (type == 'u')
idmap->idtype = ID_TYPE_UID;
@@ -2124,7 +2149,6 @@ static int set_config_idmaps(const char *key, const char *value,
on_error:
free(idmaplist);
free(idmap);
- free(dup);
return -1;
}
From ef019d918762d95bb6ec03a4cbaf3094d2b1bf53 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 1 Jun 2017 23:43:34 +0200
Subject: [PATCH 2/2] tests: add unit tests for idmap parser
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/tests/parse_config_file.c | 53 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/src/tests/parse_config_file.c b/src/tests/parse_config_file.c
index 509370615..1ae145f0c 100644
--- a/src/tests/parse_config_file.c
+++ b/src/tests/parse_config_file.c
@@ -28,6 +28,7 @@
#include <errno.h>
#include <string.h>
+#include "confile.c"
#include "lxc/state.h"
#include "lxctest.h"
@@ -103,6 +104,53 @@ static int set_get_compare_clear_save_load(struct lxc_container *c,
return 0;
}
+int test_idmap_parser(void)
+{
+ size_t i;
+ struct idmap_check {
+ bool is_valid;
+ const char *idmap;
+ };
+ static struct idmap_check idmaps[] = {
+ /* valid idmaps */
+ { true, "u 0 0 0" },
+ { true, "g 0 0 0" },
+ { true, "u 1000 165536 65536" },
+ { true, "g 999 999 1" },
+ { true, "u 0 5000 100000" },
+ { true, "g 577 789 5" },
+ { true, "u 65536 65536 1 " },
+ /* invalid idmaps */
+ { false, "1u 0 0 0" },
+ { false, "1g 0 0 0a" },
+ { false, "1 u 0 0 0" },
+ { false, "1g 0 0 0 1" },
+ { false, "1u a0 b0 c0 d1" },
+ { false, "1g 0 b0 0 d1" },
+ { false, "1u a0 0 c0 1" },
+ { false, "g -1 0 -10" },
+ { false, "a 1 0 10" },
+ { false, "u 1 1 0 10" },
+ { false, "g 1 0 10 z " },
+ };
+
+ for (i = 0; i < sizeof(idmaps) / sizeof(struct idmap_check); i++) {
+ unsigned long hostid, nsid, range;
+ char type;
+ int ret;
+ ret = parse_idmaps(idmaps[i].idmap, &type, &nsid, &hostid,
+ &range);
+ if ((ret < 0 && idmaps[i].is_valid) ||
+ (ret == 0 && !idmaps[i].is_valid)) {
+ lxc_error("failed to parse idmap \"%s\"\n",
+ idmaps[i].idmap);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
int main(int argc, char *argv[])
{
struct lxc_container *c;
@@ -489,6 +537,11 @@ int main(int argc, char *argv[])
goto non_test_error;
}
+ if (test_idmap_parser() < 0) {
+ lxc_error("%s\n", "failed to test parser for \"lxc.id_map\"");
+ goto non_test_error;
+ }
+
ret = EXIT_SUCCESS;
non_test_error:
c->destroy(c);
More information about the lxc-devel
mailing list