When setting the logging with omitting the domains, we would
use the previously set logging domains. That was wrong since
the addition of the 'KEEP' level:
(1) $ nmcli g l level INFO domains DNS,CORE
$ nmcli g l
LEVEL DOMAINS
INFO DNS,CORE
(2) $ nmcli g l level KEEP domains PPP:TRACE
$ nmcli g l
LEVEL DOMAINS
INFO PPP:TRACE,DNS,CORE
(3) $ nmcli g l level ERR
$ nmcli g l
LEVEL DOMAINS
ERR PPP:TRACE
with this change, command (3) effectively translates to:
$ nmcli g l level ERR domains PPP,DNS,CORE
$ nmcli g l
LEVEL DOMAINS
ERR PPP,DNS,CORE
"nm-logging.c" uses several global variables. As their name doesn't
indicate that they are global variables, this is quite confusing.
Pack them all into a struct @global, which effectively puts the
variables into a separate namespace.
When debug-logging for platform is enabled, every access to sysctl
is cached (to log the last values).
This cache can grow quite large if the system has a large number of
interfaces (e.g. docker creating veth pairs for each container).
We already used to clear the cache, when we were about to access
sysctl *and* logging was disabled in the meantime.
Now, when logging setup changes, immediately clear the cache.
Having "nm-logging.c" call into platform code is a bit of a hack
and a better design would be to have logging code emit a signal to
which platform would subscribe. But that seems to involve much
more code (especially, as no other users care about such a signal
and because nm-logging is not a GObject).
Also, log a warning when the cache grows large to inform the user
about the cache and what he can do to clear it. The extra effort to
clear the cache when changing logging setup is done so that we do
what we tell the user: changing the logging level, will clear the
cache -- right away, not some time later when the next message is
logged.
Without this, the user cannot configure only certain logging domains
without touching them all.
E.g.
# nmcli general logging level DEBUG domains PLATFORM
will disable all non-PLATFORM domains.
Well, the user can do:
# nmcli general logging level INFO domains PLATFORM:DEBUG
# nmcli general logging level DEBUG domains ALL:INFO,PLATFORM
but in this case all non-PLATFORM domains are reset explicitly.
Now the user can:
# nmcli general logging level KEEP domains PLATFORM:DEBUG
# nmcli general logging level DEBUG domains ALL:KEEP,PLATFORM
which will only change the platform domain.
Especially systemd, which makes use of the error argument for logging, likes
to represent errors as negative numbers. We hence must invert a negative error
code to get the real errno.
The localization headers are now included via "nm-default.h".
Also fixes several places, where we wrongly included <glib/gi18n-lib.h>
instead of <glib/gi18n.h>. For example under "clients/" directory.
"NONE" was wrongly part of @domain_descs and thus advertised
via `NetworkManager --help`. But since its @num was set to
LOGD_NONE (zero), it was already rejected by nm_logging_setup().
The only way to disable logging for a domain entirely is to
omit the domain from the "domains" list. For example:
"level=INFO, domains=PLATFORM,..."
Now add an explicit level "OFF" to facilitate configuration like:
"level=INFO, domains=ALL,WIFI_SCAN:OFF"
It also supports
"level=OFF, domains=PLATFORM:INFO"
but this is for the most part equivalent to
"level=INFO, domains=PLATFORM"
Rather than randomly including one or more of <glib.h>,
<glib-object.h>, and <gio/gio.h> everywhere (and forgetting to include
"nm-glib-compat.h" most of the time), rename nm-glib-compat.h to
nm-glib.h, include <gio/gio.h> from there, and then change all .c
files in NM to include "nm-glib.h" rather than including the glib
headers directly.
(Public headers files still have to include the real glib headers,
since nm-glib.h isn't installed...)
Also, remove glib includes from header files that are already
including a base object header file (which must itself already include
the glib headers).
Remove nm_logging_syslog_closelog(). The reasons are:
- closelog() is optional according to the manual.
- we called nm_logging_syslog_closelog() at the end of the
main() function. But we have destructors running afterwards,
so we were closing the log before logging the last line.
Apparently that had no bad consequences either, so why was
closelog() even useful?
Also, it's hard to determine when we log the last line and
only closelog() afterwards.
- closelog() does not revert what openlog() did, this is ugly.
The actual logging implementation is not supposed to be called
directly, because there are macros that capture the call site
information __FILE__, __LINE__, and G_STRFUNC.
Rename the function to make clear that this is the actual
implementation.
Even Fedora is no longer shipping the WiMAX SDK, so it's likely we'll
eventually accidentally break some of the code in src/devices/wimax/
(if we haven't already). Discussion on the list showed a consensus for
dropping support for WiMAX.
So, remove the SDK checks from configure.ac, remove the WiMAX device
plugin and associated manager support, and deprecate all the APIs.
For compatibility reasons, it is still possible to create and save
WiMAX connections, to toggle the software WiMAX rfkill state, and to
change the "WIMAX" log level, although none of these have any effect,
since no NMDeviceWimax will ever be created.
nmcli was only compiling in support for most WiMAX operations when NM
as a whole was built with WiMAX support, so that code has been removed
now as well. (It is still possible to use nmcli to create and edit
WiMAX connections, but those connections will never be activatable.)
A gnu extension to printf adds the format specifier "%m"
to print @errno. To preserve the error number until the
point where the logging statement is constructed, pass
it as an additional argument to _nm_log().
This is not (yet) used from NM internal code. But systemd is adding
similar functionality to its logging functions. Add the same also to
nm-logging, to support systemd's usage of "%m".
Enum types larger then the native 'int' type are undefined behavior
according to C standard. Assert that our compiler does the right thing.
the expression that defines the value of an enumeration constant shall
be an integer constant expression that has a value representable as an
int
Previously, we would only pass one argument @loc to _nm_log()
which was set to G_STRLOC.
That has the disadvantage, that for every logging line the binary
contains an individual string __FILE__:__LINE__.
By splitting up @loc into @file and @line, we reduce the number
of strings in the NetworkManager binary by about 50k.
https://bugzilla.gnome.org/show_bug.cgi?id=741651
This way the compiler issues a warning when accidently
switching the level and domain arguments when logging.
Make LOGD_ALL and LOGD_DEFAULT members of the enum instead
defining them. Previously the LOGD_ALL define included all
the defined domains, hence this is no functional change.
Also define the logging domain aliases as enum members (instead
of preprocessor defines).
Signed-off-by: Thomas Haller <thaller@redhat.com>
NMManagerError has other operation-specific errors (like
NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE), so it makes sense to move
NM_LOGGING_ERROR_UNKNOWN_LEVEL and NM_LOGGING_ERROR_UNKNOWN_DOMAIN
there too rather than having them in their own tiny error domain.
Ensure that nm_logging_setup() was called for all functions
where it actually makes a difference.
This is especially important for nm_logging_enabled(),
so that the behavior of the following is identical:
nm_log_info(LOGD_CORE, "hello world");
and
if (nm_logging_enabled (LOGL_INFO, LOGD_CORE))
nm_log_info(LOGD_CORE, "hello world");
Signed-off-by: Thomas Haller <thaller@redhat.com>
Some subdirectories of src/ encapsulate large chunks of functionality,
but src/config/, src/logging/, and src/posix-signals/ are really only
separated out because they used to be built into separate
sub-libraries that were needed either for test programs, or to prevent
circular dependencies. Since this is no longer relevant, simplify
things by moving their files back into the main source directory.
Some stuff we build (the DHCP manager) gets built independently
so that we can use it for unit tests. For that, we need to build
the logging bits separately too, since the independent DHCP
library can't use them if they are embedded in NM.