Almost all programs are simple and have only a single command. When
printing options, let's just use the first COMMAND block found by default.
This means we can drop the explicit program-name argument and reduce
copy&paste boilerplate.
This commit tweaks the in_first_boot() code to make it
a proper shared helper. It tweaks the comments about the
caching policy. This is important because while this is
simialr to `in_initrd()` there is a suble difference:
we never cache the result of access() because other parts
of systemd will use this file to signal if anything about
firstboot changes.
This also tweaks it to return an int instead of a bool.
So any error is returned as -errno. This allows other
parts of systemd (like the random-seed) that need to make
decisions about "unknown" first-boot state.
This also means that the consumers need to get updated
and we can now also use the new helper in random-seed-tool.c
and have only a single helper to check for first-boot.
At line 285, ftruncate() failure was logged using 'r' which is 0
from the preceding successful loop_write() call. log_error_errno(0, ...)
triggers an assertion crash in developer builds (ASSERT_NON_ZERO) and
silently returns success in release builds, swallowing the ftruncate error.
Replace with errno which is set by ftruncate() on failure.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
Co-developed-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
I am really not a fan of full code lines passed to macros as parameters.
Let's get rid of the 3rd parameter of FOREACH_OPTION() hence:
1. Let's return errors just as a regular value (though a negative one),
that can be handled via a OPTION_ERROR case statement for the switch.
This normalizes handling of the error, just like any other event
returned by the option parser.
2. In order to avoid exploding the amount of boilerplate in each use
(that just propagates the error on OPTION_ERROR), let's then
introduce an explicit FOREACH_OPTION_OR_RETURN(), that returns from
the calling function on its own (and makes that clear in the name).
Together this cleans up, normalizes the logic and shortens the code.
It was requested to make the 'c', 'opt', and 'arg' params the same, i.e.
defined through the FOREACH_OPTION macro. But we can't do that easily,
because 'c' was defined in the for loop definition, and we can only
define variables of the same type in that way. Also, in some cases we
need only 'c', in other cases with need 'c' and 'arg, in some cases 'c'
and 'opt', and in other cases all three. We'd need to either
conditionalize or mark those variables with _unused_ to deal with
compiler warnings. But a different approach works quite nicely: add
state.opt and state.arg to show the current option and it's argument.
(The short names are picked on purpose to reduce verbosity since those
are used a lot.)
The path is fairly long and by embedding it in the message, we get a longer
data section in our binary. By using %s, we can make the template strings
shorter, deduplicating bytes in our binary. Those are error messages, i.e. by
definition they are only used very rarely, so it's completely fine if printf
does a bit more work when generating the message.
$ strings build/systemd-random-seed.0 | rg '/var/lib/systemd/random-seed'
/var/lib/systemd/random-seed
Failed to open /var/lib/systemd/random-seed for writing: %m
Failed to open /var/lib/systemd/random-seed for reading: %m
Failed to open /var/lib/systemd/random-seed: %m
Failed to stat() seed file /var/lib/systemd/random-seed: %m
Failed to read seed from /var/lib/systemd/random-seed: %m
Seed file /var/lib/systemd/random-seed not yet initialized, proceeding.
$ strings build/systemd-random-seed | rg '/var/lib/systemd/random-seed'
/var/lib/systemd/random-seed
$ ls -l build/systemd-random-seed{,.0}
-rwxr-xr-x 1 zbyszek zbyszek 68872 May 31 13:39 build/systemd-random-seed.0
-rwxr-xr-x 1 zbyszek zbyszek 64912 May 31 13:45 build/systemd-random-seed
That's a ~6% smaller binary!
Let's ensure all of our source file names are unique without having
to take the directory into account.
This allows us to create meson targets or unit tests identified by the
the name of the source file they operate on without having to include
the full path of the source file in the target or test name to avoid
conflicts.
This commit cleans up the includes for all the small tools across
the tree.
A few cases of returning EXIT_SUCCESS are replaced with returning
0 to avoid including <stdlib.h>.
Split out of #37344.
Plus, linux/random.h never defined getrandom(), hence remove
the custom machinery for sys/random.h vs linux/random.h
in favor of single HAVE_GETRANDOM.
The ESP is simply not mounted early enough for this. We want that the
regular random seed handling runs as early as we possibly could, but we
don't want to delay this until the ESP is actually mounted.
Hence, let's remove this from random-seed.c here. A follow-up commit
will then add this back in, in a separate service which just calls
"bootctl random-seed".
Effectively reverts: f913c784adFixes: #25769
-1 was used everywhere, but -EBADF or -EBADFD started being used in various
places. Let's make things consistent in the new style.
Note that there are two candidates:
EBADF 9 Bad file descriptor
EBADFD 77 File descriptor in bad state
Since we're initializating the fd, we're just assigning a value that means
"no fd yet", so it's just a bad file descriptor, and the first errno fits
better. If instead we had a valid file descriptor that became invalid because
of some operation or state change, the other errno would fit better.
In some places, initialization is dropped if unnecessary.
Since this runs at shutdown to write a new seed, we should also keep the
bootloader's seed maximally fresh by doing the same. So we follow the
same pattern - hash some new random bytes with the old seed to make a
new seed. We let this fail without warning, because it's just an
opportunistic thing. If the user happens to have set up the random seed
with bootctl, and the RNG is initialized, then things should be fine. If
not, we create a new seed if systemd-boot is in use. And if not, then we
just don't do anything.
We want the size to lie within [/proc/sys/kernel/random/poolsize,RANDOM_POOL_SIZE_MAX]
interval. Let's make it more obvious.
Also move the logic in a dedicated function.
It's not really necessary since systemd-random-seed is an internal tool for the
moment but this might change in future (to allow system installers to
initialize a random seed file for example).
Also introducing new options will be easier.
If we're consuming an on-disk seed, we usually write out a new one after
consuming it. In that case, we might be at early boot and the randomness
could be rather poor, and the kernel doesn't guarantee that it'll use
the new randomness right away for us. In order to prevent the new
entropy from getting any worse, hash together the old seed and the new
seed, and replace the final bytes of the new seed with the hash output.
This way, entropy strictly increases and never regresses.
Fixes: https://github.com/systemd/systemd/issues/21983
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>