diff options
author | Thomas Haller <thaller@redhat.com> | 2019-11-26 00:23:41 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-11-26 10:02:58 +0100 |
commit | 2078acfddc5400e77ae556e2f21403c1d5258f3d (patch) | |
tree | e81f2af7cbbc0ff3f13cd023b88a6c76a5e1a3f6 /libnm/libnm.ver | |
parent | ee52656ce34b827ba7bef0406786f35ab8646b65 (diff) | |
download | NetworkManager-2078acfddc5400e77ae556e2f21403c1d5258f3d.tar.gz |
libnm: fix leaking internal GMainContext for synchronously initialized NMClient
NMClient makes asynchronous D-Bus calls via g_dbus_connection_call().
This references the current GMainContext to later invoke the
asynchronous callback. Even when we cancel the asynchronous call,
the callback will still be invoked (later) to complete the request.
In particular this means when we destroy (unref) an NMClient, there
are quite possibly pending requests in the GMainContext. Although they
are cancelled, they keep the GMainContext alive.
With synchronous initialization, we have an internal GMainContext.
When we destroy the NMClient, we cannot just unhook the integrated
source, instead, we need to keep it integrated in the caller's main
context, as long as there are pending requests.
Add a mechanism to track those pending requests and fix the leak for the
internal GMainContext. Also expose the same mechanism to the user via a new
API called nm_client_get_context_busy_watcher(). This allows the user
to know when it can stop iterating the main context and when all
resources are reclaimed.
For example the following will lead to a crash:
for i in range(1,2000):
nmc = NM.Client.new(None)
This creates a number of NMClient instances and destroys them again.
Note that here the GMainContext is never iterated, because
synchronous initialization does not iterate the caller's context. So,
while we correctly unref and dispose the created NMClient instances,
there are pending requests left in the inner GMainContext. These pile
up and soon the program will crash because it runs out of file descriptors.
We can have a similar problem with asynchronous initialization, when
we create a new GMainContext per client, and don't iterate it after
we are done with the client.
Note that this patch does not avoid the problem in general. The problem
cannot be avoided, the user must iterate the main contex at some point.
Otherwise resources (memory and file descriptors) will be leaked.
Fixes: ce0e898fb476 ('libnm: refactor caching of D-Bus objects in NMClient')
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/347
Diffstat (limited to 'libnm/libnm.ver')
-rw-r--r-- | libnm/libnm.ver | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/libnm/libnm.ver b/libnm/libnm.ver index f2979443ac..4eeea730bf 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1636,6 +1636,7 @@ global: libnm_1_22_0 { global: + nm_client_get_context_busy_watcher; nm_client_get_dbus_connection; nm_client_get_dbus_name_owner; nm_client_get_metered; |