summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-06-02 17:20:49 +0200
committerThomas Haller <thaller@redhat.com>2016-06-02 18:42:09 +0200
commitd2efff41eed1337cbb854a15ab6a3051d0bdb5fa (patch)
tree69ebd3e327b20df36f15215a7f44dd7728c9d8aa
parentaa04e04c83a953be8fa8cb0787cf20e57b1d968d (diff)
downloadNetworkManager-th/rc-manager-file-follow.tar.gz
dns: follow resolv.conf if it is a symlink ('rc-manager=file-follow')th/rc-manager-file-follow
Until before 1.2.0, NetworkManager would always write resolv.conf as file, but if /etc/resolv.conf was a symlink, it would follow the link instead of replacing it with a file ([1], [2]). With 1.2.0, we dropped that behavior and added a new 'rc-manager=none' which writes resolv.conf to /var/run/NetworkManager and symlinks resolv.conf [3]. In case resolv.conf being already a symlink to another target, it would not be replaced [4]. Also, we added 'rc-manager=file', which always writes /etc/resolv.conf as file [5]. With 1.4.0, we will rename 'rc-manager=none' to 'rc-manager=symlink' [6]. This commit adds yet another 'rc-manager=file-follow' which restores the pre-1.2 behavior. [1] 5761e328b81ce8894c2657ce0994ba401923ba35 [2] https://bugs.launchpad.net/ubuntu/+source/network-manager/+bug/324233 [3] 4805be2ed27b71a6099477d86dbc109adb41b819 [4] 583568e12f9e580cd2903811637c9f9b7a2f1088 [5] 288799713dc78bc45e2b0a9cf41d228f5d95315f [6] cd6a469668028fbc347919ed3580275f9894a1f2
-rw-r--r--configure.ac8
-rw-r--r--man/NetworkManager.conf.xml3
-rw-r--r--src/dns-manager/nm-dns-manager.c29
-rw-r--r--src/dns-manager/nm-dns-manager.h3
4 files changed, 32 insertions, 11 deletions
diff --git a/configure.ac b/configure.ac
index dbcc024572..e6cc78075d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -779,8 +779,12 @@ fi
# resolvconf and netconfig support
AC_ARG_WITH(resolvconf, AS_HELP_STRING([--with-resolvconf=yes|no|path], [Enable resolvconf support]))
AC_ARG_WITH(netconfig, AS_HELP_STRING([--with-netconfig=yes|no], [Enable SUSE netconfig support]))
-AC_ARG_WITH(config-dns-rc-manager-default, AS_HELP_STRING([--with-config-dns-rc-manager-default=symlink|file|netconfig|resolvconf], [Configure default value for main.rc-manager setting]), [config_dns_rc_manager_default=$withval])
-if test "$config_dns_rc_manager_default" != symlink -a "$config_dns_rc_manager_default" != file -a "$config_dns_rc_manager_default" != netconfig -a "$config_dns_rc_manager_default" != resolvconf; then
+AC_ARG_WITH(config-dns-rc-manager-default, AS_HELP_STRING([--with-config-dns-rc-manager-default=symlink|file|file-follow|netconfig|resolvconf], [Configure default value for main.rc-manager setting]), [config_dns_rc_manager_default=$withval])
+if test "$config_dns_rc_manager_default" != symlink -a \
+ "$config_dns_rc_manager_default" != file -a \
+ "$config_dns_rc_manager_default" != file-follow -a \
+ "$config_dns_rc_manager_default" != netconfig -a \
+ "$config_dns_rc_manager_default" != resolvconf; then
AC_MSG_WARN([Unknown --with-config-dns-rc-manager-default=$config_dns_rc_manager_default setting.])
config_dns_rc_manager_default=
fi
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 23038dbbc1..d116cf5e6f 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -330,6 +330,9 @@ no-auto-default=*
somewhere else.</para>
<para><literal>file</literal>: NetworkManager will write
<filename>/etc/resolv.conf</filename> as file.</para>
+ <para><literal>file-follow</literal>: like <literal>file</literal>,
+ but if <filename>/etc/resolv.conf</filename> is a symlink, follow
+ it and update the link target instead.</para>
<para><literal>resolvconf</literal>: NetworkManager will run
resolvconf to update the DNS configuration.</para>
<para><literal>netconfig</literal>: NetworkManager will run
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c
index 114b33d6c0..cc11055934 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -181,6 +181,7 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_rc_manager_to_string, NMDnsManagerResolvConf
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE, "immutable"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK, "symlink"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE, "file"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE_FOLLOW, "file-follow"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF, "resolvconf"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG, "netconfig"),
);
@@ -674,6 +675,8 @@ update_resolv_conf (NMDnsManager *self,
gs_free char *content = NULL;
SpawnResult write_file_result = SR_SUCCESS;
int errsv;
+ const char *rc_path = _PATH_RESCONF;
+ nm_auto_free char *rc_path_real = NULL;
/* If we are not managing /etc/resolv.conf and it points to
* MY_RESOLV_CONF, don't write the private DNS configuration to
@@ -694,21 +697,26 @@ update_resolv_conf (NMDnsManager *self,
content = create_resolv_conf (searches, nameservers, options);
- if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE) {
+ if (NM_IN_SET (rc_manager, NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE, NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE_FOLLOW)) {
GError *local = NULL;
+ if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE_FOLLOW) {
+ rc_path_real = realpath (_PATH_RESCONF, NULL);
+ rc_path = rc_path_real;
+ }
+
/* we first write to /etc/resolv.conf directly. If that fails,
* we still continue to write to runstatedir but remember the
* error. */
- if (!g_file_set_contents (_PATH_RESCONF, content, -1, &local)) {
- _LOGT ("update-resolv-conf: write to %s failed (rc-managed=file, %s)",
- _PATH_RESCONF, local->message);
+ if (!g_file_set_contents (rc_path, content, -1, &local)) {
+ _LOGT ("update-resolv-conf: write to %s failed (rc-manager=%s, %s)",
+ rc_path, _rc_manager_to_string (rc_manager), local->message);
write_file_result = SR_ERROR;
g_propagate_error (error, local);
error = NULL;
} else {
- _LOGT ("update-resolv-conf: write to %s succeeded (rc-managed=file)",
- _PATH_RESCONF);
+ _LOGT ("update-resolv-conf: write to %s succeeded (rc-manager=%s)",
+ rc_path, _rc_manager_to_string (rc_manager));
}
}
@@ -764,9 +772,9 @@ update_resolv_conf (NMDnsManager *self,
return SR_ERROR;
}
- if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE) {
- _LOGT ("update-resolv-conf: write internal file %s succeeded (rc-manager=file)",
- MY_RESOLV_CONF);
+ if (NM_IN_SET (rc_manager, NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE, NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE_FOLLOW)) {
+ _LOGT ("update-resolv-conf: write internal file %s succeeded (rc-manager=%s)",
+ rc_path, _rc_manager_to_string (rc_manager));
return write_file_result;
}
@@ -1126,6 +1134,7 @@ update_dns (NMDnsManager *self,
switch (priv->rc_manager) {
case NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK:
case NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE:
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE_FOLLOW:
result = update_resolv_conf (self, searches, nameservers, options, error, priv->rc_manager);
resolv_conf_updated = TRUE;
break;
@@ -1546,6 +1555,8 @@ again:
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK;
else if (nm_streq (man, "file"))
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE;
+ else if (nm_streq (man, "file-follow"))
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE_FOLLOW;
else if (nm_streq (man, "resolvconf"))
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF;
else if (nm_streq (man, "netconfig"))
diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h
index 50f050e544..d32301d900 100644
--- a/src/dns-manager/nm-dns-manager.h
+++ b/src/dns-manager/nm-dns-manager.h
@@ -98,6 +98,8 @@ void nm_dns_manager_set_hostname (NMDnsManager *self,
* by symlinking it to the run state directory.
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: Like SYMLINK, but instead of
* symlinking /etc/resolv.conf, write it as a file.
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE_FOLLOW: Like FILE, but if /etc/resolv.conf
+ * is a symlink, follow it and replace the file instead.
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF: NM is managing resolv.conf
through resolvconf
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG: NM is managing resolv.conf
@@ -111,6 +113,7 @@ typedef enum {
NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE,
NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK,
NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE,
+ NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE_FOLLOW,
NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF,
NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG,
} NMDnsManagerResolvConfManager;