Commit graph

204 commits

Author SHA1 Message Date
Thomas Haller
fdf9614ba7
build: move "libnm-core/" to "src/" and split it
"libnm-core/" is rather complicated. It provides a static library that
is linked into libnm.so and NetworkManager. It also contains public
headers (like "nm-setting.h") which are part of public libnm API.

Then we have helper libraries ("libnm-core/nm-libnm-core-*/") which
only rely on public API of libnm-core, but are themself static
libraries that can be used by anybody who uses libnm-core. And
"libnm-core/nm-libnm-core-intern" is used by libnm-core itself.

Move "libnm-core/" to "src/". But also split it in different
directories so that they have a clearer purpose.

The goal is to have a flat directory hierarchy. The "src/libnm-core*/"
directories correspond to the different modules (static libraries and set
of headers that we have). We have different kinds of such modules because
of how we combine various code together. The directory layout now reflects
this.
2021-02-18 19:46:51 +01:00
Thomas Haller
4a50d5a448
libnm: add assertion in _dbus_handle_properties_changed()
(cherry picked from commit 3ceec9c6ac)
2021-02-15 10:24:33 +01:00
Thomas Haller
1db2314a73
libnm: fix tracking object state in NMClient cache
NMClient has a NMLDBusObject instance for each D-Bus object
that it sees. This object can be in different states, like that we
already saw it on D-Bus or that it is only referred to by another
property. Due to a bug, we would wrongly not update the state and
trigger an assertion.

Reproduce with python-dbusmock (commit e89e28bf1bc0254a1eb71b71cf68ef7a97d11e5b)
by running `pytest -v -s tests/test_networkmanager.py -k test_one_wifi_with_accesspoints`.
With LIBNM_CLIENT_DEBUG we get:

>>> libnm-dbus[96085]: <trace> [6464.06459] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: properties-changed: properties changed for interface org.freedesktop.NetworkManager.Device { {'ActiveConnection': <objectpath '/org/freedesktop/NetworkManager/ActiveConnection/0'>} }
    libnm-dbus[96085]: <trace> [6464.06459] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: properties-changed: set property org.freedesktop.NetworkManager.Device.ActiveConnection
    libnm-dbus[96085]: <trace> [6464.06459] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x01 linked
    libnm-dbus[96085]: <trace> [6464.06459] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x01 consumed
>>> libnm-dbus[96085]: <trace> [6464.06459] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: set D-Bus object state watched-only
    libnm-dbus[96085]: <trace> [6464.06459] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x02 linked
    libnm-dbus[96085]: <trace> [6464.06459] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager]: changed-type 0x02 linked
    libnm-dbus[96085]: <trace> [6464.06459] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x02 consumed
>>> libnm-dbus[96085]: <error> [6464.06459] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: property ActiveConnection references /org/freedesktop/NetworkManager/ActiveConnection/0 but object is not present on D-Bus
    libnm-dbus[96085]: <trace> [6464.06459] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager]: changed-type 0x02 consumed
    libnm-dbus[96085]: <trace> [6464.06460] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: properties-changed: properties changed for interface org.freedesktop.NetworkManager.Device { {'State': <uint32 100>} }
    libnm-dbus[96085]: <trace> [6464.06460] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: properties-changed: set property org.freedesktop.NetworkManager.Device.State
    libnm-dbus[96085]: <trace> [6464.06460] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x01 linked
    libnm-dbus[96085]: <trace> [6464.06460] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x01 consumed
    libnm-dbus[96085]: <trace> [6464.06460] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x02 linked
    libnm-dbus[96085]: <trace> [6464.06460] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager]: changed-type 0x02 linked
    libnm-dbus[96085]: <trace> [6464.06461] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x02 consumed
    libnm-dbus[96085]: <trace> [6464.06461] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager]: changed-type 0x02 consumed
    libnm-dbus[96085]: <trace> [6464.06462] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: properties-changed: properties changed for interface org.freedesktop.NetworkManager.Device { {'StateReason': <(uint32 100, uint32 0)>} }
    libnm-dbus[96085]: <trace> [6464.06462] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: properties-changed: set property org.freedesktop.NetworkManager.Device.StateReason
    libnm-dbus[96085]: <trace> [6464.06462] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x01 linked
    libnm-dbus[96085]: <trace> [6464.06462] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x01 consumed
    libnm-dbus[96085]: <trace> [6464.06462] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x02 linked
    libnm-dbus[96085]: <trace> [6464.06462] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager]: changed-type 0x02 linked
    libnm-dbus[96085]: <trace> [6464.06462] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/Devices/mock_WiFi2]: changed-type 0x02 consumed
    libnm-dbus[96085]: <trace> [6464.06462] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager]: changed-type 0x02 consumed
