diff options
author | Thomas Haller <thaller@redhat.com> | 2016-06-03 11:16:03 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-06-03 12:18:47 +0200 |
commit | 47118679151ac1296ed9b8e2b3edcf90a38004fe (patch) | |
tree | 6251f2f2a5d03e4cfec183c60b3158747cb5c0fe | |
parent | 718fd2243690b8c72dd1cb32f67114f304542082 (diff) | |
download | NetworkManager-47118679151ac1296ed9b8e2b3edcf90a38004fe.tar.gz |
dns: update detection of immutable resolv.conf
Before, we would first check whether the file is immuable before
parsing main.rc-manager setting. That means, if you configured
[main]
dns=default
rc-manager=unmanged
we would still first try to detect whether the file is immutable.
The result of course is only minor, e.g. showing up in logging
as rc-manager=immutable instead of rc-manager=unmanged.
Also, an immutable resolv.conf would suppress a warning about
a bogus rc-manager setting.
Also, when selecting rc-manager=symlink and resolv.conf is a symlink
to an immutable file, we don't actually care about that. The reason is,
that if the link-target is not /var/run/NetworkManager/resolv.conf,
we anyway wouldn't modify the file.
The effect of this change is pretty minor, now in logging you would see:
dns-mgr: init: dns=default, rc-manager=symlink
dns-mgr: update-resolv-conf: write internal file /var/run/NetworkManager/resolv.conf succeeded but don't update /etc/resolv.conf as it points to /some/where/else
instead of
dns-mgr: init: dns=default, rc-manager=immutable
dns-mgr: update-resolv-conf: write internal file /var/run/NetworkManager/resolv.conf succeeded
Which feels slightly more right.
Note that symlinks cannot have file attributes.
-rw-r--r-- | src/dns-manager/nm-dns-manager.c | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index 8134f2f4a4..8690be8a36 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -1508,19 +1508,53 @@ _clear_plugin (NMDnsManager *self) return FALSE; } -static bool -_get_resconf_immutable (void) +static NMDnsManagerResolvConfManager +_check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager) { + struct stat st; int fd, flags; bool immutable = FALSE; - fd = open (_PATH_RESCONF, O_RDONLY); - if (fd != -1) { - if (ioctl (fd, FS_IOC_GETFLAGS, &flags) != -1) - immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL); - close (fd); + switch (rc_manager) { + case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN: + case NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE: + nm_assert_not_reached (); + /* fall-through */ + case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED: + return NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED; + default: + + if (lstat (_PATH_RESCONF, &st) != 0) + return rc_manager; + + if (S_ISLNK (st.st_mode)) { + /* only regular files and directories can have extended file attributes. */ + switch (rc_manager) { + case NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK: + /* we don't care whether the link-target is immutable. + * If the symlink points to another file, rc-manager=symlink anyway backs off. + * Otherwise, we would only check whether our internal resolv.conf is immutable. */ + return NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK; + case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN: + case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED: + case NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE: + nm_assert_not_reached (); + /* fall-through */ + case NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: + case NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF: + case NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG: + break; + } + } + + fd = open (_PATH_RESCONF, O_RDONLY); + if (fd != -1) { + if (ioctl (fd, FS_IOC_GETFLAGS, &flags) != -1) + immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL); + close (fd); + } + return immutable ? NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE : rc_manager; } - return immutable; } NM_DEFINE_SINGLETON_GETTER (NMDnsManager, nm_dns_manager_get, NM_TYPE_DNS_MANAGER); @@ -1537,8 +1571,6 @@ init_resolv_conf_mode (NMDnsManager *self, gboolean force_reload_plugin) if (nm_streq0 (mode, "none")) rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED; - else if (_get_resconf_immutable ()) - rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE; else { const char *man; @@ -1570,6 +1602,8 @@ again: } } + rc_manager = _check_resconf_immutable (rc_manager); + if (nm_streq0 (mode, "dnsmasq")) { if (force_reload_plugin || !NM_IS_DNS_DNSMASQ (priv->plugin)) { _clear_plugin (self); |