diff options
author | Daniel Mack <github@zonque.org> | 2015-11-10 21:01:35 +0100 |
---|---|---|
committer | Daniel Mack <github@zonque.org> | 2015-11-10 21:01:35 +0100 |
commit | e3c4a681db0b7004904b95d55fd1a443161c9397 (patch) | |
tree | a5b08abba6a533a3c4fc2a8f1bb9097957580c46 /src | |
parent | 092b6e188b6b75be4450c6f20fc82599dcaf9552 (diff) | |
parent | de7399eb7427da46c5cd355181080274f69567a2 (diff) |
Merge pull request #1835 from poettering/grabbag-of-stuff
Lots of small fixes
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/calendarspec.c | 4 | ||||
-rw-r--r-- | src/basic/def.h | 24 | ||||
-rw-r--r-- | src/basic/parse-util.c | 100 | ||||
-rw-r--r-- | src/basic/time-util.c | 33 | ||||
-rw-r--r-- | src/basic/time-util.h | 1 | ||||
-rw-r--r-- | src/basic/virt.c | 2 | ||||
-rw-r--r-- | src/binfmt/binfmt.c | 2 | ||||
-rw-r--r-- | src/bootchart/bootchart.c | 6 | ||||
-rw-r--r-- | src/cgls/cgls.c | 5 | ||||
-rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 4 | ||||
-rw-r--r-- | src/core/load-fragment.c | 218 | ||||
-rw-r--r-- | src/core/load-fragment.h | 2 | ||||
-rw-r--r-- | src/core/main.c | 10 | ||||
-rw-r--r-- | src/journal-remote/journal-remote.c | 2 | ||||
-rw-r--r-- | src/journal-remote/journal-upload.c | 2 | ||||
-rw-r--r-- | src/journal/coredump.c | 4 | ||||
-rw-r--r-- | src/journal/journald-server.c | 16 | ||||
-rw-r--r-- | src/login/logind.c | 4 | ||||
-rw-r--r-- | src/modules-load/modules-load.c | 2 | ||||
-rw-r--r-- | src/resolve/resolved-conf.c | 4 | ||||
-rw-r--r-- | src/shared/sleep-config.c | 2 | ||||
-rw-r--r-- | src/sysctl/sysctl.c | 2 | ||||
-rw-r--r-- | src/sysusers/sysusers.c | 2 | ||||
-rw-r--r-- | src/test/test-time.c | 23 | ||||
-rw-r--r-- | src/test/test-unit-file.c | 61 | ||||
-rw-r--r-- | src/timesync/timesyncd-conf.c | 4 | ||||
-rw-r--r-- | src/tmpfiles/tmpfiles.c | 2 |
27 files changed, 401 insertions, 140 deletions
diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c index a6a906f453..7151fc3d0c 100644 --- a/src/basic/calendarspec.c +++ b/src/basic/calendarspec.c @@ -562,7 +562,7 @@ static int parse_date(const char **p, CalendarSpec *c) { return -EINVAL; } -static int parse_time(const char **p, CalendarSpec *c) { +static int parse_calendar_time(const char **p, CalendarSpec *c) { CalendarComponent *h = NULL, *m = NULL, *s = NULL; const char *t; int r; @@ -802,7 +802,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { if (r < 0) goto fail; - r = parse_time(&p, c); + r = parse_calendar_time(&p, c); if (r < 0) goto fail; diff --git a/src/basic/def.h b/src/basic/def.h index 950f693899..0657ac7367 100644 --- a/src/basic/def.h +++ b/src/basic/def.h @@ -76,17 +76,19 @@ #define NOTIFY_FD_MAX 768 #define NOTIFY_BUFFER_MAX PIPE_BUF -/* Return a nulstr for a standard cascade of configuration directories, - * suitable to pass to conf_files_list_nulstr or config_parse_many. */ -#define CONF_DIRS_NULSTR(n) \ - "/etc/" n ".d\0" \ - "/run/" n ".d\0" \ - "/usr/local/lib/" n ".d\0" \ - "/usr/lib/" n ".d\0" \ - CONF_DIR_SPLIT_USR(n) - #ifdef HAVE_SPLIT_USR -#define CONF_DIR_SPLIT_USR(n) "/lib/" n ".d\0" +#define _CONF_PATHS_SPLIT_USR(n) "/lib/" n "\0" #else -#define CONF_DIR_SPLIT_USR(n) +#define _CONF_PATHS_SPLIT_USR(n) #endif + +/* Return a nulstr for a standard cascade of configuration paths, + * suitable to pass to conf_files_list_nulstr() or config_parse_many() + * to implement drop-in directories for extending configuration + * files. */ +#define CONF_PATHS_NULSTR(n) \ + "/etc/" n "\0" \ + "/run/" n "\0" \ + "/usr/local/lib/" n "\0" \ + "/usr/lib/" n "\0" \ + _CONF_PATHS_SPLIT_USR(n) diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index b6358c459a..151067e916 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -67,11 +67,14 @@ int parse_mode(const char *s, mode_t *ret) { assert(s); assert(ret); + s += strspn(s, WHITESPACE); + if (s[0] == '-') + return -ERANGE; + errno = 0; l = strtol(s, &x, 8); if (errno != 0) return -errno; - if (!x || x == s || *x) return -EINVAL; if (l < 0 || l > 07777) @@ -162,15 +165,15 @@ int parse_size(const char *t, uint64_t base, uint64_t *size) { unsigned i; p += strspn(p, WHITESPACE); - if (*p == '-') - return -ERANGE; errno = 0; l = strtoull(p, &e, 10); - if (errno > 0) + if (errno != 0) return -errno; if (e == p) return -EINVAL; + if (*p == '-') + return -ERANGE; if (*e == '.') { e++; @@ -181,7 +184,7 @@ int parse_size(const char *t, uint64_t base, uint64_t *size) { char *e2; l2 = strtoull(e, &e2, 10); - if (errno > 0) + if (errno != 0) return -errno; /* Ignore failure. E.g. 10.M is valid */ @@ -307,12 +310,24 @@ int safe_atou(const char *s, unsigned *ret_u) { assert(s); assert(ret_u); - errno = 0; - l = strtoul(s, &x, 0); + /* strtoul() is happy to parse negative values, and silently + * converts them to unsigned values without generating an + * error. We want a clean error, hence let's look for the "-" + * prefix on our own, and generate an error. But let's do so + * only after strtoul() validated that the string is clean + * otherwise, so that we return EINVAL preferably over + * ERANGE. */ - if (!x || x == s || *x || errno) - return errno > 0 ? -errno : -EINVAL; + s += strspn(s, WHITESPACE); + errno = 0; + l = strtoul(s, &x, 0); + if (errno != 0) + return -errno; + if (!x || x == s || *x) + return -EINVAL; + if (s[0] == '-') + return -ERANGE; if ((unsigned long) (unsigned) l != l) return -ERANGE; @@ -329,10 +344,10 @@ int safe_atoi(const char *s, int *ret_i) { errno = 0; l = strtol(s, &x, 0); - - if (!x || x == s || *x || errno) - return errno > 0 ? -errno : -EINVAL; - + if (errno != 0) + return -errno; + if (!x || x == s || *x) + return -EINVAL; if ((long) (int) l != l) return -ERANGE; @@ -347,11 +362,16 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) { assert(s); assert(ret_llu); + s += strspn(s, WHITESPACE); + errno = 0; l = strtoull(s, &x, 0); - - if (!x || x == s || *x || errno) - return errno ? -errno : -EINVAL; + if (errno != 0) + return -errno; + if (!x || x == s || *x) + return -EINVAL; + if (*s == '-') + return -ERANGE; *ret_llu = l; return 0; @@ -366,9 +386,10 @@ int safe_atolli(const char *s, long long int *ret_lli) { errno = 0; l = strtoll(s, &x, 0); - - if (!x || x == s || *x || errno) - return errno ? -errno : -EINVAL; + if (errno != 0) + return -errno; + if (!x || x == s || *x) + return -EINVAL; *ret_lli = l; return 0; @@ -381,12 +402,16 @@ int safe_atou8(const char *s, uint8_t *ret) { assert(s); assert(ret); + s += strspn(s, WHITESPACE); + errno = 0; l = strtoul(s, &x, 0); - - if (!x || x == s || *x || errno) - return errno > 0 ? -errno : -EINVAL; - + if (errno != 0) + return -errno; + if (!x || x == s || *x) + return -EINVAL; + if (s[0] == '-') + return -ERANGE; if ((unsigned long) (uint8_t) l != l) return -ERANGE; @@ -401,12 +426,16 @@ int safe_atou16(const char *s, uint16_t *ret) { assert(s); assert(ret); + s += strspn(s, WHITESPACE); + errno = 0; l = strtoul(s, &x, 0); - - if (!x || x == s || *x || errno) - return errno > 0 ? -errno : -EINVAL; - + if (errno != 0) + return -errno; + if (!x || x == s || *x) + return -EINVAL; + if (s[0] == '-') + return -ERANGE; if ((unsigned long) (uint16_t) l != l) return -ERANGE; @@ -423,10 +452,10 @@ int safe_atoi16(const char *s, int16_t *ret) { errno = 0; l = strtol(s, &x, 0); - - if (!x || x == s || *x || errno) - return errno > 0 ? -errno : -EINVAL; - + if (errno != 0) + return -errno; + if (!x || x == s || *x) + return -EINVAL; if ((long) (int16_t) l != l) return -ERANGE; @@ -448,10 +477,13 @@ int safe_atod(const char *s, double *ret_d) { errno = 0; d = strtod_l(s, &x, loc); - - if (!x || x == s || *x || errno) { + if (errno != 0) { freelocale(loc); - return errno ? -errno : -EINVAL; + return -errno; + } + if (!x || x == s || *x) { + freelocale(loc); + return -EINVAL; } freelocale(loc); diff --git a/src/basic/time-util.c b/src/basic/time-util.c index e629d91cb2..b36fbe4f09 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -705,7 +705,8 @@ finish: return 0; } -int parse_sec(const char *t, usec_t *usec) { +int parse_time(const char *t, usec_t *usec, usec_t default_unit) { + static const struct { const char *suffix; usec_t usec; @@ -737,7 +738,6 @@ int parse_sec(const char *t, usec_t *usec) { { "y", USEC_PER_YEAR }, { "usec", 1ULL }, { "us", 1ULL }, - { "", USEC_PER_SEC }, /* default is sec */ }; const char *p, *s; @@ -746,6 +746,7 @@ int parse_sec(const char *t, usec_t *usec) { assert(t); assert(usec); + assert(default_unit > 0); p = t; @@ -764,6 +765,7 @@ int parse_sec(const char *t, usec_t *usec) { long long l, z = 0; char *e; unsigned i, n = 0; + usec_t multiplier, k; p += strspn(p, WHITESPACE); @@ -806,21 +808,24 @@ int parse_sec(const char *t, usec_t *usec) { for (i = 0; i < ELEMENTSOF(table); i++) if (startswith(e, table[i].suffix)) { - usec_t k = (usec_t) z * table[i].usec; - - for (; n > 0; n--) - k /= 10; - - r += (usec_t) l * table[i].usec + k; + multiplier = table[i].usec; p = e + strlen(table[i].suffix); - - something = true; break; } - if (i >= ELEMENTSOF(table)) - return -EINVAL; + if (i >= ELEMENTSOF(table)) { + multiplier = default_unit; + p = e; + } + + something = true; + + k = (usec_t) z * multiplier; + for (; n > 0; n--) + k /= 10; + + r += (usec_t) l * multiplier + k; } *usec = r; @@ -828,6 +833,10 @@ int parse_sec(const char *t, usec_t *usec) { return 0; } +int parse_sec(const char *t, usec_t *usec) { + return parse_time(t, usec, USEC_PER_SEC); +} + int parse_nsec(const char *t, nsec_t *nsec) { static const struct { const char *suffix; diff --git a/src/basic/time-util.h b/src/basic/time-util.h index 925bf18eb2..0417c29cdd 100644 --- a/src/basic/time-util.h +++ b/src/basic/time-util.h @@ -104,6 +104,7 @@ int dual_timestamp_deserialize(const char *value, dual_timestamp *t); int parse_timestamp(const char *t, usec_t *usec); int parse_sec(const char *t, usec_t *usec); +int parse_time(const char *t, usec_t *usec, usec_t default_unit); int parse_nsec(const char *t, nsec_t *nsec); bool ntp_synced(void); diff --git a/src/basic/virt.c b/src/basic/virt.c index ff006e96c6..d088b7a804 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -400,7 +400,7 @@ int detect_container(void) { goto finish; } - r = VIRTUALIZATION_NONE; + r = VIRTUALIZATION_CONTAINER_OTHER; finish: cached_found = r; diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c index 42ad0adb02..03fb413fe5 100644 --- a/src/binfmt/binfmt.c +++ b/src/binfmt/binfmt.c @@ -37,7 +37,7 @@ #include "strv.h" #include "util.h" -static const char conf_file_dirs[] = CONF_DIRS_NULSTR("binfmt"); +static const char conf_file_dirs[] = CONF_PATHS_NULSTR("binfmt.d"); static int delete_rule(const char *rule) { _cleanup_free_ char *x = NULL, *fn = NULL; diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c index 852febb225..6a0e1d6b14 100644 --- a/src/bootchart/bootchart.c +++ b/src/bootchart/bootchart.c @@ -95,8 +95,6 @@ static void signal_handler(int sig) { exiting = 1; } -#define BOOTCHART_CONF "/etc/systemd/bootchart.conf" - #define BOOTCHART_MAX (16*1024*1024) static void parse_conf(void) { @@ -117,8 +115,8 @@ static void parse_conf(void) { { NULL, NULL, NULL, 0, NULL } }; - config_parse_many(BOOTCHART_CONF, - CONF_DIRS_NULSTR("systemd/bootchart.conf"), + config_parse_many(PKGSYSCONFDIR "/bootchart.conf", + CONF_PATHS_NULSTR("systemd/bootchart.conf.d"), NULL, config_item_table_lookup, items, true, NULL); if (init != NULL) diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c index 4e9a76a100..22efc58ac9 100644 --- a/src/cgls/cgls.c +++ b/src/cgls/cgls.c @@ -165,8 +165,10 @@ static int get_cgroup_root(char **ret) { } static void show_cg_info(const char *controller, const char *path) { - if (cg_unified() <= 0) + + if (cg_unified() <= 0 && controller && !streq(controller, SYSTEMD_CGROUP_CONTROLLER)) printf("Controller %s; ", controller); + printf("Control group %s:\n", isempty(path) ? "/" : path); fflush(stdout); } @@ -270,6 +272,7 @@ int main(int argc, char *argv[]) { show_cg_info(SYSTEMD_CGROUP_CONTROLLER, root); + printf("-.slice\n"); r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0, arg_kernel_threads, output_flags); } } diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 5b7954dbf9..75388659e3 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -58,7 +58,7 @@ $1.RestrictAddressFamilies, config_parse_address_families, 0, $1.SystemCallArchitectures, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 $1.SystemCallErrorNumber, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 $1.RestrictAddressFamilies, config_parse_warn_compat, DISABLED_CONFIGURATION, 0') -$1.LimitCPU, config_parse_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit) +$1.LimitCPU, config_parse_sec_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit) $1.LimitFSIZE, config_parse_bytes_limit, RLIMIT_FSIZE, offsetof($1, exec_context.rlimit) $1.LimitDATA, config_parse_bytes_limit, RLIMIT_DATA, offsetof($1, exec_context.rlimit) $1.LimitSTACK, config_parse_bytes_limit, RLIMIT_STACK, offsetof($1, exec_context.rlimit) @@ -73,7 +73,7 @@ $1.LimitSIGPENDING, config_parse_limit, RLIMIT_SIGP $1.LimitMSGQUEUE, config_parse_bytes_limit, RLIMIT_MSGQUEUE, offsetof($1, exec_context.rlimit) $1.LimitNICE, config_parse_limit, RLIMIT_NICE, offsetof($1, exec_context.rlimit) $1.LimitRTPRIO, config_parse_limit, RLIMIT_RTPRIO, offsetof($1, exec_context.rlimit) -$1.LimitRTTIME, config_parse_limit, RLIMIT_RTTIME, offsetof($1, exec_context.rlimit) +$1.LimitRTTIME, config_parse_usec_limit, RLIMIT_RTTIME, offsetof($1, exec_context.rlimit) $1.ReadWriteDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_write_dirs) $1.ReadOnlyDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_only_dirs) $1.InaccessibleDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.inaccessible_dirs) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index a514052772..79cabd26e7 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -974,23 +974,22 @@ int config_parse_exec_secure_bits(const char *unit, return 0; } -int config_parse_bounding_set(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) { +int config_parse_bounding_set( + 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) { uint64_t *capability_bounding_set_drop = data; - uint64_t capability_bounding_set; + uint64_t capability_bounding_set, sum = 0; bool invert = false; - uint64_t sum = 0; - const char *prev; - const char *cur; + const char *p; assert(filename); assert(lvalue); @@ -1007,35 +1006,32 @@ int config_parse_bounding_set(const char *unit, * non-inverted everywhere to have a fully normalized * interface. */ - prev = cur = rvalue; + p = rvalue; for (;;) { _cleanup_free_ char *word = NULL; - int cap; - int r; + int cap, r; - r = extract_first_word(&cur, &word, NULL, EXTRACT_QUOTES); + r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); if (r == 0) break; if (r == -ENOMEM) return log_oom(); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Trailing garbage in bounding set, ignoring: %s", prev); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse word, ignoring: %s", rvalue); break; } cap = capability_from_name(word); if (cap < 0) { log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse capability in bounding set, ignoring: %s", word); - prev = cur; continue; } - sum |= ((uint64_t) 1ULL) << (uint64_t) cap; - prev = cur; + sum |= ((uint64_t) UINT64_C(1)) << (uint64_t) cap; } capability_bounding_set = invert ? ~sum : sum; - if (*capability_bounding_set_drop && capability_bounding_set) + if (*capability_bounding_set_drop != 0 && capability_bounding_set != 0) *capability_bounding_set_drop = ~(~*capability_bounding_set_drop | capability_bounding_set); else *capability_bounding_set_drop = ~capability_bounding_set; @@ -1043,19 +1039,21 @@ int config_parse_bounding_set(const char *unit, return 0; } -int config_parse_limit(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) { +int config_parse_limit( + 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) { struct rlimit **rl = data; - unsigned long long u; + rlim_t v; + int r; assert(filename); assert(lvalue); @@ -1065,15 +1063,22 @@ int config_parse_limit(const char *unit, rl += ltype; if (streq(rvalue, "infinity")) - u = (unsigned long long) RLIM_INFINITY; + v = RLIM_INFINITY; else { - int r; + uint64_t u; - r = safe_atollu(rvalue, &u); + /* setrlimit(2) suggests rlim_t is always 64bit on Linux. */ + assert_cc(sizeof(rlim_t) == sizeof(uint64_t)); + + r = safe_atou64(rvalue, &u); + if (r >= 0 && u >= (uint64_t) RLIM_INFINITY) + r = -ERANGE; if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue); return 0; } + + v = (rlim_t) u; } if (!*rl) { @@ -1082,23 +1087,25 @@ int config_parse_limit(const char *unit, return log_oom(); } - (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) u; + (*rl)->rlim_cur = (*rl)->rlim_max = v; return 0; } -int config_parse_bytes_limit(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) { +int config_parse_bytes_limit( + 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) { struct rlimit **rl = data; - uint64_t bytes; + rlim_t bytes; + int r; assert(filename); assert(lvalue); @@ -1108,15 +1115,120 @@ int config_parse_bytes_limit(const char *unit, rl += ltype; if (streq(rvalue, "infinity")) - bytes = (uint64_t) RLIM_INFINITY; + bytes = RLIM_INFINITY; else { - int r; + uint64_t u; + + r = parse_size(rvalue, 1024, &u); + if (r >= 0 && u >= (uint64_t) RLIM_INFINITY) + r = -ERANGE; + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue); + return 0; + } + + bytes = (rlim_t) u; + } + + if (!*rl) { + *rl = new(struct rlimit, 1); + if (!*rl) + return log_oom(); + } + + (*rl)->rlim_cur = (*rl)->rlim_max = bytes; + return 0; +} + +int config_parse_sec_limit( + 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) { + + struct rlimit **rl = data; + rlim_t seconds; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + rl += ltype; + + if (streq(rvalue, "infinity")) + seconds = RLIM_INFINITY; + else { + usec_t t; + + r = parse_sec(rvalue, &t); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue); + return 0; + } + + if (t == USEC_INFINITY) + seconds = RLIM_INFINITY; + else + seconds = (rlim_t) (DIV_ROUND_UP(t, USEC_PER_SEC)); + } + + if (!*rl) { + *rl = new(struct rlimit, 1); + if (!*rl) + return log_oom(); + } + + (*rl)->rlim_cur = (*rl)->rlim_max = seconds; + return 0; +} - r = parse_size(rvalue, 1024, &bytes); + +int config_parse_usec_limit( + 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) { + + struct rlimit **rl = data; + rlim_t useconds; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + rl += ltype; + + if (streq(rvalue, "infinity")) + useconds = RLIM_INFINITY; + else { + usec_t t; + + r = parse_time(rvalue, &t, 1); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue); return 0; } + + if (t == USEC_INFINITY) + useconds = RLIM_INFINITY; + else + useconds = (rlim_t) t; } if (!*rl) { @@ -1125,7 +1237,7 @@ int config_parse_bytes_limit(const char *unit, return log_oom(); } - (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) bytes; + (*rl)->rlim_cur = (*rl)->rlim_max = useconds; return 0; } diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 029775bb46..0cf821289c 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -57,6 +57,8 @@ int config_parse_exec_secure_bits(const char *unit, const char *filename, unsign int config_parse_bounding_set(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); int config_parse_limit(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); int config_parse_bytes_limit(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); +int config_parse_sec_limit(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); +int config_parse_usec_limit(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); int config_parse_sysv_priority(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); int config_parse_kill_signal(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); int config_parse_exec_mount_flags(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); diff --git a/src/core/main.c b/src/core/main.c index 950315e857..a86080642d 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -682,8 +682,14 @@ static int parse_config_file(void) { const char *fn, *conf_dirs_nulstr; - fn = arg_running_as == MANAGER_SYSTEM ? PKGSYSCONFDIR "/system.conf" : PKGSYSCONFDIR "/user.conf"; - conf_dirs_nulstr = arg_running_as == MANAGER_SYSTEM ? CONF_DIRS_NULSTR("systemd/system.conf") : CONF_DIRS_NULSTR("systemd/user.conf"); + fn = arg_running_as == MANAGER_SYSTEM ? + PKGSYSCONFDIR "/system.conf" : + PKGSYSCONFDIR "/user.conf"; + + conf_dirs_nulstr = arg_running_as == MANAGER_SYSTEM ? + CONF_PATHS_NULSTR("systemd/system.conf.d") : + CONF_PATHS_NULSTR("systemd/user.conf.d"); + config_parse_many(fn, conf_dirs_nulstr, "Manager\0", config_item_table_lookup, items, false, NULL); diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index 6eb0ee9d9e..b2f5fbf6b4 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -1188,7 +1188,7 @@ static int parse_config(void) { {}}; return config_parse_many(PKGSYSCONFDIR "/journal-remote.conf", - CONF_DIRS_NULSTR("systemd/journal-remote.conf"), + CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"), "Remote\0", config_item_table_lookup, items, false, NULL); } diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c index 42d14dc7c4..6302266ccb 100644 --- a/src/journal-remote/journal-upload.c +++ b/src/journal-remote/journal-upload.c @@ -542,7 +542,7 @@ static int parse_config(void) { {}}; return config_parse_many(PKGSYSCONFDIR "/journal-upload.conf", - CONF_DIRS_NULSTR("systemd/journal-upload.conf"), + CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"), "Upload\0", config_item_table_lookup, items, false, NULL); } diff --git a/src/journal/coredump.c b/src/journal/coredump.c index 4c83e311db..f750ddfcbd 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -126,8 +126,8 @@ static int parse_config(void) { {} }; - return config_parse_many("/etc/systemd/coredump.conf", - CONF_DIRS_NULSTR("systemd/coredump.conf"), + return config_parse_many(PKGSYSCONFDIR "/coredump.conf", + CONF_PATHS_NULSTR("systemd/coredump.conf.d"), "Coredump\0", config_item_table_lookup, items, false, NULL); diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 7a70dcbc57..36fe739073 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1296,10 +1296,22 @@ static int setup_signals(Server *s) { if (r < 0) return r; + /* Let's process SIGTERM late, so that we flush all queued + * messages to disk before we exit */ + r = sd_event_source_set_priority(s->sigterm_event_source, SD_EVENT_PRIORITY_NORMAL+20); + if (r < 0) + return r; + + /* When journald is invoked on the terminal (when debugging), + * it's useful if C-c is handled equivalent to SIGTERM. */ r = sd_event_add_signal(s->event, &s->sigint_event_source, SIGINT, dispatch_sigterm, s); if (r < 0) return r; + r = sd_event_source_set_priority(s->sigint_event_source, SD_EVENT_PRIORITY_NORMAL+20); + if (r < 0) + return r; + return 0; } @@ -1360,8 +1372,8 @@ static int server_parse_proc_cmdline(Server *s) { static int server_parse_config_file(Server *s) { assert(s); - return config_parse_many("/etc/systemd/journald.conf", - CONF_DIRS_NULSTR("systemd/journald.conf"), + return config_parse_many(PKGSYSCONFDIR "/journald.conf", + CONF_PATHS_NULSTR("systemd/journald.conf.d"), "Journal\0", config_item_perf_lookup, journald_gperf_lookup, false, s); diff --git a/src/login/logind.c b/src/login/logind.c index 83896ea627..be6bbe5b5c 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -1102,8 +1102,8 @@ static int manager_run(Manager *m) { static int manager_parse_config_file(Manager *m) { assert(m); - return config_parse_many("/etc/systemd/logind.conf", - CONF_DIRS_NULSTR("systemd/logind.conf"), + return config_parse_many(PKGSYSCONFDIR "/logind.conf", + CONF_PATHS_NULSTR("systemd/logind.conf.d"), "Login\0", config_item_perf_lookup, logind_gperf_lookup, false, m); diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c index 13784763f1..a7fdcb09cf 100644 --- a/src/modules-load/modules-load.c +++ b/src/modules-load/modules-load.c @@ -38,7 +38,7 @@ static char **arg_proc_cmdline_modules = NULL; -static const char conf_file_dirs[] = CONF_DIRS_NULSTR("modules-load"); +static const char conf_file_dirs[] = CONF_PATHS_NULSTR("modules-load.d"); static void systemd_kmod_log(void *data, int priority, const char *file, int line, const char *fn, const char *format, va_list args) { diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c index de1bd26174..9207719551 100644 --- a/src/resolve/resolved-conf.c +++ b/src/resolve/resolved-conf.c @@ -150,8 +150,8 @@ int config_parse_support( int manager_parse_config_file(Manager *m) { assert(m); - return config_parse_many("/etc/systemd/resolved.conf", - CONF_DIRS_NULSTR("systemd/resolved.conf"), + return config_parse_many(PKGSYSCONFDIR "/resolved.conf", + CONF_PATHS_NULSTR("systemd/resolved.conf.d"), "Resolve\0", config_item_perf_lookup, resolved_gperf_lookup, false, m); diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index 102c5cc992..39b836d053 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -54,7 +54,7 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states) { }; config_parse_many(PKGSYSCONFDIR "/sleep.conf", - CONF_DIRS_NULSTR("systemd/sleep.conf"), + CONF_PATHS_NULSTR("systemd/sleep.conf.d"), "Sleep\0", config_item_table_lookup, items, false, NULL); diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c index 152c98b348..25b5ff52ea 100644 --- a/src/sysctl/sysctl.c +++ b/src/sysctl/sysctl.c @@ -41,7 +41,7 @@ static char **arg_prefixes = NULL; -static const char conf_file_dirs[] = CONF_DIRS_NULSTR("sysctl"); +static const char conf_file_dirs[] = CONF_PATHS_NULSTR("sysctl.d"); static int apply_all(Hashmap *sysctl_options) { char *property, *value; diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 008b1bde24..675f94906b 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -72,7 +72,7 @@ typedef struct Item { static char *arg_root = NULL; -static const char conf_file_dirs[] = CONF_DIRS_NULSTR("sysusers"); +static const char conf_file_dirs[] = CONF_PATHS_NULSTR("sysusers.d"); static Hashmap *users = NULL, *groups = NULL; static Hashmap *todo_uids = NULL, *todo_gids = NULL; diff --git a/src/test/test-time.c b/src/test/test-time.c index 3840fff061..820e4aaee2 100644 --- a/src/test/test-time.c +++ b/src/test/test-time.c @@ -57,6 +57,28 @@ static void test_parse_sec(void) { assert_se(parse_sec(".3 infinity", &u) < 0); } +static void test_parse_time(void) { + usec_t u; + + assert_se(parse_time("5", &u, 1) >= 0); + assert_se(u == 5); + + assert_se(parse_time("5", &u, USEC_PER_MSEC) >= 0); + assert_se(u == 5 * USEC_PER_MSEC); + + assert_se(parse_time("5", &u, USEC_PER_SEC) >= 0); + assert_se(u == 5 * USEC_PER_SEC); + + assert_se(parse_time("5s", &u, 1) >= 0); + assert_se(u == 5 * USEC_PER_SEC); + + assert_se(parse_time("5s", &u, USEC_PER_SEC) >= 0); + assert_se(u == 5 * USEC_PER_SEC); + + assert_se(parse_time("5s", &u, USEC_PER_MSEC) >= 0); + assert_se(u == 5 * USEC_PER_SEC); +} + static void test_parse_nsec(void) { nsec_t u; @@ -161,6 +183,7 @@ static void test_get_timezones(void) { int main(int argc, char *argv[]) { test_parse_sec(); + test_parse_time(); test_parse_nsec(); test_format_timespan(1); test_format_timespan(USEC_PER_MSEC); diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index f9107e0d0d..3648ec9c58 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -681,6 +681,66 @@ static void test_config_parse_bounding_set(void) { assert_se(capability_bounding_set_drop == ~(make_cap(CAP_NET_RAW) | make_cap(CAP_NET_ADMIN))); } +static void test_config_parse_rlimit(void) { + struct rlimit * rl[_RLIMIT_MAX] = {}; + + assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55", rl, NULL) >= 0); + assert_se(rl[RLIMIT_NOFILE]); + assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 55); + assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max); + + assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "infinity", rl, NULL) >= 0); + assert_se(rl[RLIMIT_NOFILE]); + assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY); + assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max); + + rl[RLIMIT_NOFILE] = mfree(rl[RLIMIT_NOFILE]); + + assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "56", rl, NULL) >= 0); + assert_se(rl[RLIMIT_CPU]); + assert_se(rl[RLIMIT_CPU]->rlim_cur == 56); + assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max); + + assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "57s", rl, NULL) >= 0); + assert_se(rl[RLIMIT_CPU]); + assert_se(rl[RLIMIT_CPU]->rlim_cur == 57); + assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max); + + assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "infinity", rl, NULL) >= 0); + assert_se(rl[RLIMIT_CPU]); + assert_se(rl[RLIMIT_CPU]->rlim_cur == RLIM_INFINITY); + assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max); + + assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "1234ms", rl, NULL) >= 0); + assert_se(rl[RLIMIT_CPU]); + assert_se(rl[RLIMIT_CPU]->rlim_cur == 2); + assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max); + + rl[RLIMIT_CPU] = mfree(rl[RLIMIT_CPU]); + + assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58", rl, NULL) >= 0); + assert_se(rl[RLIMIT_RTTIME]); + assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 58); + assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max); + + assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "59s", rl, NULL) >= 0); + assert_se(rl[RLIMIT_RTTIME]); + assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 59 * USEC_PER_SEC); + assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max); + + assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "infinity", rl, NULL) >= 0); + assert_se(rl[RLIMIT_RTTIME]); + assert_se(rl[RLIMIT_RTTIME]->rlim_cur == RLIM_INFINITY); + assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max); + + assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "2345ms", rl, NULL) >= 0); + assert_se(rl[RLIMIT_RTTIME]); + assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 2345 * USEC_PER_MSEC); + assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max); + + rl[RLIMIT_RTTIME] = mfree(rl[RLIMIT_RTTIME]); +} + int main(int argc, char *argv[]) { int r; @@ -690,6 +750,7 @@ int main(int argc, char *argv[]) { r = test_unit_file_get_set(); test_config_parse_exec(); test_config_parse_bounding_set(); + test_config_parse_rlimit(); test_load_env_file_1(); test_load_env_file_2(); test_load_env_file_3(); diff --git a/src/timesync/timesyncd-conf.c b/src/timesync/timesyncd-conf.c index 001a0f4d41..5881bc0c45 100644 --- a/src/timesync/timesyncd-conf.c +++ b/src/timesync/timesyncd-conf.c @@ -100,8 +100,8 @@ int config_parse_servers( int manager_parse_config_file(Manager *m) { assert(m); - return config_parse_many("/etc/systemd/timesyncd.conf", - CONF_DIRS_NULSTR("systemd/timesyncd.conf"), + return config_parse_many(PKGSYSCONFDIR "/timesyncd.conf", + CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"), "Time\0", config_item_perf_lookup, timesyncd_gperf_lookup, false, m); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index ffae91a3ca..64f0c9396c 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -159,7 +159,7 @@ static char **arg_include_prefixes = NULL; static char **arg_exclude_prefixes = NULL; static char *arg_root = NULL; -static const char conf_file_dirs[] = CONF_DIRS_NULSTR("tmpfiles"); +static const char conf_file_dirs[] = CONF_PATHS_NULSTR("tmpfiles.d"); #define MAX_DEPTH 256 |