>>> libnm-dbus[96085]: <trace> [6464.06465] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: properties changed for interface org.freedesktop.NetworkManager.Connection.Active { {'Devices': <[objectpath '/org/freedesktop/NetworkManager/Devices/mock_WiFi2']>, 'Default6': <false>, 'Default': <true>, 'Type': <'802-11-wireless'>, 'Vpn': <false>, 'Connection': <objectpath '/org/freedesktop/NetworkManager/Settings/Mock_AP3'>, 'Master': <objectpath '/'>, 'SpecificObject': <objectpath '/org/freedesktop/NetworkManager/AccessPoint/Mock_AP3'>, 'Uuid': <'72757a57-8cb6-4052-a18f-4e2be4ba27d9'>, 'State': <uint32 2>, 'Id': <'AP_3'>} }
>>> here we lack "set D-Bus object state on-dbus"
    libnm-dbus[96085]: <trace> [6464.06465] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.Devices
    libnm-dbus[96085]: <trace> [6464.06465] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.Default6
    libnm-dbus[96085]: <trace> [6464.06465] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.Default
    libnm-dbus[96085]: <trace> [6464.06465] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.Type
    libnm-dbus[96085]: <trace> [6464.06465] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.Vpn
    libnm-dbus[96085]: <trace> [6464.06465] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.Connection
    libnm-dbus[96085]: <trace> [6464.06465] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.Master
    libnm-dbus[96085]: <trace> [6464.06465] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.SpecificObject
    libnm-dbus[96085]: <trace> [6464.06466] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.Uuid
    libnm-dbus[96085]: <trace> [6464.06466] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.State
    libnm-dbus[96085]: <trace> [6464.06466] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: interfaces-added: set property org.freedesktop.NetworkManager.Connection.Active.Id
    libnm-dbus[96085]: <trace> [6464.06466] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: changed-type 0x01 linked
    libnm-dbus[96085]: <trace> [6464.06466] nmclient[c9bf1eaa1f4b6c99]: [/org/freedesktop/NetworkManager/ActiveConnection/0]: changed-type 0x01 consumed
    Bail out! libnm:ERROR:libnm/nm-client.c:2863:_dbus_handle_obj_changed_dbus: assertion failed: (dbobj->obj_state >= NML_DBUS_OBJ_STATE_ON_DBUS)

Backtrace:

  #3  0x00007f0bd11173bf in g_assertion_message_expr
      (domain=domain@entry=0x7f0bd1576018 "libnm", file=file@entry=0x7f0bd1576006 "libnm/nm-client.c", line=line@entry=2863, func=func@entry=0x7f0bd157f1b0 <__func__.170> "_dbus_handle_obj_changed_dbus", expr=expr@entry=0x7f0bd157cba0 "dbobj->obj_state >= NML_DBUS_OBJ_STATE_ON_DBUS") at ../glib/gtestutils.c:2963
  #4  0x00007f0bd14959dd in _dbus_handle_obj_changed_dbus (self=self@entry=0x5612d4f5a130, log_context=<optimized out>) at libnm/nm-client.c:2863
  #5  0x00007f0bd1495c29 in _dbus_handle_changes (self=self@entry=0x5612d4f5a130, log_context=<optimized out>, allow_init_start_check_complete=allow_init_start_check_complete@entry=1)
      at libnm/nm-client.c:2909
  #6  0x00007f0bd1497e56 in _dbus_managed_objects_changed_cb
      (connection=<optimized out>, sender_name=<optimized out>, arg_object_path=<optimized out>, interface_name=<optimized out>, signal_name=<optimized out>, parameters=0x7f0bb800d720, user_data=0x5612d4f5a130) at libnm/nm-client.c:3172
  #7  0x00007f0bd132a8df in emit_signal_instance_in_idle_cb (data=data@entry=0x7f0bb8003700) at ../gio/gdbusconnection.c:3789
  #8  0x00007f0bd10f1b5b in g_idle_dispatch (source=source@entry=0x7f0bb8012260, callback=0x7f0bd132a860 <emit_signal_instance_in_idle_cb>, user_data=0x7f0bb8003700) at ../glib/gmain.c:5836
  #9  0x00007f0bd10f2a9f in g_main_dispatch (context=0x5612d4f4b630) at ../glib/gmain.c:3325
  #10 g_main_context_dispatch (context=0x5612d4f4b630) at ../glib/gmain.c:4043
  #11 0x00007f0bd1144a98 in g_main_context_iterate.constprop.0 (context=0x5612d4f4b630, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:4119
  #12 0x00007f0bd10f2163 in g_main_loop_run (loop=0x5612d4f4b720) at ../glib/gmain.c:4317
  #13 0x00005612d44b6543 in main (argc=7, argv=0x7fff4414f1d8) at clients/cli/nmcli.c:1036

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=982613
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/662

