]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Move config_parse_join_controllers to shared, add test
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 16 Feb 2018 08:56:29 +0000 (09:56 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 19 Feb 2018 14:02:13 +0000 (15:02 +0100)
config_parse_join_controllers would free the destination argument on failure,
which is contrary to our normal style, where failed parsing has no effect.
Moving it to shared also allows a test to be added.

src/basic/strv.h
src/core/main.c
src/core/manager.c
src/shared/conf-parser.c
src/shared/conf-parser.h
src/test/test-conf-parser.c

index 44fe1f279c940b7b35c0447e3225b497cb1925ec..f169ac5d4f611884fe1e52cf898cde1253834626 100644 (file)
@@ -179,6 +179,7 @@ static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, i
 }
 
 char ***strv_free_free(char ***l);
+DEFINE_TRIVIAL_CLEANUP_FUNC(char***, strv_free_free);
 
 char **strv_skip(char **l, size_t n);
 
index 56200a8fad313311583910e5b70823672f120627..44ebf4f1dad3b81a91d0700a566fe0cfd98d8b37 100644 (file)
@@ -652,107 +652,6 @@ static int config_parse_crash_chvt(
         return 0;
 }
 
-static int config_parse_join_controllers(const char *unit,
-                                         const char *filename,
-                                         unsigned line,
-                                         const char *section,
-                                         unsigned section_line,
-                                         const char *lvalue,
-                                         int ltype,
-                                         const char *rvalue,
-                                         void *data,
-                                         void *userdata) {
-
-        const char *whole_rvalue = rvalue;
-        unsigned n = 0;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-
-        arg_join_controllers = strv_free_free(arg_join_controllers);
-
-        for (;;) {
-                _cleanup_free_ char *word = NULL;
-                char **l;
-                int r;
-
-                r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
-                        return r;
-                }
-                if (r == 0)
-                        break;
-
-                l = strv_split(word, ",");
-                if (!l)
-                        return log_oom();
-                strv_uniq(l);
-
-                if (strv_length(l) <= 1) {
-                        strv_free(l);
-                        continue;
-                }
-
-                if (!arg_join_controllers) {
-                        arg_join_controllers = new(char**, 2);
-                        if (!arg_join_controllers) {
-                                strv_free(l);
-                                return log_oom();
-                        }
-
-                        arg_join_controllers[0] = l;
-                        arg_join_controllers[1] = NULL;
-
-                        n = 1;
-                } else {
-                        char ***a;
-                        char ***t;
-
-                        t = new0(char**, n+2);
-                        if (!t) {
-                                strv_free(l);
-                                return log_oom();
-                        }
-
-                        n = 0;
-
-                        for (a = arg_join_controllers; *a; a++) {
-
-                                if (strv_overlap(*a, l)) {
-                                        if (strv_extend_strv(&l, *a, false) < 0) {
-                                                strv_free(l);
-                                                strv_free_free(t);
-                                                return log_oom();
-                                        }
-
-                                } else {
-                                        char **c;
-
-                                        c = strv_copy(*a);
-                                        if (!c) {
-                                                strv_free(l);
-                                                strv_free_free(t);
-                                                return log_oom();
-                                        }
-
-                                        t[n++] = c;
-                                }
-                        }
-
-                        t[n++] = strv_uniq(l);
-
-                        strv_free_free(arg_join_controllers);
-                        arg_join_controllers = t;
-                }
-        }
-        if (!isempty(rvalue))
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
-
-        return 0;
-}
-
 static int parse_config_file(void) {
 
         const ConfigTableItem items[] = {
index e4ef461ac77984a50ca9377348c0ab62fe816407..d22c0e1d428c565fd6cd52316eab63a4244825df 100644 (file)
@@ -2710,7 +2710,6 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
         }
 
         if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
-
                 if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
                         log_error_errno(errno, "connect() failed: %m");
                 return;
index daddb7cf20b20b42b9d210160921c01c9c98f18c..5c033e0ec03349139960f862f7584fe5b54bee82 100644 (file)
@@ -1021,3 +1021,108 @@ int config_parse_ip_port(
 
         return 0;
 }
+
+int config_parse_join_controllers(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char ****ret = data;
+        const char *whole_rvalue = rvalue;
+        unsigned n = 0;
+        _cleanup_(strv_free_freep) char ***controllers = NULL;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(ret);
+
+        for (;;) {
+                _cleanup_free_ char *word = NULL;
+                char **l;
+                int r;
+
+                r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
+                        return r;
+                }
+                if (r == 0)
+                        break;
+
+                l = strv_split(word, ",");
+                if (!l)
+                        return log_oom();
+                strv_uniq(l);
+
+                if (strv_length(l) <= 1) {
+                        strv_free(l);
+                        continue;
+                }
+
+                if (!controllers) {
+                        controllers = new(char**, 2);
+                        if (!controllers) {
+                                strv_free(l);
+                                return log_oom();
+                        }
+
+                        controllers[0] = l;
+                        controllers[1] = NULL;
+
+                        n = 1;
+                } else {
+                        char ***a;
+                        char ***t;
+
+                        t = new0(char**, n+2);
+                        if (!t) {
+                                strv_free(l);
+                                return log_oom();
+                        }
+
+                        n = 0;
+
+                        for (a = controllers; *a; a++)
+                                if (strv_overlap(*a, l)) {
+                                        if (strv_extend_strv(&l, *a, false) < 0) {
+                                                strv_free(l);
+                                                strv_free_free(t);
+                                                return log_oom();
+                                        }
+
+                                } else {
+                                        char **c;
+
+                                        c = strv_copy(*a);
+                                        if (!c) {
+                                                strv_free(l);
+                                                strv_free_free(t);
+                                                return log_oom();
+                                        }
+
+                                        t[n++] = c;
+                                }
+
+                        t[n++] = strv_uniq(l);
+
+                        strv_free_free(controllers);
+                        controllers = t;
+                }
+        }
+        if (!isempty(rvalue))
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
+
+        strv_free_free(*ret);
+        *ret = controllers;
+        controllers = NULL;
+
+        return 0;
+}
index 8cbb569696a04cab3ae41702eec51bb36ba34ff3..908f530713fddeeaebca83ac741b3f04966dd759 100644 (file)
@@ -157,6 +157,7 @@ int config_parse_signal(GENERIC_PARSER_ARGS);
 int config_parse_personality(GENERIC_PARSER_ARGS);
 int config_parse_ifname(GENERIC_PARSER_ARGS);
 int config_parse_ip_port(GENERIC_PARSER_ARGS);
