We call _nmtst_exit() atexit(), which in turn calls g_test_assert_expected_messages().
We must not assert there against initialized tests.
$ ./src/platform/tests/monitor -h
Usage:
./src/platform/tests/monitor [OPTION...]
**
NetworkManager:ERROR:monitor.c:11:_nmtst_exit: assertion failed: (nmtst_initialized ())
Aborted (core dumped)
After the device is unrealized a lot of its properites are reset. Notably, it
doesn't have an ifindex anymore so there's nothing to unconfigure really. This
makes at least NMDeviceBond unhappy:
(bond device with a slave is removed externally)
NetworkManager[21022]: <info> (bond0): device state change: activated -> unmanaged (reason 'unmanaged') [100 10 3]
NetworkManager[21022]: nm_platform_link_release: assertion 'master > 0' failed
Program received signal SIGTRAP, Trace/breakpoint trap.
g_logv (log_domain=0x5555557592b1 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd370) at gmessages.c:1046
1046 g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
(gdb) bt
#0 0x00007ffff4ec88c3 in g_logv (log_domain=0x5555557592b1 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd370) at gmessages.c:1046
#1 0x00007ffff4ec8a3f in g_log (log_domain=log_domain@entry=0x5555557592b1 "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff4f3673d "%s: assertion '%s' failed")
at gmessages.c:1079
#2 0x00007ffff4ec8a79 in g_return_if_fail_warning (log_domain=log_domain@entry=0x5555557592b1 "NetworkManager", pretty_function=pretty_function@entry=0x55555575ea50 <__FUNCTION__.33801> "nm_platform_link_relea8
#3 0x000055555560559a in nm_platform_link_release (self=0x555555a27bb0 [NMLinuxPlatform], master=master@entry=0, slave=slave@entry=3) at platform/nm-platform.c:1326
#4 0x00005555555b506e in release_slave (device=<optimized out>, slave=0x555555b6d770 [NMDeviceEthernet], configure=<optimized out>) at devices/nm-device-bond.c:423
#5 0x00005555555dab7b in nm_device_master_release_one_slave (self=self@entry=0x555555bf0cc0 [NMDeviceBond], slave=0x555555b6d770 [NMDeviceEthernet], configure=configure@entry=1, reason=reason@entry=
NM_DEVICE_STATE_REASON_NOW_UNMANAGED) at devices/nm-device.c:1137
#6 0x00005555555dadb6 in nm_device_master_release_slaves (self=self@entry=0x555555bf0cc0 [NMDeviceBond]) at devices/nm-device.c:2344
#7 0x00005555555dd12f in nm_device_cleanup (self=self@entry=0x555555bf0cc0 [NMDeviceBond], reason=reason@entry=NM_DEVICE_STATE_REASON_NOW_UNMANAGED, cleanup_type=cleanup_type@entry=CLEANUP_TYPE_DECONFIGURE)
at devices/nm-device.c:9133
#8 0x00005555555de3ea in _set_state_full (self=self@entry=0x555555bf0cc0 [NMDeviceBond], state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=
NM_DEVICE_STATE_REASON_NOW_UNMANAGED, quitting=quitting@entry=0) at devices/nm-device.c:9510
#9 0x00005555555dedb7 in nm_device_state_changed (self=self@entry=0x555555bf0cc0 [NMDeviceBond], state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_NOW_UNMANAGED)
at devices/nm-device.c:9769
#10 0x00005555555e11b4 in nm_device_unrealize (self=self@entry=0x555555bf0cc0 [NMDeviceBond], remove_resources=remove_resources@entry=0, error=error@entry=0x7fffffffd788) at devices/nm-device.c:2062
#11 0x000055555565c9c5 in _platform_link_cb_idle (data=0x555555c6e2b0) at nm-manager.c:2055
#12 0x00007ffff4ec179a in g_main_context_dispatch (context=0x555555a226c0) at gmain.c:3109
#13 0x00007ffff4ec179a in g_main_context_dispatch (context=context@entry=0x555555a226c0) at gmain.c:3708
#14 0x00007ffff4ec1ae8 in g_main_context_iterate (context=0x555555a226c0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3779
#15 0x00007ffff4ec1dba in g_main_loop_run (loop=0x555555a22780) at gmain.c:3973
#16 0x00005555555b3e5f in main (argc=1, argv=0x7fffffffdb18) at main.c:488
Do the reporting in system_create_virtual_device() only. None of the callers
checked for errors and some of the callees did issue a warning despite also
passing back a GError.
Also, drop the return value. It didn't make much sense and was not used anyway.
Fixes this:
nmcli c add type bridge # Creates and realizes the device, autoconnects connection
nmcli c del bridge # Device unrealizes
nmcli c add type bridge # The new connection does not autoconnect, since the
# device stays unrealized
Older version of iproute2 fail to add the vxlan (e.g. on Ubuntu 12.04)
Running command: ip link add nm-test-device type vxlan id 42 dev nm-test-parent local 23.1.2.164 group 239.1.2.134 ttl 0 tos 00 dstport 4789 srcport 0 0 ageing 1245
Garbage instead of arguments "id ...". Try "ip link help".
Fallback using only platform.
Strangely on Ubuntu 12.04, when not setting the port range for a vxlan
device, kernel chooses
5: nm-test-device: <BROADCAST,MULTICAST> mtu 1450 qdisc noop state DOWN mode DEFAULT group default
link/ether 72:09:79:62:9c:45 brd ff:ff:ff:ff:ff:ff promiscuity 0
vxlan id 42 group 239.1.2.134 local 23.1.2.164 dev nm-test-parent srcport 32768 61000 dstport 4789 ageing 1245
An IPv6 address might have been added externally and the device is yet to
traverse to a connected state.
On the other hand, the externally added devices still traverse through
DISCONNECTED state and we don't want to attempt the LL addition there. Let's
check if the link still exists instead.
The macro EWOULDBLOCK is another name for EAGAIN; they are always the
same in the GNU C Library.
https://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Error-Codes.html
Otherwise, we would need a workaround for EWOULDBLOCK too, because
libnl maps that to NLE_FAILURE. So we would have to detect EAGAIN
as (nle == -NLE_FAILURE && errno == EWOULDBLOCK).
When the errno was accidentally set to EAGAIN or EWOULDBLOCK,
we would only read one single message and return that there is
nothing to read.
This means, if there were more then one messages ready to read,
we would only read the first one and return to the main-loop
(which then again calls back to platform as more data is ready
to be read).
The explainations no longer hold for the most part. Documentation
that is not directly the code is bound the expire.
The code is the best documentation!! :)
With g_return() we try to catch wrong invocations of a function
or passing invalid arguments.
Having ~forgot~ to overwrite a virtual function is such a serious
and fundamental issue, that checking for it at runtime is wasteful
and unnessesary.
If we ever hit such a situation, just crash.
Link related functions should have a "nm_platform_link" prefix. Rename.
Naming is a subjective matter and one might argue that omitting
the "link" part from the name is shorter and even preferred.
However, I think functions related to links should have a common
prefix as the underlyings are strongly related.
Let the link-add functions return the internal pointer to the platform
link object. Similar to link-get, which doesn't copy the link either.
Also adjust the sole users of the add-functions (create-and-realize)
to take the pointer.
Eventually we still copy the returned data, because accessing platform can
invalidate the returned pointer. Thus we don't actually safe any copying
by this (at least every use of the function currently leads to the data
being copied).
Still change it, because I think the API of NMPlatform should look like that.
NMPlatformLink is a plain struct (not a GObject, for which we usually
don't use const). We certainly don't want the functions to modify the
passed-in data.
There are the link-types NONE and UNKNOWN. NONE is a linktype that is never
returned by platform, but UNKNOWN is very much a valid (albeit unspecified)
type.
Effectively, create_and_realized() should create a link of a known type,
thus it should never return an UNKNOWN link type at this point. Still
change it because it feels more correct.
After commit 8ca6e412c1, libnm-glib is
able to instantiate unknown devices as dummy objects without creating
a D-Bus proxy for them. Enable this behavior for every new unknown
device type.