meson's target has a few issues:
- Runs on all source files regardless if they're included in the
build or not
- Doesn't have any dependencies on generated sources which means we
have to do a full build first before we can run clang-tidy
- Doesn't allow us to pass any extra arguments
To work around these, let's define our own clang-tidy target instead
using llvm's run-clang-tidy script. Alongside the clang-tidy target,
let's start keeping track of all generated sources which we make the
clang-tidy target depend on. We also add a new target which will only
generate source files which is useful for setting up the source tree
for running code analysis against it.
mkosi: Run clangd within the tools tree instead of the build container
Running within the build sandbox has a number of disadvantages:
- We have a separate clangd cache for each distribution/release combo
- It requires to build the full image before clangd can be used
- It breaks every time the image becomes out of date and requires a
rebuild
- We can't look at system headers as we don't have the knowledge to map
them from inside the build sandbox to the corresponding path on the host
Instead, let's have mkosi.clangd run clangd within the tools tree. We
already require building systemd for both the host and the target anyway,
and all the dependencies to build systemd are installed in the tools tree
already for that, as well as clangd since it's installed together with the
other clang tooling we install in the tools tree. Unlike the previous approach,
this approach only requires the mkosi tools tree to be built upfront, which has
a much higher chance of not invalidating its cache. We can also trivially map
system header lookups from within the sandbox to the path within mkosi.tools
on the host so that starts working as well.
Let's add a basic clang-tidy check to the linter workflow. This
gives us the following:
- A check so that we don't introduce any new cyclic header dependencies
- A check to make sure all of our header files are standalone, as clang-tidy
will fail to parse header files that don't include all their dependencies.
Add .clangd configuration file that disables the unused include check
The clangd include checker is rather broken and is littered with false
positives in our codebase, so let's disable the feature until it improves
a bit.
We already have LOG_CONTEXT_PUSH_EXEC() which with two additions
does exactly the same as the custom logging macros, so let's get rid
of the custom logging macros and use LOG_CONTEXT_PUSH_EXEC() instead.
timedate: Drop custom logging macros in favor of log context
Additionally, using the log context makes sure the extra fields are
applied to all log messages generated while the context is in place,
rather than only log messages logged with log_unit_xxx() in timedated
itself.
It also means the unit name is prefixed to all log messages logged
within that context. While it's not clear whether we always want the
unit name to be attached to library log messages, we also don't want
the unit name to not be attached to any library log messages, so we opt
to add more rather than less information by adding the unit name everywhere
for now.
In the future we can look into some log.h helpers to enable/disable
adding the prefix to the following log messages or not.
unit: Make sure individual unit maximum log level always takes priority
Currently LogLevelMax= can only be used to decrease the maximum log level
for a unit but not to increase it. Let's make sure the latter works as
well, so LogLevelMax=debug can be used to enable debug logging for specific
units without enabling debug logging globally.
basic: Move various macros from assert-util.h to assert-fundamental.h
ASSERT_PTR() and friends in assert-fundamental.h make use of assert()
and assert_se() which when not building for sd-boot are defined in
assert-util.h. Because assert() from glibc is only overridden in
assert-util.h, the macros in assert-fundamental.h still end up using
the glibc assert.
Let's fix this by moving the required macros and related logic to
assert-fundamental.h.
tree-wide: Use assert_se() instead of assert() in various places
assert() is compiled away if NDEBUG is set which causes an unused
variable warning in various places when the next commit is applied
so let's use assert_se() to avoid these warnings.
journal: Always compile journal authentication related files
Tooling such as clang-tidy is bad at dealing with condition
compilation on the build system level instead of at the source file
level. What happens? It still tries to analyze the file and fails
horribly if the required headers aren't available. Let's work around
the issue and make things more consistent at the same time by doing
the necessary HAVE_GCRYPT checks inside of the source files instead
of doing them at the build system level.
We also add some typedefs to allow getting rid of various HAVE_GCRYPT
checks.
libsystemd: Skip _sd-common.h include check when __clang_analyzer__ is defined
This check doesn't work properly when tools such as clang-tidy are
analyzing headers. Since we don't care about the check in that case,
skip it if __clang_analyzer__ is defined similar to how we skip it as
well if __COVERITY__ is defined.
The static inline declaration in iovec-fundamental.h causes static
analyze tooling warnings (clang-tidy). Let's get around it by making
free() non-inline. LTO will make sure it's still inlined properly.
basic: Use _Static_assert() in missing_audit.h instead of assert_cc()
We want to make the header standalone so it includes all the stuff it
needs. However, including macro.h for assert_cc() doesn't work because
of generate-audit_type-list.sh which would have to become more complex
to handle the extra include directories.
Instead, let's just use _Static_assert() directly which is a builtin and
doesn't need any extra includes.
resolve: Move implementations of some functions to resolved-dns-packet.c
These depend on a full definition of DnsResourceRecord which we want
to forward declare in the next commit, so let's move the implementation
of these functions to the implementation file and make them lowercase.
network: Remove circular header dependencies in network/tc
Include the headers in the implementation file (and the gperf file)
instead of in the qdisc.h header. I opted to keep them separate from
the other headers since they're slightly different than regular headers.
core: Remove circular dependencies between headers
Currently there are various circular dependencies between headers
in core/. Let's get rid of these by making judicious use of forward
declarations and moving includes into implementation files instead of
having them in header files.
Getting rid of circular header includes simplifies the code and makes
various clang based tooling such as iwyu work much better on our code.
The most important change is getting rid of the manager.h include in
unit.h which is possible thanks to the previous commits. We also move
the OOMPolicy and StatusType enums to unit.h to remove the need for
other unit headers to include manager.h to get access to these enums.
core: Turn manager unit log fields into unit functions
There's no need for these to be fields inside the manager struct,
let's turn them into functions in unit.h instead, again to allow
forward declaring the Manager struct in a later commit.
sd-device: fix sysname check in sd_device_new_from_subsystem_sysname()
For example, consider the following device:
- syspath: /sys/bus/mdio_bus/drivers/Qualcomm Atheros AR8031!AR8033
- subsystem: "drivers"
- driver subsystem: "mdio_bus"
- sysname: "Qualcomm Atheros AR8031/AR8033" <-- '!' is replaced with '/'
When sd_device_new_from_subsystem_sysname() is called to get the device,
the arguments to sd_device_new_from_subsystem_sysname() should be
- subsystem: "drivers"
- sysname (concatenated with driver subsystem): "mdio_bus:Qualcomm Atheros AR8031/AR8033"
In that case, we need to pass to device_new_from_path_join() the following:
- subsystem: "drivers"
- driver subsystem: "mdio_bus"
- sysname: "Qualcomm Atheros AR8031/AR8033"
- a: "/sys/bus"
- b: "drivers"
- c: "mdio_bus"
- d: "Qualcomm Atheros AR8031!AR8033"
Here, the important point is that the `sysname` argument and the
last argument `d` are differnt: the `sysname` argument needs to match
the sysname obtained by `sd_device_get_sysname()`, but `d` must be
the last path component of the syspath.
Previously, we passed a wrong sysname to device_new_from_path_join().
This fixes the issue.
core: add concurrency limits to slice units (#36831)
I needed something to hack on "offline", during a long transatlantic
flight. I decided to implement #35862, since I could do that without
checking any online docs nor needing GitHub.
Previously, all queued events were discarded on exit, hence several
events might not be processed by udevd when it is restarted. Such
situation especially easily happens on switching root.
This makes queued events serialized on exit, and deserialized in the
next invocation. Hence, no events should be lost during restarting
udevd.
This is important with the several aspects. Basically
systemd-udev-trigger.service (re)triggers all devices anyway after
switching root, But the service may be disabled or modified by admin.
Moreover, the service produces only 'add' events, and thus the service
cannot cover events with other actions generated by the kernel during
switching root. Also, the userspace triggered events may not contain
some parameters compared with events triggered by the kernel.
The test does not request each unit file exists, but keeping legacy unit
names in test sounds spurious. Let's remove them. Hopefully we still
have enough test cases.
man/sd-bus: Add at least one reference per sd-bus function man page
Some sd-bus man pages did not have any references on the main
sd-bus man page. Unless you accidentally stumbled on them from
other pages it was difficult to discover them.
man/sd_bus_emit_signal: Fix extra const for strv functions
The functions `sd_bus_emit_interfaces_added_strv`, `sd_bus_emit_interfaces_removed_strv`
and `sd_bus_emit_properties_changed_strv` take an `char **` not
`const char **` as last argument.
See `src/systemd/sd-bus.h` for the function definition.
Since OpenSSH 10.0p1, specifically
https://anongit.mindrot.org/openssh.git/commit/?id=487cf4c18c123b66c1f3f733398cd37e6b2ab6ab
ssh refuses comma in hostname by default.
network: enable ARP= when IPv4LL/IPv4ACD is enabled
We can run sd-ipv4ll/sd-ipv4acd also on an interface with IFF_NOARP
flag, but that may cause address conflict with other hosts.
Let's enable ARPing when sd-ipv4ll/sd-ipv4acd are enabled unless ARP= is
explicitly disabled.
Mike Yuan [Wed, 8 Jan 2025 12:50:35 +0000 (13:50 +0100)]
logind: drop session fifo logic, rely solely on pidfd for exit notification
Traditionally, logind installed a fifo in the PAM session and
used EOF on the fd as signal for session close. With the addition of
pidfd (76f2191d8eb54d7b9e39ab230c9c62b8a8c42265) however,
logind tracks the leader process and the session is terminated
as soon as that exits. I think the new behavior generally makes
more sense, and the behavior got changed *in the mentioned commit
already* without anyone ever showing up to complain. It hence
feels safe to kill the concept now (also before the varlink interface
gets rolled out).
Note that the 'PID' field in CreateSession() Varlink method
is now marked as strict, i.e. failure to acquire pidfd
is immediately treated as fatal.
udev: serialize queued events on exit, and deserialize them in the next invocation
To make systemd-udevd not lose received uevents on restart. This may be
important on switching root, even though we typically trigger all devices
after switching root by systemd-udev-trigger.service, but it may be
disabled or modified by admin.