Commit Graph
4679 Commits
Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 37900a6265 tests: convert manual test binaries to VERB_COMMAND and --introspect-cli
The last five hand-written help() functions are replaced by COMMAND()
descriptions: test-homectl-prompts, test-libudev,
test-modem-manager-mock, test-chase-manual, and test-journal-append
(which open-coded the help inside the option parsing loop). None of the
binaries are installed, so no man pages are referenced and they are not
added to the introspection smoke test.
2026-08-28 14:50:10 +02:00
Zbigniew Jędrzejewski-Szmek a677a39c1e test-journal-append: use DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE
Negative return values, e.g. from option parsing, were propagated verbatim
as the exit status of main() and truncated to meaningless values (-EINVAL
became 234). The positive-failure variant is needed because the binary may
exit with EXIT_TEST_SKIP.

Also propagate EXIT_TEST_SKIP instead of suppressing it.
2026-08-28 14:50:10 +02:00
Yu Watanabe a2de89f622 libc: call epoll_pwait2 syscall directly instead of resolving glibc symbols
As mentioned in a05fe6684a, glibc provides two
wrappers for epoll_pwait2() on 32-bit architectures, and sys/epoll.h,
together with features-time64.h, selects the appropriate one.

To avoid depending on symbols introduced in newer glibc releases, that
commit relied on the glibc internal macro __USE_TIME_BITS64 to determine
which wrapper to use. However, that is incorrect on some architectures.
See:
https://sourceware.org/git/?p=glibc.git;a=commit;h=a4ed0471d71739928a0d0fa3258b3ff3b158e9b9

The above glibc commit introduces a new internal macro,
__USE_TIME64_REDIRECTS, which correctly describes whether the time64
wrapper should be used. However, we cannot rely on it because it was
introduced in glibc 2.40, while our baseline remains glibc 2.34.

Moreover, even after raising the baseline, relying on glibc internal
implementation details is undesirable.

Instead, call the epoll_pwait2 syscall directly. This avoids any
dependency on glibc wrapper selection logic while preserving the original
goal of avoiding newer glibc symbols.

As a side effect, this also enables epoll_pwait2() on musl, which does not
currently provide a libc wrapper for it.

Currently, epoll_pwait2() is only used by sd-event, so this is also the
simplest solution.
2026-08-28 06:19:13 +09:00
Yu Watanabe ded83144eb sd-journal: constify several arguments 2026-08-23 15:27:41 +09:00
Jakub Stasiak 354b51ddbf sd-device: ignore invalid ordinary properties
I had a situation where Dell Wyse 3040 with SK Hynix eMMC stopped booting
after upgrading from Fedora 42 to Fedora 44 with systemd 259.8.

The card reports a product name containing byte 0x92, but the kernel event
also contains the valid module alias needed to load mmc_block:

    MMC_NAME=H8G4a\222
    MODALIAS=mmc:block

I inserted the mmc_block kernel module manually and booted successfully.
Then after enabling udevd debug logging and retriggering the MMC add event
via

    udevadm control -l debug
    udevadm trigger -v -c add -s mmc
    udevadm settle

I saw the failure in the "journalctl -b -u systemd-udevd.service"
output:

    mmc0:0001: sd-device: Refusing invalid property: MMC_NAME=H8G4a\222
    mmc0:0001: sd-device: Failed to add property 'MMC_NAME=H8G4a<92>': Invalid argument
    sd-device-monitor(manager): Failed to create device from received message: Invalid argument

Since PR 41001, strict property validation returns EINVAL for the bad
MMC_NAME. device_new_from_nulstr() propagated that error and discarded
the whole event, so udev never processed MODALIAS and did not load
mmc_block.

Skip ordinary properties whose keys or values fail validation. Do not store
them, but continue processing the remaining properties. Required and typed
properties are handled separately and remain fatal when invalid, as do
malformed records and all other errors.

