Compare commits

..

9 Commits

Author SHA1 Message Date
Lennart Poettering e78228b1b0 update TODO 2020-06-26 15:43:36 +02:00
Lennart Poettering 10f9436c2d
Merge pull request #16281 from poettering/logind-cache-more-efi
logind: cache two more EFI variables in logind
2020-06-26 15:12:57 +02:00
Gaoyi 0090b551e6 Add quotes for -n
According to SC2070, -n doesn't work with unquoted arguments
https://github.com/koalaman/shellcheck/wiki/SC2070

Signed-off-by: Gaoyi <ymuemc@163.com>
2020-06-26 15:12:29 +02:00
Lennart Poettering 22aa58adc9 JOURNAL_FILE_FORMAT: minor markdown fixes 2020-06-26 13:55:18 +02:00
Lennart Poettering 1f19ae0ffb NEWS: add more items for 246 2020-06-26 13:54:54 +02:00
Lennart Poettering af2697e83d logind: also cache LoaderEntryOneShot EFI variable
With this we are now caching all EFI variables that we expose as
property in logind. Thus a client invoking GetAllProperties() should
only trgger a single read of each variable, but never repeated ones.

Obsoletes: #16190
Fixes: #14828
2020-06-26 10:43:42 +02:00
Lennart Poettering e8df4eee65 efi-loader: cache LoaderConfigTimeoutOneShot too
The data from this EFI variable is exposed as dbus property, and gdbus
clients are happy to issue GetAllProperties() as if it was free. Hence
make sure it's actually free and cache LoaderConfigTimeoutOneShot, since
it's easy.
2020-06-26 10:43:42 +02:00
Lennart Poettering 6eea6e30ab tmpfile-util: typo fixes 2020-06-26 10:41:52 +02:00
Yu Watanabe 95fc17bf46 util: add missing header guard 2020-06-26 08:02:21 +02:00
11 changed files with 235 additions and 52 deletions

107
NEWS
View File

