summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-06-24 13:42:16 +0200
committerThomas Haller <thaller@redhat.com>2015-06-24 15:17:16 +0200
commitd48902e60597ac8acc82c65e21049d1efd295577 (patch)
tree22b1948ac94729192d0e2327b46d0c642ec302d7
parent84b5fa21ed04729d9ac9e02d07e06a7ab9eb9ba6 (diff)
downloadNetworkManager-d48902e60597ac8acc82c65e21049d1efd295577.tar.gz
core: delay handling of link-changed platform event in manager
Backtrace: NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1) NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE) #0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0 #1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0 #2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0 #3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040 #4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801 #5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6 #6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6 #7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0 #8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0 #9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0 #10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0 #11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0 #12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry= NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425 #13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704 #14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0) at platform/nm-linux-platform.c:1951 #15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491 #16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573 #17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588 #18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1) at platform/nm-linux-platform.c:1954 #19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753 #20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141 #21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437 #22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED) at devices/nm-device.c:1049 #23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781 #24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752 #25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128 #26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED) at devices/nm-device.c:8319 #27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343 #28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0 #29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0 #30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0 #31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
-rw-r--r--src/nm-manager.c73
1 files changed, 44 insertions, 29 deletions
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 6138ce2de5..f9a7e7c9f6 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -164,8 +164,6 @@ typedef struct {
NMConfig *config;
NMConnectivity *connectivity;
- int ignore_link_added_cb;
-
NMPolicy *policy;
NMDBusManager *dbus_mgr;
@@ -1032,12 +1030,6 @@ system_create_virtual_device (NMManager *self, NMConnection *connection, GError
goto out;
}
- /* Block notification of link added since we're creating the device
- * explicitly here, otherwise adding the platform/kernel device would
- * create it before this function can do the rest of the setup.
- */
- priv->ignore_link_added_cb++;
-
nm_owned = !nm_platform_link_get_by_ifname (NM_PLATFORM_GET, iface);
device = nm_device_factory_create_virtual_device_for_connection (factory,
@@ -1056,8 +1048,6 @@ system_create_virtual_device (NMManager *self, NMConnection *connection, GError
g_object_unref (device);
}
- priv->ignore_link_added_cb--;
-
out:
g_free (iface);
return device;
@@ -1878,10 +1868,8 @@ _register_device_factory (NMDeviceFactory *factory, gpointer user_data)
static void
platform_link_added (NMManager *self,
int ifindex,
- NMPlatformLink *plink,
- NMPlatformReason reason)
+ NMPlatformLink *plink)
{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMDeviceFactory *factory;
NMDevice *device = NULL;
GError *error = NULL;
@@ -1889,9 +1877,6 @@ platform_link_added (NMManager *self,
g_return_if_fail (ifindex > 0);
- if (priv->ignore_link_added_cb > 0)
- return;
-
if (nm_manager_get_device_by_ifindex (self, ifindex))
return;
@@ -1936,6 +1921,38 @@ platform_link_added (NMManager *self,
}
}
+typedef struct {
+ NMManager *self;
+ int ifindex;
+} PlatformLinkCbData;
+
+static gboolean
+_platform_link_cb_idle (PlatformLinkCbData *data)
+{
+ NMManager *self = data->self;
+
+ if (self) {
+ const NMPlatformLink *l;
+
+ l = nm_platform_link_get (NM_PLATFORM_GET, data->ifindex);
+ if (l) {
+ NMPlatformLink pllink;
+
+ pllink = *l; /* make a copy of the link instance */
+ platform_link_added (self, data->ifindex, &pllink);
+ } else {
+ NMDevice *device;
+
+ device = nm_manager_get_device_by_ifindex (self, data->ifindex);
+ if (device)
+ remove_device (self, device, FALSE, TRUE);
+ }
+ g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *) &data->self);
+ }
+ g_slice_free (PlatformLinkCbData, data);
+ return G_SOURCE_REMOVE;
+}
+
static void
platform_link_cb (NMPlatform *platform,
int ifindex,
@@ -1944,22 +1961,20 @@ platform_link_cb (NMPlatform *platform,
NMPlatformReason reason,
gpointer user_data)
{
+ PlatformLinkCbData *data;
+
switch (change_type) {
case NM_PLATFORM_SIGNAL_ADDED:
- platform_link_added (NM_MANAGER (user_data), ifindex, plink, reason);
- break;
- case NM_PLATFORM_SIGNAL_REMOVED: {
- NMManager *self = NM_MANAGER (user_data);
- NMDevice *device;
-
- device = nm_manager_get_device_by_ifindex (self, ifindex);
- if (device)
- remove_device (self, device, FALSE, TRUE);
+ case NM_PLATFORM_SIGNAL_REMOVED:
+ data = g_slice_new (PlatformLinkCbData);
+ data->self = NM_MANAGER (user_data);
+ data->ifindex = ifindex;
+ g_object_add_weak_pointer (G_OBJECT (data->self), (gpointer *) &data->self);
+ g_idle_add ((GSourceFunc) _platform_link_cb_idle, data);
break;
- }
- default:
+ default:
break;
- }
+ }
}
static void
@@ -1972,7 +1987,7 @@ platform_query_devices (NMManager *self)
links_array = nm_platform_link_get_all (NM_PLATFORM_GET);
links = (NMPlatformLink *) links_array->data;
for (i = 0; i < links_array->len; i++)
- platform_link_added (self, links[i].ifindex, &links[i], NM_PLATFORM_REASON_INTERNAL);
+ platform_link_added (self, links[i].ifindex, &links[i]);
g_array_unref (links_array);
}