Fixes: ce0e898fb4 ('libnm: refactor caching of D-Bus objects in NMClient')
(cherry picked from commit e1e9abdf04)
2021-02-15 09:49:48 +01:00
Thomas Haller
9e743475b6
libnm: avoid assertion failure in _dbus_handle_properties_changed() for logging no properties
(cherry picked from commit 1f9622358a)
2021-02-15 09:49:48 +01:00
Thomas Haller
a38afcb1d9
all: add "libnm/nm-default-libnm.h" as replacement for "nm-default.h" 2021-02-09 12:38:18 +01:00
Thomas Haller
977ea352a0
all: update deprecated SPDX license identifiers
These SPDX license identifiers are deprecated ([1]). Update them.

[1] https://spdx.org/licenses/

  sed \
     -e '1 s%^/\* SPDX-License-Identifier: \(GPL-2.0\|LGPL-2.1\)+ \*/$%/* SPDX-License-Identifier: \1-or-later */%' \
     -e '1,2 s%^\(--\|#\|//\) SPDX-License-Identifier: \(GPL-2.0\|LGPL-2.1\)+$%\1 SPDX-License-Identifier: \2-or-later%' \
     -i \
     $(git grep -l SPDX-License-Identifier -- \
         ':(exclude)shared/c-*/' \
         ':(exclude)shared/n-*/' \
         ':(exclude)shared/systemd/src' \
         ':(exclude)src/systemd/src')
2021-01-05 09:46:21 +01:00
Thomas Haller
ef6edd8dbd
libnm: fix re-entrancy of NMClient.dispose() for _init_release_all()
GObject's dispose() functions may be called multiple times
to break reference cycles.

As dispose() calls _init_release_all(), the object might
already be partially destroyed.

Fixes: ce0e898fb4 ('libnm: refactor caching of D-Bus objects in NMClient')
2020-12-08 15:41:52 +01:00
Fernando Fernandez Mancera
23972add8c
libnm/trivial: rename enums NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_*
We will need more levels of priority. Change the naming
to make room for that.

  sed 's/NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_LOW/NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_10/g' `git grep -l NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_ ` -i
  sed 's/NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_LOW/NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_10/g' `git grep -l NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_ ` -i
  ./contrib/scripts/nm-code-format-container.sh

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>

