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.
This commit is contained in:
Dan Williams 2013-08-08 15:54:32 -05:00
parent dd9cf657ef
commit b5170903c0
4 changed files with 50 additions and 11 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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);
}
}