diff options
author | Thomas Haller <thaller@redhat.com> | 2016-06-02 17:20:49 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-06-02 18:42:09 +0200 |
commit | d2efff41eed1337cbb854a15ab6a3051d0bdb5fa (patch) | |
tree | 69ebd3e327b20df36f15215a7f44dd7728c9d8aa | |
parent | aa04e04c83a953be8fa8cb0787cf20e57b1d968d (diff) | |
download | NetworkManager-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.ac | 8 | ||||
-rw-r--r-- | man/NetworkManager.conf.xml | 3 | ||||
-rw-r--r-- | src/dns-manager/nm-dns-manager.c | 29 | ||||
-rw-r--r-- | src/dns-manager/nm-dns-manager.h | 3 |
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; |