Closes: https://github.com/systemd/systemd/issues/42930
Related: https://github.com/systemd/systemd/issues/41339
Related: https://github.com/systemd/systemd/issues/43008
Similar: https://github.com/systemd/systemd/pull/42316
Similar: https://github.com/systemd/systemd/pull/43061
Regression: https://github.com/systemd/systemd/pull/41001
2026-08-23 13:23:32 +09:00
Yu Watanabe 90481c0b1b tree-wide: add missing assertions
Found by coccinelle.
2026-08-18 06:30:10 +09:00
Yu Watanabe 63da977f64 sd-varlink: do not call disconnect callback for incomplete connection
The connect callback is called after sd_varlink_server_add_connection()
succeeds. Do not call the disconnect callback for connections that have
not been established yet.
2026-08-14 23:56:19 +09:00
ShiroKSH db08fdbc33 sd-varlink: decrement connection counters on failure
Previously, sd_varlink_server_add_connection_pair() did not decrement
the connection counters when json_stream_attach_fds() failed.

Set the ucred before calling json_stream_attach_fds() so that
sd_varlink_close() also decrements the counters when it fails.
2026-08-14 23:56:19 +09:00
Yu Watanabe 0bd40fdc07 json-stream: do not take ownership of passed fds on failure
This makes json_stream_attach_fds() and json_stream_connect_fd_pair()
leave the passed file descriptors with the caller on failure. Callers
should call TAKE_FD() only after a successful call.

Also make qmp_client_connect_fd() always take ownership of the passed
file descriptor, including on failure. Previously, ownership of the
passed file descriptor on failure was unclear and depended on where
the function failed.
2026-08-14 23:55:51 +09:00
Yu Watanabe dc5de3fc03 json-stream: refuse to attach already attached fds
json_stream_attach_fds() closes already attached fds.
Hence, the new fds must be different from the already attached ones.
2026-08-14 00:54:52 +09:00
Yu Watanabe 3e96a99bab sd-varlink: fix memleak on failure path 2026-08-14 00:54:52 +09:00
dongshengyuan f4284e9ceb path-lookup: reject empty env path components
Only trailing empty components have special meaning:
they request appending the built-in defaults.

Share the validation between normal path lookup and
systemd-analyze verify, so verify does not compose
values that path lookup later rejects.

Propagate generator path parse errors instead of
turning them into empty generator paths.

Follow-up for: cf7d80a5fe
2026-08-14 00:27:09 +09:00
Frantisek Sumsal ae940730c6 sd-journal: prefer machine ID from the tail entry
compare_boot_ids() (from 262299dccb) skips
the tail entry realtime timestamp ordering when the compared locations
are from two different machines (and hence have two different machine
IDs) - in that case we fall through to a realtime comparison between the
two locations. This works fine except for journals that were imported
via systemd-journal-remote - the machine ID in the journal header is set
to the receiving machine's ID instead of the original one; but the
original machine ID is kept in the _MACHINE_ID= field.

This, however, defeats the check in compare_boot_ids() so we treat the
remote journals as local ones and try to compare the boots based on
their tail entry realtime timestamps, which results in grouping the
entries by their boot ID instead of interleaving them by their realtime
timestamp.

Given that we (transitively) call journal_file_read_tail_timestamp()
from compare_boot_ids(), where we both (re)set the newest_machine_id
field to the machine ID from the journal header and have the tail entry
at hand, let's try to get the _MACHINE_ID= field from the tail entry and
set newest_machine_id to that if it's present and valid. This way
compare_boot_ids() will correctly determine that the entries are from
two different machines and compare_locations() eventually falls through
to the entry realtime check, so we end up with properly interleaved
entries instead of entries grouped by boot ID.

The performance impact should be pretty negligible in vast majority of
cases, as we'd do this only when:
  - opening a new file
  - comparing entries across different boots
  - advancing to a next location

