From b5170903c0c5bdb5fb3820822aa0d57b3e11cf8f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 8 Aug 2013 15:54:32 -0500 Subject: [PATCH] settings: correctly handle connection deletion after unsaved and monitor-connection-files Plugins that could save connections to disk previously depended on inotify events from the kernel to know when to signal connection removal; that is in response to a 'delete' request they would unlink the backing filesystem resources, get the inotify signal, and cause NM_SETTINGS_CONNECTION_REMOVED to be emitted. Unsaved connections don't have any backing resources, so they would never get the signal emitted, and NMSettings would never forget about them. Also, when monitor-connection-files=false in the configuration, obviously the inotify signals will never come in because they aren't set up. Given that we can no longer rely on inotify, it's best to just explicitly send out the NM_SETTINGS_CONNECTION_REMOVED signal whenever a connection is deleted via the D-Bus interface or internally. --- src/settings/nm-settings-connection.c | 3 +++ src/settings/plugins/ifcfg-rh/plugin.c | 10 ++++++++ src/settings/plugins/ifnet/plugin.c | 34 +++++++++++++++++--------- src/settings/plugins/keyfile/plugin.c | 14 +++++++++++ 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index dcca265ec4..03c46d692a 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -624,7 +624,10 @@ do_delete (NMSettingsConnection *connection, /* Remove connection from seen-bssids database file */ remove_entry_from_db (connection, "seen-bssids"); + nm_settings_connection_signal_remove (connection); + callback (connection, NULL, user_data); + g_object_unref (connection); } diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c index b7a8751943..dbfc496fd4 100644 --- a/src/settings/plugins/ifcfg-rh/plugin.c +++ b/src/settings/plugins/ifcfg-rh/plugin.c @@ -115,6 +115,13 @@ connection_ifcfg_changed (NMIfcfgConnection *connection, gpointer user_data) connection_new_or_changed (plugin, path, connection, NULL); } +static void +connection_removed_cb (NMSettingsConnection *obj, gpointer user_data) +{ + g_hash_table_remove (SC_PLUGIN_IFCFG_GET_PRIVATE (user_data)->connections, + nm_connection_get_uuid (NM_CONNECTION (obj))); +} + static NMIfcfgConnection * _internal_new_connection (SCPluginIfcfg *self, const char *path, @@ -148,6 +155,9 @@ _internal_new_connection (SCPluginIfcfg *self, g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection))), connection); PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid); + g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connection_removed_cb), + self); if (nm_ifcfg_connection_get_unmanaged_spec (connection)) { const char *spec; diff --git a/src/settings/plugins/ifnet/plugin.c b/src/settings/plugins/ifnet/plugin.c index 169110643a..93ee9305b0 100644 --- a/src/settings/plugins/ifnet/plugin.c +++ b/src/settings/plugins/ifnet/plugin.c @@ -222,6 +222,24 @@ cancel_monitors (NMIfnetConnection * connection, gpointer user_data) } } +static void +connection_removed_cb (NMSettingsConnection *obj, gpointer user_data) +{ + g_hash_table_remove (SC_PLUGIN_IFNET_GET_PRIVATE (user_data)->connections, + nm_connection_get_uuid (NM_CONNECTION (obj))); +} + +static void +track_new_connection (SCPluginIfnet *self, NMIfnetConnection *connection) +{ + g_hash_table_insert (SC_PLUGIN_IFNET_GET_PRIVATE (self)->connections, + (gpointer) nm_connection_get_uuid (NM_CONNECTION (connection)), + g_object_ref (connection)); + g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connection_removed_cb), + self); +} + static void reload_connections (NMSystemConfigInterface *config) { @@ -286,11 +304,7 @@ reload_connections (NMSystemConfigInterface *config) PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Auto refreshing %s", conn_name); nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (old)); - g_hash_table_remove (priv->connections, - nm_connection_get_uuid (NM_CONNECTION (old))); - g_hash_table_insert (priv->connections, - (gpointer) nm_connection_get_uuid (NM_CONNECTION (new)), - g_object_ref (new)); + track_new_connection (self, new); if (is_managed_plugin () && is_managed (conn_name)) g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new); } @@ -308,9 +322,7 @@ reload_connections (NMSystemConfigInterface *config) } g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); } else if (new) { - g_hash_table_insert (priv->connections, - (gpointer) nm_connection_get_uuid (NM_CONNECTION (new)), - g_object_ref (new)); + track_new_connection (self, new); if (is_managed_plugin () && is_managed (conn_name)) g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new); } @@ -361,9 +373,9 @@ add_connection (NMSystemConfigInterface *config, } else { new = nm_ifnet_connection_new (source, NULL); if (new) { - g_hash_table_insert (priv->connections, - (gpointer) nm_connection_get_uuid (NM_CONNECTION (new)), - new); + track_new_connection (SC_PLUGIN_IFNET (config), new); + /* track_new_connection refs 'new' */ + g_object_unref (new); } } diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c index 9b54fe75b1..e9041bf6a1 100644 --- a/src/settings/plugins/keyfile/plugin.c +++ b/src/settings/plugins/keyfile/plugin.c @@ -69,6 +69,13 @@ typedef struct { gboolean disposed; } SCPluginKeyfilePrivate; +static void +connection_removed_cb (NMSettingsConnection *obj, gpointer user_data) +{ + g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (user_data)->connections, + nm_connection_get_uuid (NM_CONNECTION (obj))); +} + static NMSettingsConnection * _internal_new_connection (SCPluginKeyfile *self, const char *full_path, @@ -83,6 +90,9 @@ _internal_new_connection (SCPluginKeyfile *self, g_hash_table_insert (priv->connections, (gpointer) nm_connection_get_uuid (NM_CONNECTION (connection)), connection); + g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connection_removed_cb), + self); } return (NMSettingsConnection *) connection; @@ -198,6 +208,10 @@ new_connection (SCPluginKeyfile *self, (gpointer) nm_connection_get_uuid (NM_CONNECTION (tmp)), tmp); g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, tmp); + + g_signal_connect (tmp, NM_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connection_removed_cb), + self); } }