We have various options for strerror(), with ups and downsides:
- strerror()
- returns pointer that is overwritten on next call. It's convenient
to use, but dangerous.
- not thread-safe.
- not guaranteed to be UTF-8.
- strerror_r()
- takes input buffer and is less convenient to use. At least, we
are in control of when the buffer gets overwritten.
- there is a Posix/XSI and a glibc variant, making it sligthly
inconvenient to used. This could be solved by a wrapper we implement.
- thread-safe.
- not guaranteed to be UTF-8.
- g_strerror()
- convenient and safe to use. Also the buffer is never released for the
remainder of the program.
- passing untrusted error numbers to g_strerror() can result in a
denial of service, as the internal buffer grows until out-of-memory.
- thread-safe.
- guaranteed to be UTF-8 (depending on locale).
Add our own wrapper nm_strerror_native(). It is:
- convenient to use (returning a buffer that does not require
management).
- slightly dangerous as the buffer gets overwritten on the next call
(like strerror()).
- thread-safe.
- guaranteed to be UTF-8 (depending on locale).
- doesn't keep an unlimited cache of strings, unlike g_strerror().
You can't have it all. g_strerror() is leaking all generated error messages.
I think that is unacceptable, because it would mean we need to
keep track where our error numbers come from (and trust libraries we
use to only set a restricted set of known error numbers).
Use the NM_ERRNO_NATIVE() macro that asserts that these errno numbers are
indeed positive. Using the macro also serves as a documentation of what
the meaning of these numbers is.
That is often not obvious, whether we have an nm_errno(), an nm_errno_native()
(from <errno.h>), or another error number (e.g. WaitForNlResponseResult). This
situation already improved by merging netlink error codes (nle),
NMPlatformError enum and <errno.h> as nm_errno(). But we still must
always be careful about not to mix error codes from different
domains or transform them appropriately (like nm_errno_from_native()).
The native error numbers (from <errno.h>) and our nmerr extention on top
of them are almost the same. But there are peculiarities.
Both errno and nmerr must be positive values. That is because some API
(systemd) like to return negative error codes. So, a positive errno and
its negative counter part indicate the same error. We need normalization
functions that make an error number positive (these are nm_errno() and
nm_errno_native()).
This means, G_MININT needs special treatment, because it cannot be
represented as a positive integer. Also, zero needs special
treatment, because we want to encode an error, and zero already encodes
no-error. Take care of these special cases.
On top of that, nmerr reserves a range within native error numbers for
NetworkManager specific failure codes. So we need to transition from native
numbers to nmerr numbers via nm_errno_from_native().
Take better care of some special cases and clean them up.
Also add NM_ERRNO_NATIVE() macro. While nm_errno_native() coerces a
value in the suitable range, NM_ERRNO_NATIVE() asserts that the number
is already positive (and returns it as-is). It's use is only for
asserting and implicitly documenting the requirements we have on the
number passed to it.
Using strtol() correctly proves to be hard.
Usually, we want to also check that the end pointer is points to the end
of the string. Othewise, we silently accept trailing garbage.
When the logging level is DEBUG or TRACE, we keep all the sysctl
values we read in a cache to log how they change. Currently there is
no limit on the size of this cache and it can take a large amount of
memory.
Implement a LRU cache where the oldest entries are deleted to make
space for new ones.
https://github.com/NetworkManager/NetworkManager/pull/294
nm_ip_route_get_prefix() and plen are guint type, hence the following
is not correct:
plen = nm_ip_route_get_prefix (route1);
r = plen - nm_ip_route_get_prefix (route2);
if (r)
return r > 0 ? 1 : -1;
Use the macro, it gets subtle cases like this right.
Fixes: b32bb36c61
This enables -Werror for meson builds on gitlab-ci and semaphore.
Not on Travis, the compiler there is too old, giving too many bogus
warnings.
This reverts commit 928d68d04a ("m4:
disable -Wmissing-braces for newer clang").
The right way is IN6_ADDR_INIT_ANY.
While at it, don't initialize multiple variables in the same line.
../src/devices/nm-device-ip-tunnel.c:153:29: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
struct in6_addr local6 = { 0 }, remote6 = { 0 };
^
{}
NMIPAddr contains an unnamed union. We have to either explicitly
initialize one field, or omit it.
../shared/nm-utils/nm-shared-utils.c:38:36: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
const NMIPAddr nm_ip_addr_zero = { 0 };
^
{}
The cast is bogus and leads to a compiler warning:
[424/583] Compiling C object src/devices/wifi/914a32e@@nm-device-plugin-wifi@sha/nm-device-iwd.c.o.
In file included from ../shared/nm-default.h:293,
from ../src/devices/wifi/nm-device-iwd.c:21:
../src/devices/wifi/nm-device-iwd.c: In function ‘nm_device_iwd_set_dbus_object’:
../src/devices/wifi/nm-device-iwd.c:2404:28: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
if (!nm_g_object_ref_set ((GObject **) &priv->dbus_obj, (GObject *) object))
../shared/nm-utils/nm-macros-internal.h:1048:13: note: in definition of macro ‘nm_g_object_ref_set’
typeof (*(pp)) *const _pp = (pp); \
^~
The test should check the behavior with "const typeof(a)" in a macro,
where "a" itself is const. For that we don't need a double const
declaration of v2.
Also, that fixes an actual compiler warning:
../src/tests/test-general.c: In function ‘test_duplicate_decl_specifier’:
../src/tests/test-general.c:1669:8: warning: duplicate ‘const’ declaration specifier [-Wduplicate-decl-specifier]
const const int v2 = 3;
^~~~~
It's not useful for us.
In file included from ../src/systemd/src/libsystemd/sd-event/sd-event.c:14:
../src/systemd/src/libsystemd/sd-event/event-source.h:195:36: error: field 'buffer' with variable sized type 'union inotify_event_buffer' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]
union inotify_event_buffer buffer;
^
Also, let one docker image do multiple builds. We fetch a fedora docker
image, and then install 250 MB of packages. That alone takes a lot of
time and resources. Instead of running a large number of docker images
that only do one build, let one image do several builds.
Also, install ccache. Hopefully this way we can benefit from
building the same sources multiple times.
Also note that building docs does not work currently with clang,
due to g-ir-scanner. See commit 05568860cce5332977d92b85f7c25b8ed646cd58.
g-ir-scanner does not support building with clang, due to [1], [2], [3].
It triggers
checking if /usr/bin/g-ir-scanner works... no (compiler failure -- check config.log)
configure: error: introspection enabled but can't be used
with
clang-7: error: unknown argument: '-fstack-clash-protection'
See also commit 99b92fd992, which adds this configure
check.
Honor the environment variable WITH_DOCS to allow the caller to overwrite
the automatic detection that the script does.
[1] https://bugzilla.gnome.org/show_bug.cgi?id=757934
[2] https://gitlab.gnome.org/GNOME/gobject-introspection/issues/150
[3] c14d037228
To run the tests with python3, we need python3-gobject.
Note that "contrib/fedora/REQUIRED_PACKAGES" is called by
"contrib/scripts/nm-ci-run.sh" script to install the packages
in Fedora.
Currently, default-routes cannot be added like regular static-routes
as ipv4.routes setting.
Instead, one has to configure "ipv4.gateway" and "ipv4.never-default".
That of course should be fixed, for example to configure a default-route
in different routing tables.
As it is, both nmcli's parse function and libnm's
NMSettingIPConfig:verify() functions reject default-routes.
But nmcli goes way beyond that, it also rejects all networks with
"0.0.0.0"/"::" even if their prefix length is not zero. Such routes are
not default-routes, and nmcli has no business rejecting them. The
correct way for checking for a default-route is to check the prefix-length
for zero.
Drop the wrong validation in nmcli.
Note, it may still not be the best idea to add catch-all routes like
"0.0.0.0/1" and "128.0.0.0/1". It just defeats what counts as a default-route.
NM has other means (like configuring the route-metric) to handle routing
in face of multiple interfaces. But sure, whatever works for you.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/114https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/75
Otherwise the following fails:
$ ./contrib/fedora/rpm/build_clean.sh -g -s x.1
...
error: parse error in expression
error: /data/src/_NetworkManager/contrib/fedora/rpm/NetworkManager.20190207-165257.XOkW4i/SPECS/NetworkManager.spec:35: bad %if condition
ERROR: rpmbuild FAILED
Even with the fix, not all characters are allowed:
$ ./contrib/fedora/rpm/build_clean.sh -g -s x-1
...
error: line 112: Illegal char '-' (0x2d) in: Release: 22165.x-1.25b13e2053.fc29
ERROR: rpmbuild FAILED
We need to build libnm-core first. Especially, because libnm
sources require the "libnm-core/nm-core-enum-types.h" header
to be generated first.
Add a missing dependency.