resolve: several further fixes for reloading config (#37856)

Fixes #37843.
This commit is contained in:
Yu Watanabe
2025-06-17 00:23:56 +09:00
committed by GitHub
4 changed files with 50 additions and 35 deletions

View File

@@ -1419,7 +1419,7 @@ int manager_dns_stub_start(Manager *m) {
r == -EADDRINUSE ? "Another process is already listening on %s.\n"
"Turning off local DNS stub support." :
"Failed to listen on %s: %m.\n"
"Turning off local DNS stub support.",
"Turning off local DNS stub support.",
busy_socket);
manager_dns_stub_stop(m);
break;

View File

@@ -650,44 +650,41 @@ static int manager_dispatch_reload_signal(sd_event_source *s, const struct signa
(void) notify_reloading();
manager_set_defaults(m);
dns_server_unlink_on_reload(m->dns_servers);
dns_server_unlink_on_reload(m->fallback_dns_servers);
m->dns_extra_stub_listeners = ordered_set_free(m->dns_extra_stub_listeners);
manager_dns_stub_stop(m);
dnssd_service_clear_on_reload(m->dnssd_services);
m->unicast_scope = dns_scope_free(m->unicast_scope);
m->delegates = hashmap_free(m->delegates);
dns_trust_anchor_flush(&m->trust_anchor);
manager_set_defaults(m);
r = dns_trust_anchor_load(&m->trust_anchor);
if (r < 0)
return r;
return sd_event_exit(sd_event_source_get_event(s), r);
r = manager_parse_config_file(m);
if (r < 0)
log_warning_errno(r, "Failed to parse config file on reload: %m");
log_warning_errno(r, "Failed to parse configuration file on reload, ignoring: %m");
else
log_info("Config file reloaded.");
r = dnssd_load(m);
if (r < 0)
log_warning_errno(r, "Failed to load DNS-SD configuration files: %m");
manager_load_delegates(m);
(void) dnssd_load(m);
(void) manager_load_delegates(m);
/* The default scope configuration is influenced by the manager's configuration (modes, etc.), so
* recreate it on reload. */
r = dns_scope_new(m, &m->unicast_scope, DNS_SCOPE_GLOBAL, /* link= */ NULL, /* delegate= */ NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
if (r < 0)
return r;
return sd_event_exit(sd_event_source_get_event(s), r);
/* The configuration has changed, so reload the per-interface configuration too in order to take
* into account any changes (e.g.: enable/disable DNSSEC). */
r = on_network_event(/* source= */ NULL, -EBADF, /* revents= */ 0, m);
if (r < 0)
log_warning_errno(r, "Failed to update network information: %m");
log_warning_errno(r, "Failed to update network information on reload, ignoring: %m");
/* We have new configuration, which means potentially new servers, so close all connections and drop
* all caches, so that we can start fresh. */
@@ -695,6 +692,10 @@ static int manager_dispatch_reload_signal(sd_event_source *s, const struct signa
manager_flush_caches(m, LOG_INFO);
manager_verify_all(m);
r = manager_dns_stub_start(m);
if (r < 0)
return sd_event_exit(sd_event_source_get_event(s), r);
(void) sd_notify(/* unset_environment= */ false, NOTIFY_READY_MESSAGE);
return 0;
}
@@ -734,7 +735,7 @@ int manager_new(Manager **ret) {
r = manager_parse_config_file(m);
if (r < 0)
log_warning_errno(r, "Failed to parse configuration file: %m");
log_warning_errno(r, "Failed to parse configuration file, ignoring: %m");
#if ENABLE_DNS_OVER_TLS
r = dnstls_manager_init(m);
@@ -756,11 +757,8 @@ int manager_new(Manager **ret) {
if (r < 0)
return r;
r = dnssd_load(m);
if (r < 0)
log_warning_errno(r, "Failed to load DNS-SD configuration files: %m");
manager_load_delegates(m);
(void) dnssd_load(m);
(void) manager_load_delegates(m);
r = dns_scope_new(m, &m->unicast_scope, DNS_SCOPE_GLOBAL, /* link= */ NULL, /* delegate= */ NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
if (r < 0)
@@ -829,7 +827,7 @@ int manager_start(Manager *m) {
return 0;
}
Manager *manager_free(Manager *m) {
Manager* manager_free(Manager *m) {
Link *l;
if (!m)

View File

@@ -56,11 +56,10 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return log_error_errno(r, "Could not create runtime directory: %m");
/* Drop privileges, but keep three caps. Note that we drop two of those too, later on (see below) */
/* Drop privileges, but keep two caps. */
r = drop_privileges(uid, gid,
(UINT64_C(1) << CAP_NET_RAW)| /* needed for SO_BINDTODEVICE */
(UINT64_C(1) << CAP_NET_BIND_SERVICE)| /* needed to bind on port 53 */
(UINT64_C(1) << CAP_SETPCAP) /* needed in order to drop the caps later */);
(UINT64_C(1) << CAP_NET_RAW)| /* needed for SO_BINDTODEVICE */
(UINT64_C(1) << CAP_NET_BIND_SERVICE)); /* needed to bind on port 53 */
if (r < 0)
return log_error_errno(r, "Failed to drop privileges: %m");
}
@@ -78,11 +77,6 @@ static int run(int argc, char *argv[]) {
(void) manager_check_resolv_conf(m);
/* Let's drop the remaining caps now */
r = capability_bounding_set_drop((UINT64_C(1) << CAP_NET_RAW), true);
if (r < 0)
return log_error_errno(r, "Failed to drop remaining caps: %m");
notify_stop = notify_start(NOTIFY_READY_MESSAGE, NOTIFY_STOPPING_MESSAGE);
r = sd_event_loop(m->event);

View File

@@ -1003,16 +1003,39 @@ testcase_12_resolvectl2() {
{
echo "[Resolve]"
echo "DNS=8.8.8.8"
echo "DNSStubListenerExtra=127.0.0.153"
} >/run/systemd/resolved.conf.d/reload.conf
resolvectl dns dns0 1.1.1.1
systemctl reload systemd-resolved.service
resolvectl status
resolvectl dns dns0 | grep -qF "1.1.1.1"
# For some reason piping this last command to grep fails with:
# 'resolvectl[1378]: Failed to print table: Broken pipe'
# so use an intermediate file in /tmp/
resolvectl >/tmp/output
grep -qF "DNS Servers: 8.8.8.8" /tmp/output
run resolvectl dns dns0
grep -qF "1.1.1.1" "$RUN_OUT"
run resolvectl dns
grep -qF "8.8.8.8" "$RUN_OUT"
run ss -4nl
grep -qF '127.0.0.153' "$RUN_OUT"
{
echo "[Resolve]"
echo "DNS=8.8.4.4"
echo "DNSStubListenerExtra=127.0.0.154"
} >/run/systemd/resolved.conf.d/reload.conf
systemctl reload systemd-resolved.service
resolvectl status
run resolvectl dns dns0
grep -qF "1.1.1.1" "$RUN_OUT"
run resolvectl dns
(! grep -qF "8.8.8.8" "$RUN_OUT")
grep -qF "8.8.4.4" "$RUN_OUT"
run ss -4nl
(! grep -qF '127.0.0.153' "$RUN_OUT")
grep -qF '127.0.0.154' "$RUN_OUT"
# Check if resolved exits cleanly.
restart_resolved