[thaller@redhat.com: split original patch]
2020-11-18 10:21:57 +01:00
Beniamino Galvani
dfd2fcde0f shared: add c-list macros to iterate backwards 2020-11-16 16:43:39 +01:00
Thomas Haller
cc030b9112
all/trivial: rename local variable for user_data for nm_utils_user_data_unpack()
In almost all cases, the variable of this kind is named "user_data".
Rename it for consistency.
2020-10-22 15:14:44 +02:00
Thomas Haller
88071abb43
all: unify comment style for SPDX-License-Identifier tag
Our coding style recommends C style comments (/* */) instead of C++
(//). Also, systemd (which we partly fork) uses C style comments for
the SPDX-License-Identifier.

Unify the style.

  $ sed -i '1 s#// SPDX-License-Identifier: \([^ ]\+\)$#/* SPDX-License-Identifier: \1 */#' -- $(git ls-files -- '*.[hc]' '*.[hc]pp')
2020-09-29 16:50:53 +02:00
Thomas Haller
740b092fda
format: replace tabs for indentation in code comments
sed -i \
     -e 's/^'$'\t'' \*/     */g' \
     -e 's/^'$'\t\t'' \*/         */g' \
     -e 's/^'$'\t\t\t'' \*/             */g' \
     -e 's/^'$'\t\t\t\t'' \*/                 */g' \
     -e 's/^'$'\t\t\t\t\t'' \*/                     */g' \
     -e 's/^'$'\t\t\t\t\t\t'' \*/                         */g' \
     -e 's/^'$'\t\t\t\t\t\t\t'' \*/                             */g' \
     $(git ls-files -- '*.[hc]')
2020-09-28 16:07:52 +02:00
Antonio Cardace
328fb90f3e
all: reformat all with new clang-format style
Run:

    ./contrib/scripts/nm-code-format.sh -i
    ./contrib/scripts/nm-code-format.sh -i

Yes, it needs to run twice because the first run doesn't yet produce the
final result.

Signed-off-by: Antonio Cardace <acardace@redhat.com>
2020-09-28 16:07:51 +02:00
Thomas Haller
b8811d97a4
all: require a semicolon after NM_CACHED_QUARK_FCN() 2020-09-23 10:55:17 +02:00
Thomas Haller
e2fba6c4b3
libnm: trace log the call and the completion event for D-Bus methods 2020-07-15 12:39:50 +02:00
Thomas Haller
39264bdb13
libnm: add trace logging for D-Bus calls
libnm-dbus: <trace> [394618.09943] nmclient[97de7f355f14dfa9]: call D-Bus method on :1.17: /org/freedesktop/NetworkManager/Settings/17, org.freedesktop.NetworkManager.Settings.Connection.GetSettings -> (a{sa{sv}}) (())
2020-07-15 11:20:47 +02:00
Yuri Chornoivan
4e33f8cd89
all: fix minor typos
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/565
2020-07-07 11:33:46 +02:00
Sayed Shah
7337ab8959
all: fix typo in man pages
There should be a comma after 'Otherwise' and 'Currently'.

https://bugzilla.redhat.com/show_bug.cgi?id=1852452

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/560
2020-07-03 10:48:04 +02:00
Beniamino Galvani
d0a2eb8f05 libnm: fix wrong assertion in nm_client_check_connectivity_finish()
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/476

Fixes: b44d883d92 ('libnm: implement nm_client_check_connectivity_async() by using GDBusConnection directly')
2020-06-25 14:11:36 +02:00
Thomas Haller
7b9cb1f952
libnm: fix documentation for value argument of nm_client_dbus_call()
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/451
2020-05-22 08:51:21 +02:00
Thomas Haller
da757f80cc libnm/doc: fix spelling in nm_client_add_and_activate_connection2() documentation
(cherry picked from commit c8a9703130)
2020-04-28 18:36:47 +02:00
Thomas Haller
06da903bb6 libnm: advise using D-Bus instead of deprecated synchronous methods
With 1.22, various synchronous functions for invoking D-Bus methods were
deprecated. The reason was that D-Bus is fundamentally asynchronous, and
providing synchronous API in NMClient is inherently wrong. That is
because NMClient essentially is a cache of the D-Bus API, and invoking
g_dbus_connection_call_sync() messes up the order of events from D-Bus.
In particular, when the synchronous function completes, the content of
the cache does not yet reflect the change.

Since they got deprecated, the question is with what to replace them.

Instead of adding a (e.g.) nm_client_networking_set_enabled_async()
for nm_client_networking_set_enabled(), just expect the user to call
D-Bus directly.

D-Bus itself defines a reasonable API, and with GDBusConnection it
is fine (and convenient) to just call D-Bus operations directly.
Often libraries try to abstract D-Bus by providing convenience
wrappers around D-Bus API. I think that often is wrong and unnecessary.

Note that libnm's NMClient does a lot more than just wrapping simple
D-Bus calls. It provides a complete client-side cache of the D-Bus
interface. As such, what libnm's NMClient does is more than simple
wrappers around D-Bus. NMClient is a reasonable thing to do.

However, it is unnecessary to add API like nm_client_networking_set_enabled_async()
that only calls g_dbus_connection_call(). Don't pretend that we would need such
trivial wrappers in libnm.

Instead, recommend to use g_dbus_connection_call(). Or alternatively,
the convenience wrappers nm_client_dbus_call() and
nm_client_dbus_set_property().
2020-03-23 09:33:51 +01:00
Thomas Haller
a7b8c82ee2 libnm: add nm_client_dbus_set_property() API
Similar to nm_client_dbus_call(), but useful for setting a D-Bus
property on NetworkManager's D-Bus interface.

Note that we currently have various synchronous API for setting D-Bus
properties (like nm_client_networking_set_enabled()). Synchronous
API does not play well with the content of NMClient's cache, and was
thus deprecated. However, until now no async variant exists.

Instead of adding multiple async operations, I think it should be
sufficient to only add one nm_client_dbus_set_property() property.
It's still reasonably convenient to use for setting a property.
2020-03-23 09:33:01 +01:00
Thomas Haller
1a36bdbb2c libnm: add nm_client_dbus_call() API
Add an API for calling D-Bus methods arbitrary objects of
NetworkManager's API.

Of course, this is basically just a call to g_dbus_connection_call(),
using the current name owner, nm_client_get_dbus_connection() and
nm_client_get_main_context().

All of this could also be achieved without this new API. However,
nm_client_dbus_call() also gracefully handles if the current name
owner is %NULL.

It's a valid concern whether such API is useful, as the users already
have all pieces to do it themself. I think it is.
2020-03-23 09:32:04 +01:00
Thomas Haller
61615781c5 libnm/doc: fix gtk-doc for deprecated markers in libnm 2020-03-23 09:32:04 +01:00
Thomas Haller
cd31437024 shared: drop _STATIC variant of macros that define functions
Several macros are used to define function. They had a "_STATIC" variant,
to define the function as static.

I think those macros should not try to abstract entirely what they do.
They should not accept the function scope as argument (or have two
variants per scope). This also because it might make sense to add
additional __attribute__(()) to the function. That only works, if
the macro does not pretend to *not* define a plain function.

Instead, embrace what the function does and let the users place the
function scope as they see fit.

This also follows what is already done with

    static NM_CACHED_QUARK_FCN ("autoconnect-root", autoconnect_root_quark)
2020-02-13 17:17:07 +01:00
Thomas Haller
53f6858a27 all: add nm_utils_error_is_cancelled() and nm_utils_error_is_cancelled_or_disposing()
Most callers would pass FALSE to nm_utils_error_is_cancelled(). That's
not very useful. Split the two functions and have nm_utils_error_is_cancelled()
and nm_utils_error_is_cancelled_is_disposing().
2020-02-10 19:11:50 +01:00
Thomas Haller
425412a363 libnm: hide NMActiveConnection until NMRemoteConnection is ready
Generally, libnm's NMClient cache only wants to expose NMObjects that
are fully initalized. Most objects don't require anything special,
except NMRemoteConnection which waits for the GetSettings() call to complete.

NMObjects reference each other. For example, NMActiveConnection
references NMDevice and NMRemoteConnection. There is a desire that an
object is only ready, if the objects that it references are ready too.
In practice that is not done, because usually every objects references
other objects, that means all objects would be declared as non-ready
as long as any of them is still initializing. That does not seem
desirable. Instead, most objects (except NMRemoteConnection and now
NMActiveConnection) are considered ready and visible, once their first
notification completes. In case the objects reference any object that is
not yet ready, the references is NULL (but the source object is visible
already). This is also done this way, to cope with cycles where
objects reference each other. In practice, such cycles should not be
exposed by NetworkManager. However, libnm should be robust against that.

This has the undesired effect that when you call AddAndActivate(), then
the NMActiveConnection might already be visible while its
NMRemoteConnection isn't. That means, ac.get_connection() will
initially return NULL, until the remote connection becomes ready.
Also add a special handling that NMActiveConnection waits for their
NMRemoteConnection to be ready, before being ready itself.

Fixes: ce0e898fb4 ('libnm: refactor caching of D-Bus objects in NMClient')
2020-02-10 19:02:42 +01:00
Thomas Haller
6b745e0725 libnm: minor cleanup of libnm trace logging 2020-02-10 19:02:42 +01:00
Thomas Haller
0382e54d8d libnm: expose nml_cleanup_context_busy_watcher_on_idle() helper for reuse
This can be used by NMSecretAgentOld.
2020-01-28 10:54:14 +01:00
Thomas Haller
587c35b1f4 libnm: factor out nml_init_data_return() for reuse 2020-01-28 10:54:14 +01:00
Thomas Haller
718e524a7f libnm: move InitData to nm-libnm-utils.h for sharing
It can be reused.
2020-01-28 10:54:14 +01:00
Thomas Haller
50bda649b1 libnm: expose nm_context_busy_watcher_integrate_source() as internal API for reuse
This will also be useful for NMSecretAgentOld.

The mechanics how NMClient handles the GMainContext and the
context-busy-watcher apply really to every GObject that uses
GDBusConnection and registers to signals.

At least, as long as the API provides no shutdown/stop method,
because that means shutdown/stop happens when unreferencing the
instance, at which point pending operations get cancelled (but
they cannot complete right away due to the nature of GTask and
g_dbus_connection_call()). If there is a shutdown/stop API, then all
pending operations could keep the instance alive, and the instance
would sticks around (and keeps the GMainContext busy) until shutdown is
completed. Basically, then the instance could be the context-busy-watcher
itself.

But in existing API which does not require the user to explicitly shutdown,
that is not a feasible (backward compatible) addition. But the context-busy-watcher
object is.
2020-01-28 10:54:14 +01:00
Thomas Haller
2c4f57be19 libnm: log message when NMClient gets disposed
This is useful as a last message to know when the instance is gone
for good.
2020-01-28 10:54:14 +01:00
Thomas Haller
c2f8400e66 libnm: fix another leak when cleaning up NMClient
We now move the deletion of the context-busy-watcher to and idle handler
on the D-Bus GMainContext.

Note that the idle source does not take an additional reference on the
context. Hence, in certain cases it might happen that the context will
be completely unrefed before the idle handler runs. In that case, we
would leak the object.

Avoid that, by taking an additional reference to the GMainContext.

Note that the alternative would be to unref the context-busy-watcher
via the GSource's GDestroyNotify. That is not done, because then the
busy watcher might be unrefed in a different thread. Instead, we want
that to happen for the right context. The only minor downside of this
is that the user now always pays the price and must iterate the context
to fully clean up. But note that the user anyway must be prepared to
iterate the context after NMClient is gone. And that depends on some
unpredictable events that the user cannot control. That means, either
the user handles this correctly already, or the problem anyway exists
(randomly).

Of course all of the discussed "problems" are very specific. In practice, the
users uses the g_main_context_default() instance and anyway will either
keep iterating it or quit the process after the NMClient instance goes
away.
2020-01-16 14:43:29 +01:00
Thomas Haller
b572c0542a libnm: keep context-busy-watcher of NMClient alive for one more idle round
The context-busy-watch has two purposes:

1) it allows the user to watch whether the NMClient still has pending
  GSource'es attached to the GMainContext.
