summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Zaborowski <andrew.zaborowski@intel.com>2020-10-06 10:40:13 +0200
committerThomas Haller <thaller@redhat.com>2020-10-06 14:17:14 +0200
commit1c1f4a3b40bd2cb899fcb011c122014c06e148f3 (patch)
treeda33e2de07710904fe62bdc6e1ea97b902aa2d20
parentc2c68ce16992d48ded27f5f1d7fb024243944f7e (diff)
downloadNetworkManager-1c1f4a3b40bd2cb899fcb011c122014c06e148f3.tar.gz
iwd: Subscribe to object-added/removed ObjectManager signals
GDBusObjectManagerClient's interface-added and interface-removed signals are not emitted when the new interfaces are added to a completely new object or the removal results in the object disappearing. In other words one interface is never reported both through interface-added and object-added (or -removed) signals. This kind of makes sense but isn't documented explicitly so interface-added seemed to correspond to DBus InterfacesAdded signals which it doesn't. We need to watch for both kinds of signals and although most things work without us receiving the signals at all, it causes some race conditions. For example on hotplug, devices wouldn't transition to "disconnected" if a device was discovered by NMManager before it appeared on IWD's dbus interface because that scenario relied on the dbus signal.
-rw-r--r--src/devices/wifi/nm-iwd-manager.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c
index bdff20ac9f..6a56201440 100644
--- a/src/devices/wifi/nm-iwd-manager.c
+++ b/src/devices/wifi/nm-iwd-manager.c
@@ -632,6 +632,38 @@ interface_removed(GDBusObjectManager *object_manager,
}
static void
+object_added(GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data)
+{
+ GList *interfaces, *iter;
+
+ interfaces = g_dbus_object_get_interfaces(object);
+
+ for (iter = interfaces; iter; iter = iter->next) {
+ GDBusInterface *interface = G_DBUS_INTERFACE(iter->data);
+
+ interface_added(NULL, object, interface, user_data);
+ }
+
+ g_list_free_full(interfaces, g_object_unref);
+}
+
+static void
+object_removed(GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data)
+{
+ GList *interfaces, *iter;
+
+ interfaces = g_dbus_object_get_interfaces(object);
+
+ for (iter = interfaces; iter; iter = iter->next) {
+ GDBusInterface *interface = G_DBUS_INTERFACE(iter->data);
+
+ interface_removed(NULL, object, interface, user_data);
+ }
+
+ g_list_free_full(interfaces, g_object_unref);
+}
+
+static void
connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data)
{
NMIwdManager * self = user_data;
@@ -697,22 +729,6 @@ _om_has_name_owner(GDBusObjectManager *object_manager)
}
static void
-object_added(NMIwdManager *self, GDBusObject *object)
-{
- GList *interfaces, *iter;
-
- interfaces = g_dbus_object_get_interfaces(object);
-
- for (iter = interfaces; iter; iter = iter->next) {
- GDBusInterface *interface = G_DBUS_INTERFACE(iter->data);
-
- interface_added(NULL, object, interface, self);
- }
-
- g_list_free_full(interfaces, g_object_unref);
-}
-
-static void
release_object_manager(NMIwdManager *self)
{
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
@@ -852,12 +868,14 @@ got_object_manager(GObject *object, GAsyncResult *result, gpointer user_data)
"interface-removed",
G_CALLBACK(interface_removed),
self);
+ g_signal_connect(priv->object_manager, "object-added", G_CALLBACK(object_added), self);
+ g_signal_connect(priv->object_manager, "object-removed", G_CALLBACK(object_removed), self);
g_hash_table_remove_all(priv->known_networks);
objects = g_dbus_object_manager_get_objects(object_manager);
for (iter = objects; iter; iter = iter->next)
- object_added(self, G_DBUS_OBJECT(iter->data));
+ object_added(NULL, G_DBUS_OBJECT(iter->data), self);
g_list_free_full(objects, g_object_unref);