summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2013-09-25 19:03:17 +0200
committerThomas Haller <dcbw@redhat.com>2013-09-26 16:40:01 +0200
commit814c8c57460303d185c7619af54e5fad063cd0e8 (patch)
tree32700418c8787c78de6b73239e28fc7bd5efc742
parent25c310af176922e224706ccfcf1b8b38d3c55f33 (diff)
downloadNetworkManager-th/bgo532815_hostname.tar.gz
cfg: add reading/setting the hostname in NM core as fallback (bgo #699458)th/bgo532815_hostname
Add reading and writing the hostname to /etc/hostname as fallback in nm-settings. https://bugzilla.gnome.org/show_bug.cgi?id=699458 Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r--src/settings/nm-settings.c122
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.c10
2 files changed, 100 insertions, 32 deletions
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 0a5123f29a..566a4ec9aa 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -31,6 +31,7 @@
#include <pwd.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
+#include <gio/gio.h>
#include <NetworkManager.h>
#include <nm-connection.h>
@@ -135,6 +136,9 @@ typedef struct {
gboolean connections_loaded;
GHashTable *connections;
GSList *unmanaged_specs;
+
+ char *hostname_cache;
+ GFileMonitor *hostname_monitor;
} NMSettingsPrivate;
#define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate))
@@ -170,6 +174,67 @@ plugin_connection_added (NMSystemConfigInterface *config,
claim_connection (NM_SETTINGS (user_data), connection, TRUE);
}
+
+#define HOSTNAME_FILE "/etc/hostname"
+
+static gboolean
+hostname_reload (NMSettings *self)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+ char *hostname = NULL;
+
+ /* Select the hostname returned from the first plugin that provides one. */
+ for (iter = priv->plugins; iter; iter = iter->next) {
+ NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
+
+ g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
+ if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
+ g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL);
+ if (hostname && *hostname)
+ goto END;
+ g_free (hostname);
+ }
+ }
+
+ /* as fallback, try to read the HOSTNAME_FILE... */
+ if (g_file_get_contents (HOSTNAME_FILE, &hostname, NULL, NULL)) {
+ g_strchomp (hostname);
+ if (!*hostname) {
+ g_free (hostname);
+ hostname = NULL;
+ }
+ }
+
+END:
+ if (g_strcmp0 (priv->hostname_cache, hostname) == 0) {
+ g_free (hostname);
+ return FALSE;
+ }
+
+ g_free (priv->hostname_cache);
+ priv->hostname_cache = hostname;
+ return TRUE;
+}
+
+
+static void
+hostname_changed (NMSettings *self)
+{
+ if (hostname_reload (self))
+ g_object_notify (G_OBJECT (self), NM_SETTINGS_HOSTNAME);
+}
+
+static void
+hostname_changed_monitor (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ hostname_changed (NM_SETTINGS (user_data));
+}
+
static void
load_connections (NMSettings *self)
{
@@ -437,30 +502,14 @@ get_plugin (NMSettings *self, guint32 capability)
return NULL;
}
+
/* Returns an allocated string which the caller owns and must eventually free */
char *
nm_settings_get_hostname (NMSettings *self)
{
- NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
- GSList *iter;
- char *hostname = NULL;
-
- /* Hostname returned is the hostname returned from the first plugin
- * that provides one.
- */
- for (iter = priv->plugins; iter; iter = iter->next) {
- NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
-
- g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
- if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
- g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL);
- if (hostname && strlen (hostname))
- return hostname;
- g_free (hostname);
- }
- }
+ g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
- return NULL;
+ return g_strdup (NM_SETTINGS_GET_PRIVATE (self)->hostname_cache);
}
static gboolean
@@ -505,11 +554,11 @@ unmanaged_specs_changed (NMSystemConfigInterface *config,
}
static void
-hostname_changed (NMSystemConfigInterface *config,
- GParamSpec *pspec,
- gpointer user_data)
+hostname_changed_plugin (NMSystemConfigInterface *config,
+ GParamSpec *pspec,
+ gpointer user_data)
{
- g_object_notify (G_OBJECT (user_data), NM_SETTINGS_HOSTNAME);
+ hostname_changed (NM_SETTINGS (user_data));
}
static void
@@ -526,7 +575,7 @@ add_plugin (NMSettings *self, NMSystemConfigInterface *plugin)
priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin));
- g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self);
+ g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed_plugin), self);
nm_system_config_interface_init (plugin, NULL);
@@ -1673,6 +1722,9 @@ nm_settings_new (GError **error)
return NULL;
}
+ /* force reload of the hostname */
+ hostname_changed (self);
+
unmanaged_specs_changed (NULL, self);
nm_dbus_manager_register_object (priv->dbus_mgr, NM_DBUS_PATH_SETTINGS, self);
@@ -1691,12 +1743,22 @@ connection_provider_init (NMConnectionProvider *cp_class)
static void
nm_settings_init (NMSettings *self)
{
+ GFile *file;
+ GFileMonitor *monitor;
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
priv->session_monitor = nm_session_monitor_get ();
+ file = g_file_new_for_path (HOSTNAME_FILE);
+ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (file);
+ if (monitor) {
+ g_signal_connect (monitor, "changed", G_CALLBACK (hostname_changed_monitor), self);
+ priv->hostname_monitor = monitor;
+ }
+
/* Hold a reference to the agent manager so it stays alive; the only
* other holders are NMSettingsConnection objects which are often
* transient, and we don't want the agent manager to get destroyed and
@@ -1714,14 +1776,20 @@ dispose (GObject *object)
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
+ if (priv->hostname_monitor) {
+ g_signal_handlers_disconnect_by_func (priv->hostname_monitor, G_CALLBACK (hostname_changed_monitor), self);
+ g_file_monitor_cancel (priv->hostname_monitor);
+ g_clear_object (&priv->hostname_monitor);
+ }
+
for (iter = priv->auths; iter; iter = g_slist_next (iter))
nm_auth_chain_unref ((NMAuthChain *) iter->data);
g_slist_free (priv->auths);
priv->dbus_mgr = NULL;
- g_object_unref (priv->session_monitor);
- g_object_unref (priv->agent_mgr);
+ g_clear_object (&priv->session_monitor);
+ g_clear_object (&priv->agent_mgr);
G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object);
}
@@ -1739,6 +1807,8 @@ finalize (GObject *object)
g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
g_slist_free (priv->plugins);
+ g_free (priv->hostname_cache);
+
G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object);
}
diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c
index dbfc496fd4..be3d4b21f5 100644
--- a/src/settings/plugins/ifcfg-rh/plugin.c
+++ b/src/settings/plugins/ifcfg-rh/plugin.c
@@ -831,11 +831,10 @@ dispose (GObject *object)
}
if (priv->hostname_monitor) {
- if (priv->hostname_monitor_id)
- g_signal_handler_disconnect (priv->hostname_monitor, priv->hostname_monitor_id);
+ g_signal_handler_disconnect (priv->hostname_monitor, priv->hostname_monitor_id);
g_file_monitor_cancel (priv->hostname_monitor);
- g_object_unref (priv->hostname_monitor);
+ g_clear_object (&priv->hostname_monitor);
}
g_free (priv->hostname);
@@ -846,11 +845,10 @@ dispose (GObject *object)
}
if (priv->ifcfg_monitor) {
- if (priv->ifcfg_monitor_id)
- g_signal_handler_disconnect (priv->ifcfg_monitor, priv->ifcfg_monitor_id);
+ g_signal_handler_disconnect (priv->ifcfg_monitor, priv->ifcfg_monitor_id);
g_file_monitor_cancel (priv->ifcfg_monitor);
- g_object_unref (priv->ifcfg_monitor);
+ g_clear_object (&priv->ifcfg_monitor);
}
G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);