summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2017-07-03 09:14:50 +0200
committerLubomir Rintel <lkundrak@v3.sk>2017-07-12 08:53:19 +0200
commita647cdcb1440392b16b1e65d6868cb349e68da73 (patch)
tree8255c3d946657608cb1a211c998cd3f5c5b18d4a
parentffe52feea851d047dbff66b8096672ae4f1ac268 (diff)
downloadNetworkManager-lr/dns-mode-multiple.tar.gz
dns: turn main.dns=<mode> into a listlr/dns-mode-multiple
This effectively allows us to keep systemd-resolved up to date even if the resolver is not using it as a local DNS forwarder. The default dns mode is now "default,systemd-resolved", meaning that systemd-resolved is kept up to date, but we're not changing resolv.conf to use it.
-rw-r--r--man/NetworkManager.conf.xml28
-rw-r--r--src/dns/nm-dns-dnsmasq.c4
-rw-r--r--src/dns/nm-dns-manager.c339
-rw-r--r--src/dns/nm-dns-plugin.c12
-rw-r--r--src/dns/nm-dns-plugin.h16
-rw-r--r--src/dns/nm-dns-systemd-resolved.c4
-rw-r--r--src/dns/nm-dns-unbound.c4
-rw-r--r--src/nm-config-data.c33
-rw-r--r--src/nm-config-data.h2
-rw-r--r--src/nm-config.c1
-rw-r--r--src/nm-config.h1
11 files changed, 195 insertions, 249 deletions
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index d8fa1b3b95..1da3395758 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -309,24 +309,15 @@ no-auto-default=*
</varlistentry>
<varlistentry>
<term><varname>dns</varname></term>
- <listitem><para>Set the DNS (<filename>resolv.conf</filename>) processing mode.
- If the key is unspecified, <literal>default</literal> is used,
- unless <filename>/etc/resolv.conf</filename> is a symlink to
- <filename>/run/systemd/resolve/resolv.conf</filename>,
- <filename>/lib/systemd/resolv.conf</filename> or
- <filename>/usr/lib/systemd/resolv.conf</filename>.
- In that case, <literal>systemd-resolved</literal> is chosen automatically.
- </para>
- <para><literal>default</literal>: NetworkManager will update
- <filename>/etc/resolv.conf</filename> to reflect the nameservers
- provided by currently active connections.</para>
+ <listitem><para>Set the list of DNS (<filename>resolv.conf</filename>) handlers.
+ The available options are:</para>
+ <para><literal>default</literal>: NetworkManager will update the resolver
+ to use the nameservers provided by currently active connections.</para>
<para><literal>dnsmasq</literal>: NetworkManager will run
dnsmasq as a local caching nameserver, using a "split DNS"
- configuration if you are connected to a VPN, and then update
- <filename>resolv.conf</filename> to point to the local
- nameserver. It is possible to pass custom options to the
- dnsmasq instance by adding them to files in the
- "<filename>&sysconfdir;/NetworkManager/dnsmasq.d/</filename>"
+ configuration if you are connected to a VPN. It is possible to pass custom
+ options to the dnsmasq instance by adding them to files in the
+ <filename>&sysconfdir;/NetworkManager/dnsmasq.d/</filename>
directory. Note that when multiple upstream servers are
available, dnsmasq will initially contact them in parallel and
then use the fastest to respond, probing again other servers
@@ -342,6 +333,11 @@ no-auto-default=*
<para><literal>none</literal>: NetworkManager will not
modify resolv.conf. This implies
<literal>rc-manager</literal>&nbsp;<literal>unmanaged</literal></para>
+ <para>If the first or only entry in the list is a local caching DNS forwarder,
+ the resolver will be configured to use it. If the key is unspecified,
+ <literal>default,systemd-resolved</literal> is used, which means that the resolver
+ will be configured to use the discovered DNS servers directly, while
+ systemd-resolved will be updated as well if it is available.</para>
</listitem>
</varlistentry>
diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c
index 91a42a6e61..937950246b 100644
--- a/src/dns/nm-dns-dnsmasq.c
+++ b/src/dns/nm-dns-dnsmasq.c
@@ -552,7 +552,7 @@ start_dnsmasq (NMDnsDnsmasq *self)
self);
}
-static gboolean
+static void
update (NMDnsPlugin *plugin,
const GPtrArray *configs,
const NMGlobalDnsConfig *global_config,
@@ -585,8 +585,6 @@ update (NMDnsPlugin *plugin,
priv->set_server_ex_args = g_variant_ref_sink (g_variant_new ("(aas)", &servers));
send_dnsmasq_update (self);
-
- return TRUE;
}
/*****************************************************************************/
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c
index e048f9bc78..a4fdf5eb09 100644
--- a/src/dns/nm-dns-manager.c
+++ b/src/dns/nm-dns-manager.c
@@ -120,6 +120,7 @@ typedef struct {
bool need_sort:1;
bool dns_touched:1;
bool is_stopped:1;
+ bool use_local_plugin:1;
char *hostname;
guint updates_queue;
@@ -129,7 +130,7 @@ typedef struct {
NMDnsManagerResolvConfManager rc_manager;
char *mode;
- NMDnsPlugin *plugin;
+ GSList *plugins;
NMConfig *config;
} NMDnsManagerPrivate;
@@ -1074,7 +1075,7 @@ _collect_resolv_conf_data (NMDnsManager *self, /* only for logging context, no o
static gboolean
update_dns (NMDnsManager *self,
- gboolean no_caching,
+ NMDnsPlugin *plugin,
GError **error)
{
NMDnsManagerPrivate *priv;
@@ -1088,6 +1089,7 @@ update_dns (NMDnsManager *self,
SpawnResult result = SR_ERROR;
NMConfigData *data;
NMGlobalDnsConfig *global_config;
+ GSList *iter;
g_return_val_if_fail (!error || !*error, FALSE);
@@ -1121,35 +1123,39 @@ update_dns (NMDnsManager *self,
_collect_resolv_conf_data (self, global_config, priv->configs, priv->hostname,
&searches, &options, &nameservers, &nis_servers, &nis_domain);
- /* Let any plugins do their thing first */
- if (priv->plugin) {
- NMDnsPlugin *plugin = priv->plugin;
- const char *plugin_name = nm_dns_plugin_get_name (plugin);
-
- if (no_caching) {
- _LOGD ("update-dns: plugin %s ignored (caching disabled)",
- plugin_name);
- goto skip;
+ if (plugin) {
+ if (nm_dns_plugin_get_state (plugin) == NM_DNS_PLUGIN_STATE_STOPPED) {
+ /* We're reviving a stopped plugin. The failed plugins have to wait until
+ * the next update. */
+ _LOGD ("update-dns: restarting plugin %s", nm_dns_plugin_get_name (plugin));
+ g_signal_handlers_block_by_func (plugin, plugin_state_changed, self);
+ nm_dns_plugin_update (plugin,
+ priv->configs,
+ global_config,
+ priv->hostname);
+ g_signal_handlers_unblock_by_func (plugin, plugin_state_changed, self);
}
- caching = TRUE;
-
- _LOGD ("update-dns: updating plugin %s", plugin_name);
- g_signal_handlers_block_by_func (plugin, plugin_state_changed, self);
- if (!nm_dns_plugin_update (plugin,
- priv->configs,
- global_config,
- priv->hostname)) {
- _LOGW ("update-dns: plugin %s update failed", plugin_name);
-
- /* If the plugin failed to update, we shouldn't write out a local
- * caching DNS configuration to resolv.conf.
- */
- caching = FALSE;
+ }
+
+ for (iter = priv->plugins; iter; iter = iter->next) {
+ NMDnsPlugin *this_plugin = NM_DNS_PLUGIN (iter->data);
+
+ g_signal_handlers_block_by_func (this_plugin, plugin_state_changed, self);
+ if (!plugin) {
+ /* No specific plugin was passed. Update all. */
+ _LOGD ("update-dns: updating plugin %s", nm_dns_plugin_get_name (this_plugin));
+ g_signal_handlers_block_by_func (this_plugin, plugin_state_changed, self);
+ nm_dns_plugin_update (this_plugin,
+ priv->configs,
+ global_config,
+ priv->hostname);
+ g_signal_handlers_unblock_by_func (this_plugin, plugin_state_changed, self);
}
- g_signal_handlers_unblock_by_func (plugin, plugin_state_changed, self);
+ g_signal_handlers_unblock_by_func (this_plugin, plugin_state_changed, self);
- skip:
- ;
+ if ( priv->use_local_plugin
+ && nm_dns_plugin_get_state (this_plugin) != NM_DNS_PLUGIN_STATE_FAILED)
+ caching = TRUE;
}
/* If caching was successful, we only send 127.0.0.1 to /etc/resolv.conf
@@ -1217,21 +1223,21 @@ plugin_state_changed (NMDnsPlugin *plugin, GParamSpec *pspec, gpointer user_data
switch (nm_dns_plugin_get_state (plugin)) {
case NM_DNS_PLUGIN_STATE_STOPPED:
_LOGI ("dns: plugin %s stopped, restarting it", plugin_name);
- if (!update_dns (self, FALSE, &error)) {
- _LOGW ("could not commit DNS changes: %s", error->message);
- g_clear_error (&error);
- }
break;
case NM_DNS_PLUGIN_STATE_FAILED:
_LOGW ("dns: plugin %s failed", plugin_name);
- if (!update_dns (self, TRUE, &error)) {
- _LOGW ("could not commit DNS changes: %s", error->message);
- g_clear_error (&error);
- }
break;
default:
return;
}
+
+ /* Retry the DNS update, so that a stopped plugin could be restarted or
+ * nameserver configuration reverted to a non-caching mode if no plugins
+ * are non-failed. */
+ if (!update_dns (self, plugin, &error)) {
+ _LOGW ("could not commit DNS changes: %s", error->message);
+ g_clear_error (&error);
+ }
}
static void
@@ -1309,7 +1315,7 @@ nm_dns_manager_add_ip_config (NMDnsManager *self,
}
}
- if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
+ if (!priv->updates_queue && !update_dns (self, NULL, &error)) {
_LOGW ("could not commit DNS changes: %s", error->message);
g_clear_error (&error);
}
@@ -1355,7 +1361,7 @@ nm_dns_manager_remove_ip_config (NMDnsManager *self, gpointer config)
forget_data (self, data);
g_ptr_array_remove_index (priv->configs, i);
- if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
+ if (!priv->updates_queue && !update_dns (self, NULL, &error)) {
_LOGW ("could not commit DNS changes: %s", error->message);
g_clear_error (&error);
}
@@ -1414,7 +1420,7 @@ nm_dns_manager_set_hostname (NMDnsManager *self,
if (skip_update)
return;
- if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
+ if (!priv->updates_queue && !update_dns (self, NULL, &error)) {
_LOGW ("could not commit DNS changes: %s", error->message);
g_clear_error (&error);
}
@@ -1431,7 +1437,7 @@ nm_dns_manager_get_resolv_conf_explicit (NMDnsManager *self)
if ( NM_IN_SET (priv->rc_manager, NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED,
NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE)
- || priv->plugin)
+ || priv->plugins)
return FALSE;
return TRUE;
@@ -1484,7 +1490,7 @@ nm_dns_manager_end_updates (NMDnsManager *self, const char *func)
/* Commit all the outstanding changes */
_LOGD ("(%s): committing DNS changes (%d)", func, priv->updates_queue);
- if (!update_dns (self, FALSE, &error)) {
+ if (!update_dns (self, NULL, &error)) {
_LOGW ("could not commit DNS changes: %s", error->message);
g_clear_error (&error);
}
@@ -1492,49 +1498,23 @@ nm_dns_manager_end_updates (NMDnsManager *self, const char *func)
memset (priv->prev_hash, 0, sizeof (priv->prev_hash));
}
-void
-nm_dns_manager_stop (NMDnsManager *self)
-{
- NMDnsManagerPrivate *priv;
- GError *error = NULL;
-
- priv = NM_DNS_MANAGER_GET_PRIVATE (self);
-
- if (priv->is_stopped)
- g_return_if_reached ();
-
- _LOGT ("stopping...");
-
- /* If we're quitting, leave a valid resolv.conf in place, not one
- * pointing to 127.0.0.1 if any plugins were active. Thus update
- * DNS after disposing of all plugins. But if we haven't done any
- * DNS updates yet, there's no reason to touch resolv.conf on shutdown.
- */
- if (priv->dns_touched) {
- if (!update_dns (self, TRUE, &error)) {
- _LOGW ("could not commit DNS changes on shutdown: %s", error->message);
- g_clear_error (&error);
- }
- priv->dns_touched = FALSE;
- }
-
- priv->is_stopped = TRUE;
-}
-
/*****************************************************************************/
-static gboolean
-_clear_plugin (NMDnsManager *self)
+static void
+_clear_plugins (NMDnsManager *self)
{
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+ GSList *iter;
- if (priv->plugin) {
- g_signal_handlers_disconnect_by_func (priv->plugin, plugin_state_changed, self);
- nm_dns_plugin_stop (priv->plugin);
- g_clear_object (&priv->plugin);
- return TRUE;
+ for (iter = priv->plugins; iter; iter = iter->next) {
+ NMDnsPlugin *plugin = NM_DNS_PLUGIN (iter->data);
+
+ g_signal_handlers_disconnect_by_func (plugin, plugin_state_changed, self);
+ nm_dns_plugin_stop (plugin);
}
- return FALSE;
+ g_slist_free (priv->plugins);
+ priv->plugins = NULL;
+ priv->use_local_plugin = FALSE;
}
static NMDnsManagerResolvConfManager
@@ -1586,86 +1566,53 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager)
}
}
-static gboolean
-_resolvconf_resolved_managed (void)
+static void
+init_resolv_conf_mode (NMDnsManager *self, gboolean reload_dns_mode)
{
- static const char *const RESOLVED_PATHS[] = {
- "/run/systemd/resolve/resolv.conf",
- "/lib/systemd/resolv.conf",
- "/usr/lib/systemd/resolv.conf",
- };
- struct stat st, st_test;
- guint i;
+ NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+ NMDnsManagerResolvConfManager rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN;
+ gs_strfreev char **mode = NULL;
+ gboolean rc_manager_changed = FALSE;
+ int i;
- if (lstat (_PATH_RESCONF, &st) != 0)
- return FALSE;
+ if (reload_dns_mode) {
+ mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config));
+
+ _clear_plugins (self);
+ for (i = 0; mode[i]; i++) {
+ NMDnsPlugin *plugin = NULL;
+
+ if (nm_streq0 (mode[i], "systemd-resolved")) {
+ plugin = nm_dns_systemd_resolved_new ();
+ } else if (nm_streq0 (mode[i], "dnsmasq")) {
+ plugin = nm_dns_dnsmasq_new ();
+ } else if (nm_streq0 (mode[i], "unbound")) {
+ plugin = nm_dns_unbound_new ();
+ } else if (nm_streq0 (mode[i], "none")) {
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED;
+ } else if (!nm_streq0 (mode[i], "default")) {
+ _LOGW ("init: unknown dns mode '%s'", mode[i]);
+ }
- if (S_ISLNK (st.st_mode)) {
- gs_free char *full_path = NULL;
- nm_auto_free char *real_path = NULL;
-
- /* see if resolv.conf is a symlink with a target that is
- * exactly like one of the candidates.
- *
- * This check will work for symlinks, even if the target
- * does not exist and realpath() cannot resolve anything.
- *
- * We want to handle that, because systemd-resolved might not
- * have started yet. */
- full_path = g_file_read_link (_PATH_RESCONF, NULL);
- if (nm_utils_strv_find_first ((char **) RESOLVED_PATHS,
- G_N_ELEMENTS (RESOLVED_PATHS),
- full_path) >= 0)
- return TRUE;
+ if (plugin) {
+ _LOGI ("init: dns=%s%s%s%s",
+ mode[i], NM_PRINT_FMT_QUOTED (plugin, ", plugin=",
+ nm_dns_plugin_get_name (plugin), "", ""));
- /* see if resolv.conf is a symlink that resolves exactly one
- * of the candidate paths.
- *
- * This check will work for symlinks that can be resolved
- * to a realpath, but the actual file might not exist.
- *
- * We want to handle that, because systemd-resolved might not
- * have started yet. */
- real_path = realpath (_PATH_RESCONF, NULL);
- if (nm_utils_strv_find_first ((char **) RESOLVED_PATHS,
- G_N_ELEMENTS (RESOLVED_PATHS),
- real_path) >= 0)
- return TRUE;
+ g_signal_connect (plugin,
+ "notify::" NM_DNS_PLUGIN_STATE,
+ G_CALLBACK (plugin_state_changed),
+ self);
+ priv->plugins = g_slist_append (priv->plugins, plugin);
+ }
- /* fall-through and resolve the symlink, to check the file
- * it points to (below).
- *
- * This check is the most reliable, but it only works if
- * systemd-resolved already started and created the file. */
- if (stat (_PATH_RESCONF, &st) != 0)
- return FALSE;
- }
-
- /* see if resolv.conf resolves to one of the candidate
- * paths (or whether it is hard-linked). */
- for (i = 0; i < G_N_ELEMENTS (RESOLVED_PATHS); i++) {
- if ( stat (RESOLVED_PATHS[i], &st_test) == 0
- && st.st_dev == st_test.st_dev
- && st.st_ino == st_test.st_ino)
- return TRUE;
+ /* Prefer the local plugin only if it's first in the list. */
+ if (i == 0)
+ priv->use_local_plugin = (plugin != NULL);
+ }
}
- return FALSE;
-}
-
-static void
-init_resolv_conf_mode (NMDnsManager *self, gboolean force_reload_plugin)
-{
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
- NMDnsManagerResolvConfManager rc_manager;
- const char *mode;
- gboolean param_changed = FALSE, plugin_changed = FALSE;
-
- mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config));
-
- if (nm_streq0 (mode, "none"))
- rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED;
- else {
+ if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN) {
const char *man;
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN;
@@ -1698,61 +1645,23 @@ again:
rc_manager = _check_resconf_immutable (rc_manager);
- if ( (!mode && _resolvconf_resolved_managed ())
- || nm_streq0 (mode, "systemd-resolved")) {
- if ( force_reload_plugin
- || !NM_IS_DNS_SYSTEMD_RESOLVED (priv->plugin)) {
- _clear_plugin (self);
- priv->plugin = nm_dns_systemd_resolved_new ();
- plugin_changed = TRUE;
- }
- mode = "systemd-resolved";
- } else if (nm_streq0 (mode, "dnsmasq")) {
- if (force_reload_plugin || !NM_IS_DNS_DNSMASQ (priv->plugin)) {
- _clear_plugin (self);
- priv->plugin = nm_dns_dnsmasq_new ();
- plugin_changed = TRUE;
- }
- } else if (nm_streq0 (mode, "unbound")) {
- if (force_reload_plugin || !NM_IS_DNS_UNBOUND (priv->plugin)) {
- _clear_plugin (self);
- priv->plugin = nm_dns_unbound_new ();
- plugin_changed = TRUE;
- }
- } else {
- if (!NM_IN_STRSET (mode, "none", "default")) {
- if (mode)
- _LOGW ("init: unknown dns mode '%s'", mode);
- mode = "default";
- }
- if (_clear_plugin (self))
- plugin_changed = TRUE;
- }
-
- if (plugin_changed && priv->plugin)
- g_signal_connect (priv->plugin, "notify::" NM_DNS_PLUGIN_STATE, G_CALLBACK (plugin_state_changed), self);
-
g_object_freeze_notify (G_OBJECT (self));
- if (!nm_streq0 (priv->mode, mode)) {
+ if (!nm_streq0 (priv->mode, mode[0])) {
g_free (priv->mode);
- priv->mode = g_strdup (mode);
- param_changed = TRUE;
+ priv->mode = g_strdup (mode[0]);
+ rc_manager_changed = TRUE;
_notify (self, PROP_MODE);
}
if (priv->rc_manager != rc_manager) {
priv->rc_manager = rc_manager;
- param_changed = TRUE;
+ rc_manager_changed = TRUE;
_notify (self, PROP_RC_MANAGER);
}
- if (param_changed || plugin_changed) {
- _LOGI ("init: dns=%s, rc-manager=%s%s%s%s",
- mode, _rc_manager_to_string (rc_manager),
- NM_PRINT_FMT_QUOTED (priv->plugin, ", plugin=",
- nm_dns_plugin_get_name (priv->plugin), "", ""));
- }
+ if (rc_manager_changed)
+ _LOGI ("init: rc-manager=%s", _rc_manager_to_string (rc_manager));
g_object_thaw_notify (G_OBJECT (self));
}
@@ -1775,7 +1684,8 @@ config_changed_cb (NMConfig *config,
* is immutable, thus, without the configuration changing, we always want to
* re-configure the mode. */
init_resolv_conf_mode (self,
- NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP
+ NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_DNS_MODE
+ | NM_CONFIG_CHANGE_CAUSE_SIGHUP
| NM_CONFIG_CHANGE_CAUSE_DNS_FULL));
}
@@ -1786,7 +1696,7 @@ config_changed_cb (NMConfig *config,
NM_CONFIG_CHANGE_DNS_MODE |
NM_CONFIG_CHANGE_RC_MANAGER |
NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG)) {
- if (!update_dns (self, FALSE, &error)) {
+ if (!update_dns (self, NULL, &error)) {
_LOGW ("could not commit DNS changes: %s", error->message);
g_clear_error (&error);
}
@@ -2028,6 +1938,39 @@ nm_dns_manager_init (NMDnsManager *self)
init_resolv_conf_mode (self, TRUE);
}
+void
+nm_dns_manager_stop (NMDnsManager *self)
+{
+ NMDnsManagerPrivate *priv;
+ GError *error = NULL;
+
+ priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+
+ if (priv->is_stopped)
+ g_return_if_reached ();
+
+ _LOGT ("stopping...");
+
+ /* Clear plugins first so that subsequent update_dns reverts to a
+ * non-caching configuration. */
+ _clear_plugins (self);
+
+ /* If we're quitting, leave a valid resolv.conf in place, not one
+ * pointing to 127.0.0.1 if any plugins were active. Thus update
+ * DNS after disposing of all plugins. But if we haven't done any
+ * DNS updates yet, there's no reason to touch resolv.conf on shutdown.
+ */
+ if (priv->dns_touched) {
+ if (!update_dns (self, NULL, &error)) {
+ _LOGW ("could not commit DNS changes on shutdown: %s", error->message);
+ g_clear_error (&error);
+ }
+ priv->dns_touched = FALSE;
+ }
+
+ priv->is_stopped = TRUE;
+}
+
static void
dispose (GObject *object)
{
@@ -2041,8 +1984,6 @@ dispose (GObject *object)
if (!priv->is_stopped)
nm_dns_manager_stop (self);
- _clear_plugin (self);
-
if (priv->config) {
g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, self);
g_clear_object (&priv->config);
diff --git a/src/dns/nm-dns-plugin.c b/src/dns/nm-dns-plugin.c
index a998da5807..81b3e00d23 100644
--- a/src/dns/nm-dns-plugin.c
+++ b/src/dns/nm-dns-plugin.c
@@ -82,7 +82,7 @@ G_DEFINE_TYPE_EXTENDED (NMDnsPlugin, nm_dns_plugin, G_TYPE_OBJECT, G_TYPE_FLAG_A
/*****************************************************************************/
-gboolean
+void
nm_dns_plugin_update (NMDnsPlugin *self,
const GPtrArray *configs,
const NMGlobalDnsConfig *global_config,
@@ -90,14 +90,14 @@ nm_dns_plugin_update (NMDnsPlugin *self,
{
NMDnsPluginPrivate *priv = NM_DNS_PLUGIN_GET_PRIVATE (self);
- g_return_val_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update != NULL, FALSE);
+ g_return_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update != NULL);
nm_clear_g_source (&priv->plugin_ratelimit.timer);
- return NM_DNS_PLUGIN_GET_CLASS (self)->update (self,
- configs,
- global_config,
- hostname);
+ NM_DNS_PLUGIN_GET_CLASS (self)->update (self,
+ configs,
+ global_config,
+ hostname);
}
const char *
diff --git a/src/dns/nm-dns-plugin.h b/src/dns/nm-dns-plugin.h
index e4a6cd40fa..be624730d2 100644
--- a/src/dns/nm-dns-plugin.h
+++ b/src/dns/nm-dns-plugin.h
@@ -48,10 +48,10 @@ typedef struct {
* 'global_config' is the optional global DNS
* configuration.
*/
- gboolean (*update) (NMDnsPlugin *self,
- const GPtrArray *configs,
- const NMGlobalDnsConfig *global_config,
- const char *hostname);
+ void (*update) (NMDnsPlugin *self,
+ const GPtrArray *configs,
+ const NMGlobalDnsConfig *global_config,
+ const char *hostname);
/* Subclasses should override this and return their plugin name */
const char *(*get_name) (NMDnsPlugin *self);
@@ -76,10 +76,10 @@ const char *nm_dns_plugin_get_name (NMDnsPlugin *self);
NMDnsPluginState nm_dns_plugin_get_state (NMDnsPlugin *self);
void nm_dns_plugin_set_state (NMDnsPlugin *self, NMDnsPluginState state);
-gboolean nm_dns_plugin_update (NMDnsPlugin *self,
- const GPtrArray *configs,
- const NMGlobalDnsConfig *global_config,
- const char *hostname);
+void nm_dns_plugin_update (NMDnsPlugin *self,
+ const GPtrArray *configs,
+ const NMGlobalDnsConfig *global_config,
+ const char *hostname);
void nm_dns_plugin_stop (NMDnsPlugin *self);
diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c
index a48f78d259..e92d00a77c 100644
--- a/src/dns/nm-dns-systemd-resolved.c
+++ b/src/dns/nm-dns-systemd-resolved.c
@@ -288,7 +288,7 @@ send_updates (NMDnsSystemdResolved *self)
}
}
-static gboolean
+static void
update (NMDnsPlugin *plugin,
const GPtrArray *configs,
const NMGlobalDnsConfig *global_config,
@@ -322,8 +322,6 @@ update (NMDnsPlugin *plugin,
g_array_free (interfaces, TRUE);
send_updates (self);
-
- return TRUE;
}
/*****************************************************************************/
diff --git a/src/dns/nm-dns-unbound.c b/src/dns/nm-dns-unbound.c
index e86e51e08a..f7390083e8 100644
--- a/src/dns/nm-dns-unbound.c
+++ b/src/dns/nm-dns-unbound.c
@@ -37,7 +37,7 @@ G_DEFINE_TYPE (NMDnsUnbound, nm_dns_unbound, NM_TYPE_DNS_PLUGIN)
/*****************************************************************************/
-static gboolean
+static void
update (NMDnsPlugin *plugin,
const GPtrArray *configs,
const NMGlobalDnsConfig *global_config,
@@ -63,8 +63,6 @@ update (NMDnsPlugin *plugin,
nm_dns_plugin_set_state (plugin,
success ? NM_DNS_PLUGIN_STATE_RUNNING : NM_DNS_PLUGIN_STATE_FAILED);
-
- return success;
}
static const char *
diff --git a/src/nm-config-data.c b/src/nm-config-data.c
index 21ad1a7346..119f5534a5 100644
--- a/src/nm-config-data.c
+++ b/src/nm-config-data.c
@@ -217,8 +217,10 @@ nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, c
return value;
}
-char **
-nm_config_data_get_plugins (const NMConfigData *self, gboolean allow_default)
+static char **
+get_string_list (const NMConfigData *self,
+ const char *group, const char *key, const char *dfl,
+ gboolean allow_default)
{
const NMConfigDataPrivate *priv;
char **list;
@@ -227,17 +229,24 @@ nm_config_data_get_plugins (const NMConfigData *self, gboolean allow_default)
priv = NM_CONFIG_DATA_GET_PRIVATE (self);
- list = g_key_file_get_string_list (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NULL, NULL);
+ list = g_key_file_get_string_list (priv->keyfile, group, key, NULL, NULL);
if (!list && allow_default) {
gs_unref_keyfile GKeyFile *kf = nm_config_create_keyfile ();
/* let keyfile split the default string according to it's own escaping rules. */
- g_key_file_set_value (kf, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NM_CONFIG_DEFAULT_MAIN_PLUGINS);
- list = g_key_file_get_string_list (kf, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NULL, NULL);
+ g_key_file_set_value (kf, group, key, dfl);
+ list = g_key_file_get_string_list (kf, group, key, NULL, NULL);
}
return _nm_utils_strv_cleanup (list, TRUE, TRUE, TRUE);
}
+char **
+nm_config_data_get_plugins (const NMConfigData *self, gboolean allow_default)
+{
+ return get_string_list (self, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins",
+ NM_CONFIG_DEFAULT_MAIN_PLUGINS, allow_default);
+}
+
const char *
nm_config_data_get_connectivity_uri (const NMConfigData *self)
{
@@ -283,12 +292,11 @@ nm_config_data_get_no_auto_default_for_device (const NMConfigData *self, NMDevic
|| nm_device_spec_match_list (device, priv->no_auto_default.specs_config);
}
-const char *
+char **
nm_config_data_get_dns_mode (const NMConfigData *self)
{
- g_return_val_if_fail (self, NULL);
-
- return NM_CONFIG_DATA_GET_PRIVATE (self)->dns_mode;
+ return get_string_list (self, NM_CONFIG_KEYFILE_GROUP_MAIN, "dns",
+ NM_CONFIG_DEFAULT_MAIN_DNS, TRUE);
}
const char *
@@ -574,6 +582,7 @@ static const struct {
const char *value;
} default_values[] = {
{ NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NM_CONFIG_DEFAULT_MAIN_PLUGINS },
+ { NM_CONFIG_KEYFILE_GROUP_MAIN, "dns", NM_CONFIG_DEFAULT_MAIN_DNS },
{ NM_CONFIG_KEYFILE_GROUP_MAIN, "rc-manager", NM_CONFIG_DEFAULT_MAIN_RC_MANAGER },
{ NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_AUTH_POLKIT, NM_CONFIG_DEFAULT_MAIN_AUTH_POLKIT },
{ NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_DHCP, NM_CONFIG_DEFAULT_MAIN_DHCP },
@@ -1363,6 +1372,8 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data)
{
NMConfigChangeFlags changes = NM_CONFIG_CHANGE_NONE;
NMConfigDataPrivate *priv_old, *priv_new;
+ gs_strfreev char **dns_mode_old = NULL;
+ gs_strfreev char **dns_mode_new = NULL;
g_return_val_if_fail (NM_IS_CONFIG_DATA (old_data), NM_CONFIG_CHANGE_NONE);
g_return_val_if_fail (NM_IS_CONFIG_DATA (new_data), NM_CONFIG_CHANGE_NONE);
@@ -1389,7 +1400,9 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data)
|| !_slist_str_equals (priv_old->no_auto_default.specs_config, priv_new->no_auto_default.specs_config))
changes |= NM_CONFIG_CHANGE_NO_AUTO_DEFAULT;
- if (g_strcmp0 (nm_config_data_get_dns_mode (old_data), nm_config_data_get_dns_mode (new_data)))
+ dns_mode_old = nm_config_data_get_dns_mode (old_data);
+ dns_mode_new = nm_config_data_get_dns_mode (new_data);
+ if (!_nm_utils_strv_equal (dns_mode_old, dns_mode_new))
changes |= NM_CONFIG_CHANGE_DNS_MODE;
if (g_strcmp0 (nm_config_data_get_rc_manager (old_data), nm_config_data_get_rc_manager (new_data)))
diff --git a/src/nm-config-data.h b/src/nm-config-data.h
index 98c667516c..2b001e21bc 100644
--- a/src/nm-config-data.h
+++ b/src/nm-config-data.h
@@ -166,7 +166,7 @@ const char *nm_config_data_get_connectivity_response (const NMConfigData *config
const char *const*nm_config_data_get_no_auto_default (const NMConfigData *config_data);
gboolean nm_config_data_get_no_auto_default_for_device (const NMConfigData *self, NMDevice *device);
-const char *nm_config_data_get_dns_mode (const NMConfigData *self);
+char **nm_config_data_get_dns_mode (const NMConfigData *self);
const char *nm_config_data_get_rc_manager (const NMConfigData *self);
gboolean nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device);
diff --git a/src/nm-config.c b/src/nm-config.c
index 608ef23e1f..f272f281bc 100644
--- a/src/nm-config.c
+++ b/src/nm-config.c
@@ -636,6 +636,7 @@ _setting_is_string_list (const char *group, const char *key)
{
return _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins")
|| _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG)
+ || _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "dns")
|| _IS (NM_CONFIG_KEYFILE_GROUP_LOGGING, "domains")
|| g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST);
#undef _IS
diff --git a/src/nm-config.h b/src/nm-config.h
index c5ff7c67d6..b65668e87d 100644
--- a/src/nm-config.h
+++ b/src/nm-config.h
@@ -38,6 +38,7 @@
/* Signals */
#define NM_CONFIG_SIGNAL_CONFIG_CHANGED "config-changed"
+#define NM_CONFIG_DEFAULT_MAIN_DNS "default,systemd-resolved"
#define NM_CONFIG_DEFAULT_CONNECTIVITY_INTERVAL 300
#define NM_CONFIG_DEFAULT_CONNECTIVITY_RESPONSE "NetworkManager is online" /* NOT LOCALIZED */