summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Giudici <fgiudici@redhat.com>2017-02-17 15:33:27 +0100
committerFrancesco Giudici <fgiudici@redhat.com>2017-03-24 15:18:08 +0100
commitbdd2e1c2aa0c8340743b307c3e78b38cda2a6934 (patch)
treed913973ba30f2606676e2c739e4ce082fbbd7a06
parentf20bdebae9b8979953938599f9f45ecc00f9cd6a (diff)
downloadNetworkManager-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.c71
-rw-r--r--src/settings/nm-settings.c22
-rw-r--r--src/settings/nm-settings.h3
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__ */