Merge pull request #31951 from bluca/resolve_reload

resolved: support reloading configuration at runtime
This commit is contained in:
Yu Watanabe
2024-03-27 02:37:52 +09:00
committed by GitHub
13 changed files with 167 additions and 24 deletions
+1
View File
@@ -1890,6 +1890,7 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
if (r < 0)
return r;
service->originator = euid;
service->config_source = RESOLVE_CONFIG_SOURCE_DBUS;
r = sd_bus_message_read(message, "sssqqq", &name, &name_template, &type,
&service->port, &service->priority,
+1 -1
View File
@@ -55,7 +55,7 @@ static int manager_add_dns_server_by_string(Manager *m, DnsServerType type, cons
return 0;
}
return dns_server_new(m, NULL, type, NULL, family, &address, port, ifindex, server_name);
return dns_server_new(m, NULL, type, NULL, family, &address, port, ifindex, server_name, RESOLVE_CONFIG_SOURCE_FILE);
}
int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string) {
+8
View File
@@ -3,6 +3,14 @@
#include "conf-parser.h"
typedef enum ResolveConfigSource {
RESOLVE_CONFIG_SOURCE_FILE,
RESOLVE_CONFIG_SOURCE_NETWORKD,
RESOLVE_CONFIG_SOURCE_DBUS,
_RESOLVE_CONFIG_SOURCE_MAX,
_RESOLVE_CONFIG_SOURCE_INVALID = -EINVAL,
} ResolveConfigSource;
#include "resolved-dns-server.h"
int manager_parse_config_file(Manager *m);
+14 -1
View File
@@ -28,7 +28,8 @@ int dns_server_new(
const union in_addr_union *in_addr,
uint16_t port,
int ifindex,
const char *server_name) {
const char *server_name,
ResolveConfigSource config_source) {
_cleanup_free_ char *name = NULL;
DnsServer *s;
@@ -67,6 +68,7 @@ int dns_server_new(
.port = port,
.ifindex = ifindex,
.server_name = TAKE_PTR(name),
.config_source = config_source,
};
dns_server_reset_features(s);
@@ -794,6 +796,17 @@ void dns_server_unlink_all(DnsServer *first) {
dns_server_unlink_all(next);
}
void dns_server_unlink_on_reload(DnsServer *server) {
while (server) {
DnsServer *next = server->servers_next;
if (server->config_source == RESOLVE_CONFIG_SOURCE_FILE)
dns_server_unlink(server);
server = next;
}
}
bool dns_server_unlink_marked(DnsServer *server) {
bool changed = false;
+8 -1
View File
@@ -24,6 +24,8 @@ typedef enum DnsServerType {
_DNS_SERVER_TYPE_INVALID = -EINVAL,
} DnsServerType;
#include "resolved-conf.h"
const char* dns_server_type_to_string(DnsServerType i) _const_;
DnsServerType dns_server_type_from_string(const char *s) _pure_;
@@ -100,6 +102,9 @@ struct DnsServer {
/* If linked is set, then this server appears in the servers linked list */
bool linked:1;
LIST_FIELDS(DnsServer, servers);
/* Servers registered via D-Bus are not removed on reload */
ResolveConfigSource config_source;
};
int dns_server_new(
@@ -111,7 +116,8 @@ int dns_server_new(
const union in_addr_union *address,
uint16_t port,
int ifindex,
const char *server_string);
const char *server_string,
ResolveConfigSource config_source);
DnsServer* dns_server_ref(DnsServer *s);
DnsServer* dns_server_unref(DnsServer *s);
@@ -145,6 +151,7 @@ void dns_server_warn_downgrade(DnsServer *server);
DnsServer *dns_server_find(DnsServer *first, int family, const union in_addr_union *in_addr, uint16_t port, int ifindex, const char *name);
void dns_server_unlink_all(DnsServer *first);
void dns_server_unlink_on_reload(DnsServer *server);
bool dns_server_unlink_marked(DnsServer *first);
void dns_server_mark_all(DnsServer *first);
+10
View File
@@ -57,6 +57,16 @@ DnssdService *dnssd_service_free(DnssdService *service) {
return mfree(service);
}
void dnssd_service_clear_on_reload(Hashmap *services) {
DnssdService *service;
HASHMAP_FOREACH(service, services)
if (service->config_source == RESOLVE_CONFIG_SOURCE_FILE) {
hashmap_remove(services, service->name);
dnssd_service_free(service);
}
}
static int dnssd_service_load(Manager *manager, const char *filename) {
_cleanup_(dnssd_service_freep) DnssdService *service = NULL;
_cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
+5
View File
@@ -3,6 +3,7 @@
#pragma once
#include "list.h"
#include "resolved-conf.h"
typedef struct DnssdService DnssdService;
typedef struct DnssdTxtData DnssdTxtData;
@@ -44,6 +45,9 @@ struct DnssdService {
Manager *manager;
/* Services registered via D-Bus are not removed on reload */
ResolveConfigSource config_source;
bool withdrawn:1;
uid_t originator;
};
@@ -51,6 +55,7 @@ struct DnssdService {
DnssdService *dnssd_service_free(DnssdService *service);
DnssdTxtData *dnssd_txtdata_free(DnssdTxtData *txt_data);
DnssdTxtData *dnssd_txtdata_free_all(DnssdTxtData *txt_data);
void dnssd_service_clear_on_reload(Hashmap *services);
DEFINE_TRIVIAL_CLEANUP_FUNC(DnssdService*, dnssd_service_free);
DEFINE_TRIVIAL_CLEANUP_FUNC(DnssdTxtData*, dnssd_txtdata_free);
+1 -1
View File
@@ -274,7 +274,7 @@ static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, voi
if (s)
dns_server_move_back_and_unmark(s);
else {
r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, dns[i]->family, &dns[i]->address, dns[i]->port, 0, dns[i]->server_name);
r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, dns[i]->family, &dns[i]->address, dns[i]->port, 0, dns[i]->server_name, RESOLVE_CONFIG_SOURCE_DBUS);
if (r < 0) {
dns_server_unlink_all(l->dns_servers);
goto finalize;
+1 -1
View File
@@ -273,7 +273,7 @@ static int link_update_dns_server_one(Link *l, const char *str) {
return 0;
}
return dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a, port, 0, name);
return dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a, port, 0, name, RESOLVE_CONFIG_SOURCE_NETWORKD);
}
static int link_update_dns_servers(Link *l) {
+71 -7
View File
@@ -11,6 +11,7 @@
#include "af-list.h"
#include "alloc-util.h"
#include "bus-polkit.h"
#include "daemon-util.h"
#include "dirent-util.h"
#include "dns-domain.h"
#include "event-util.h"
@@ -565,6 +566,73 @@ static int manager_memory_pressure_listen(Manager *m) {
return 0;
}
static void manager_set_defaults(Manager *m) {
assert(m);
m->llmnr_support = DEFAULT_LLMNR_MODE;
m->mdns_support = DEFAULT_MDNS_MODE;
m->dnssec_mode = DEFAULT_DNSSEC_MODE;
m->dns_over_tls_mode = DEFAULT_DNS_OVER_TLS_MODE;
m->enable_cache = DNS_CACHE_MODE_YES;
m->dns_stub_listener_mode = DNS_STUB_LISTENER_YES;
m->read_etc_hosts = true;
m->resolve_unicast_single_label = false;
m->cache_from_localhost = false;
m->stale_retention_usec = 0;
}
static int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
Manager *m = ASSERT_PTR(userdata);
int r;
(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);
dnssd_service_clear_on_reload(m->dnssd_services);
m->unicast_scope = dns_scope_free(m->unicast_scope);
dns_trust_anchor_flush(&m->trust_anchor);
r = dns_trust_anchor_load(&m->trust_anchor);
if (r < 0)
return r;
r = manager_parse_config_file(m);
if (r < 0)
log_warning_errno(r, "Failed to parse config file on reload: %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");
/* 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, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
if (r < 0)
return 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(/* sd_event_source= */ NULL, -EBADF, /* revents= */ 0, m);
if (r < 0)
log_warning_errno(r, "Failed to update network information: %m");
/* We have new configuration, which means potentially new servers, so close all connections and drop
* all caches, so that we can start fresh. */
(void) dns_stream_disconnect_all(m);
manager_flush_caches(m, LOG_INFO);
manager_verify_all(m);
(void) sd_notify(/* unset= */ false, NOTIFY_READY);
return 0;
}
int manager_new(Manager **ret) {
_cleanup_(manager_freep) Manager *m = NULL;
int r;
@@ -584,21 +652,16 @@ int manager_new(Manager **ret) {
.mdns_ipv6_fd = -EBADF,
.hostname_fd = -EBADF,
.llmnr_support = DEFAULT_LLMNR_MODE,
.mdns_support = DEFAULT_MDNS_MODE,
.dnssec_mode = DEFAULT_DNSSEC_MODE,
.dns_over_tls_mode = DEFAULT_DNS_OVER_TLS_MODE,
.enable_cache = DNS_CACHE_MODE_YES,
.dns_stub_listener_mode = DNS_STUB_LISTENER_YES,
.read_resolv_conf = true,
.need_builtin_fallbacks = true,
.etc_hosts_last = USEC_INFINITY,
.read_etc_hosts = true,
.sigrtmin18_info.memory_pressure_handler = manager_memory_pressure,
.sigrtmin18_info.memory_pressure_userdata = m,
};
manager_set_defaults(m);
r = dns_trust_anchor_load(&m->trust_anchor);
if (r < 0)
return r;
@@ -619,6 +682,7 @@ int manager_new(Manager **ret) {
(void) sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
(void) sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
(void) sd_event_add_signal(m->event, NULL, SIGHUP | SD_EVENT_SIGNAL_PROCMASK, manager_dispatch_reload_signal, m);
(void) sd_event_set_watchdog(m->event, true);