The kernel sometimes sends uevents in a random order, so previously the
received events were not sorted by their seqnum. We determine which
event is ready for processing by using the assumption that queued events
are sorted by their seqnum. Let's sort the received events before queue
them, to make events processed in a correct ordering.
This mostly makes sure we do something reasonable when our tool is
called from a boot of an entry that was already marked as definitely
"bad" on a previous boot. Such an entry we can return into a "good"
state, but we cannot return it into an "indeterminate" state, because
the status quo ante is already known.
Fixes: #37350
If we are booting a known bad entry, and we are asked to mark it as bad,
we so far would end up renaming the entry onto itself, which resulted in
EEXIST and is really borked operation. Let's catch that case and handle
it explicitly.
The bless-boot logic currently assumes that if the name of the boot
entry reported via the EFI var matches the name on disk that the state
is "indeterminate", as we haven't counted down the counter (to mark it
bad) or drop the counter (to mark it good) yet. But there's one corner
case we so far didn't care about: what if the entry already reached 0
left tries in a previous boot, i.e. if the user invoked an entry already
known to be completely bad. In that case we'd still return
"indeterminate", but that's kinda misleading, because we *know* the
currently booted entry is bad, however we inherited that fact from a
previous boot, we didn't determine it on the current.
hence, let's introduce a new status we report in this case, that is both
distinct from "bad" (which indicates whether the *current* boot is bad)
and "indirect" (which indicates the current boot has not been decided on
yet): "dirty".
Why "dirty"? To mirror "clean" which we already have, which indicates a
boot already marked good in a previous boot, which is a relatively
symmetric state.
This is a really weak api break of sorts, because it introduces a new
state we never reported before, but I think it's fine, because the old
reporting was just wrong, and in a way this is bugfix, that we now
report correctly something where previously returned kind of rubbish
(though systematic rubbish).
Replaces: #37350
`networkctl status LINK` gained support for showing the netdev
configuration files associated with a link in
c9837c17d5, but these netdev files were
never added to the JSON output too.
This pull-request fixes that by adding two new fields (`NetDevFile` and
`NetDevFileDropins`) to the `networkctl` (and `D-Bus`) JSON output.
This test requires root, but the check was mistakenly dropped, causing it
to fail with an assert when running without root:
src/test/test-bpf-foreign-programs.c:308: Assertion failed: expected "test_bpf_cgroup_programs(m, "single_prog.service", single_prog, ELEMENTSOF(single_prog))" to succeed, but got error: Operation not permitted
Restore the uid check
Follow-up for 22e2f06428
Unfortunately, the kernel may send events in a random order:
```
[ 25.769624] systemd-udevd[194]: sdi7: Device is queued (SEQNUM=2843, ACTION=add)
[ 25.769893] systemd-udevd[194]: sda5: Device is queued (SEQNUM=2842, ACTION=add)
[ 25.770517] systemd-udevd[194]: sdi8: Device is queued (SEQNUM=2844, ACTION=add)
```
As you can see, udevd receives the event with SEQNUM=2843 earlier than
one with SEQNUM=2842.
Let's make queued events sorted, as our logic of determining which event
is ready for being processed assumes that queued events are sorted.
See event_build_dependencies().
Also, refuse to queue an event if another event with the same seqnum is
already queued.
Previously, when an event for block device is queued or an inotify event
for a block device is triggered, all queued events were checked by
event_queue_assume_block_device_unlocked(), and its cost may be huge
on early boot stage.
This makes locked events are managed in separated prioq and hashmap,
to reduce the cost of event_queue_assume_block_device_unlocked(),
which is now renamed to manager_requeue_locked_events_by_device().
This also changes the clockid of timer events for requeueing and
timeout of retry from CLOCK_BOOTTIME to CLOCK_MONOTONIC. Otherwise,
if the system suspend while an event is locked, the event may be
requeued immediately after come back from the suspend and timed out.
Since shim 16 the plain BS->LoadImage() will just work (TM), we do not need
anymore to set up manual overrides and manually call in the shim-specific
lock protocol or to set shim-specific EFIVAR to make addons work or to load
shim-signed kernels.
Check if the new protocol added in v16 is present, and if so, skip
all that. Once versions < 16 are no longer supported/revoked, all
the code can be dropped entirely.
The timeout event sources are enabled only when the event is being
processed by a worker, hence they are not necessary to be owned by the
event.
No effective functional change, just refactoring.
Note, BPF_PROG_TYPE_CGROUP_DEVICE is supported since kernel v4.15.
As our baseline on the kernel is v5.4, we can assume the bpf type is
always supported.
Note, BPF_PROG_TYPE_CGROUP_SKB is supported since kernel v4.10, and
BPF_F_ALLOW_MULTI and program name is supported since kernel v4.15.
As our baseline on the kernel is v5.4, we can assume that the type,
flag, and naming is supported when bpf_program_supported() succeeds.
BPF_PROG_TYPE_CGROUP_SKB is supported since kernel v4.10
(0e33661de493db325435d565a4a722120ae4cbf3) and
BPF_PROG_TYPE_CGROUP_SOCK_ADDR is supported since kernel v4.17
(4fbac77d2d092b475dda9eea66da674369665427).
Our baseline on the kernel is v5.4. The check is not necessary.
After 3988e2489a, the function is a simple
wrapper of bpf_dlopen() with logging. Let's introduce dlopen_bpf_full()
that takes log level, and replace cgroup_bpf_supported() with it.
The lz4 functions are only used in test-compress.c, so let's just
put the declarations and includes in there instead of having everyone
including compress.h pull in the lz4 headers.
Instead of unconditionally including sys/param.h in
macro-fundamental.h which itself includes a bunch of other unnecessary
headers, let's override it with an empty file to avoid it from overriding
our MAX() macro. We can't make including it an error as it's included (
for seemingly no good reason) by <resolv.h>.