The first case is a one-time thing only per journal. The second and
third case might call this a bit more frequently, but we fall through to
the _MACHINE_ID= parsing only if the journal file got a new entry since
the last check. The most significant impact would be on journals that
are being actively written into, but even then iterating through the
handful of typical fields is negligible compared to what the rest of the
function does. Also, since 8f8ab4bf98 the
journal_file_read_tail_timestamp() calls are ratelimited when walking
through the journal, lessening the impact even further.

Resolves: #34169
2026-08-08 04:05:25 +09:00
Yu Watanabe 0e410a6b9d sd-journal: prefer exact cursor match after seek (#43297)
Fixes #31516.
2026-08-06 05:48:05 +09:00
Frantisek Sumsal 8e762e6b9f test: verify cursor-seeking in the opposite direction as well 2026-08-05 21:06:43 +02:00
Frantisek Sumsal 868d07d1d4 sd-journal: prefer exact cursor match after seek
Since 262299dccb compare_locations() falls
through to a realtime-based comparison in compare_boot_ids() if the
compared entries have different boot IDs (and seqnum IDs). This can,
however, cause us to pick up the wrong entry/file on systems with
unreliable/missing RTC, where early-boot entries of a boot might have
earlier realtime timestamp compared to the previous boot.

For example, here's a minimal reproducer consisting of two journal files
containing three entries from two separate boot IDs:

$ journalctl --file one.journal -o export
__CURSOR=s=ba37c62fcacf406aad088166c4963cd1;i=1;b=c220efc91dd440deb89d82c98ddb11a5;m=186a0;t=1e8480;x=39d4323a8e5a248d
__REALTIME_TIMESTAMP=2000000
__MONOTONIC_TIMESTAMP=100000
__SEQNUM=1
__SEQNUM_ID=ba37c62fcacf406aad088166c4963cd1
_BOOT_ID=c220efc91dd440deb89d82c98ddb11a5
NUMBER=1

$ journalctl --file two.journal -o export
__CURSOR=s=9d15197efcc54d8ca5d6e7cce28373e2;i=1;b=686dc35e78f64b6ba126018ab6e8bae9;m=186a0;t=f4240;x=57db1c7bd38b37ed
__REALTIME_TIMESTAMP=1000000
__MONOTONIC_TIMESTAMP=100000
__SEQNUM=1
__SEQNUM_ID=9d15197efcc54d8ca5d6e7cce28373e2
_BOOT_ID=686dc35e78f64b6ba126018ab6e8bae9
NUMBER=2

__CURSOR=s=9d15197efcc54d8ca5d6e7cce28373e2;i=2;b=686dc35e78f64b6ba126018ab6e8bae9;m=30d40;t=2dc6c0;x=3513732159948113
__REALTIME_TIMESTAMP=3000000
__MONOTONIC_TIMESTAMP=200000
__SEQNUM=2
__SEQNUM_ID=9d15197efcc54d8ca5d6e7cce28373e2
_BOOT_ID=686dc35e78f64b6ba126018ab6e8bae9
NUMBER=3

The first file (one.journal) contains a single entry from the first boot
(c220efc91dd440deb89d82c98ddb11a5) and a realtime timestamp of 2s. The
second file (two.journal) contains two entries from the second boot
(686dc35e78f64b6ba126018ab6e8bae9) - the first entry has a realtime
timestamp of 1s (i.e. _earlier_ than the tail timestamp of the first
boot), and the second entry has a realtime timestamp of 3s (i.e.  after
a time correction).

This works fine for forward iteration, but seeking directly to the
second entry is when things go south:

First entry:
$ python3 <<EOF
c = "s=ba37c62fcacf406aad088166c4963cd1;i=1;b=c220efc91dd440deb89d82c98ddb11a5;m=186a0;t=1e8480;x=39d4323a8e5a248d"
from systemd import journal; j = journal.Reader(path="."); j.seek_cursor(c); j.get_next(); print(j.test_cursor(c))
EOF
True

Second entry:
$ python3 <<EOF
c = "s=9d15197efcc54d8ca5d6e7cce28373e2;i=1;b=686dc35e78f64b6ba126018ab6e8bae9;m=186a0;t=f4240;x=57db1c7bd38b37ed"
from systemd import journal; j = journal.Reader(path="."); j.seek_cursor(c); j.get_next(); print(j.test_cursor(c))
EOF
False

That's because:
  - we call sd_journal_seek_cursor(...) and parse it (seqnum, seqnum_id,
    boot_id, realtime, ...)
  - we call sd_journal_next() -> real_journal_next() which iterates over
    all open journal files to find all candidate entries and pick the
    best one
  - for each journal file we call next_beyond_location()
  - for next_beyond_location(one.journal) we get:
    - last_direction is _DIRECTION_INVALID, so we call find_location_with_matches()
    - we fall all the way through to journal_file_move_to_entry_by_realtime()
    - here we try to find the first entry with realtime >= 1s; this file
      has only one entry with realtime = 2s which matches
  - we got a match and new_file is unset, so we set it to one.journal
  - for next_beyond_location(two.journal) we get:
    - we fall through to find_location_with_matches()
    - here we have a matching seqnum, so we call journal_file_move_to_entry_by_seqnum()
  - we got another match but new_file is set, so we call compare_locations(two.journal, one.journal):
    - we fall through to compare_boot_ids()
    - we get the tail timestamps of both journal files and return
      CMP(second boot, first boot) -> CMP(3s, 2s) = 1
  - this bubbles up back to real_journal_next() where found = false, so
    new_file remains one.journal (the wrong journal file)
  - this is followed by set_location(one.journal), which makes the
    following sd_journal_test_cursor() call fail, as the
    boot_id/seqnum_id/... of the current position don't match with the
    cursor

To fix this, let's track the journal file that holds the exact cursor
match, and override the chosen candidate if needed once we process all
open journals.

Resolves: #31516
2026-08-05 21:06:43 +02:00
dongshengyuan 1a43aec562 sd-netlink: append multipart messages in O(1)
Commit 52ceba53d3 made multipart replies append in receive
order, but each append walked the chain from the head.

Cache the tail on the chain head, so new fragments can be
linked directly. The visible next-pointer chain and order stay
unchanged.

Follow-up for: 52ceba53d3
2026-08-05 23:18:09 +09:00
Chris Down b6fba48f0f bus: Reduce sd_bus_message size by 9.9% by dropping offset bookkeeping
sd_bus_message carries an array of header field offsets and a counter,
but their only reader was part of the D-Bus v2/GVariant sealing path
removed in 0dd4876815 ("sd-bus: drop D-Bus version 2 format support").

There are three remaining callers of message_extend_fields(), for
SD_BUS_MESSAGE_HEADER_DESTINATION, _PATH, and _INTERFACE, and all of
them pass false for add_offset. The receive path does not populate the
array either, so nothing reads or writes it any more.

Let's drop the two fields and the now unused add_offset argument and
branch.

This reduces sizeof(sd_bus_message) from 792...

    $ gdb -batch build-baseline/test-bus-benchmark \
          -ex 'ptype /o struct sd_bus_message'
                              ...
                              /* 688 |     8 */ usec_t timeout;
                              /* 696 |    80 */ size_t header_offsets[10];
                              /* 776 |     4 */ unsigned int n_header_offsets;
                              /* XXX  4-byte hole */
                              /* 784 |     8 */ uint64_t read_counter;
                              /* total size (bytes):  792 */

to 704 bytes:

    $ gdb -batch build-patched/test-bus-benchmark \
          -ex 'ptype /o struct sd_bus_message'
                              ...
                              /* 688 |     8 */ usec_t timeout;
                              /* 696 |     8 */ uint64_t read_counter;
                              /* total size (bytes):  704 */

On Fedora 43 aarch64 with glibc 2.42, the usable allocation for a
method-call message falls from 808 to 728 bytes, a reduction of 9.9%.

In my tests, retaining 400,000 method-call messages reduces in median
peak RSS from 363M to 332M.

Using `test-bus-benchmark chart direct 500ms` across message sizes from
1 byte to 2 MiB one can also see things are around 1% faster, which is
another nice incidental boost.
2026-08-03 13:48:05 +09:00
dongshengyuan 3bb3c54f3d sd-id128: parse UUID URNs
Accept RFC4122 UUID URN strings with the `urn:uuid:` prefix in
sd_id128_from_string(), while keeping plain 128-bit IDs and regular
UUID strings working as before.
2026-08-02 19:17:03 +09:00
Eric Boucher bc9870a923 sd-json: encode pidref fd_id as unsigned
PidRef.fd_id is uint64_t.
2026-08-02 14:14:46 +09:00
Yu Watanabe 8eede7122f sd-device: allow non-safe characters in uevent files
This partially reverts 13ce62caba.

Sometimes, the kernel passes non-safe characters in uevent files,
such as the UNIQ= property for USB serial devices.

Instead of rejecting the entire uevent file, let's only ignore the
specific key-value pairs that contain non-safe characters.

Fixes #43008.
2026-07-21 12:19:32 +09:00
Yu Watanabe 7f1ca24bb9 sd-device: use network_namespace_is_init() 2026-07-18 05:29:59 +09:00
Lennart Poettering 093cac3fe8 string-util: replace version_is_valid()/version_is_valid_version_spec() by a common call
Let's take inspiration from string_is_safe() and take a flags field that
allows fine tuning the validation.

Then port over all current users of either function to the new logic.
Note that this *does* change behaviour in various cases:

1. Generally: we'll now always accept the full UAPI.10 alphabet,
   including the "~" and "^" characters. As far as I can see there's no
   downside to this liberalization as none of the current consumers of
   the two functions uses these characters for anything else.

2. systemd-analyze compare-version will now accept version strings with
   "_" and "+" without complaining. I see no downside here, it just
   normalizes these debugging tools, to make them accept what most our
   other tools accept.

3. "bootctl link" will not accept empty version strings anymore
   Which is a bugfix I guess.

4. vpick will now refuse "_" and "+" in version strings. It kinda
   already did, because when parsing versions from filenames it uses "_"
   and "+" as name, architecture and attempt counter separators. We now
   systematically refuse it everywhere else in vpick too. This is hence
   a clean-up.

Fixes: #28906
Replaces: #42815 #41937
2026-07-14 22:32:27 +02:00
Yu Watanabe 01e1303f9c Rename basic-forward.h, sd-forward.h, and shared-forward.h to forward.h
Follow-up for 74d392ed1b.
2026-07-15 02:18:05 +09:00
dongshengyuan 63b30468a5 portablectl: retry inspect with PORTABLE_PREFIXES
When no prefix is specified, portablectl inspect first tries the
prefix derived from the image name. This keeps inspect aligned with
attach behavior.

If that lookup finds no matching units, retry with validated
PORTABLE_PREFIXES read from the image os-release. This makes inspect
work for images whose filename does not match their portable service
prefix.

Keep metadata error handling explicit so request-construction failures
are not logged twice, while sd_bus_call() failures still include the
inspect context.

Add a TEST-29-PORTABLE regression case for a directory image whose
name does not match the portable service prefix.

Fixes #37296.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-14 11:26:40 +02:00
Lennart Poettering 953d21846a sd-varlink: add sd_varlink_call_and_upgradeb() + sd_varlink_call_and_upgradebo()
This are to the existing sd_varlink_call_and_upgrade() what
sd_varlink_callb() and sd_varlink_callbo() are to sd_varlink_call():
they put together an object on the fly, via the usual JSON builder
logic.
2026-07-12 22:44:03 +02:00
Lennart Poettering 746d10d106 sd-varlink: add async server-side upgrade API 2026-07-12 22:44:03 +02:00
Lennart Poettering f194afa164 sd-varlink: move varlink_handle_upgrade_fds() before sd_varlink_process()
This is a simple move, in preparation for using this as part of the
sd_varlink_process() callchain.
2026-07-12 22:37:51 +02:00
Lennart Poettering 260fcf9763 sd-varlink: fold separate 'protocol_upgrade' flag into state machine 2026-07-12 22:37:48 +02:00
Lennart Poettering 755f1cff89 json-stream: add helper json_stream_has_buffered_output() 2026-07-12 22:32:40 +02:00
Yu Watanabe 05bdf4bfa9 compress: split compress_blob() and friends to minimize dlopen dependencies
Previously, even though sd-journal does not support bzip2 and gzip
compression, the dlopen ELF notes for those libraries were still being
attached to libsystemd.so and various journal-handling executables.
This occurred because the unified compression/decompression interfaces
handled all formats unconditionally, causing the compiler and linker to
pull in all associated dlopen notes across the board.

To resolve this, split these functions into generic and journal-specific
variants (e.g., introducing compress_blob_journal() and decompress_blob_journal()).
The journal-specific variants only handle formats actually supported by
the journal (LZ4, XZ, and ZSTD).

By updating sd-journal, journald, journalctl, and related utilities to
use these new `_journal` interfaces and switching them to the narrower
COMPRESS_JOURNAL_NOTE macro, we ensure that unnecessary dlopen notes
(for bzip2 and gzip) are no longer embedded into these binaries.
2026-07-10 16:35:19 +09:00
Lennart Poettering 04915e3d37 Assorted coverity fixes (#42933) 2026-07-09 11:01:03 +02:00
Frantisek Sumsal 9ae50c78cc sd-event: use CLOCK_BOOTTIME for rate limits
When a rate limit is armed, for example via StartLimitInterval=, and the
machine is suspended, the rate limit's "clock" is suspended as well,
since the elapse checks use CLOCK_MONOTONIC. This then causes unexpected
situations where a rate limit armed via StartLimitInterval=1h, followed
by a 10 hour suspend, would elapse after 11 hours total.

Let's avoid this by switching the rate limits to CLOCK_BOOTTIME, which
works the same as CLOCK_MONOTONIC, but accounts for the time spent in
suspend as well.

There's one slight concern when it comes to upgrade path - the old
"begin" value of the rate limit is stored as CLOCK_MONOTONIC, but after
upgrading systemd and serializing/deserializing the state it will be
suddenly compared against now(CLOCK_BOOTTIME), which might cause some
rate limits to elapse "prematurely". But this is just a one-time thing,
after which the rate limit timers should re-assess themselves.

Resolves: #42912
2026-07-08 15:38:39 +01:00
Luca Boccassi 7967b6b6d5 sd-device: check fd validity before using in sendmsg in test
CID#1663676

Follow-up for 7003a9bf09
2026-07-08 13:36:32 +01:00
Luca Boccassi 6248f1b774 sd-bus: voidify bus_match_remove call
It cannot fail, just returns 0 or 1 for not found/found

CID#1663675
2026-07-08 10:54:04 +01:00
Luca Boccassi b7b1303209 sd-bus: drop half-registered vtable members on failure
add_object_vtable_internal() inserts BusVTableMember entries into the
global vtable_methods/vtable_properties sets as it walks the vtable, but
only sets node_vtable.node (which gates the disconnect-time cleanup)
after the loop. A failure mid-loop thus left the already-inserted
members behind, dangling once the slot's interface string and the node's
path were freed, so a later registration reading those keys hit a
use-after-free. Remove this slot's members on the fail path.

The test asserts the failed registration leaves no member behind.

Follow-up for 19befb2d5f
2026-07-06 13:42:22 +01:00
Luca Boccassi 058b0de7bf sd-bus: re-check match_callbacks_modified in the argNhas value loop
The CAN_HASH branch of bus_match_run() that iterates the array values of
an argNhas= match dispatches a callback per value but, unlike the leaf
and manual-iteration branches, does not re-check bus->match_callbacks_modified
afterwards. A callback that adds or removes a match (freeing the node)
would then have the next hashmap_get(node->compare.children, ...) read
freed memory. Add the same check the sibling branches already have.

Follow-up for 198b158f49
2026-07-06 13:42:22 +01:00
Luca Boccassi 25c016f472 sd-netlink: disconnect the slot on async/match error paths
netlink_slot_allocate() links the slot into nl->slots and takes an nl
reference, but sd_netlink_call_async() and netlink_add_match_internal()
hold it in a _cleanup_free_, so an error after allocation frees the slot
with a bare free()

Follow-up for ee38400bba
2026-07-06 13:42:22 +01:00
Luca Boccassi 7003a9bf09 sd-device: avoid 32-bit overflow in the monitor properties bounds check
"properties_off + 32 > n" is evaluated in 32-bit arithmetic, so a
properties_off near UINT32_MAX wraps but passes the check.

Follow-up for efbd4b3ca8
2026-07-06 13:42:21 +01:00
Luca Boccassi 2f72db10d9 sd-device: bound the tag filter BPF program size
The tag-match loop emits 6 instructions per tag into a fixed 512-entry
stack array without a bounds check (unlike the subsystem loop below),
so enough tags overflow the stack. Refuse with -E2BIG instead.

Follow-up for b1c097af8d
2026-07-06 13:42:21 +01:00
Lennart Poettering 85a210c688 varlink: properly linebreak upgrade/more flag generation
Let's not manually create comments, but use the usual
varlink_idl_format_comment() function which does line break handling
properly.

This polishes the output for very narrow outputs, since we'll line break
these synthetic comments too.
2026-07-03 23:26:08 +02:00
Lennart Poettering 61ddb06754 test: register SysInstall Varlink IDL in test-varlink-idl.c 2026-07-03 17:55:31 +02:00
Yu Watanabe 5280cd7bdb tree-wide: check if necessary cflags dependencies are set
This makes each `foo_cflags` dependency define a `SYSTEMD_CFLAGS_MARKER_FOO`
macro, and checks if the macro is set when headers provided by external
libraries are included.

With this, we can fail fast at compile time if necessary `_cflags`
dependencies are omitted in meson.build. Missing dependencies found by this
mechanism have been added across the tree.
2026-07-03 21:50:45 +09:00
Yu Watanabe cff424864d meson: merge three glib cflags dependencies
They are always used together, and only used by a unit test.
Fine-graded cflags dependencies are not necessary.
2026-07-03 21:50:45 +09:00
Yu Watanabe 193749a52e journal: move audit-type.[ch] and related generators to src/journal
It is only used by systemd-journald and own unit test.
2026-07-03 17:07:49 +09:00
Lennart Poettering 805742a9c5 Allow systemd to be built as as single statically-linked binary (#42820)
The idea is that we can build a container by building a single-binary
systemd:
```console
$ meson setup build-static --default-library=static --prefer-static --auto-features=disabled -Dbuild-static=true -Dsystemd-multicall-binary=true && ninja -C build-static systemd
$ mkdir /var/tmp/container/usr/lib -p
$ cp build-static/systemd /var/tmp/container/usr/lib/
$ echo 'ID=quick' >/var/tmp/container/usr/lib/os-release
$ systemd-nspawn --restrict-address-families=af_unix --register=no --private-users=managed -D /var/tmp/container/ /usr/lib/systemd
░ Spawning container container on /var/tmp/container.
░ Press Ctrl-] three times within 1s to kill container; two times followed by r
░ to reboot container; two times followed by p to poweroff container.
Selected user namespace base 1855193088 and range 65536.
systemd 262~devel running in system mode (-PAM -AUDIT +SELINUX -APPARMOR +IMA +IPE +SMACK -SECCOMP -GCRYPT +GNUTLS +OPENSSL -ACL +BLKID +CURL -ELFUTILS -FIDO2 +IDN2 +KMOD +LIBCRYPTSETUP +LIBCRYPTSETUP_PLUGINS +LIBFDISK +PCRE2 -PWQUALITY +P11KIT +QRENCODE +TPM2 -BZIP2 -LZ4 +XZ +ZLIB +ZSTD -BPF_FRAMEWORK -BTF -XKBCOMMON +UTMP -LIBARCHIVE)
Detected virtualization systemd-nspawn.
Detected architecture x86-64.
Detected first boot.

Welcome to Linux!

Initializing machine ID from container UUID.
Failed to open netlink, ignoring: Address family not supported by protocol
Applying preset policy.
Populated /etc with preset unit settings.
Unit default.target not found.
Falling back to graphical.target.
Mount unit not supported, skipping *MountsFor= dependencies.
Queued start job for default target graphical.target.
[  OK  ] Reached target sysinit.target.
[  OK  ] Reached target basic.target.
System is tainted: unmerged-bin:var-run-bad
[  OK  ] Reached target multi-user.target.
[  OK  ] Reached target graphical.target.
Startup finished in 61ms.
```
The container can be reloaded with SIGTERM, powered off with SIGRTMIN+4,
etc. SIGRTMIN+5 should cause a reboot but it currently fails:
```
...
Rebooting.
Container container is being rebooted.
Failed to attach root directory: Invalid argument
Failed to receive mount namespace fd from outer child: Input/output error
```
It's a bug … somewhere, but probably not caused by the linking changes
being done here.
2026-07-02 21:56:27 +02:00
Kai Lüke ff30101e81 vmspawn/nspawn: Always use a per-machine runtime subdirectory
Some state files were prefixed with the machine name which protected
against collisions when running concurrent machines in a systemd unit
with RuntimeDirectory= set. However, the socket files tpm.sock and
control were not, which caused a race. Prefixing these socket files
does not work because the path gets too long when both the subdirectory
and the socket file within it get unique identifiers.

Instead of prefixing all files, we can rather always create a
subdirectory and use simple names within in. This makes paths shorter
in the normal case and protects against races with RuntimeDirectory=
were instead of directly reusing RUNTIME_DIRECTORY we also create the
normal per-machine subdirectory. Since this here is about runtime state
it should not impact any running VMs/containers. The ssh-proxy looks
only at the normal case and does not support RUNTIME_DIRECTORY, so no
impact there as well.
2026-07-02 17:24:18 +02:00
Zbigniew Jędrzejewski-Szmek bbeef4b948 various: add -Dbuild-static and alternatives to libc functions
When we try to build with -static, the linker refuses dlopen and
various functions related to nss. This commit adds the basic support
to compile with -static and allow the link to pass.
2026-07-02 17:19:18 +02:00
Luca Boccassi 04f8927173 Add more shutdown timestamps and preserve via LUO (#42671)
Add more shutdown timestamps, export them via D-Bus/Varlink, use them in
`systemd-analyze time`, and preserve them across kexec via LUO. This is
useful to measure reboot performance with added measurement points and
more granular intervals.
2026-07-01 14:12:21 +01:00
dongshengyuan 8f8ab4bf98 sd-journal: rate-limit tail timestamp refresh during iteration
journal_file_read_tail_timestamp() is called unconditionally in
next_beyond_location() for every file on every iteration step,
resulting in O(N x files) volatile mmap reads. For large queries
like 'journalctl -n 1000000' this makes the command unusably slow
(~5 minutes on systems with many journal files).

Rather than suppressing the call entirely (which would make the
inotify path fully load-bearing for cross-boot ordering), rate-limit
it to at most once per second per file. This reduces the overhead
from O(N x files) to O(T x files) where T is the iteration time in
seconds, while still providing periodic refresh as a fallback for
any missed inotify events and keeping cross-boot ordering
reasonably fresh.

Embed a RateLimit struct in JournalFile for this purpose.

Measured improvement on a real system: 5:24 -> 2:39 (-51%) for
'journalctl -n 1000000'.

Fixes: #42521
Regression introduced in: #26355 (34af74946e)

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-06-30 13:46:05 +01:00