@ -38,8 +38,9 @@ CHANGES WITH 246 in spe:
[GenericRandomEarlyDetection], "SFB" in [StochasticFairBlue], "cake"
in [CAKE], "PIE" in [PIE], "DRR" in [DeficitRoundRobinScheduler] and
[DeficitRoundRobinSchedulerClass], "BFIFO" in [BFIFO],
"PFIFOHeadDrop" in [PFIFOHeadDrop], "PFIFOFast" in [PFIFOFast] and
"HHF" in [HeavyHitterFilter].
"PFIFOHeadDrop" in [PFIFOHeadDrop], "PFIFOFast" in [PFIFOFast], "HHF"
in [HeavyHitterFilter], "ETS" in [EnhancedTransmissionSelection] and
"QFQ" in [QuickFairQueueingClass].
* systemd-networkd gained support for a new Termination= setting in the
[CAN] section for configuring the termination resistor. It also
@ -107,7 +108,7 @@ CHANGES WITH 246 in spe:
freeze and thaw respectively, or via D-Bus.
* systemd-udevd gained new configuration option timeout_signal= as well
as coresponding kernel command line option udev.timeout_signal.
as corresponding kernel command line option udev.timeout_signal=.
The option can be used to configure the UNIX signal that the main
daemon sends to the worker processes on timeout.
@ -272,6 +273,12 @@ CHANGES WITH 246 in spe:
* systemd-repart drop-ins now support a new UUID= setting to control
the UUID to assign to a newly created partition.
* systemd-repart's SizeMin= per-partition parameter now defaults to 10M
instead of 0.
* systemd-repart's Label= setting now support the usual, simple
specifier expansion.
* StandardError= and StandardOutput= in unit files no longer support
the "syslog" and "syslog-console" switches. They were long removed
from the documentation, but will now result in warnings when used,
@ -377,6 +384,100 @@ CHANGES WITH 246 in spe:
[IPv6AcceptRA] sections have been renamed DenyList=. The old names
are still understood to provide compatibility.
* systemd-journald gained support for zstd compression of large fields
in journal files. The hash tables in journal files have been hardened
against hash collisions. This is an incompatible change and means
that journal files created with new systemd versions are not readable
with old versions. If the $SYSTEMD_JOURNAL_KEYED_HASH boolean
environment variable for systemd-journald.service is set to 0 this
new hardening functionality may be turned off, so that generated
journal files remain compatible with older journalctl
implementations.
* Documentation for the on-disk Journal file format has been updated
and has now moved to:
https://systemd.io/JOURNAL_FILE_FORMAT
* systemd service units gained a new setting RootHash= which may be
used to specify the root hash for verity enabled disk images which
are specified in RootImage=. RootVerity= may be used to specify a
path to the Verity data matching a RootImage= file system. (The
latter is only useful for images that do not contain the Verity data
embedded into the same image that carries a GPT partition table
following the Discoverable Partition Specification). Similar,
systemd-nspawn gained a new switch --verity-data= that takes a path
to a file with the verity data of the disk image supplied in
--image=, if the image doesn't contain the verity data itself.
* systemd service units gained a new setting RootHashSignature= which
takes either a base64 encoded PKCS#7 signature of the root hash
specified with RootHash=, or a path to a file to read the signature
from. This allows validation of the root hash against public keys
available in the kernel keyring, and is only supported on recent
kernels (>= 5.4)/libcryptsetup (>= 2.30). A similar switch has been
added to systemd-nspawn and systemd-dissect
(--root-hash-sig=). Support for this mechanism has also been added to
systemd-veritysetup.
* A new 'hwdb' file has been added that collects information about PCI
and USB devices that correctly support auto-suspend, on top of the
databases for this we import from the ChromiumOS project. If you have
a device that supports auto-suspend correctly and where it should be
enabled by default, please submit a patch that adds it to the
database (see hwdb.d/60-autosuspend.hwdb).
* The service manager (PID1) gained a new D-Bus method call
SetShowStatus() which may be used to control whether it shall show
boot-time status output on the console. This method has a similar
effect to sending SIGRTMIN+20/SIGRTMIN+21 to PID 1.
* PID 1 may now automatically load pre-compiled AppArmor policies from
/etc/apparmor/earlypolicy during early boot.
* systemd-cryptsetup may now activate Microsoft BitLocker volumes via
/etc/crypttab, during boot.
* systemd service unit files gained two new options
TimeoutStartFailureMode=/TimeoutStopFailureMode= that may be used to
tune behaviour if a start or stop timeout is hit, i.e. whether to
terminate the service with SIGTERM, SIGABRT or SIGKILL.
* A kernel command line option "udev.blockdev_read_only" has been
added. If specified all hardware block devices that show up are
immediately marked as read-only by udev. This option is useful for
making sure that a specific boot under no circumstances modifies data
on disk. Use "blockdev --setrw" to undo the effect of this, per
device.
* Most options in systemd that accept hexadecimal values prefixed with
0x in additional to the usual decimal notation now also support octal
notation when he 0o prefix is used and binary notation if the 0b
prefix is used.
* "booctl" gained a new verb "reboot-to-firmware" that may be used
to query and change the firmware's reboot into firmware setup flag.
* journalctl will now include a clickable link in the default output for
each log message for which an URL with further documentation is
known. This is only supported on terminal emulators that support
clickable hyperlinks, and is turned off if a pager is used (since
"less" still doesn't support hyperlinks,
unfortunately). Documentation URLs may be included in log messages
either by including a DOCUMENTATION= journal field in it, or by
associating a journal message catalog entry with the log message's
MESSAGE_ID, which then carries a "Documentation:" tag.
* systemd-firstboot gained a new switch --kernel-command-line= that may
be used to initialize the /etc/kernel/cmdline file of the image. It
also gained a new switch --root-password-hashed= which is like
--root-password= but accepts a pre-hashed UNIX password as
argument. The new option --delete-root-password may be used to unset
any password for the root user (dangerous!). A new --force option may
be used to override any already set settings with the parameters
specified on the command line (by default, the tool will not override
what has already been set before, i.e. is purely incremental).
CHANGES WITH 245:
* A new tool "systemd-repart" has been added, that operates as an

4
TODO
View File

@ -30,6 +30,10 @@ Features:
* if /usr/bin/swapoff fails due to OOM, log a friendly explanatory message about it
* warn if User=nobody is used in a unit file. It's the overflow UID after all,
and the service might thus get access to files it really should not get
access to on NFS and userns environments.
* build short web pages out of each catalog entry, build them along with man
pages, and include hyperlinks to them in the journal output

View File

