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.
If we want to allow method replies to be extended without this breaking
compat, then we should set this flag. Do so at various method call
replies hence.
Also do it when parsing user/group records, which are expressly
documented to be extensible, as well as the hibernate JSON record.
Follow-up for a628d933cc
HibernateInfo.from_efi is not actually useful. info.efi is only
set if the system identifier stored in EFI variable matches with
that of the running system, and thus the variable should be cleared
no matter whether resume= is set from kernel cmdline or not.
Let's be friendly in what we accept: whenever we define a JSON
structure, let's also allow decimal strings where we want an integer.
This patch purely replaces JSON_VARIANT_UNSIGNED by
_JSON_VARIANT_TYPE_INVALID in the various JsonDispatch[] tables, so that
we'll happily accept any type in json_dispatch(), so that
json_dispatch_uint64() and related tools can do their thing.
This does not switch over OCI (as a JSON structure not defined by us).
varlink_dispatch() is a simple wrapper around json_dispatch() that
returns clean, standards-compliant InvalidParameter error back to
clients, if the specified JSON cannot be parsed properly.
For this json_dispatch() is extended to return the offending field's
name. Because it already has quite a few parameters, I then renamed
json_dispatch() to json_dispatch_full() and made json_dispatch() a
wrapper around it that passes the new argument as NULL. While doing so I
figured we should also get rid of the bad= argument in the short
wrapper, since it's only used in the OCI code.
To simplify the OCI code this adds a second wrapper oci_dispatch()
around json_dispatch_full(), that fills in bad= the way we want.
Net result: instead of one json_dispatch() call there are now:
1. json_dispatch_full() for the fully feature mother of all dispathers.
2. json_dispatch() for the simpler version that you want to use most of
the time.
3. varlink_dispatch() that generates nice Varlink errors
4. oci_dispatch() that does the OCI specific error handling
And that's all there is.
We already had a similar check that was removed, see
8340b762e4 (*). The kernel supports loading of a
resume image from a different kernel version. This makes sense, because the
goal of "resume" is to replace the running system by a saved memory image, so
it doesn't really matter that the short-lived kernel is different.
By removing the check, we make the process more reliable: for example, the user
may select a different kernel from a list, or not have the previously running
kernel in /boot at all, etc. Requiring the exact same kernel version makes the
process more fragile for no benefit.
Similar reasoning holds for the image version: the image may be updated, and
for example an older kernel+initrd might be used, with an embedded VERSION_ID
that is not the latest. This is fine, and the check is not useful.
I left the check for ID/IMAGE_ID: we probably don't want to use the resume
image if the hibernation was done from a different installation.
(Note: why not check VERSION_ID/IMAGE_VERSION? Because of the following
scenario: a user has an installation of Fedora 35, and they upgrade to Fedora
36, which means that the os-release file on disk gets replaced and now
specifies VERSION_ID=36. But the running kernel is not replaced, and its
package is not removed because the running kernel version is never removed, so
we still have a boot entry that in initrd-release says VERSION_ID=35. Without
rebooting, the user does hibernation. When resuming, we want to resume, no
matter if one of the new entries with VERSION_ID=36 or one of the old entries
with VERSION_ID=35 is picked in the boot loader menu.
If the installation is image-based, i.e. it has IMAGE_ID+IMAGE_VERSION, the
situation is similar: after an upgrade, we may still have an boot entry from
before the upgrade. Using an older kernel+initrd to boot and switch-root into a
newer installation is supported and is rather common.
In fact, it is a rather common situation that the version reported by the boot
entry (or stored internally in the initrd-release in the initrd) does not match
the actual system on disk. Generally, this metadata is saved when the boot menu
entry is written and does not reflect subsequent upgrades. Various
distributions generally keep at least 3 kernels after a upgrade, and during an
upgrade only install one new, which means that after a major upgrade, generally
there will be at least two kernels which have mismatched version information.)
OTOH, I think it is useful to *write* all the details to the EFI var. As
discussed in https://github.com/systemd/systemd/issues/29037, we may want to
show this information in the boot loader. It is also useful for debugging.
(*) Also again discussed and verified in
https://github.com/systemd/systemd/pull/27330#discussion_r1234332080.
", ignored" is dropped, since this failure is likely to cause the following
check to fail. Better not to say anything then to say the misleading thing.
Before this commit, the hibernate location logic only exists in
the generator. Also, we compare device nodes (devnode_same()) and
clear EFI variable HibernateLocation in the generator too. This is
not ideal though: when the generator gets to run, udev hasn't yet
started, so effectively devnode_same() always fails. Moreover, if
the boot process is interrupted by e.g. battery-check, the hibernate
information is lost.
Therefore, let's split out the logic of finding hibernate location.
The generator only does the initial validation of system info and
enables systemd-hibernate-resume.service, and when the service
actually runs we validate everything again, which includes comparing
the device nodes and clearing the EFI variable. This should make
things more robust, plus systems that don't utilize a systemd-enabled
initrd can use the exact same logic to resume using the EFI variable.
I.e., systemd-hibernate-resume can be used standalone.
If the key does not contain '-' or '_', then it is not necessary to use
proc_cmdline_key_streq(), and streq() is sufficient.
This also adds missing assertions about 'key' argument.
This log message is shown pretty regular at boot in various scenarios
(such as CI builds), and it's not a reason for any concern, it's just the
immediate effect of explicit configuration. Hence let's downgrade from
LOG_NOTICE to LOG_INFO so that it is still usually in the boot output,
but not particularly highlighted, since there's really no reason to.
With these settings we intend to turn off timeouts for possibly
interactive/slow commands. The officially documented way to turn off the
time-outs is to setting them to infinity. So far we set them to zero
here though.
This lead to some confusiong, for example #18224. Let's fix this by
uniformly spelling out TimeoutSec=infinity.
This doesn't change behaviour. It just makes our generated files match
what we document, without relying on historic compat support.
Fixes: #18224
I changed imports of util.h to initrd-util.h, or added an import of
initrd-util.h, to keep compilation working. It turns out that many files didn't
import util.h directly.
When viewing the patch, don't be confused by git rename detection logic:
a new .c file is added and two functions moved into it.
In most cases we refernced the concept as "initrd". Let's convert most
remaining uses of "initramfs" to "initrd" too, to stay internally
consistent.
This leaves "initramfs" only where it's relevant to explain historical
concepts or where "initramfs" is part of the API (i.e. in
/run/initramfs).
Follow-up for: b66a6e1a58
Previously the mkdir_label() family of calls was implemented in
src/shared/mkdir-label.c but its functions partly declared ins
src/shared/label.h and partly in src/basic/mkdir.h (!!). That's weird
(and wrong).
Let's clean this up, and add a proper mkdir-label.h matching the .c
file.
The naming of variables is very inconsistent. I tried to use more
modern style naming (UNDERSCORED_TITLE_CASE), but I didn't change existing
names too much. Only SYSTEM_DATA_UNIT_PATH is renamed to SYSTEM_DATA_UNIT_DIR
to match SYSTEM_CONFIG_UNIT_DIR.
This makes changes similar to the parent commit, but for hibernate-resume-generator.
If resume= is specified on the kernel command line, we'll set JobRunningTimeoutSec=0
for the device. This matches what we do for the root device.
In practice, other timeouts will take effect. For example dracut tries (and
fails :[ ) to start dracut-emergency.service after some time.
Fixes#7242, https://bugzilla.redhat.com/show_bug.cgi?id=1705522.
Adds the resumeflags= kernel command line option to allow setting a
custom device timeout for the resume device (defaults to the same as the
root device).
Fixes#7242
Sets the systemd device timeout for the resume device to the same as
the root device. This prevents systemd-hibernate-resume@.service from
silently timing out and booting into a fresh session instead of the
saved hibernation state when the user is using luks, has set
rootflags=x-systemd.device-timeout=X to longer than the default timeout,
and the luks password is entered after the default timeout.
Ideally, coccinelle would strip unnecessary braces too. But I do not see any
option in coccinelle for this, so instead, I edited the patch text using
search&replace to remove the braces. Unfortunately this is not fully automatic,
in particular it didn't deal well with if-else-if-else blocks and ifdefs, so
there is an increased likelikehood be some bugs in such spots.
I also removed part of the patch that coccinelle generated for udev, where we
returns -1 for failure. This should be fixed independently.
systemd already sets the umask (see e3b8d0637d). When
running under systemd, we don't need to set it. And when *not* running under
systemd, for example during development, there is no reason to override the user
config. Let's just drop those calls.
$ git grep -e 'umask\(' -l 'src/*generator*' |xargs perl -i -0pe 's|^[^\n]*umask\([^\n]+\n\n||gms'