+int config_parse_join_controllers(GENERIC_PARSER_ARGS);
 
 #define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg)                \
         int function(GENERIC_PARSER_ARGS) {                             \
index 770bb9600fb4e63fc4cbd59b629c9ebe166b0ce8..84789e3bb8be44ee0e29ee6993840330db06e566 100644 (file)
@@ -226,6 +226,43 @@ static void test_config_parse_iec_uint64(void) {
         assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
 }
 
+static void test_config_parse_join_controllers(void) {
+        int r;
+        _cleanup_(strv_free_freep) char ***c = NULL;
+        char ***c2;
+
+        /* Test normal operation */
+        r = config_parse_join_controllers(NULL, "example.conf", 11, "Section", 10, "JoinControllers", 0, "cpu,cpuacct net_cls,netprio", &c, NULL);
+        assert_se(r == 0);
+        assert_se(c);
+        assert_se(strv_length(c[0]) == 2);
+        assert_se(strv_equal(c[0], STRV_MAKE("cpu", "cpuacct")));
+        assert_se(strv_length(c[1]) == 2);
+        assert_se(strv_equal(c[1], STRV_MAKE("net_cls", "netprio")));
+        assert_se(c[2] == NULL);
+
+        /* Test special case of no mounted controllers */
+        r = config_parse_join_controllers(NULL, "example.conf", 12, "Section", 10, "JoinControllers", 0, "", &c, NULL);
+        assert_se(r == 0);
+        assert_se(c == NULL);
+
+        /* Test merging of overlapping lists */
+        r = config_parse_join_controllers(NULL, "example.conf", 13, "Section", 10, "JoinControllers", 0, "a,b b,c", &c, NULL);
+        assert_se(r == 0);
+        assert_se(c);
+        assert_se(strv_length(c[0]) == 3);
+        assert_se(strv_contains(c[0], "a"));
+        assert_se(strv_contains(c[0], "b"));
+        assert_se(strv_contains(c[0], "c"));
+        assert_se(c[1] == NULL);
+
+        /* Test ignoring of bad lines */
+        c2 = c;
+        r = config_parse_join_controllers(NULL, "example.conf", 14, "Section", 10, "JoinControllers", 0, "a,\"b ", &c, NULL);
+        assert_se(r < 0);
+        assert_se(c == c2);
+}
+
 #define x10(x) x x x x x x x x x x
 #define x100(x) x10(x10(x))
 #define x1000(x) x10(x100(x))
@@ -365,6 +402,7 @@ int main(int argc, char **argv) {
         test_config_parse_sec();
         test_config_parse_nsec();
         test_config_parse_iec_uint64();
+        test_config_parse_join_controllers();
 
         for (i = 0; i < ELEMENTSOF(config_file); i++)
                 test_config_parse(i, config_file[i]);