summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2020-06-03 08:25:28 +0900
committerGitHub <noreply@github.com>2020-06-03 08:25:28 +0900
commit6161b35d5e870e92f8c30fd4ba3217f057756adf (patch)
tree3085485924840cbe9aef3459eea648aca5147de1
parentc9e06956754036177442e0e225f8c63b1f7eac5f (diff)
parent4f9ff96a55187927a4164a19df580329f4c6522b (diff)
downloadsystemd-6161b35d5e870e92f8c30fd4ba3217f057756adf.tar.gz
Merge pull request #16048 from poettering/conf-parser-mtime
conf-parser: automatically pick up newest mtime when parsing configuration files
-rw-r--r--src/basic/fs-util.c28
-rw-r--r--src/basic/fs-util.h1
-rw-r--r--src/core/load-dropin.c13
-rw-r--r--src/core/load-fragment.c4
-rw-r--r--src/core/main.c8
-rw-r--r--src/coredump/coredump.c13
-rw-r--r--src/fuzz/fuzz-unit-file.c11
-rw-r--r--src/home/homed-conf.c13
-rw-r--r--src/journal-remote/journal-remote-main.c12
-rw-r--r--src/journal-remote/journal-upload.c15
-rw-r--r--src/journal/journald-server.c23
-rw-r--r--src/login/logind-core.c12
-rw-r--r--src/network/netdev/netdev.c21
-rw-r--r--src/network/networkd-conf.c14
-rw-r--r--src/network/networkd-network.c118
-rw-r--r--src/nspawn/nspawn-settings.c2
-rw-r--r--src/partition/repart.c7
-rw-r--r--src/pstore/pstore.c13
-rw-r--r--src/resolve/resolved-conf.c13
-rw-r--r--src/resolve/resolved-dnssd.c11
-rw-r--r--src/shared/conf-parser.c54
-rw-r--r--src/shared/conf-parser.h11
-rw-r--r--src/shared/install.c3
-rw-r--r--src/shared/sleep-config.c12
-rw-r--r--src/test/test-conf-parser.c10
-rw-r--r--src/timesync/timesyncd-conf.c13
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c4
-rw-r--r--src/udev/net/link-config.c3
-rw-r--r--src/xdg-autostart-generator/xdg-autostart-service.c3
29 files changed, 274 insertions, 191 deletions
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 7bbcb6051e..943bc56319 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -353,28 +353,38 @@ int fchmod_opath(int fd, mode_t m) {
return 0;
}
-int fd_warn_permissions(const char *path, int fd) {
- struct stat st;
-
- if (fstat(fd, &st) < 0)
- return -errno;
+int stat_warn_permissions(const char *path, const struct stat *st) {
+ assert(path);
+ assert(st);
/* Don't complain if we are reading something that is not a file, for example /dev/null */
- if (!S_ISREG(st.st_mode))
+ if (!S_ISREG(st->st_mode))
return 0;
- if (st.st_mode & 0111)
+ if (st->st_mode & 0111)
log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
- if (st.st_mode & 0002)
+ if (st->st_mode & 0002)
log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
- if (getpid_cached() == 1 && (st.st_mode & 0044) != 0044)
+ if (getpid_cached() == 1 && (st->st_mode & 0044) != 0044)
log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
return 0;
}
+int fd_warn_permissions(const char *path, int fd) {
+ struct stat st;
+
+ assert(path);
+ assert(fd >= 0);
+
+ if (fstat(fd, &st) < 0)
+ return -errno;
+
+ return stat_warn_permissions(path, &st);
+}
+
int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
char fdpath[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
_cleanup_close_ int fd = -1;
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index dd101c61cc..b184570f9f 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -40,6 +40,7 @@ int fchmod_umask(int fd, mode_t mode);
int fchmod_opath(int fd, mode_t m);
int fd_warn_permissions(const char *path, int fd);
+int stat_warn_permissions(const char *path, const struct stat *st);
#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index f61e9da6f2..0da3eafb12 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -114,12 +114,13 @@ int unit_load_dropin(Unit *u) {
}
STRV_FOREACH(f, u->dropin_paths)
- (void) config_parse(u->id, *f, NULL,
- UNIT_VTABLE(u)->sections,
- config_item_perf_lookup, load_fragment_gperf_lookup,
- 0, u);
-
- u->dropin_mtime = now(CLOCK_REALTIME);
+ (void) config_parse(
+ u->id, *f, NULL,
+ UNIT_VTABLE(u)->sections,
+ config_item_perf_lookup, load_fragment_gperf_lookup,
+ 0,
+ u,
+ &u->dropin_mtime);
return 0;
}
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index a24c7877f9..49fdcaff7e 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -4864,7 +4864,9 @@ int unit_load_fragment(Unit *u) {
r = config_parse(u->id, fragment, f,
UNIT_VTABLE(u)->sections,
config_item_perf_lookup, load_fragment_gperf_lookup,
- CONFIG_PARSE_ALLOW_INCLUDE, u);
+ CONFIG_PARSE_ALLOW_INCLUDE,
+ u,
+ NULL);
if (r == -ENOEXEC)
log_unit_notice_errno(u, r, "Unit configuration has fatal error, unit will not be started.");
if (r < 0)
diff --git a/src/core/main.c b/src/core/main.c
index 32b963d4a4..e1de821e66 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -657,7 +657,13 @@ static int parse_config_file(void) {
CONF_PATHS_NULSTR("systemd/system.conf.d") :
CONF_PATHS_NULSTR("systemd/user.conf.d");
- (void) config_parse_many_nulstr(fn, conf_dirs_nulstr, "Manager\0", config_item_table_lookup, items, CONFIG_PARSE_WARN, NULL);
+ (void) config_parse_many_nulstr(
+ fn, conf_dirs_nulstr,
+ "Manager\0",
+ config_item_table_lookup, items,
+ CONFIG_PARSE_WARN,
+ NULL,
+ NULL);
/* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we used USEC_INFINITY
* like everywhere else. */
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index 42231dbd6b..d156d98efc 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -155,11 +155,14 @@ static int parse_config(void) {
{}
};
- return config_parse_many_nulstr(PKGSYSCONFDIR "/coredump.conf",
- CONF_PATHS_NULSTR("systemd/coredump.conf.d"),
- "Coredump\0",
- config_item_table_lookup, items,
- CONFIG_PARSE_WARN, NULL);
+ return config_parse_many_nulstr(
+ PKGSYSCONFDIR "/coredump.conf",
+ CONF_PATHS_NULSTR("systemd/coredump.conf.d"),
+ "Coredump\0",
+ config_item_table_lookup, items,
+ CONFIG_PARSE_WARN,
+ NULL,
+ NULL);
}
static uint64_t storage_size_max(void) {
diff --git a/src/fuzz/fuzz-unit-file.c b/src/fuzz/fuzz-unit-file.c
index d3993cf123..34f59a4437 100644
--- a/src/fuzz/fuzz-unit-file.c
+++ b/src/fuzz/fuzz-unit-file.c
@@ -70,10 +70,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
name = strjoina("a.", unit_type_to_string(t));
assert_se(unit_new_for_name(m, unit_vtable[t]->object_size, name, &u) >= 0);
- (void) config_parse(name, name, f,
- UNIT_VTABLE(u)->sections,
- config_item_perf_lookup, load_fragment_gperf_lookup,
- CONFIG_PARSE_ALLOW_INCLUDE, u);
+ (void) config_parse(
+ name, name, f,
+ UNIT_VTABLE(u)->sections,
+ config_item_perf_lookup, load_fragment_gperf_lookup,
+ CONFIG_PARSE_ALLOW_INCLUDE,
+ u,
+ NULL);
g = open_memstream_unlocked(&out, &out_size);
assert_se(g);
diff --git a/src/home/homed-conf.c b/src/home/homed-conf.c
index 14ec8b336d..df3a17358b 100644
--- a/src/home/homed-conf.c
+++ b/src/home/homed-conf.c
@@ -10,11 +10,14 @@ int manager_parse_config_file(Manager *m) {
assert(m);
- r = config_parse_many_nulstr(PKGSYSCONFDIR "/homed.conf",
- CONF_PATHS_NULSTR("systemd/homed.conf.d"),
- "Home\0",
- config_item_perf_lookup, homed_gperf_lookup,
- CONFIG_PARSE_WARN, m);
+ r = config_parse_many_nulstr(
+ PKGSYSCONFDIR "/homed.conf",
+ CONF_PATHS_NULSTR("systemd/homed.conf.d"),
+ "Home\0",
+ config_item_perf_lookup, homed_gperf_lookup,
+ CONFIG_PARSE_WARN,
+ m,
+ NULL);
if (r < 0)
return r;
diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c
index 551b84130d..948b2d2fce 100644
--- a/src/journal-remote/journal-remote-main.c
+++ b/src/journal-remote/journal-remote-main.c
@@ -762,10 +762,14 @@ static int parse_config(void) {
{}
};
- return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-remote.conf",
- CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
- "Remote\0", config_item_table_lookup, items,
- CONFIG_PARSE_WARN, NULL);
+ return config_parse_many_nulstr(
+ PKGSYSCONFDIR "/journal-remote.conf",
+ CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
+ "Remote\0",
+ config_item_table_lookup, items,
+ CONFIG_PARSE_WARN,
+ NULL,
+ NULL);
}
static int help(void) {
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index bf656ac670..bd58fdbcdf 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -562,12 +562,17 @@ static int parse_config(void) {
{ "Upload", "ServerKeyFile", config_parse_path_or_ignore, 0, &arg_key },
{ "Upload", "ServerCertificateFile", config_parse_path_or_ignore, 0, &arg_cert },
{ "Upload", "TrustedCertificateFile", config_parse_path_or_ignore, 0, &arg_trust },
- {}};
+ {}
+ };
- return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-upload.conf",
- CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"),
- "Upload\0", config_item_table_lookup, items,
- CONFIG_PARSE_WARN, NULL);
+ return config_parse_many_nulstr(
+ PKGSYSCONFDIR "/journal-upload.conf",
+ CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"),
+ "Upload\0",
+ config_item_table_lookup, items,
+ CONFIG_PARSE_WARN,
+ NULL,
+ NULL);
}
static int help(void) {
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 9efa65a294..5865bf9809 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1633,23 +1633,24 @@ static int server_parse_config_file(Server *s) {
/* If we are running in namespace mode, load the namespace specific configuration file, and nothing else */
namespaced = strjoina(PKGSYSCONFDIR "/journald@", s->namespace, ".conf");
- r = config_parse(
- NULL,
- namespaced, NULL,
- "Journal\0",
- config_item_perf_lookup, journald_gperf_lookup,
- CONFIG_PARSE_WARN, s);
+ r = config_parse(NULL,
+ namespaced, NULL,
+ "Journal\0",
+ config_item_perf_lookup, journald_gperf_lookup,
+ CONFIG_PARSE_WARN, s,
+ NULL);
if (r < 0)
return r;
return 0;
}
- return config_parse_many_nulstr(PKGSYSCONFDIR "/journald.conf",
- CONF_PATHS_NULSTR("systemd/journald.conf.d"),
- "Journal\0",
- config_item_perf_lookup, journald_gperf_lookup,
- CONFIG_PARSE_WARN, s);
+ return config_parse_many_nulstr(
+ PKGSYSCONFDIR "/journald.conf",
+ CONF_PATHS_NULSTR("systemd/journald.conf.d"),
+ "Journal\0",
+ config_item_perf_lookup, journald_gperf_lookup,
+ CONFIG_PARSE_WARN, s, NULL);
}
static int server_dispatch_sync(sd_event_source *es, usec_t t, void *userdata) {
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index 1375f438e4..4289461df6 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -69,11 +69,13 @@ void manager_reset_config(Manager *m) {
int manager_parse_config_file(Manager *m) {
assert(m);
- return config_parse_many_nulstr(PKGSYSCONFDIR "/logind.conf",
- CONF_PATHS_NULSTR("systemd/logind.conf.d"),
- "Login\0",
- config_item_perf_lookup, logind_gperf_lookup,
- CONFIG_PARSE_WARN, m);
+ return config_parse_many_nulstr(
+ PKGSYSCONFDIR "/logind.conf",
+ CONF_PATHS_NULSTR("systemd/logind.conf.d"),
+ "Login\0",
+ config_item_perf_lookup, logind_gperf_lookup,
+ CONFIG_PARSE_WARN, m,
+ NULL);
}
int manager_add_device(Manager *m, const char *sysfs, bool master, Device **ret_device) {
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index a990c64b55..1889f6f13c 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -686,10 +686,13 @@ int netdev_load_one(Manager *manager, const char *filename) {
};
dropin_dirname = strjoina(basename(filename), ".d");
- r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
- NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS,
- config_item_perf_lookup, network_netdev_gperf_lookup,
- CONFIG_PARSE_WARN, netdev_raw, NULL);
+ r = config_parse_many(
+ filename, NETWORK_DIRS, dropin_dirname,
+ NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS,
+ config_item_perf_lookup, network_netdev_gperf_lookup,
+ CONFIG_PARSE_WARN,
+ netdev_raw,
+ NULL);
if (r < 0)
return r;
@@ -726,10 +729,12 @@ int netdev_load_one(Manager *manager, const char *filename) {
if (NETDEV_VTABLE(netdev)->init)
NETDEV_VTABLE(netdev)->init(netdev);
- r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
- NETDEV_VTABLE(netdev)->sections,
- config_item_perf_lookup, network_netdev_gperf_lookup,
- CONFIG_PARSE_WARN, netdev, NULL);
+ r = config_parse_many(
+ filename, NETWORK_DIRS, dropin_dirname,
+ NETDEV_VTABLE(netdev)->sections,
+ config_item_perf_lookup, network_netdev_gperf_lookup,
+ CONFIG_PARSE_WARN,
+ netdev, NULL);
if (r < 0)
return r;
diff --git a/src/network/networkd-conf.c b/src/network/networkd-conf.c
index 350fea634c..30625117e4 100644
--- a/src/network/networkd-conf.c
+++ b/src/network/networkd-conf.c
@@ -23,11 +23,15 @@ int manager_parse_config_file(Manager *m) {
assert(m);
- r = config_parse_many_nulstr(PKGSYSCONFDIR "/networkd.conf",
- CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
- "Network\0DHCP\0",
- config_item_perf_lookup, networkd_gperf_lookup,
- CONFIG_PARSE_WARN, m);
+ r = config_parse_many_nulstr(
+ PKGSYSCONFDIR "/networkd.conf",
+ CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
+ "Network\0"
+ "DHCP\0",
+ config_item_perf_lookup, networkd_gperf_lookup,
+ CONFIG_PARSE_WARN,
+ m,
+ NULL);
if (r < 0)
return r;
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index b928f7585c..50e50fd945 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -335,7 +335,6 @@ int network_verify(Network *network) {
int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename) {
_cleanup_free_ char *fname = NULL, *name = NULL;
_cleanup_(network_unrefp) Network *network = NULL;
- _cleanup_strv_free_ char **dropins = NULL;
_cleanup_fclose_ FILE *file = NULL;
const char *dropin_dirname;
char *d;
@@ -477,54 +476,57 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ip_service_type = -1,
};
- r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
- "Match\0"
- "Link\0"
- "Network\0"
- "Address\0"
- "Neighbor\0"
- "IPv6AddressLabel\0"
- "RoutingPolicyRule\0"
- "Route\0"
- "NextHop\0"
- "DHCP\0" /* compat */
- "DHCPv4\0"
- "DHCPv6\0"
- "DHCPServer\0"
- "IPv6AcceptRA\0"
- "IPv6NDPProxyAddress\0"
- "Bridge\0"
- "BridgeFDB\0"
- "BridgeVLAN\0"
- "IPv6PrefixDelegation\0"
- "IPv6Prefix\0"
- "IPv6RoutePrefix\0"
- "LLDP\0"
- "TrafficControlQueueingDiscipline\0"
- "CAN\0"
- "QDisc\0"
- "BFIFO\0"
- "CAKE\0"
- "ControlledDelay\0"
- "DeficitRoundRobinScheduler\0"
- "DeficitRoundRobinSchedulerClass\0"
- "PFIFO\0"
- "PFIFOFast\0"
- "PFIFOHeadDrop\0"
- "FairQueueing\0"
- "FairQueueingControlledDelay\0"
- "GenericRandomEarlyDetection\0"
- "HeavyHitterFilter\0"
- "HierarchyTokenBucket\0"
- "HierarchyTokenBucketClass\0"
- "NetworkEmulator\0"
- "PIE\0"
- "StochasticFairBlue\0"
- "StochasticFairnessQueueing\0"
- "TokenBucketFilter\0"
- "TrivialLinkEqualizer\0",
- config_item_perf_lookup, network_network_gperf_lookup,
- CONFIG_PARSE_WARN, network, &dropins);
+ r = config_parse_many(
+ filename, NETWORK_DIRS, dropin_dirname,
+ "Match\0"
+ "Link\0"
+ "Network\0"
+ "Address\0"
+ "Neighbor\0"
+ "IPv6AddressLabel\0"
+ "RoutingPolicyRule\0"
+ "Route\0"
+ "NextHop\0"
+ "DHCP\0" /* compat */
+ "DHCPv4\0"
+ "DHCPv6\0"
+ "DHCPServer\0"
+ "IPv6AcceptRA\0"
+ "IPv6NDPProxyAddress\0"
+ "Bridge\0"
+ "BridgeFDB\0"
+ "BridgeVLAN\0"
+ "IPv6PrefixDelegation\0"
+ "IPv6Prefix\0"
+ "IPv6RoutePrefix\0"
+ "LLDP\0"
+ "TrafficControlQueueingDiscipline\0"
+ "CAN\0"
+ "QDisc\0"
+ "BFIFO\0"
+ "CAKE\0"
+ "ControlledDelay\0"
+ "DeficitRoundRobinScheduler\0"
+ "DeficitRoundRobinSchedulerClass\0"
+ "PFIFO\0"
+ "PFIFOFast\0"
+ "PFIFOHeadDrop\0"
+ "FairQueueing\0"
+ "FairQueueingControlledDelay\0"
+ "GenericRandomEarlyDetection\0"
+ "HeavyHitterFilter\0"
+ "HierarchyTokenBucket\0"
+ "HierarchyTokenBucketClass\0"
+ "NetworkEmulator\0"
+ "PIE\0"
+ "StochasticFairBlue\0"
+ "StochasticFairnessQueueing\0"
+ "TokenBucketFilter\0"
+ "TrivialLinkEqualizer\0",
+ config_item_perf_lookup, network_network_gperf_lookup,
+ CONFIG_PARSE_WARN,
+ network,
+ &network->timestamp);
if (r < 0)
return r;
@@ -539,24 +541,6 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
log_warning_errno(r, "%s: Failed to add default route on device, ignoring: %m",
network->filename);
- struct stat stats;
- if (stat(filename, &stats) >= 0)
- network->timestamp = timespec_load(&stats.st_mtim);
-
- char **f;
- STRV_FOREACH(f, dropins) {
- usec_t t;
-
- if (stat(*f, &stats) < 0) {
- network->timestamp = 0;
- break;
- }
-
- t = timespec_load(&stats.st_mtim);
- if (t > network->timestamp)
- network->timestamp = t;
- }
-
if (network_verify(network) < 0)
/* Ignore .network files that do not match the conditions. */
return 0;
diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c
index 4e1cb3835c..996c0027c3 100644
--- a/src/nspawn/nspawn-settings.c
+++ b/src/nspawn/nspawn-settings.c
@@ -78,7 +78,7 @@ int settings_load(FILE *f, const char *path, Settings **ret) {
"Files\0",
config_item_perf_lookup, nspawn_gperf_lookup,
CONFIG_PARSE_WARN,
- s);
+ s, NULL);
if (r < 0)
return r;
diff --git a/src/partition/repart.c b/src/partition/repart.c
index 16cb5e45c4..4c6e459529 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -976,7 +976,12 @@ static int partition_read_definition(Partition *p, const char *path) {
};
int r;
- r = config_parse(NULL, path, NULL, "Partition\0", config_item_table_lookup, table, CONFIG_PARSE_WARN, p);
+ r = config_parse(NULL, path, NULL,
+ "Partition\0",
+ config_item_table_lookup, table,
+ CONFIG_PARSE_WARN,
+ p,
+ NULL);
if (r < 0)
return r;
diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c
index 5c812b5d5b..59d0b5b74e 100644
--- a/src/pstore/pstore.c
+++ b/src/pstore/pstore.c
@@ -78,11 +78,14 @@ static int parse_config(void) {
{}
};
- return config_parse_many_nulstr(PKGSYSCONFDIR "/pstore.conf",
- CONF_PATHS_NULSTR("systemd/pstore.conf.d"),
- "PStore\0",
- config_item_table_lookup, items,
- CONFIG_PARSE_WARN, NULL);
+ return config_parse_many_nulstr(
+ PKGSYSCONFDIR "/pstore.conf",
+ CONF_PATHS_NULSTR("systemd/pstore.conf.d"),
+ "PStore\0",
+ config_item_table_lookup, items,
+ CONFIG_PARSE_WARN,
+ NULL,
+ NULL);
}
/* File list handling - PStoreEntry is the struct and
diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c
index e915343c01..9a6b1e88e1 100644
--- a/src/resolve/resolved-conf.c
+++ b/src/resolve/resolved-conf.c
@@ -381,11 +381,14 @@ int manager_parse_config_file(Manager *m) {
assert(m);
- r = config_parse_many_nulstr(PKGSYSCONFDIR "/resolved.conf",
- CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
- "Resolve\0",
- config_item_perf_lookup, resolved_gperf_lookup,
- CONFIG_PARSE_WARN, m);
+ r = config_parse_many_nulstr(
+ PKGSYSCONFDIR "/resolved.conf",
+ CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
+ "Resolve\0",
+ config_item_perf_lookup, resolved_gperf_lookup,
+ CONFIG_PARSE_WARN,
+ m,
+ NULL);
if (r < 0)
return r;
diff --git a/src/resolve/resolved-dnssd.c b/src/resolve/resolved-dnssd.c
index c331b2d94c..4458ad1d2d 100644
--- a/src/resolve/resolved-dnssd.c
+++ b/src/resolve/resolved-dnssd.c
@@ -86,10 +86,13 @@ static int dnssd_service_load(Manager *manager, const char *filename) {
dropin_dirname = strjoina(service->name, ".dnssd.d");
- r = config_parse_many(filename, DNSSD_SERVICE_DIRS, dropin_dirname,
- "Service\0",
- config_item_perf_lookup, resolved_dnssd_gperf_lookup,
- false, service, NULL);
+ r = config_parse_many(
+ filename, DNSSD_SERVICE_DIRS, dropin_dirname,
+ "Service\0",
+ config_item_perf_lookup, resolved_dnssd_gperf_lookup,
+ CONFIG_PARSE_WARN,
+ service,
+ NULL);
if (r < 0)
return r;
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index b04eb3912c..2122657342 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -199,7 +199,7 @@ static int parse_line(
if (!fn)
return -ENOMEM;
- return config_parse(unit, fn, NULL, sections, lookup, table, flags, userdata);
+ return config_parse(unit, fn, NULL, sections, lookup, table, flags, userdata, NULL);
}
if (!utf8_is_valid(l))
@@ -289,13 +289,15 @@ int config_parse(const char *unit,
ConfigItemLookup lookup,
const void *table,
ConfigParseFlags flags,
- void *userdata) {
+ void *userdata,
+ usec_t *ret_mtime) {
_cleanup_free_ char *section = NULL, *continuation = NULL;
_cleanup_fclose_ FILE *ours = NULL;
unsigned line = 0, section_line = 0;
bool section_ignored = false, bom_seen = false;
int r, fd;
+ usec_t mtime;
assert(filename);
assert(lookup);
@@ -313,8 +315,16 @@ int config_parse(const char *unit,
}
fd = fileno(f);
- if (fd >= 0) /* stream might not have an fd, let's be careful hence */
- fd_warn_permissions(filename, fd);
+ if (fd >= 0) { /* stream might not have an fd, let's be careful hence */
+ struct stat st;
+
+ if (fstat(fd, &st) < 0)
+ return log_full_errno(FLAGS_SET(flags, CONFIG_PARSE_WARN) ? LOG_ERR : LOG_DEBUG, errno,
+ "Failed to fstat(%s): %m", filename);
+
+ (void) stat_warn_permissions(filename, &st);
+ mtime = timespec_load(&st.st_mtim);
+ }
for (;;) {
_cleanup_free_ char *buf = NULL;
@@ -331,7 +341,7 @@ int config_parse(const char *unit,
return r;
}
if (r < 0) {
- if (CONFIG_PARSE_WARN)
+ if (FLAGS_SET(flags, CONFIG_PARSE_WARN))
log_error_errno(r, "%s:%u: Error while reading configuration file: %m", filename, line);
return r;
@@ -434,6 +444,9 @@ int config_parse(const char *unit,
}
}
+ if (ret_mtime)
+ *ret_mtime = mtime;
+
return 0;
}
@@ -444,23 +457,32 @@ static int config_parse_many_files(
ConfigItemLookup lookup,
const void *table,
ConfigParseFlags flags,
- void *userdata) {
+ void *userdata,
+ usec_t *ret_mtime) {
+ usec_t mtime = 0;
char **fn;
int r;
if (conf_file) {
- r = config_parse(NULL, conf_file, NULL, sections, lookup, table, flags, userdata);
+ r = config_parse(NULL, conf_file, NULL, sections, lookup, table, flags, userdata, &mtime);
if (r < 0)
return r;
}
STRV_FOREACH(fn, files) {
- r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata);
+ usec_t t;
+
+ r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &t);
if (r < 0)
return r;
+ if (t > mtime) /* Find the newest */
+ mtime = t;
}
+ if (ret_mtime)
+ *ret_mtime = mtime;
+
return 0;
}
@@ -472,7 +494,8 @@ int config_parse_many_nulstr(
ConfigItemLookup lookup,
const void *table,
ConfigParseFlags flags,
- void *userdata) {
+ void *userdata,
+ usec_t *ret_mtime) {
_cleanup_strv_free_ char **files = NULL;
int r;
@@ -481,7 +504,7 @@ int config_parse_many_nulstr(
if (r < 0)
return r;
- return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata);
+ return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata, ret_mtime);
}
/* Parse each config file in the directories specified as strv. */
@@ -494,7 +517,7 @@ int config_parse_many(
const void *table,
ConfigParseFlags flags,
void *userdata,
- char ***ret_dropins) {
+ usec_t *ret_mtime) {
_cleanup_strv_free_ char **dropin_dirs = NULL;
_cleanup_strv_free_ char **files = NULL;
@@ -510,14 +533,7 @@ int config_parse_many(
if (r < 0)
return r;
- r = config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata);
- if (r < 0)
- return r;
-
- if (ret_dropins)
- *ret_dropins = TAKE_PTR(files);
-
- return 0;
+ return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata, ret_mtime);
}
#define DEFINE_PARSER(type, vartype, conv_func) \
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index 480988f392..6c8c1092ea 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -10,6 +10,7 @@
#include "alloc-util.h"
#include "log.h"
#include "macro.h"
+#include "time-util.h"
/* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
@@ -84,11 +85,12 @@ int config_parse(
const char *unit,
const char *filename,
FILE *f,
- const char *sections, /* nulstr */
+ const char *sections, /* nulstr */
ConfigItemLookup lookup,
const void *table,
ConfigParseFlags flags,
- void *userdata);
+ void *userdata,
+ usec_t *ret_mtime); /* possibly NULL */
int config_parse_many_nulstr(
const char *conf_file, /* possibly NULL */
@@ -97,7 +99,8 @@ int config_parse_many_nulstr(
ConfigItemLookup lookup,
const void *table,
ConfigParseFlags flags,
- void *userdata);
+ void *userdata,
+ usec_t *ret_mtime); /* possibly NULL */
int config_parse_many(
const char *conf_file, /* possibly NULL */
@@ -108,7 +111,7 @@ int config_parse_many(
const void *table,
ConfigParseFlags flags,
void *userdata,
- char ***ret_dropins); /* possibly NULL */
+ usec_t *ret_mtime); /* possibly NULL */
CONFIG_PARSER_PROTOTYPE(config_parse_int);
CONFIG_PARSER_PROTOTYPE(config_parse_unsigned);
diff --git a/src/shared/install.c b/src/shared/install.c
index 60005967e7..5dd5d2aa9a 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1304,7 +1304,8 @@ static int unit_file_load(
"-Target\0"
"-Timer\0",
config_item_table_lookup, items,
- CONFIG_PARSE_ALLOW_INCLUDE, info);
+ CONFIG_PARSE_ALLOW_INCLUDE, info,
+ NULL);
if (r < 0)
return log_debug_errno(r, "Failed to parse %s: %m", info->name);
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
index 5cee1ce1aa..81862c776d 100644
--- a/src/shared/sleep-config.c
+++ b/src/shared/sleep-config.c
@@ -59,10 +59,14 @@ int parse_sleep_config(SleepConfig **ret_sleep_config) {
{}
};
- (void) config_parse_many_nulstr(PKGSYSCONFDIR "/sleep.conf",
- CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
- "Sleep\0", config_item_table_lookup, items,
- CONFIG_PARSE_WARN, NULL);
+ (void) config_parse_many_nulstr(
+ PKGSYSCONFDIR "/sleep.conf",
+ CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
+ "Sleep\0",
+ config_item_table_lookup, items,
+ CONFIG_PARSE_WARN,
+ NULL,
+ NULL);
/* use default values unless set */
sc->allow_suspend = allow_suspend != 0;
diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c
index 510b1de72d..07edc17f92 100644
--- a/src/test/test-conf-parser.c
+++ b/src/test/test-conf-parser.c
@@ -335,13 +335,17 @@ static void test_config_parse(unsigned i, const char *s) {
ConfigItemLookup lookup,
const void *table,
ConfigParseFlags flags,
- void *userdata)
+ void *userdata,
+ usec_t *ret_mtime)
*/
r = config_parse(NULL, name, f,
- "Section\0-NoWarnSection\0",
+ "Section\0"
+ "-NoWarnSection\0",
config_item_table_lookup, items,
- CONFIG_PARSE_WARN, NULL);
+ CONFIG_PARSE_WARN,
+ NULL,
+ NULL);
switch (i) {
case 0 ... 4:
diff --git a/src/timesync/timesyncd-conf.c b/src/timesync/timesyncd-conf.c
index a26c2dad7f..532d6ea7ec 100644
--- a/src/timesync/timesyncd-conf.c
+++ b/src/timesync/timesyncd-conf.c
@@ -102,11 +102,14 @@ int manager_parse_config_file(Manager *m) {
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);
+ 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;
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 0e33c0b48f..eb84719111 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -192,7 +192,9 @@ static int process_one_password_file(const char *filename) {
r = config_parse(NULL, filename, NULL,
NULL,
config_item_table_lookup, items,
- CONFIG_PARSE_RELAXED|CONFIG_PARSE_WARN, NULL);
+ CONFIG_PARSE_RELAXED|CONFIG_PARSE_WARN,
+ NULL,
+ NULL);
if (r < 0)
return r;
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 806f457458..abe1276dfa 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -161,7 +161,8 @@ int link_load_one(link_config_ctx *ctx, const char *filename) {
r = config_parse(NULL, filename, file,
"Match\0Link\0",
config_item_perf_lookup, link_config_gperf_lookup,
- CONFIG_PARSE_WARN, link);
+ CONFIG_PARSE_WARN, link,
+ NULL);
if (r < 0)
return r;
diff --git a/src/xdg-autostart-generator/xdg-autostart-service.c b/src/xdg-autostart-generator/xdg-autostart-service.c
index c99b6cc883..6d10d7052b 100644
--- a/src/xdg-autostart-generator/xdg-autostart-service.c
+++ b/src/xdg-autostart-generator/xdg-autostart-service.c
@@ -319,7 +319,8 @@ XdgAutostartService *xdg_autostart_service_parse_desktop(const char *path) {
r = config_parse(NULL, service->path, NULL,
"Desktop Entry\0",
xdg_config_item_table_lookup, items,
- CONFIG_PARSE_WARN, service);
+ CONFIG_PARSE_WARN, service,
+ NULL);
/* If parsing failed, only hide the file so it will still mask others. */
if (r < 0) {
log_warning_errno(r, "Failed to parse %s, ignoring it", service->path);