mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-25 23:21:33 +03:00
Merge pull request #16048 from poettering/conf-parser-mtime
conf-parser: automatically pick up newest mtime when parsing configuration files
This commit is contained in:
commit
6161b35d5e
@ -353,26 +353,36 @@ int fchmod_opath(int fd, mode_t m) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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) {
|
int fd_warn_permissions(const char *path, int fd) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
assert(path);
|
||||||
|
assert(fd >= 0);
|
||||||
|
|
||||||
if (fstat(fd, &st) < 0)
|
if (fstat(fd, &st) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
/* Don't complain if we are reading something that is not a file, for example /dev/null */
|
return stat_warn_permissions(path, &st);
|
||||||
if (!S_ISREG(st.st_mode))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
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 touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
|
int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
|
||||||
|
@ -40,6 +40,7 @@ int fchmod_umask(int fd, mode_t mode);
|
|||||||
int fchmod_opath(int fd, mode_t m);
|
int fchmod_opath(int fd, mode_t m);
|
||||||
|
|
||||||
int fd_warn_permissions(const char *path, int fd);
|
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)
|
#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)
|
||||||
|
|
||||||
|
@ -114,12 +114,13 @@ int unit_load_dropin(Unit *u) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
STRV_FOREACH(f, u->dropin_paths)
|
STRV_FOREACH(f, u->dropin_paths)
|
||||||
(void) config_parse(u->id, *f, NULL,
|
(void) config_parse(
|
||||||
UNIT_VTABLE(u)->sections,
|
u->id, *f, NULL,
|
||||||
config_item_perf_lookup, load_fragment_gperf_lookup,
|
UNIT_VTABLE(u)->sections,
|
||||||
0, u);
|
config_item_perf_lookup, load_fragment_gperf_lookup,
|
||||||
|
0,
|
||||||
u->dropin_mtime = now(CLOCK_REALTIME);
|
u,
|
||||||
|
&u->dropin_mtime);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4864,7 +4864,9 @@ int unit_load_fragment(Unit *u) {
|
|||||||
r = config_parse(u->id, fragment, f,
|
r = config_parse(u->id, fragment, f,
|
||||||
UNIT_VTABLE(u)->sections,
|
UNIT_VTABLE(u)->sections,
|
||||||
config_item_perf_lookup, load_fragment_gperf_lookup,
|
config_item_perf_lookup, load_fragment_gperf_lookup,
|
||||||
CONFIG_PARSE_ALLOW_INCLUDE, u);
|
CONFIG_PARSE_ALLOW_INCLUDE,
|
||||||
|
u,
|
||||||
|
NULL);
|
||||||
if (r == -ENOEXEC)
|
if (r == -ENOEXEC)
|
||||||
log_unit_notice_errno(u, r, "Unit configuration has fatal error, unit will not be started.");
|
log_unit_notice_errno(u, r, "Unit configuration has fatal error, unit will not be started.");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -657,7 +657,13 @@ static int parse_config_file(void) {
|
|||||||
CONF_PATHS_NULSTR("systemd/system.conf.d") :
|
CONF_PATHS_NULSTR("systemd/system.conf.d") :
|
||||||
CONF_PATHS_NULSTR("systemd/user.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
|
/* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we used USEC_INFINITY
|
||||||
* like everywhere else. */
|
* like everywhere else. */
|
||||||
|
@ -155,11 +155,14 @@ static int parse_config(void) {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/coredump.conf",
|
return config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/coredump.conf.d"),
|
PKGSYSCONFDIR "/coredump.conf",
|
||||||
"Coredump\0",
|
CONF_PATHS_NULSTR("systemd/coredump.conf.d"),
|
||||||
config_item_table_lookup, items,
|
"Coredump\0",
|
||||||
CONFIG_PARSE_WARN, NULL);
|
config_item_table_lookup, items,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t storage_size_max(void) {
|
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));
|
name = strjoina("a.", unit_type_to_string(t));
|
||||||
assert_se(unit_new_for_name(m, unit_vtable[t]->object_size, name, &u) >= 0);
|
assert_se(unit_new_for_name(m, unit_vtable[t]->object_size, name, &u) >= 0);
|
||||||
|
|
||||||
(void) config_parse(name, name, f,
|
(void) config_parse(
|
||||||
UNIT_VTABLE(u)->sections,
|
name, name, f,
|
||||||
config_item_perf_lookup, load_fragment_gperf_lookup,
|
UNIT_VTABLE(u)->sections,
|
||||||
CONFIG_PARSE_ALLOW_INCLUDE, u);
|
config_item_perf_lookup, load_fragment_gperf_lookup,
|
||||||
|
CONFIG_PARSE_ALLOW_INCLUDE,
|
||||||
|
u,
|
||||||
|
NULL);
|
||||||
|
|
||||||
g = open_memstream_unlocked(&out, &out_size);
|
g = open_memstream_unlocked(&out, &out_size);
|
||||||
assert_se(g);
|
assert_se(g);
|
||||||
|
@ -10,11 +10,14 @@ int manager_parse_config_file(Manager *m) {
|
|||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
r = config_parse_many_nulstr(PKGSYSCONFDIR "/homed.conf",
|
r = config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/homed.conf.d"),
|
PKGSYSCONFDIR "/homed.conf",
|
||||||
"Home\0",
|
CONF_PATHS_NULSTR("systemd/homed.conf.d"),
|
||||||
config_item_perf_lookup, homed_gperf_lookup,
|
"Home\0",
|
||||||
CONFIG_PARSE_WARN, m);
|
config_item_perf_lookup, homed_gperf_lookup,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
m,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -762,10 +762,14 @@ static int parse_config(void) {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-remote.conf",
|
return config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
|
PKGSYSCONFDIR "/journal-remote.conf",
|
||||||
"Remote\0", config_item_table_lookup, items,
|
CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
|
||||||
CONFIG_PARSE_WARN, NULL);
|
"Remote\0",
|
||||||
|
config_item_table_lookup, items,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int help(void) {
|
static int help(void) {
|
||||||
|
@ -562,12 +562,17 @@ static int parse_config(void) {
|
|||||||
{ "Upload", "ServerKeyFile", config_parse_path_or_ignore, 0, &arg_key },
|
{ "Upload", "ServerKeyFile", config_parse_path_or_ignore, 0, &arg_key },
|
||||||
{ "Upload", "ServerCertificateFile", config_parse_path_or_ignore, 0, &arg_cert },
|
{ "Upload", "ServerCertificateFile", config_parse_path_or_ignore, 0, &arg_cert },
|
||||||
{ "Upload", "TrustedCertificateFile", config_parse_path_or_ignore, 0, &arg_trust },
|
{ "Upload", "TrustedCertificateFile", config_parse_path_or_ignore, 0, &arg_trust },
|
||||||
{}};
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-upload.conf",
|
return config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"),
|
PKGSYSCONFDIR "/journal-upload.conf",
|
||||||
"Upload\0", config_item_table_lookup, items,
|
CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"),
|
||||||
CONFIG_PARSE_WARN, NULL);
|
"Upload\0",
|
||||||
|
config_item_table_lookup, items,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int help(void) {
|
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 */
|
/* If we are running in namespace mode, load the namespace specific configuration file, and nothing else */
|
||||||
namespaced = strjoina(PKGSYSCONFDIR "/journald@", s->namespace, ".conf");
|
namespaced = strjoina(PKGSYSCONFDIR "/journald@", s->namespace, ".conf");
|
||||||
|
|
||||||
r = config_parse(
|
r = config_parse(NULL,
|
||||||
NULL,
|
namespaced, NULL,
|
||||||
namespaced, NULL,
|
"Journal\0",
|
||||||
"Journal\0",
|
config_item_perf_lookup, journald_gperf_lookup,
|
||||||
config_item_perf_lookup, journald_gperf_lookup,
|
CONFIG_PARSE_WARN, s,
|
||||||
CONFIG_PARSE_WARN, s);
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/journald.conf",
|
return config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/journald.conf.d"),
|
PKGSYSCONFDIR "/journald.conf",
|
||||||
"Journal\0",
|
CONF_PATHS_NULSTR("systemd/journald.conf.d"),
|
||||||
config_item_perf_lookup, journald_gperf_lookup,
|
"Journal\0",
|
||||||
CONFIG_PARSE_WARN, s);
|
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) {
|
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) {
|
int manager_parse_config_file(Manager *m) {
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/logind.conf",
|
return config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/logind.conf.d"),
|
PKGSYSCONFDIR "/logind.conf",
|
||||||
"Login\0",
|
CONF_PATHS_NULSTR("systemd/logind.conf.d"),
|
||||||
config_item_perf_lookup, logind_gperf_lookup,
|
"Login\0",
|
||||||
CONFIG_PARSE_WARN, m);
|
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) {
|
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");
|
dropin_dirname = strjoina(basename(filename), ".d");
|
||||||
r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
|
r = config_parse_many(
|
||||||
NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS,
|
filename, NETWORK_DIRS, dropin_dirname,
|
||||||
config_item_perf_lookup, network_netdev_gperf_lookup,
|
NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS,
|
||||||
CONFIG_PARSE_WARN, netdev_raw, NULL);
|
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
netdev_raw,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -726,10 +729,12 @@ int netdev_load_one(Manager *manager, const char *filename) {
|
|||||||
if (NETDEV_VTABLE(netdev)->init)
|
if (NETDEV_VTABLE(netdev)->init)
|
||||||
NETDEV_VTABLE(netdev)->init(netdev);
|
NETDEV_VTABLE(netdev)->init(netdev);
|
||||||
|
|
||||||
r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
|
r = config_parse_many(
|
||||||
NETDEV_VTABLE(netdev)->sections,
|
filename, NETWORK_DIRS, dropin_dirname,
|
||||||
config_item_perf_lookup, network_netdev_gperf_lookup,
|
NETDEV_VTABLE(netdev)->sections,
|
||||||
CONFIG_PARSE_WARN, netdev, NULL);
|
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
netdev, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -23,11 +23,15 @@ int manager_parse_config_file(Manager *m) {
|
|||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
r = config_parse_many_nulstr(PKGSYSCONFDIR "/networkd.conf",
|
r = config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
|
PKGSYSCONFDIR "/networkd.conf",
|
||||||
"Network\0DHCP\0",
|
CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
|
||||||
config_item_perf_lookup, networkd_gperf_lookup,
|
"Network\0"
|
||||||
CONFIG_PARSE_WARN, m);
|
"DHCP\0",
|
||||||
|
config_item_perf_lookup, networkd_gperf_lookup,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
m,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -335,7 +335,6 @@ int network_verify(Network *network) {
|
|||||||
int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename) {
|
int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename) {
|
||||||
_cleanup_free_ char *fname = NULL, *name = NULL;
|
_cleanup_free_ char *fname = NULL, *name = NULL;
|
||||||
_cleanup_(network_unrefp) Network *network = NULL;
|
_cleanup_(network_unrefp) Network *network = NULL;
|
||||||
_cleanup_strv_free_ char **dropins = NULL;
|
|
||||||
_cleanup_fclose_ FILE *file = NULL;
|
_cleanup_fclose_ FILE *file = NULL;
|
||||||
const char *dropin_dirname;
|
const char *dropin_dirname;
|
||||||
char *d;
|
char *d;
|
||||||
@ -477,54 +476,57 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
|||||||
.ip_service_type = -1,
|
.ip_service_type = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
|
r = config_parse_many(
|
||||||
"Match\0"
|
filename, NETWORK_DIRS, dropin_dirname,
|
||||||
"Link\0"
|
"Match\0"
|
||||||
"Network\0"
|
"Link\0"
|
||||||
"Address\0"
|
"Network\0"
|
||||||
"Neighbor\0"
|
"Address\0"
|
||||||
"IPv6AddressLabel\0"
|
"Neighbor\0"
|
||||||
"RoutingPolicyRule\0"
|
"IPv6AddressLabel\0"
|
||||||
"Route\0"
|
"RoutingPolicyRule\0"
|
||||||
"NextHop\0"
|
"Route\0"
|
||||||
"DHCP\0" /* compat */
|
"NextHop\0"
|
||||||
"DHCPv4\0"
|
"DHCP\0" /* compat */
|
||||||
"DHCPv6\0"
|
"DHCPv4\0"
|
||||||
"DHCPServer\0"
|
"DHCPv6\0"
|
||||||
"IPv6AcceptRA\0"
|
"DHCPServer\0"
|
||||||
"IPv6NDPProxyAddress\0"
|
"IPv6AcceptRA\0"
|
||||||
"Bridge\0"
|
"IPv6NDPProxyAddress\0"
|
||||||
"BridgeFDB\0"
|
"Bridge\0"
|
||||||
"BridgeVLAN\0"
|
"BridgeFDB\0"
|
||||||
"IPv6PrefixDelegation\0"
|
"BridgeVLAN\0"
|
||||||
"IPv6Prefix\0"
|
"IPv6PrefixDelegation\0"
|
||||||
"IPv6RoutePrefix\0"
|
"IPv6Prefix\0"
|
||||||
"LLDP\0"
|
"IPv6RoutePrefix\0"
|
||||||
"TrafficControlQueueingDiscipline\0"
|
"LLDP\0"
|
||||||
"CAN\0"
|
"TrafficControlQueueingDiscipline\0"
|
||||||
"QDisc\0"
|
"CAN\0"
|
||||||
"BFIFO\0"
|
"QDisc\0"
|
||||||
"CAKE\0"
|
"BFIFO\0"
|
||||||
"ControlledDelay\0"
|
"CAKE\0"
|
||||||
"DeficitRoundRobinScheduler\0"
|
"ControlledDelay\0"
|
||||||
"DeficitRoundRobinSchedulerClass\0"
|
"DeficitRoundRobinScheduler\0"
|
||||||
"PFIFO\0"
|
"DeficitRoundRobinSchedulerClass\0"
|
||||||
"PFIFOFast\0"
|
"PFIFO\0"
|
||||||
"PFIFOHeadDrop\0"
|
"PFIFOFast\0"
|
||||||
"FairQueueing\0"
|
"PFIFOHeadDrop\0"
|
||||||
"FairQueueingControlledDelay\0"
|
"FairQueueing\0"
|
||||||
"GenericRandomEarlyDetection\0"
|
"FairQueueingControlledDelay\0"
|
||||||
"HeavyHitterFilter\0"
|
"GenericRandomEarlyDetection\0"
|
||||||
"HierarchyTokenBucket\0"
|
"HeavyHitterFilter\0"
|
||||||
"HierarchyTokenBucketClass\0"
|
"HierarchyTokenBucket\0"
|
||||||
"NetworkEmulator\0"
|
"HierarchyTokenBucketClass\0"
|
||||||
"PIE\0"
|
"NetworkEmulator\0"
|
||||||
"StochasticFairBlue\0"
|
"PIE\0"
|
||||||
"StochasticFairnessQueueing\0"
|
"StochasticFairBlue\0"
|
||||||
"TokenBucketFilter\0"
|
"StochasticFairnessQueueing\0"
|
||||||
"TrivialLinkEqualizer\0",
|
"TokenBucketFilter\0"
|
||||||
config_item_perf_lookup, network_network_gperf_lookup,
|
"TrivialLinkEqualizer\0",
|
||||||
CONFIG_PARSE_WARN, network, &dropins);
|
config_item_perf_lookup, network_network_gperf_lookup,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
network,
|
||||||
|
&network->timestamp);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
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",
|
log_warning_errno(r, "%s: Failed to add default route on device, ignoring: %m",
|
||||||
network->filename);
|
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)
|
if (network_verify(network) < 0)
|
||||||
/* Ignore .network files that do not match the conditions. */
|
/* Ignore .network files that do not match the conditions. */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -78,7 +78,7 @@ int settings_load(FILE *f, const char *path, Settings **ret) {
|
|||||||
"Files\0",
|
"Files\0",
|
||||||
config_item_perf_lookup, nspawn_gperf_lookup,
|
config_item_perf_lookup, nspawn_gperf_lookup,
|
||||||
CONFIG_PARSE_WARN,
|
CONFIG_PARSE_WARN,
|
||||||
s);
|
s, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -976,7 +976,12 @@ static int partition_read_definition(Partition *p, const char *path) {
|
|||||||
};
|
};
|
||||||
int r;
|
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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -78,11 +78,14 @@ static int parse_config(void) {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/pstore.conf",
|
return config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/pstore.conf.d"),
|
PKGSYSCONFDIR "/pstore.conf",
|
||||||
"PStore\0",
|
CONF_PATHS_NULSTR("systemd/pstore.conf.d"),
|
||||||
config_item_table_lookup, items,
|
"PStore\0",
|
||||||
CONFIG_PARSE_WARN, NULL);
|
config_item_table_lookup, items,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* File list handling - PStoreEntry is the struct and
|
/* File list handling - PStoreEntry is the struct and
|
||||||
|
@ -381,11 +381,14 @@ int manager_parse_config_file(Manager *m) {
|
|||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
r = config_parse_many_nulstr(PKGSYSCONFDIR "/resolved.conf",
|
r = config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
|
PKGSYSCONFDIR "/resolved.conf",
|
||||||
"Resolve\0",
|
CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
|
||||||
config_item_perf_lookup, resolved_gperf_lookup,
|
"Resolve\0",
|
||||||
CONFIG_PARSE_WARN, m);
|
config_item_perf_lookup, resolved_gperf_lookup,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
m,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -86,10 +86,13 @@ static int dnssd_service_load(Manager *manager, const char *filename) {
|
|||||||
|
|
||||||
dropin_dirname = strjoina(service->name, ".dnssd.d");
|
dropin_dirname = strjoina(service->name, ".dnssd.d");
|
||||||
|
|
||||||
r = config_parse_many(filename, DNSSD_SERVICE_DIRS, dropin_dirname,
|
r = config_parse_many(
|
||||||
"Service\0",
|
filename, DNSSD_SERVICE_DIRS, dropin_dirname,
|
||||||
config_item_perf_lookup, resolved_dnssd_gperf_lookup,
|
"Service\0",
|
||||||
false, service, NULL);
|
config_item_perf_lookup, resolved_dnssd_gperf_lookup,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
service,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ static int parse_line(
|
|||||||
if (!fn)
|
if (!fn)
|
||||||
return -ENOMEM;
|
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))
|
if (!utf8_is_valid(l))
|
||||||
@ -289,13 +289,15 @@ int config_parse(const char *unit,
|
|||||||
ConfigItemLookup lookup,
|
ConfigItemLookup lookup,
|
||||||
const void *table,
|
const void *table,
|
||||||
ConfigParseFlags flags,
|
ConfigParseFlags flags,
|
||||||
void *userdata) {
|
void *userdata,
|
||||||
|
usec_t *ret_mtime) {
|
||||||
|
|
||||||
_cleanup_free_ char *section = NULL, *continuation = NULL;
|
_cleanup_free_ char *section = NULL, *continuation = NULL;
|
||||||
_cleanup_fclose_ FILE *ours = NULL;
|
_cleanup_fclose_ FILE *ours = NULL;
|
||||||
unsigned line = 0, section_line = 0;
|
unsigned line = 0, section_line = 0;
|
||||||
bool section_ignored = false, bom_seen = false;
|
bool section_ignored = false, bom_seen = false;
|
||||||
int r, fd;
|
int r, fd;
|
||||||
|
usec_t mtime;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
assert(lookup);
|
assert(lookup);
|
||||||
@ -313,8 +315,16 @@ int config_parse(const char *unit,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fd = fileno(f);
|
fd = fileno(f);
|
||||||
if (fd >= 0) /* stream might not have an fd, let's be careful hence */
|
if (fd >= 0) { /* stream might not have an fd, let's be careful hence */
|
||||||
fd_warn_permissions(filename, fd);
|
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 (;;) {
|
for (;;) {
|
||||||
_cleanup_free_ char *buf = NULL;
|
_cleanup_free_ char *buf = NULL;
|
||||||
@ -331,7 +341,7 @@ int config_parse(const char *unit,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (r < 0) {
|
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);
|
log_error_errno(r, "%s:%u: Error while reading configuration file: %m", filename, line);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
@ -434,6 +444,9 @@ int config_parse(const char *unit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret_mtime)
|
||||||
|
*ret_mtime = mtime;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,23 +457,32 @@ static int config_parse_many_files(
|
|||||||
ConfigItemLookup lookup,
|
ConfigItemLookup lookup,
|
||||||
const void *table,
|
const void *table,
|
||||||
ConfigParseFlags flags,
|
ConfigParseFlags flags,
|
||||||
void *userdata) {
|
void *userdata,
|
||||||
|
usec_t *ret_mtime) {
|
||||||
|
|
||||||
|
usec_t mtime = 0;
|
||||||
char **fn;
|
char **fn;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (conf_file) {
|
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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
STRV_FOREACH(fn, files) {
|
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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
if (t > mtime) /* Find the newest */
|
||||||
|
mtime = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret_mtime)
|
||||||
|
*ret_mtime = mtime;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,7 +494,8 @@ int config_parse_many_nulstr(
|
|||||||
ConfigItemLookup lookup,
|
ConfigItemLookup lookup,
|
||||||
const void *table,
|
const void *table,
|
||||||
ConfigParseFlags flags,
|
ConfigParseFlags flags,
|
||||||
void *userdata) {
|
void *userdata,
|
||||||
|
usec_t *ret_mtime) {
|
||||||
|
|
||||||
_cleanup_strv_free_ char **files = NULL;
|
_cleanup_strv_free_ char **files = NULL;
|
||||||
int r;
|
int r;
|
||||||
@ -481,7 +504,7 @@ int config_parse_many_nulstr(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
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. */
|
/* Parse each config file in the directories specified as strv. */
|
||||||
@ -494,7 +517,7 @@ int config_parse_many(
|
|||||||
const void *table,
|
const void *table,
|
||||||
ConfigParseFlags flags,
|
ConfigParseFlags flags,
|
||||||
void *userdata,
|
void *userdata,
|
||||||
char ***ret_dropins) {
|
usec_t *ret_mtime) {
|
||||||
|
|
||||||
_cleanup_strv_free_ char **dropin_dirs = NULL;
|
_cleanup_strv_free_ char **dropin_dirs = NULL;
|
||||||
_cleanup_strv_free_ char **files = NULL;
|
_cleanup_strv_free_ char **files = NULL;
|
||||||
@ -510,14 +533,7 @@ int config_parse_many(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = 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);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (ret_dropins)
|
|
||||||
*ret_dropins = TAKE_PTR(files);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_PARSER(type, vartype, conv_func) \
|
#define DEFINE_PARSER(type, vartype, conv_func) \
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
#include "time-util.h"
|
||||||
|
|
||||||
/* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
|
/* 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 *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
FILE *f,
|
FILE *f,
|
||||||
const char *sections, /* nulstr */
|
const char *sections, /* nulstr */
|
||||||
ConfigItemLookup lookup,
|
ConfigItemLookup lookup,
|
||||||
const void *table,
|
const void *table,
|
||||||
ConfigParseFlags flags,
|
ConfigParseFlags flags,
|
||||||
void *userdata);
|
void *userdata,
|
||||||
|
usec_t *ret_mtime); /* possibly NULL */
|
||||||
|
|
||||||
int config_parse_many_nulstr(
|
int config_parse_many_nulstr(
|
||||||
const char *conf_file, /* possibly NULL */
|
const char *conf_file, /* possibly NULL */
|
||||||
@ -97,7 +99,8 @@ int config_parse_many_nulstr(
|
|||||||
ConfigItemLookup lookup,
|
ConfigItemLookup lookup,
|
||||||
const void *table,
|
const void *table,
|
||||||
ConfigParseFlags flags,
|
ConfigParseFlags flags,
|
||||||
void *userdata);
|
void *userdata,
|
||||||
|
usec_t *ret_mtime); /* possibly NULL */
|
||||||
|
|
||||||
int config_parse_many(
|
int config_parse_many(
|
||||||
const char *conf_file, /* possibly NULL */
|
const char *conf_file, /* possibly NULL */
|
||||||
@ -108,7 +111,7 @@ int config_parse_many(
|
|||||||
const void *table,
|
const void *table,
|
||||||
ConfigParseFlags flags,
|
ConfigParseFlags flags,
|
||||||
void *userdata,
|
void *userdata,
|
||||||
char ***ret_dropins); /* possibly NULL */
|
usec_t *ret_mtime); /* possibly NULL */
|
||||||
|
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_int);
|
CONFIG_PARSER_PROTOTYPE(config_parse_int);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_unsigned);
|
CONFIG_PARSER_PROTOTYPE(config_parse_unsigned);
|
||||||
|
@ -1304,7 +1304,8 @@ static int unit_file_load(
|
|||||||
"-Target\0"
|
"-Target\0"
|
||||||
"-Timer\0",
|
"-Timer\0",
|
||||||
config_item_table_lookup, items,
|
config_item_table_lookup, items,
|
||||||
CONFIG_PARSE_ALLOW_INCLUDE, info);
|
CONFIG_PARSE_ALLOW_INCLUDE, info,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to parse %s: %m", info->name);
|
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",
|
(void) config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
|
PKGSYSCONFDIR "/sleep.conf",
|
||||||
"Sleep\0", config_item_table_lookup, items,
|
CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
|
||||||
CONFIG_PARSE_WARN, NULL);
|
"Sleep\0",
|
||||||
|
config_item_table_lookup, items,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
/* use default values unless set */
|
/* use default values unless set */
|
||||||
sc->allow_suspend = allow_suspend != 0;
|
sc->allow_suspend = allow_suspend != 0;
|
||||||
|
@ -335,13 +335,17 @@ static void test_config_parse(unsigned i, const char *s) {
|
|||||||
ConfigItemLookup lookup,
|
ConfigItemLookup lookup,
|
||||||
const void *table,
|
const void *table,
|
||||||
ConfigParseFlags flags,
|
ConfigParseFlags flags,
|
||||||
void *userdata)
|
void *userdata,
|
||||||
|
usec_t *ret_mtime)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
r = config_parse(NULL, name, f,
|
r = config_parse(NULL, name, f,
|
||||||
"Section\0-NoWarnSection\0",
|
"Section\0"
|
||||||
|
"-NoWarnSection\0",
|
||||||
config_item_table_lookup, items,
|
config_item_table_lookup, items,
|
||||||
CONFIG_PARSE_WARN, NULL);
|
CONFIG_PARSE_WARN,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0 ... 4:
|
case 0 ... 4:
|
||||||
|
@ -102,11 +102,14 @@ int manager_parse_config_file(Manager *m) {
|
|||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
r = config_parse_many_nulstr(PKGSYSCONFDIR "/timesyncd.conf",
|
r = config_parse_many_nulstr(
|
||||||
CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"),
|
PKGSYSCONFDIR "/timesyncd.conf",
|
||||||
"Time\0",
|
CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"),
|
||||||
config_item_perf_lookup, timesyncd_gperf_lookup,
|
"Time\0",
|
||||||
CONFIG_PARSE_WARN, m);
|
config_item_perf_lookup, timesyncd_gperf_lookup,
|
||||||
|
CONFIG_PARSE_WARN,
|
||||||
|
m,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -192,7 +192,9 @@ static int process_one_password_file(const char *filename) {
|
|||||||
r = config_parse(NULL, filename, NULL,
|
r = config_parse(NULL, filename, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
config_item_table_lookup, items,
|
config_item_table_lookup, items,
|
||||||
CONFIG_PARSE_RELAXED|CONFIG_PARSE_WARN, NULL);
|
CONFIG_PARSE_RELAXED|CONFIG_PARSE_WARN,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -161,7 +161,8 @@ int link_load_one(link_config_ctx *ctx, const char *filename) {
|
|||||||
r = config_parse(NULL, filename, file,
|
r = config_parse(NULL, filename, file,
|
||||||
"Match\0Link\0",
|
"Match\0Link\0",
|
||||||
config_item_perf_lookup, link_config_gperf_lookup,
|
config_item_perf_lookup, link_config_gperf_lookup,
|
||||||
CONFIG_PARSE_WARN, link);
|
CONFIG_PARSE_WARN, link,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -319,7 +319,8 @@ XdgAutostartService *xdg_autostart_service_parse_desktop(const char *path) {
|
|||||||
r = config_parse(NULL, service->path, NULL,
|
r = config_parse(NULL, service->path, NULL,
|
||||||
"Desktop Entry\0",
|
"Desktop Entry\0",
|
||||||
xdg_config_item_table_lookup, items,
|
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 parsing failed, only hide the file so it will still mask others. */
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_warning_errno(r, "Failed to parse %s, ignoring it", service->path);
|
log_warning_errno(r, "Failed to parse %s, ignoring it", service->path);
|
||||||
|
Loading…
Reference in New Issue
Block a user