mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-02-03 13:47:04 +03:00
conf-parser: return mtime in config_parse() and friends
This is a follow-up for 9f83091e3cceb646a66fa9df89de6d9a77c21d86. 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.
This commit is contained in:
parent
5aca2e6733
commit
4f9ff96a55
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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. */
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user