summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-03-21 21:01:25 +0100
committerThomas Haller <thaller@redhat.com>2016-03-23 09:09:06 +0100
commit288799713dc78bc45e2b0a9cf41d228f5d95315f (patch)
tree27a9e24b157c21b158ab05a64f9e8f2eb9b21c7c
parent22df466ed3f462f1ea16366b5739748d4c369237 (diff)
downloadNetworkManager-288799713dc78bc45e2b0a9cf41d228f5d95315f.tar.gz
dns: add new "rc-manager=file"
-rw-r--r--man/NetworkManager.conf.xml.in10
-rw-r--r--src/dns-manager/nm-dns-manager.c64
-rw-r--r--src/dns-manager/nm-dns-manager.h10
3 files changed, 64 insertions, 20 deletions
diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in
index cf3421dacd..2a847f8f5e 100644
--- a/man/NetworkManager.conf.xml.in
+++ b/man/NetworkManager.conf.xml.in
@@ -288,9 +288,13 @@ no-auto-default=*
<term><varname>rc-manager</varname></term>
<listitem><para>Set the <filename>resolv.conf</filename>
management mode. The default value depends on how NetworkManager
- was built.</para>
- <para><literal>none</literal>: NetworkManager will directly
- write changes to <filename>resolv.conf</filename>.</para>
+ was built. Regardless of this setting, NetworkManager will
+ always write resolv.conf to its runtime state directory.</para>
+ <para><literal>none</literal>: NetworkManager will symlink
+ <filename>/etc/resolv.conf</filename> to its private
+ resolv.conf file in the runtime state directory.</para>
+ <para><literal>file</literal>: NetworkManager will write
+ <filename>/etc/resolv.conf</filename> as file.</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 06f2b51227..b6656fc8df 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -164,8 +164,10 @@ typedef struct {
NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_rc_manager_to_string, NMDnsManagerResolvConfManager,
NM_UTILS_LOOKUP_DEFAULT_WARN (NULL),
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE, "none"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE, "file"),
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"),
+ NM_UTILS_LOOKUP_ITEM_IGNORE (_NM_DNS_MANAGER_RESOLV_CONF_MAN_INTERNAL_ONLY),
);
static void
@@ -461,15 +463,10 @@ create_resolv_conf (char **searches,
}
static gboolean
-write_resolv_conf (FILE *f,
- char **searches,
- char **nameservers,
- char **options,
- GError **error)
+write_resolv_conf_contents (FILE *f,
+ const char *content,
+ GError **error)
{
- gs_free char *content = NULL;
-
- content = create_resolv_conf (searches, nameservers, options);
if (fprintf (f, "%s", content) < 0) {
g_set_error (error,
NM_MANAGER_ERROR,
@@ -482,6 +479,19 @@ write_resolv_conf (FILE *f,
return TRUE;
}
+static gboolean
+write_resolv_conf (FILE *f,
+ char **searches,
+ char **nameservers,
+ char **options,
+ GError **error)
+{
+ gs_free char *content = NULL;
+
+ content = create_resolv_conf (searches, nameservers, options);
+ return write_resolv_conf_contents (f, content, error);
+}
+
static SpawnResult
dispatch_resolvconf (NMDnsManager *self,
char **searches,
@@ -554,18 +564,22 @@ update_resolv_conf (NMDnsManager *self,
char **nameservers,
char **options,
GError **error,
- gboolean install_etc)
+ NMDnsManagerResolvConfManager rc_manager)
{
FILE *f;
struct stat st;
gboolean success;
+ gs_free char *content = NULL;
+ SpawnResult write_file_result = SR_SUCCESS;
/* If we are not managing /etc/resolv.conf and it points to
* MY_RESOLV_CONF, don't write the private DNS configuration to
* MY_RESOLV_CONF otherwise we would overwrite the changes done by
* some external application.
- */
- if (!install_etc) {
+ *
+ * This is the only situation, where we don't try to update our
+ * internal resolv.conf file. */
+ if (rc_manager == _NM_DNS_MANAGER_RESOLV_CONF_MAN_INTERNAL_ONLY) {
gs_free char *path = g_file_read_link (_PATH_RESCONF, NULL);
if (g_strcmp0 (path, MY_RESOLV_CONF) == 0) {
@@ -575,6 +589,18 @@ update_resolv_conf (NMDnsManager *self,
}
}
+ content = create_resolv_conf (searches, nameservers, options);
+
+ if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE) {
+ /* 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, error)) {
+ write_file_result = SR_ERROR;
+ error = NULL;
+ }
+ }
+
if ((f = fopen (MY_RESOLV_CONF_TMP, "w")) == NULL) {
g_set_error (error,
NM_MANAGER_ERROR,
@@ -585,7 +611,7 @@ update_resolv_conf (NMDnsManager *self,
return SR_ERROR;
}
- success = write_resolv_conf (f, searches, nameservers, options, error);
+ success = write_resolv_conf_contents (f, content, error);
if (fclose (f) < 0) {
if (success) {
@@ -613,7 +639,10 @@ update_resolv_conf (NMDnsManager *self,
return SR_ERROR;
}
- if (!install_etc)
+ if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE)
+ return write_file_result;
+
+ if (rc_manager != NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE)
return SR_SUCCESS;
/* A symlink pointing to NM's own resolv.conf (MY_RESOLV_CONF) is always
@@ -988,7 +1017,8 @@ update_dns (NMDnsManager *self,
if (update) {
switch (priv->rc_manager) {
case NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE:
- result = update_resolv_conf (self, searches, nameservers, options, error, TRUE);
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE:
+ result = update_resolv_conf (self, searches, nameservers, options, error, priv->rc_manager);
resolv_conf_updated = TRUE;
break;
case NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF:
@@ -1005,7 +1035,7 @@ update_dns (NMDnsManager *self,
if (result == SR_NOTFOUND) {
_LOGD ("update-dns: program not available, writing to resolv.conf");
g_clear_error (error);
- result = update_resolv_conf (self, searches, nameservers, options, error, TRUE);
+ result = update_resolv_conf (self, searches, nameservers, options, error, NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE);
resolv_conf_updated = TRUE;
}
}
@@ -1013,7 +1043,7 @@ update_dns (NMDnsManager *self,
/* Unless we've already done it, update private resolv.conf in NMRUNDIR
ignoring any errors */
if (!resolv_conf_updated)
- update_resolv_conf (self, searches, nameservers, options, NULL, FALSE);
+ update_resolv_conf (self, searches, nameservers, options, NULL, _NM_DNS_MANAGER_RESOLV_CONF_MAN_INTERNAL_ONLY);
/* signal that resolv.conf was changed */
if (update && result == SR_SUCCESS)
@@ -1397,6 +1427,8 @@ init_resolv_conf_manager (NMDnsManager *self)
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 (nm_streq0 (man, "file"))
+ priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE;
else if (!g_strcmp0 (man, "resolvconf"))
priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF;
else if (!g_strcmp0 (man, "netconfig"))
diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h
index 7a55f1a297..dd5c9e9879 100644
--- a/src/dns-manager/nm-dns-manager.h
+++ b/src/dns-manager/nm-dns-manager.h
@@ -101,7 +101,13 @@ typedef enum {
/**
* NMDnsManagerResolvConfManager
- * @NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE: NM directly writes resolv.conf
+ * @_NM_DNS_MANAGER_RESOLV_CONF_MAN_INTERNAL_ONLY: dummy-manager
+ * to not write resolv.conf at all, only the internal file in
+ * NM's run state directory.
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE: NM writes resolv.conf
+ * by symlinking it to the run state directory.
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: Like NONE, but instead of symlinking
+ * resolv.conf, write it as a file.
* @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
@@ -110,7 +116,9 @@ typedef enum {
* NMDnsManager's management of resolv.conf
*/
typedef enum {
+ _NM_DNS_MANAGER_RESOLV_CONF_MAN_INTERNAL_ONLY,
NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE,
+ NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE,
NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF,
NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG,
} NMDnsManagerResolvConfManager;