summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2014-11-03 23:25:23 +0100
committerLubomir Rintel <lkundrak@v3.sk>2014-11-03 23:32:49 +0100
commit7ee77d77bddd97310d772367ba9a70b1ef2b51e8 (patch)
tree0a23960c3edd9a38a0f8c87b613c9a3e9373f80c
parentcf54aeebc057b1358c5e01bc950ef65570646412 (diff)
downloadNetworkManager-7ee77d77bddd97310d772367ba9a70b1ef2b51e8.tar.gz
libnm: Complete activation when ActiveConnection abruptly disappears
A NMActiveConnection may disappear before a match with NMDevice is found. In such case recheck_pending_activations() would never call the activation callback and the client would hang indefinitely: libnm-Message: PC: (0x95bf088) NMManager:active-connections => '['/org/freedesktop/NetworkManager/ActiveConnection/225']' (ao / NMActiveConnection) libnm-Message: PC: (0x95bf088) NMManager:activating-connection => ''/'' (o / NMActiveConnection) libnm-Message: PC: (0x95d0a28) NMActiveConnection:state => '4' (u) libnm-Message: PC: (0x95d0a28) NMActiveConnection:devices => '[]' (ao / NMDevice) libnm-Message: PC: (0x95bf088) NMManager:active-connections => '[]' (ao / NMActiveConnection) *hang* Let's listen for active-connection-removed and tear down the activation with an error if the removed connection is one we're activating.
-rw-r--r--libnm/nm-manager.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c
index 2f243ceff2..20f1458f3e 100644
--- a/libnm/nm-manager.c
+++ b/libnm/nm-manager.c
@@ -742,6 +742,8 @@ typedef struct {
char *new_connection_path;
} ActivateInfo;
+static void active_removed (NMObject *object, NMActiveConnection *active, gpointer user_data);
+
static void
activate_info_complete (ActivateInfo *info,
NMActiveConnection *active,
@@ -749,6 +751,7 @@ activate_info_complete (ActivateInfo *info,
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager);
+ g_signal_handlers_disconnect_by_func (info->manager, G_CALLBACK (active_removed), info);
if (active)
g_simple_async_result_set_op_res_gpointer (info->simple, g_object_ref (active), g_object_unref);
else
@@ -836,6 +839,22 @@ activation_cancelled (GCancellable *cancellable,
}
static void
+active_removed (NMObject *object, NMActiveConnection *active, gpointer user_data)
+{
+ ActivateInfo *info = user_data;
+ GError *error = NULL;
+
+ if (strcmp (info->active_path, nm_object_get_path (NM_OBJECT (active))))
+ return;
+
+ error = g_error_new_literal (NM_CLIENT_ERROR,
+ NM_CLIENT_ERROR_FAILED,
+ _("Active connection could not be attached to the device"));
+ activate_info_complete (info, NULL, error);
+ g_clear_error (&error);
+}
+
+static void
activate_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
@@ -851,6 +870,9 @@ activate_cb (GObject *object,
G_CALLBACK (activation_cancelled), info);
}
+ g_signal_connect (info->manager, "active-connection-removed",
+ G_CALLBACK (active_removed), info);
+
recheck_pending_activations (info->manager);
} else {
g_dbus_error_strip_remote_error (error);