2) thereby, it also keeps the inner GMainContext integrated into the
  caller's (in case of synchronous initialization of NMClient).

Especially for 2), we must not get this wrong. Otherwise, we might
un-integrate the inner GMainContext too early and it will be leaked
indefinitely (because the user has no means to access or iterate it).

To be extra careful, extend the lifetime of the context-busy-watcher
for one more idle invocation. Theoretically, this should not be necessary,
but it's not clear whether something else is still pending.

The downside of that extra safety is that it is probably unnecessary in
practice. And in case where it is necessary, it hides an actual
issue, making it harder to notice and fix it.
2020-01-16 12:44:56 +01:00
Thomas Haller
a2fd2ab55d shared: remove nm_dbus_connection_signal_subscribe_object_manager() helper
It seems to complicate things more than helping. Drop it. What we still have
is a wrapper around plain g_dbus_connection_signal_subscribe(). That one is
trivial and helpful. The previous wrapper seems to add more complexity.
2020-01-16 12:42:41 +01:00
Thomas Haller
e280124757 libnm: avoid leaking GMainContext for sync initialization after context-busy-watcher quits
When passing a destroy notify to g_dbus_connection_signal_subscribe(),
that callback gets invoked as an idle handler of the associated
GMainContext. That caused to have yet another source attached to the
context after the NMClient gets destroyed.

