Also, let's deflatten the lists of sources in preparation for the
next commit at the same time.
In systemctl, we split out systemctl-main.c to make sure the definition
of main() is in a separate object which allows us to extract the systemctl.c
object and link it in the fuzzer target without getting a multiple definition
error when linking.
Currently, when we want to add unit tests for code that is compiled into
an executable, we either compile the code at least twice (once for the
executable, and once for each test that uses it) or we create a static
library which is then used by both the executable and all the tests.
Both of these options are not ideal, compiling source files more than
once slows down the build for no reason and creating the intermediate
static libraries takes a lot of boilerplate.
Instead, let's use the extract_objects() method that meson exposes on
build targets. This allows us to extract the objects corresponding to
specific source files and use them in other executables. Because we
define all executables upfront into a dictionary, we integrate this into
the dictionary approach by adding two new fields:
- 'extract' takes a list of files for which objects should be extracted.
The extracted objects are stored in a dict keyed by the executable name
from which they were extracted.
- 'objects' takes the name of an executable from which the extracted
objects should be added to the current executable.
One side effect of this approach is that we can't build test executables
anymore without building the main executable, so we stop building test
executables unless we're also building the main executable. This allows
us to switch to using subdir_done() in all of these subdirectories to skip
parsing them if the corresponding component is disabled.
These changes get me down from 2439 => 2403 ninja targets on a full rebuild
from scratch.
Let's move some logic from _DEFINE_MAIN_FUNCTION() and other places
in main-func.h into functions that we implement in main-func.c to
allow moving some included headers from the header to the .c file.
Otherwise passing invalid data means asserts get hit instead of
handling it gracefully. Other verbs already do the same checks.
busctl get-property org.freedesktop.systemd1 '*' org.freedesktop.systemd1.Manager Version
Assertion 'object_path_is_valid(path)' failed at src/libsystemd/sd-bus/bus-message.c:562, function sd_bus_message_new_method_call(). Aborting.
Aborted (core dumped)
Now that the necessary functions from log.h have been moved to macro.h,
we can stop including log.h in macro.h. This requires modifying source
files all over the tree to include log.h instead.
Admittedly, some of our glyphs _are_ special, e.g. "O=" for SPECIAL_GLYPH_TOUCH ;)
But we don't need this in the name. The very long names make some invocations
very wordy, e.g. special_glyph(SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY).
Also, I want to add GLYPH_SPACE, which is not special at all.
We should avoid unnecessary abbreviations for such messages, and this
puts a maximum limit on things, hence it should indicate this in the
name.
Moreover, matches is a bit confusing, since most people will probably
call "busctl monitor" without any match specification, i.e. zero
matches, but that's not what was meant here at all.
Also, add a brief switch for this (-N) since I figure in particular
"-N1" might be a frequent operation people might want to use.
Follow-up for: 989e843e75
See: #34048
The --timeout= logic was implemented incorrectly, as it would not put a
a limit on the runtime of the operation, but only on the IO sleep.
However, spurious wakeups are possible, hence the timer would be reset
too often.
Fix that, by determining the absolute timestamp early, and checking
against that.
Follow-up for: 989e843e75
See: #34048
We often used a pattern like if (!FLAGS_SET(flags, SD_JSON_FORMAT_OFF)),
which is rather verbose and also contains a double negative, which we try
to avoid. Add a little helper to avoid an explicit bit check.
This change clarifies an aditional thing: in some cases we treated
SD_JSON_FORMAT_OFF as a flag (flags & SD_JSON_FORMAT_OFF), while in other cases
we treated it as an independent enum value (flags == SD_JSON_FORMAT_OFF).
In the first form, flags like SD_JSON_FORMAT_SSE do _not_ turn the json
output on, while in the second form they do. Let's use the first form
everywhere.
No functional change intended.
Initially I wasn't sure if this helper should be made public or just internal,
but it seems such a common pattern that if we expose the flags, we might just
as well expose it too, to make life easier for any consumers.
Previously using file descriptors as input arguments in busctl was
unsupported with "UNIX file descriptor not supported as type."
We fix this by parsing the file descriptor as an integer and verifying
it is an available file descriptor in busctl.
Fixes: #14954
Replaces: #34551
varlinkctl has this nice feature that it sends the varlink error it gets
via sd_notify() to the caller. With previous commits this information
is collected and exposed in "systemctl status".
Let's make sure we can provide the same in busctl: also propagate errors
the same way.
With this we can comprehensively close#6073
This is preparation for making our Varlink API a public API. Since our
Varlink API is built on top of our JSON API we need to make that public
first (it's a nice API, but JSON APIs there are already enough, this is
purely about the Varlink angle).
I made most of the json.h APIs public, and just placed them in
sd-json.h. Sometimes I wasn't so sure however, since the underlying data
structures would have to be made public too. If in doubt I didn#t risk
it, and moved the relevant API to src/libsystemd/sd-json/json-util.h
instead (without any sd_* symbol prefixes).
This is mostly a giant search/replace patch.
Let's make sure that versions generated by meson-vcs-tag.sh always
sort higher than official and stable releases. We achieve this by
immediately updating the meson version in meson.build after a new
release. To make sure this version always sorts lower than future
rcs, we suffix it with "~devel" which will sort lower than "~rcX".
The new release workflow is to update the version in meson.build
for each rc and the official release and to also update the version
number after a new release to the next development version.
The full version is exposed as PROJECT_VERSION_FULL and used where
it makes sense over PROJECT_VERSION.
We also switch to reading the version from a meson.version file in
the repo instead of hardcoding it in meson.build. This makes it
easier to access both inside and outside of the project.
The meson-vcs-tag.sh script is rewritten to query the version from
meson.version instead of passing it in via the command line. This
makes it easier to use outside of systemd since users don't have to
query the version themselves first.
Avoid passing a NULL message to sd_bus_message_is_signal(), to not trip
over an assertion:
[ 132.869436] H testsuite-82.sh[614]: + systemctl --no-block --check-inhibitors=yes soft-reboot
[ 132.967386] H systemd[1]: Created slice system-systemd\x2dcoredump.slice.
[ 133.018292] H systemd[1]: Starting inhibit.service...
[ 133.122610] H systemd[1]: Started systemd-coredump@0-665-0.service.
[ 133.163643] H systemd[1]: Started inhibit.service.
[ 133.206836] H testsuite-82.sh[614]: + exec sleep infinity
[ 133.236762] H systemd-logind[611]: The system will reboot now!
[ 135.891607] H systemd-coredump[667]: [🡕] Process 663 (busctl) of user 0 dumped core.
Stack trace of thread 663:
#0 0x00007f2ec45e6acf raise (libc.so.6 + 0x4eacf)
#1 0x00007f2ec45b9ea5 abort (libc.so.6 + 0x21ea5)
#2 0x00007f2ec4b5c9a6 log_assert_failed (libsystemd-shared-255.so + 0x1ff9a6)
#3 0x00007f2ec4b5dca5 log_assert_failed_return (libsystemd-shared-255.so + 0x200ca5)
#4 0x00007f2ec4bb3df6 sd_bus_message_is_signal (libsystemd-shared-255.so + 0x256df6)
#5 0x000000000040e478 monitor (busctl + 0xe478)
#6 0x000000000040e82f verb_monitor (busctl + 0xe82f)
#7 0x00007f2ec4b202cb dispatch_verb (libsystemd-shared-255.so + 0x1c32cb)
#8 0x00000000004074fa busctl_main (busctl + 0x74fa)
#9 0x0000000000407525 run (busctl + 0x7525)
#10 0x000000000040ff67 main (busctl + 0xff67)
#11 0x00007f2ec45d2d85 __libc_start_main (libc.so.6 + 0x3ad85)
#12 0x00000000004044be _start (busctl + 0x44be)
ELF object binary architecture: AMD x86-64
[ 136.141152] H dbus-daemon[634]: [system] Monitoring connection :1.2 closed.
[ 136.152233] H systemd[1]: busctl.service: Main process exited, code=dumped, status=6/ABRT
[ 136.153996] H systemd[1]: busctl.service: Failed with result 'core-dump'.
The asertion in question:
Assertion 'm' failed at src/libsystemd/sd-bus/bus-message.c:1015, function sd_bus_message_is_signal(). Aborting.
We can get a NULL message here through sd_bus_process() ->
bus_process_internal() -> process_running(), so let's handle this case
appropriately.
This is pretty much the same stuff as `resolvectl monitor` does, and
allows us to run `busctl monitor` in a Type=notify unit which ensures
that `busctl` is really listening for messages once the unit is marked
as started.
This allows using it with CLEANUP_ARRAY(). For the 2 call sites
where we don't need to free the array, we do a regular for loop
calling json_variant_unref() instead.