diff options
author | Francesco Giudici <fgiudici@redhat.com> | 2017-02-17 15:33:27 +0100 |
---|---|---|
committer | Francesco Giudici <fgiudici@redhat.com> | 2017-03-24 15:18:08 +0100 |
commit | bdd2e1c2aa0c8340743b307c3e78b38cda2a6934 (patch) | |
tree | d913973ba30f2606676e2c739e4ce082fbbd7a06 | |
parent | f20bdebae9b8979953938599f9f45ecc00f9cd6a (diff) | |
download | NetworkManager-bdd2e1c2aa0c8340743b307c3e78b38cda2a6934.tar.gz |
policy: try to retrieve hostname from dbus first
As we try to set the hostname through dbus, we should also try to
retrieve current hostname value from dbus first: otherwise we may end
retrieving the "old" hostname via gethostname while the dbus hostnamed
updated is pending.
-rw-r--r-- | src/nm-policy.c | 71 | ||||
-rw-r--r-- | src/settings/nm-settings.c | 22 | ||||
-rw-r--r-- | src/settings/nm-settings.h | 3 |
3 files changed, 78 insertions, 18 deletions
diff --git a/src/nm-policy.c b/src/nm-policy.c index d8e083572b..ff93c9853d 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -431,15 +431,54 @@ settings_set_hostname_cb (const char *hostname, nm_dispatcher_call_hostname (NULL, NULL, NULL); } +#define HOST_NAME_BUFSIZE (HOST_NAME_MAX + 2) + +static char * +_get_hostname (NMPolicy *self, char **hostname) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + char *buf; + + g_assert (hostname && *hostname == NULL); + + /* try to get the hostname via dbus... */ + if (nm_settings_get_transient_hostname (priv->settings, hostname)) { + _LOGT (LOGD_DNS, "gethostname: \"%s\" (from dbus)", *hostname); + return *hostname; + } + + /* ...or retrieve it by yourself */ + buf = g_malloc (HOST_NAME_BUFSIZE); + if (gethostname (buf, HOST_NAME_BUFSIZE -1) != 0) { + int errsv = errno; + + _LOGT (LOGD_DNS, "gethostname: couldn't get the system hostname: (%d) %s", + errsv, g_strerror (errsv)); + g_free (buf); + return NULL; + } + + /* the name may be truncated... */ + buf[HOST_NAME_BUFSIZE - 1] = '\0'; + if (strlen (buf) >= HOST_NAME_BUFSIZE -1) { + _LOGT (LOGD_DNS, "gethostname: system hostname too long: \"%s\"", buf); + g_free (buf); + return NULL; + } + + _LOGT (LOGD_DNS, "gethostname: \"%s\"", buf); + *hostname = buf; + return *hostname; +} + static void _set_hostname (NMPolicy *self, const char *new_hostname, const char *msg) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - char old_hostname[HOST_NAME_MAX + 1]; + gs_free char *old_hostname = NULL; const char *name; - int ret; /* The incoming hostname *can* be NULL, which will get translated to * 'localhost.localdomain' or such in the hostname policy code, but we @@ -484,19 +523,14 @@ _set_hostname (NMPolicy *self, } else name = new_hostname; - old_hostname[HOST_NAME_MAX] = '\0'; - errno = 0; - ret = gethostname (old_hostname, HOST_NAME_MAX); - if (ret != 0) { - _LOGW (LOGD_DNS, "couldn't get the system hostname: (%d) %s", - errno, strerror (errno)); - } else { - /* Don't set the hostname if it isn't actually changing */ - if (nm_streq (name, old_hostname)) - return; + /* Don't set the hostname if it isn't actually changing */ + if ( _get_hostname (self, &old_hostname) + && (nm_streq (name, old_hostname))) { + _LOGT (LOGD_DNS, "sethostname: already set to '%s' (%s)", name, msg); + return; } - _LOGI (LOGD_DNS, "setting system hostname to '%s' (%s)", name, msg); + _LOGI (LOGD_DNS, "sethostname: '%s' (%s)", name, msg); /* Ask NMSettings to update the transient hostname using its * systemd-hostnamed proxy */ @@ -2184,14 +2218,15 @@ constructed (GObject *object) { NMPolicy *self = NM_POLICY (object); NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - char hostname[HOST_NAME_MAX + 2]; + char *hostname = NULL; /* Grab hostname on startup and use that if nothing provides one */ - memset (hostname, 0, sizeof (hostname)); - if (gethostname (&hostname[0], HOST_NAME_MAX) == 0) { + if (_get_hostname (self, &hostname)) { /* only cache it if it's a valid hostname */ - if (*hostname && nm_utils_is_specific_hostname (hostname)) - priv->orig_hostname = g_strdup (hostname); + if (nm_utils_is_specific_hostname (hostname)) + priv->orig_hostname = hostname; + else + g_free (hostname); } priv->firewall_manager = g_object_ref (nm_firewall_manager_get ()); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index f738b4377a..afd1b0849c 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1685,6 +1685,28 @@ nm_settings_set_transient_hostname (NMSettings *self, info); } +gboolean +nm_settings_get_transient_hostname (NMSettings *self, char **hostname) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GVariant *v_hostname; + + if (!priv->hostname.hostnamed_proxy) + return FALSE; + + v_hostname = g_dbus_proxy_get_cached_property (priv->hostname.hostnamed_proxy, + "Hostname"); + if (!v_hostname) { + _LOGT ("transient hostname retrieval failed"); + return FALSE; + } + + *hostname = g_variant_dup_string (v_hostname, NULL); + g_variant_unref (v_hostname); + + return TRUE; +} + static gboolean write_hostname (NMSettingsPrivate *priv, const char *hostname) { diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 406e305767..7110a12ba8 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -132,4 +132,7 @@ void nm_settings_set_transient_hostname (NMSettings *self, NMSettingsSetHostnameCb cb, gpointer user_data); +gboolean nm_settings_get_transient_hostname (NMSettings *self, + char **hostname); + #endif /* __NM_SETTINGS_H__ */ |