@ -73,12 +73,12 @@ thread](https://lists.freedesktop.org/archives/systemd-devel/2012-October/007054
* All offsets, sizes, time values, hashes (and most other numeric values) are 64bit unsigned integers in LE format.
* Offsets are always relative to the beginning of the file.
* The 64bit hash function siphash24 is used for newer journal files. For older files [Jenkins lookup3](https://en.wikipedia.org/wiki/Jenkins_hash_function) is used, more specifically jenkins_hashlittle2() with the first 32bit integer it returns as higher 32bit part of the 64bit value, and the second one uses as lower 32bit part.
* The 64bit hash function siphash24 is used for newer journal files. For older files [Jenkins lookup3](https://en.wikipedia.org/wiki/Jenkins_hash_function) is used, more specifically `jenkins_hashlittle2()` with the first 32bit integer it returns as higher 32bit part of the 64bit value, and the second one uses as lower 32bit part.
* All structures are aligned to 64bit boundaries and padded to multiples of 64bit
* The format is designed to be read and written via memory mapping using multiple mapped windows.
* All time values are stored in usec since the respective epoch.
* Wall clock time values are relative to the Unix time epoch, i.e. January 1st, 1970. (CLOCK_REALTIME)
* Monotonic time values are always stored jointly with the kernel boot ID value (i.e. /proc/sys/kernel/random/boot_id) they belong to. They tend to be relative to the start of the boot, but aren't for containers. (CLOCK_MONOTONIC)
* Wall clock time values are relative to the Unix time epoch, i.e. January 1st, 1970. (`CLOCK_REALTIME`)
* Monotonic time values are always stored jointly with the kernel boot ID value (i.e. `/proc/sys/kernel/random/boot_id`) they belong to. They tend to be relative to the start of the boot, but aren't for containers. (`CLOCK_MONOTONIC`)
* Randomized, unique 128bit IDs are used in various locations. These are generally UUID v4 compatible, but this is not a requirement.
## General Rules
@ -180,7 +180,7 @@ _packed_ struct Header {
};
```
The first 8 bytes of Journal files must contain the ASCII characters LPKSHHRH.
The first 8 bytes of Journal files must contain the ASCII characters `LPKSHHRH`.
If a writer finds that the **machine_id** of a file to write to does not match
the machine it is running on it should immediately rotate the file and start a
@ -237,18 +237,18 @@ field hash table, minus one.
The format is supposed to be extensible in order to enable future additions of
features. Readers should simply skip objects of unknown types as they read
them. If a compatible feature extension is made a new bit is registered in the
header's 'compatible_flags' field. If a feature extension is used that makes
header's **compatible_flags** field. If a feature extension is used that makes
the format incompatible a new bit is registered in the header's
'incompatible_flags' field. Readers should check these two bit fields, if they
find a flag they don't understand in compatible_flags they should continue to
read the file, but if they find one in 'incompatible_flags' they should fail,
asking for an update of the software. Writers should refuse writing if there's
an unknown bit flag in either of these fields.
**incompatible_flags** field. Readers should check these two bit fields, if
they find a flag they don't understand in compatible_flags they should continue
to read the file, but if they find one in **incompatible_flags** they should
fail, asking for an update of the software. Writers should refuse writing if
there's an unknown bit flag in either of these fields.
The file header may be extended as new features are added. The size of the file
header is stored in the header. All header fields up to "n_data" are known to
header is stored in the header. All header fields up to **n_data** are known to
unconditionally exist in all revisions of the file format, all fields starting
with "n_data" needs to be explicitly checked for via a size check, since they
with **n_data** needs to be explicitly checked for via a size check, since they
were additions after the initial release.
Currently only five extensions flagged in the flags fields are known:
@ -298,7 +298,7 @@ STATE_ARCHIVED. If a writer is asked to write to a file that is not in
STATE_OFFLINE it should immediately rotate the file and start a new one,
without changing the file.
After and before the state field is changed fdatasync() should be executed on
After and before the state field is changed `fdatasync()` should be executed on
the file to ensure the dirty state hits disk.
@ -318,9 +318,9 @@ among several files, such as the system journal and many per-user journals.
The file format is designed to be usable in a simultaneous
single-writer/multiple-reader scenario. The synchronization model is very weak
in order to facilitate storage on the most basic of file systems (well, the
most basic ones that provide us with mmap() that is), and allow good
most basic ones that provide us with `mmap()` that is), and allow good
performance. No file locking is used. The only time where disk synchronization
via fdatasync() should be enforced is after and before changing the **state**
via `fdatasync()` should be enforced is after and before changing the **state**
field in the file header (see below). It is recommended to execute a memory
barrier after appending and initializing new objects at the end of the file,
and before linking them up in the earlier objects.
@ -336,11 +336,11 @@ might become consistent later on. Payload OTOH requires less scrutiny, as it
should only be linked up (and hence visible to readers) after it was
successfully written to memory (though not necessarily to disk). On non-local
file systems it is a good idea to verify the payload hashes when reading, in
order to avoid annoyances with mmap() inconsistencies.
order to avoid annoyances with `mmap()` inconsistencies.
Clients intending to show a live view of the journal should use inotify() for
this to watch for files changes. Since file writes done via mmap() do not
result in inotify() writers shall truncate the file to its current size after
Clients intending to show a live view of the journal should use `inotify()` for
this to watch for files changes. Since file writes done via `mmap()` do not
result in `inotify()` writers shall truncate the file to its current size after
writing one or more entries, which results in inotify events being
generated. Note that this is not used as a transaction scheme (it doesn't
protect anything), but merely for triggering wakeups.
@ -369,6 +369,7 @@ _packed_ struct ObjectHeader {
le64_t size;
uint8_t payload[];
};
```
The **type** field is one of the object types listed above. The **flags** field
currently knows three flags: OBJECT_COMPRESSED_XZ, OBJECT_COMPRESSED_LZ4 and
@ -397,11 +398,11 @@ _packed_ struct DataObject {
```
Data objects carry actual field data in the **payload[]** array, including a
field name, a '=' and the field data. Example:
field name, a `=` and the field data. Example:
`_SYSTEMD_UNIT=foobar.service`. The **hash** field is a hash value of the
payload. If the `HEADER_INCOMPATIBLE_KEYED_HASH` flag is set in the file header
this is the siphash24 hash value of the payload, keyed by the file ID as stored
in the `.file_id` field of the file header. If the flag is not set it is the
in the **file_id** field of the file header. If the flag is not set it is the
non-keyed Jenkins hash of the payload instead. The keyed hash is preferred as
it makes the format more robust against attackers that want to trigger hash
collisions in the hash table.

View File

@ -257,7 +257,7 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
assert((flags & O_EXCL) == 0);
/* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE in
* which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
* which case "ret_path" will be returned as NULL. If not possible the temporary path name used is returned in
* "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
fd = open_parent(target, O_TMPFILE|flags, 0640);

View File

@ -2751,8 +2751,6 @@ static int property_get_reboot_to_boot_loader_menu(
r = getenv_bool("SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU");
if (r == -ENXIO) {
_cleanup_free_ char *v = NULL;
/* EFI case: returns the current value of LoaderConfigTimeoutOneShot. Three cases are distuingished:
*
* 1. Variable not set, boot into boot loader menu is not enabled (we return UINT64_MAX to the user)
@ -2760,20 +2758,10 @@ static int property_get_reboot_to_boot_loader_menu(
* 3. Variable set to numeric value formatted in ASCII, boot into boot loader menu with the specified timeout in seconds
*/
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderConfigTimeoutOneShot", &v);
r = efi_loader_get_config_timeout_one_shot(&x);
if (r < 0) {
if (r != -ENOENT)
log_warning_errno(r, "Failed to read LoaderConfigTimeoutOneShot variable: %m");
} else {
uint64_t sec;
r = safe_atou64(v, &sec);
if (r < 0)
log_warning_errno(r, "Failed to parse LoaderConfigTimeoutOneShot value '%s': %m", v);
else if (sec > (USEC_INFINITY / USEC_PER_SEC))
log_warning("LoaderConfigTimeoutOneShot too large, ignoring: %m");
else
x = sec * USEC_PER_SEC; /* return in µs */
log_warning_errno(r, "Failed to read LoaderConfigTimeoutOneShot variable, ignoring: %m");
}
} else if (r < 0)
@ -2932,24 +2920,25 @@ static int property_get_reboot_to_boot_loader_entry(
sd_bus_error *error) {
_cleanup_free_ char *v = NULL;
Manager *m = userdata;
const char *x = NULL;
int r;
assert(bus);
assert(reply);
assert(userdata);
assert(m);
r = getenv_bool("SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY");
if (r == -ENXIO) {
/* EFI case: let's read the LoaderEntryOneShot variable */
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntryOneShot", &v);
r = efi_loader_update_entry_one_shot_cache(&m->efi_loader_entry_one_shot, &m->efi_loader_entry_one_shot_stat);
if (r < 0) {
if (r != -ENOENT)
log_warning_errno(r, "Failed to read LoaderEntryOneShot variable: %m");
} else if (!efi_loader_entry_name_valid(v)) {
log_warning("LoaderEntryOneShot contains invalid entry name '%s', ignoring.", v);
v = mfree(v);
}
log_warning_errno(r, "Failed to read LoaderEntryOneShot variable, ignoring: %m");
} else
x = m->efi_loader_entry_one_shot;
} else if (r < 0)
log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY: %m");
else if (r > 0) {
@ -2959,14 +2948,14 @@ static int property_get_reboot_to_boot_loader_entry(
r = read_one_line_file("/run/systemd/reboot-to-boot-loader-entry", &v);
if (r < 0) {
if (r != -ENOENT)
log_warning_errno(r, "Failed to read /run/systemd/reboot-to-boot-loader-entry: %m");
} else if (!efi_loader_entry_name_valid(v)) {
log_warning_errno(r, "Failed to read /run/systemd/reboot-to-boot-loader-entry, ignoring: %m");
} else if (!efi_loader_entry_name_valid(v))
log_warning("/run/systemd/reboot-to-boot-loader-entry is not valid, ignoring.");
v = mfree(v);
}
else
x = v;
}
return sd_bus_message_append(reply, "s", v);
return sd_bus_message_append(reply, "s", x);
}
static int boot_loader_entry_exists(Manager *m, const char *id) {

View File

@ -169,6 +169,7 @@ static Manager* manager_unref(Manager *m) {
free(m->action_job);
strv_free(m->efi_boot_loader_entries);
free(m->efi_loader_entry_one_shot);
return mfree(m);
}

View File

@ -126,6 +126,9 @@ struct Manager {
char **efi_boot_loader_entries;
bool efi_boot_loader_entries_set;
char *efi_loader_entry_one_shot;
struct stat efi_loader_entry_one_shot_stat;
};
void manager_reset_config(Manager *m);

View File

@ -1,4 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "sd-bus.h"

View File

@ -734,3 +734,73 @@ char *efi_tilt_backslashes(char *s) {
return s;
}
int efi_loader_get_config_timeout_one_shot(usec_t *ret) {
_cleanup_free_ char *v = NULL, *fn = NULL;
static struct stat cache_stat = {};
struct stat new_stat;
static usec_t cache;
uint64_t sec;
int r;
assert(ret);
fn = efi_variable_path(EFI_VENDOR_LOADER, "LoaderConfigTimeoutOneShot");
if (!fn)
return -ENOMEM;
/* stat() the EFI variable, to see if the mtime changed. If it did we need to cache again. */
if (stat(fn, &new_stat) < 0)
return -errno;
if (stat_inode_unmodified(&new_stat, &cache_stat)) {
*ret = cache;
return 0;
}
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderConfigTimeoutOneShot", &v);
if (r < 0)
return r;
r = safe_atou64(v, &sec);
if (r < 0)
return r;
if (sec > USEC_INFINITY / USEC_PER_SEC)
return -ERANGE;
cache_stat = new_stat;
*ret = cache = sec * USEC_PER_SEC; /* return in µs */
return 0;
}
int efi_loader_update_entry_one_shot_cache(char **cache, struct stat *cache_stat) {
_cleanup_free_ char *fn = NULL, *v = NULL;
struct stat new_stat;
int r;
assert(cache);
assert(cache_stat);
fn = efi_variable_path(EFI_VENDOR_LOADER, "LoaderEntryOneShot");
if (!fn)
return -ENOMEM;
/* stat() the EFI variable, to see if the mtime changed. If it did we need to cache again. */
if (stat(fn, &new_stat) < 0)
return -errno;
if (stat_inode_unmodified(&new_stat, cache_stat))
return 0;
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntryOneShot", &v);
if (r < 0)
return r;
if (!efi_loader_entry_name_valid(v))
return -EINVAL;
*cache_stat = new_stat;
free_and_replace(*cache, v);
return 0;
}

View File

@ -3,6 +3,8 @@
#include "efivars.h"
#include <sys/stat.h>
#if ENABLE_EFI
int efi_reboot_to_firmware_supported(void);
@ -23,6 +25,9 @@ int efi_loader_get_entries(char ***ret);
int efi_loader_get_features(uint64_t *ret);
int efi_loader_get_config_timeout_one_shot(usec_t *ret);
int efi_loader_update_entry_one_shot_cache(char **cache, struct stat *cache_stat);
#else
static inline int efi_reboot_to_firmware_supported(void) {
@ -77,6 +82,14 @@ static inline int efi_loader_get_features(uint64_t *ret) {
return -EOPNOTSUPP;
}
static inline int efi_loader_get_config_timeout_one_shot(usec_t *ret) {
return -EOPNOTSUPP;
}
static inline int efi_loader_update_entry_one_shot_cache(char **cache, struct stat *cache_stat) {
return -EOPNOTSUPP;
}
#endif
bool efi_loader_entry_name_valid(const char *s);

View File

@ -120,7 +120,7 @@ systemctlCheckNUMAProperties() {
> "$LOGFILE"
if [ -n $3 ]; then
if [ -n "$3" ]; then
systemctl show -p NUMAMask $1 > "$LOGFILE"
grep "NUMAMask=$3" "$LOGFILE"
fi