Especially with synchronous initialization of NMClient that is bad,
because we may destroy the context-busy-watcher too early. That results
in removing the integration of the inner GMainContext into the caller's
context, and thus we leak the inner context indefinitely.

Avoid that leak by not passing a cleanup function to
g_dbus_connection_signal_subscribe().

Fixes: ce0e898fb4 ('libnm: refactor caching of D-Bus objects in NMClient')
2020-01-16 12:42:41 +01:00
Thomas Haller
51b39ceb33 libnm: fix wrong assertion in nm_client_add_and_activate_connection2_finish()
Fixes: ce0e898fb4 ('libnm: refactor caching of D-Bus objects in NMClient')
2020-01-15 12:32:02 +01:00
Thomas Haller
900af25263 client: add nm_client_get_object_by_path() and nm_object_get_client() API
When iterating the GMainContext of the NMClient instance, D-Bus events
get processed. That means, every time you iterate the context (or "return to
the main loop"), the content of the cache might change completely.

It makes sense to keep a reference to an NMObject instance, do something,
and afterwards check whether the instance can still be found in the cache.

Add an API for that. nm_object_get_client() allows to know whether the
object is still cached.

Likewise, while NMClient abstracts D-Bus, it should still provide a way
to look up an NMObject by D-Bus path. Add nm_client_get_object_by_path()
for that.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/384
2020-01-08 18:33:10 +01:00
Thomas Haller
21b008d0ff libnm: add nm_client_get_capabilities() to expose server Capabilities
I hesitated to add this to libnm, because it's hardly used.

However, we already fetch the property during GetManagedObjects(),
we we should make it accessible, instead of requiring the user to
make another D-Bus call.
2019-12-21 12:25:12 +01:00
Thomas Haller
3ae97cc543 libnm: emit property changed signal when setting NM_CLIENT_DBUS_CONNECTION 2019-12-18 17:13:27 +01:00
Thomas Haller
a33ed5ad82 libnm: allow to enable/disable fetching of permissions in NMClient
Currently, NMClient by default always fetches the permissions
("GetPermissions()") and refreshes them on "CheckPermissions" signal.

Fetching permissions is relatively expensive, while they are not used
most of the time. Allow the user to opt out of this.

For that, have a NMClientInstanceFlags to enable/disable automatic
fetching. Also add a "permissions-state" property that allows the user
to understand whether the cached permissions are up to date or not.

This is a bit an awkward API for handling this. E.g. you cannot
explicitly request permissions, you can just enable/disable fetching
permissions. And then you can watch the permission-state to know whether
you are ready. It's done this way because it fits the previous model
and extends the API with a (relative) small amount of new functions and
properties.
2019-12-10 09:17:17 +01:00
Thomas Haller
f7aeda0390 libnm: add NMClient:instance-flags property
Add a flags property to control behavior of NMClient.
Possible future use cases:

 - currently it would always automatically fetch permissions. Often that
   is not used and the user could opt out of it.

 - currently, using sync init creates an internal GMainContext. This
   has an overhead and may be undesirable. We could implement another
   "sync" initialization that would merely iterate the callers mainloop
   until the initialization completes. A flag would allow to opt in.

 - currently, NMClient always fetches all connection settings
   automatically. Via a flag the user could opt out of that.
   Instead NMClient could provide an API so the user can request
   settings as they are needed.
2019-12-10 07:53:25 +01:00
Thomas Haller
51bc2c0224 libnm: track permissions in NMClient as an array of well known permissions
On D-Bus, the permission names are just the PolicyKit action names, like
"org.freedesktop.NetworkManager.wifi.scan". But NMClient already
ignores all strings that it doesn't know at compile time and only
keeps track of well known permission.

And neither does the API nm_client_get_permissions_result() allow to
expose permissions unknown to libnm.

Maybe the API of NMClient should be more generic and allow exposing
any permissions announced by NetworkManager. As it is however, it's
not necessary to track the permissions in a hash table. An array with
fixed indices is sufficient.
2019-12-10 07:53:25 +01:00
Thomas Haller
b7462b1910 libnm,shared: move nm_permission_result_to_client() to shared's nm_client_permission_result_from_string() 2019-12-10 07:53:25 +01:00
Thomas Haller
bfdd352a61 libnm,cli: cleanup mapping between NMClientPermission and strings 2019-12-10 07:53:25 +01:00
Thomas Haller
53db3a2da9 libnm: don't emit property changed "notify" signal while destructing NMClient
It seems to trip up gnome-control-center (rh #1778668). Just don't emit
anymore signals once NMClient goes down.
2019-12-03 14:50:18 +01:00
Thomas Haller
61807e9b6b libnm: add assertion for object returned by nm_device_get_active_connection()
I have a coredump that seems to indicate that nm_device_get_active_connection()
did not return a valid object. Let's add an assertion, trying to identify the
issue earlier. Aside from that, this change isn't useful, but an nm_assert()
shouldn't hurt anyway.
2019-11-28 12:47:07 +01:00
Thomas Haller
81bd50874b libnm: add nm_client_get_main_context() function
The NMClient is associated with a certain context. Add a getter
function to give the context.

The context is really not internal API of NMClient, that is because
the user must iterate this context and be aware of it.
2019-11-26 13:37:38 +01:00