summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/basic/strv.h1
-rw-r--r--src/core/main.c101
-rw-r--r--src/core/manager.c1
-rw-r--r--src/shared/conf-parser.c105
-rw-r--r--src/shared/conf-parser.h1
-rw-r--r--src/test/test-conf-parser.c38
6 files changed, 145 insertions, 102 deletions
diff --git a/src/basic/strv.h b/src/basic/strv.h
index 44fe1f279c..f169ac5d4f 100644
--- a/src/basic/strv.h
+++ b/src/basic/strv.h
@@ -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);
diff --git a/src/core/main.c b/src/core/main.c
index 56200a8fad..44ebf4f1da 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -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[] = {
diff --git a/src/core/manager.c b/src/core/manager.c
index e4ef461ac7..d22c0e1d42 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -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;
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index daddb7cf20..5c033e0ec0 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -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;
+}
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index 8cbb569696..908f530713 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -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) { \
diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c
index 770bb9600f..84789e3bb8 100644
--- a/src/test/test-conf-parser.c
+++ b/src/test/test-conf-parser.c
@@ -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]);