#define HASH_LEN 20
+#ifdef RESOLVCONF_PATH
+#define RESOLVCONF_SELECTED
+#else
+#define RESOLVCONF_PATH "/sbin/resolvconf"
+#endif
+
+#ifdef NETCONFIG_PATH
+#define NETCONFIG_SELECTED
+#else
+#define NETCONFIG_PATH "/sbin/netconfig"
+#endif
+
typedef struct {
NMIP4Config *ip4_vpn_config;
NMIP4Config *ip4_device_config;
guint8 prev_hash[HASH_LEN]; /* Hash when begin_updates() was called */
NMDnsManagerResolvConfMode resolv_conf_mode;
+ NMDnsManagerResolvConfManager rc_manager;
NMDnsPlugin *plugin;
NMConfig *config;
}
-#if defined(NETCONFIG_PATH)
-/**********************************/
-/* SUSE */
-
static GPid
run_netconfig (GError **error, gint *stdin_fd)
{
return ret > 0;
}
-#endif
-
static gboolean
write_resolv_conf (FILE *f,
return retval;
}
-#ifdef RESOLVCONF_PATH
static gboolean
dispatch_resolvconf (char **searches,
char **nameservers,
return retval;
}
-#endif
#define MY_RESOLV_CONF NMRUNDIR "/resolv.conf"
#define MY_RESOLV_CONF_TMP MY_RESOLV_CONF ".tmp"
}
if (update) {
-#if defined(RESOLVCONF_PATH)
- success = dispatch_resolvconf (searches, nameservers, error);
-#elif defined(NETCONFIG_PATH)
- success = dispatch_netconfig (searches, nameservers, nis_domain,
- nis_servers, error);
-#else
- success = update_resolv_conf (searches, nameservers, error, TRUE);
-#endif
+ switch (priv->rc_manager) {
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE:
+ success = update_resolv_conf (searches, nameservers, error, TRUE);
+ break;
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF:
+ success = dispatch_resolvconf (searches, nameservers, error);
+ break;
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG:
+ success = dispatch_netconfig (searches, nameservers, nis_domain,
+ nis_servers, error);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
}
- /* Only update private resolv.conf in NMRUNDIR, ignore errors */
- update_resolv_conf (searches, nameservers, error, FALSE);
+ /* Unless we've already done it, update private resolv.conf in NMRUNDIR
+ ignoring any errors */
+ if (!(update && priv->rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE))
+ update_resolv_conf (searches, nameservers, error, FALSE);
/* signal that resolv.conf was changed */
if (update && success)
}
}
+static void
+init_resolv_conf_manager (NMDnsManager *self)
+{
+ NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+ const char *man, *desc = "";
+
+ man = nm_config_data_get_rc_manager (nm_config_get_data (priv->config));
+ if (!g_strcmp0 (man, "none"))
+ priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE;
+ else if (!g_strcmp0 (man, "resolvconf"))
+ priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF;
+ else if (!g_strcmp0 (man, "netconfig"))
+ priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG;
+ else {
+#if defined(RESOLVCONF_SELECTED)
+ priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF;
+#elif defined(NETCONFIG_SELECTED)
+ priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG;
+#else
+ priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE;
+#endif
+ if (man)
+ nm_log_warn (LOGD_DNS, "DNS: unknown resolv.conf manager '%s'", man);
+ }
+
+ switch (priv->rc_manager) {
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF:
+ desc = "resolvconf";
+ break;
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG:
+ desc = "netconfig";
+ break;
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE:
+ desc = "none";
+ break;
+ }
+
+ nm_log_info (LOGD_DNS, "DNS: using resolv.conf manager '%s'", desc);
+}
+
static void
config_changed_cb (NMConfig *config,
NMConfigData *config_data,
{
GError *error = NULL;
- if (!(changes & NM_CONFIG_CHANGE_DNS_MODE))
+ if (!NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_DNS_MODE |
+ NM_CONFIG_CHANGE_RC_MANAGER))
return;
init_resolv_conf_mode (self);
+ init_resolv_conf_manager (self);
if (!update_dns (self, TRUE, &error)) {
nm_log_warn (LOGD_DNS, "could not commit DNS changes: %s", error->message);
g_clear_error (&error);
G_CALLBACK (config_changed_cb),
self);
init_resolv_conf_mode (self);
+ init_resolv_conf_manager (self);
}
static void
} no_auto_default;
char *dns_mode;
+ char *rc_manager;
} NMConfigDataPrivate;
return NM_CONFIG_DATA_GET_PRIVATE (self)->dns_mode;
}
+const char *
+nm_config_data_get_rc_manager (const NMConfigData *self)
+{
+ g_return_val_if_fail (self, NULL);
+
+ return NM_CONFIG_DATA_GET_PRIVATE (self)->rc_manager;
+}
+
/************************************************************************/
static gboolean
if (g_strcmp0 (nm_config_data_get_dns_mode (old_data), nm_config_data_get_dns_mode (new_data)))
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)))
+ changes |= NM_CONFIG_CHANGE_RC_MANAGER;
+
return changes;
}
g_strfreev (priv->no_auto_default.arr);
g_free (priv->dns_mode);
+ g_free (priv->rc_manager);
g_key_file_unref (priv->keyfile);
priv->connectivity.interval = MAX (0, interval);
priv->dns_mode = g_key_file_get_value (priv->keyfile, "main", "dns", NULL);
+ priv->rc_manager = g_key_file_get_value (priv->keyfile, "main", "rc-manager", NULL);
G_OBJECT_CLASS (nm_config_data_parent_class)->constructed (object);
}