diff options
Diffstat (limited to 'src/settings/nm-settings.c')
| -rw-r--r-- | src/settings/nm-settings.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 9ed03f69..9d40b06e 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -151,6 +151,8 @@ typedef struct { GSList *unmanaged_specs; GSList *unrecognized_specs; GSList *get_connections_cache; + + gboolean startup_complete; } NMSettingsPrivate; #define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate)) @@ -175,11 +177,43 @@ enum { PROP_HOSTNAME, PROP_CAN_MODIFY, PROP_CONNECTIONS, + PROP_STARTUP_COMPLETE, LAST_PROP }; static void +check_startup_complete (NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GHashTableIter iter; + NMSettingsConnection *conn; + + if (priv->startup_complete) + return; + + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) { + if (!nm_settings_connection_get_ready (conn)) + return; + } + + priv->startup_complete = TRUE; + g_object_notify (G_OBJECT (self), NM_SETTINGS_STARTUP_COMPLETE); +} + +static void +connection_ready_changed (NMSettingsConnection *conn, + GParamSpec *pspec, + gpointer user_data) +{ + NMSettings *self = NM_SETTINGS (user_data); + + if (nm_settings_connection_get_ready (conn)) + check_startup_complete (self); +} + +static void plugin_connection_added (NMSystemConfigInterface *config, NMSettingsConnection *connection, gpointer user_data) @@ -772,6 +806,7 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated), self); g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated_by_user), self); g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_visibility_changed), self); + g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self); /* Forget about the connection internally */ g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections, @@ -784,6 +819,8 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) g_signal_emit_by_name (self, NM_CP_SIGNAL_CONNECTION_REMOVED, connection); g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTIONS); + check_startup_complete (self); + g_object_unref (connection); } @@ -850,6 +887,7 @@ claim_connection (NMSettings *self, GHashTableIter iter; gpointer data; char *path; + NMSettingsConnection *existing; g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); @@ -868,6 +906,23 @@ claim_connection (NMSettings *self, return; } + existing = nm_settings_get_connection_by_uuid (self, nm_connection_get_uuid (NM_CONNECTION (connection))); + if (existing) { + /* Cannot add duplicate connections per UUID. Just return without action and + * log a warning. + * + * This means, that plugins must not provide duplicate connections (UUID). + * In fact, none of the plugins currently would do that. + * + * But globaly, over different setting plugins, there could be duplicates + * without the individual plugins being aware. Don't handle that at all, just + * error out. That should not happen unless the admin misconfigured the system + * to create conflicting connections. */ + nm_log_warn (LOGD_SETTINGS, "plugin provided duplicate connection with UUID %s", + nm_connection_get_uuid (NM_CONNECTION (connection))); + return; + } + /* Read timestamp from look-aside file and put it into the connection's data */ nm_settings_connection_read_and_fill_timestamp (connection); @@ -889,6 +944,11 @@ claim_connection (NMSettings *self, g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE, G_CALLBACK (connection_visibility_changed), self); + if (!priv->startup_complete) { + g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_READY, + G_CALLBACK (connection_ready_changed), + self); + } /* Export the connection over D-Bus */ g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); @@ -1780,6 +1840,16 @@ cp_get_connection_by_uuid (NMConnectionProvider *provider, const char *uuid) /***************************************************************/ +gboolean +nm_settings_get_startup_complete (NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + + return priv->startup_complete; +} + +/***************************************************************/ + NMSettings * nm_settings_new (GError **error) { @@ -1800,6 +1870,7 @@ nm_settings_new (GError **error) } load_connections (self); + check_startup_complete (self); nm_dbus_manager_register_object (priv->dbus_mgr, NM_DBUS_PATH_SETTINGS, self); return self; @@ -1900,6 +1971,9 @@ get_property (GObject *object, guint prop_id, g_ptr_array_add (array, g_strdup (path)); g_value_take_boxed (value, array); break; + case PROP_STARTUP_COMPLETE: + g_value_set_boolean (value, nm_settings_get_startup_complete (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; |