Systemd/src/timesync/timesyncd-conf.c
Lennart Poettering 4f9ff96a55 conf-parser: return mtime in config_parse() and friends
This is a follow-up for 9f83091e3c.

Instead of reading the mtime off the configuration files after reading,
let's do so before reading, but with the fd we read the data from. This
is not only cleaner (as it allows us to save one stat()), but also has
the benefit that we'll detect changes that happen while we read the
files.

This also reworks unit file drop-ins to use the common code for
determining drop-in mtime, instead of reading system clock for that.
2020-06-02 19:32:20 +02:00

128 lines
3.9 KiB
C

/* SPDX-License-Identifier: LGPL-2.1+ */
#include "alloc-util.h"
#include "def.h"
#include "dns-domain.h"
#include "extract-word.h"
#include "string-util.h"
#include "timesyncd-conf.h"
#include "timesyncd-manager.h"
#include "timesyncd-server.h"
int manager_parse_server_string(Manager *m, ServerType type, const char *string) {
ServerName *first;
int r;
assert(m);
assert(string);
first = type == SERVER_FALLBACK ? m->fallback_servers : m->system_servers;
if (type == SERVER_FALLBACK)
m->have_fallbacks = true;
for (;;) {
_cleanup_free_ char *word = NULL;
bool found = false;
ServerName *n;
r = extract_first_word(&string, &word, NULL, 0);
if (r < 0)
return log_error_errno(r, "Failed to parse timesyncd server syntax \"%s\": %m", string);
if (r == 0)
break;
r = dns_name_is_valid_or_address(word);
if (r < 0)
return log_error_errno(r, "Failed to check validity of NTP server name or address '%s': %m", word);
if (r == 0) {
log_error("Invalid NTP server name or address, ignoring: %s", word);
continue;
}
/* Filter out duplicates */
LIST_FOREACH(names, n, first)
if (streq_ptr(n->string, word)) {
found = true;
break;
}
if (found)
continue;
r = server_name_new(m, NULL, type, word);
if (r < 0)
return r;
}
return 0;
}
int manager_parse_fallback_string(Manager *m, const char *string) {
if (m->have_fallbacks)
return 0;
return manager_parse_server_string(m, SERVER_FALLBACK, string);
}
int config_parse_servers(
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) {
Manager *m = userdata;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue))
manager_flush_server_names(m, ltype);
else {
r = manager_parse_server_string(m, ltype, rvalue);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse NTP server string '%s'. Ignoring.", rvalue);
return 0;
}
}
return 0;
}
int manager_parse_config_file(Manager *m) {
int r;
assert(m);
r = config_parse_many_nulstr(
PKGSYSCONFDIR "/timesyncd.conf",
CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"),
"Time\0",
config_item_perf_lookup, timesyncd_gperf_lookup,
CONFIG_PARSE_WARN,
m,
NULL);
if (r < 0)
return r;
if (m->poll_interval_min_usec < 16 * USEC_PER_SEC) {
log_warning("Invalid PollIntervalMinSec=. Using default value.");
m->poll_interval_min_usec = NTP_POLL_INTERVAL_MIN_USEC;
}
if (m->poll_interval_max_usec < m->poll_interval_min_usec) {
log_warning("PollIntervalMaxSec= is smaller than PollIntervalMinSec=. Using default value.");
m->poll_interval_max_usec = MAX(NTP_POLL_INTERVAL_MAX_USEC, m->poll_interval_min_usec * 32);
}
return r;
}