From 7a025027a57bf9843c0a51a1fa51447d235830e7 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 11 Jan 2019 15:01:15 +0100 Subject: [PATCH 1/2] dns: fix updating resolv.conf after dnsmasq process dies When the dnsmasq process dies, two events are generated: (1) a NM_DNS_PLUGIN_FAILED signal in nm-dns-dnsmasq.c:name_owner_changed() (2) a NM_DNS_PLUGIN_CHILD_QUIT signal in nm-dns-plugin.c:from watch_cb() Event (1) is handled by updating resolv.conf with upstream servers, (2) by restarting the child process. The order in which the two signals are received is not deterministic, so when (1) comes after (2) the manager leaves upstream servers in resolv.conf even if a dnsmasq instance is running. When dnsmasq disappears from D-Bus and we know that the process is not running, we should not emit a FAILED signal because the disappearing is caused by the process termination, and that event is already handled by the manager. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/105 (cherry picked from commit f2a201273307129b394d9b0bb9b58bec61f99d98) --- src/dns/nm-dns-dnsmasq.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c index b48c6b87cb..b54df73088 100644 --- a/src/dns/nm-dns-dnsmasq.c +++ b/src/dns/nm-dns-dnsmasq.c @@ -254,9 +254,16 @@ name_owner_changed (GObject *object, priv->running = TRUE; send_dnsmasq_update (self); } else { - _LOGI ("dnsmasq disappeared"); - priv->running = FALSE; - g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED); + if (priv->running) { + _LOGI ("dnsmasq disappeared"); + priv->running = FALSE; + g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED); + } else { + /* The only reason for which (!priv->running) here + * is that the dnsmasq process quit. We don't care + * of that here, the manager handles child restarts + * by itself. */ + } } } From 5ef8f456adae5e5f72e3bfac57686fcc0b2a10ba Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 11 Jan 2019 15:39:51 +0100 Subject: [PATCH 2/2] dns: fail the plugin when the rate limiter hits If the child is respawning too fast, consider the plugin failed so that upstream servers are written to resolv.conf until the plugin gets restarted after the delay. (cherry picked from commit e45636659b62ad8f19a03567269ea89e1252c9e3) --- src/dns/nm-dns-manager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index a44ff3c5f8..aebe3e12e9 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -1580,6 +1580,7 @@ plugin_child_quit (NMDnsPlugin *plugin, int exit_status, gpointer user_data) } else { priv->plugin_ratelimit.num_restarts++; if (priv->plugin_ratelimit.num_restarts > PLUGIN_RATELIMIT_BURST) { + plugin_failed (plugin, self); _LOGW ("plugin %s child respawning too fast, delaying update for %u seconds", nm_dns_plugin_get_name (plugin), PLUGIN_RATELIMIT_DELAY); priv->plugin_ratelimit.timer = g_timeout_add_seconds (PLUGIN_RATELIMIT_DELAY,