diff --git a/man/nss-resolve.xml b/man/nss-resolve.xml
index 4f9e1f9c5..d8957dd34 100644
--- a/man/nss-resolve.xml
+++ b/man/nss-resolve.xml
@@ -58,6 +58,10 @@
hostnames. If you rely on that lookup being provided by DNS, you might
want to order things differently.
+
+ Communication between nss-resolve and
+ systemd-resolved.service takes place via the
+ /run/systemd/resolve/io.systemd.Resolve AF_UNIX socket.
diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml
index 9ddd129aa..a71c291ad 100644
--- a/man/sd_listen_fds.xml
+++ b/man/sd_listen_fds.xml
@@ -45,14 +45,24 @@
Description
- sd_listen_fds() may be invoked by a
- daemon to check for file descriptors passed by the service manager as
- part of the socket-based activation logic. It returns the number
- of received file descriptors. If no file descriptors have been
- received, zero is returned. The first file descriptor may be found
- at file descriptor number 3
- (i.e. SD_LISTEN_FDS_START), the remaining
- descriptors follow at 4, 5, 6, …, if any.
+ sd_listen_fds() may be invoked by a daemon to check for file descriptors
+ passed by the service manager as part of the socket-based activation logic. It returns the number of
+ received file descriptors. If no file descriptors have been received, zero is returned. The first file
+ descriptor may be found at file descriptor number 3 (i.e. SD_LISTEN_FDS_START), the
+ remaining descriptors follow at 4, 5, 6, …, if any.
+
+ The file descriptors passed this way may be closed at will by the processes receiving them: it's up
+ to the processes themselves to close them after use or whether to leave them open until the process exits
+ (in which case the kernel closes them automatically). Note that the file descriptors received by daemons
+ are duplicates of the file descriptors the service manager originally allocated and bound and of which it
+ continously keeps a copy (except if Accept=yes is used). This means any socket option
+ changes and other changes made to the sockets will visible to the service manager too. Most importanly
+ this means it's generally not a good idea to invoke shutdown2 on
+ such sockets, since it will shut down communication on the file descriptor the service manager holds for
+ the same socket, too. Also note that if a daemon is restarted (and its associated sockets are not) it
+ will receive file descriptors to the very same sockets as the earlier invocations, thus all socket
+ options applied then will still apply.
If a daemon receives more than one file descriptor, they will be passed in the same order as
configured in the systemd socket unit file (see
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 5a133dea7..b6be21ed8 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -65,6 +65,13 @@
that are shown are additionally filtered by and if those
options are specified.
+ Note that this command does not show unit templates, but only instances of unit
+ templates. Units templates that aren't instantiated are not runnable, and will thus never show up
+ in the output of this command. Specifically this means that foo@.service
+ will never be shown in this list — unless instantiated, e.g. as
+ foo@bar.service. Use list-unit-files (see below) for
+ listing installed unit template files.
+
Produces output similar to
UNIT LOAD ACTIVE SUB DESCRIPTION
sys-module-fuse.device loaded active plugged /sys/module/fuse
@@ -81,11 +88,11 @@ ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
123 loaded units listed. Pass --all to see loaded but inactive units, too.
-To show all installed unit files use 'systemctl list-unit-files'.
-
- The header and the last unit of a given type are underlined if the
- terminal supports that. A colored dot is shown next to services which
- were masked, not found, or otherwise failed.
+To show all installed unit files use 'systemctl list-unit-files'.
+
+ The header and the last unit of a given type are underlined if the terminal supports
+ that. A colored dot is shown next to services which were masked, not found, or otherwise
+ failed.
The LOAD column shows the load state, one of loaded,
not-found, bad-setting, error,
@@ -694,10 +701,13 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
list-unit-files PATTERN…
- List unit files installed on the system, in combination with their enablement state (as reported by
- is-enabled). If one or more PATTERNs are specified, only unit
- files whose name matches one of them are shown (patterns matching unit file system paths are not
- supported).
+ List unit files installed on the system, in combination with their enablement state (as
+ reported by is-enabled). If one or more PATTERNs
+ are specified, only unit files whose name matches one of them are shown (patterns matching unit
+ file system paths are not supported).
+
+ Unlike list-units this command will list template units in addition to
+ explicitly instantiated units.
diff --git a/man/systemd-cryptenroll.xml b/man/systemd-cryptenroll.xml
index c6d6c5bd6..01c8a71fe 100644
--- a/man/systemd-cryptenroll.xml
+++ b/man/systemd-cryptenroll.xml
@@ -58,6 +58,23 @@
area, which is not available in other encryption formats.
+
+ Limitations
+
+ Note that currently when enrolling a new key of one of the five supported types listed above, it is
+ required to first provide a passphrase or recovery key (i.e. one of the latter two key types). For
+ example, it's currently not possible to unlock a device with a FIDO2 key in order to enroll a new FIDO2
+ key. Instead, in order to enroll a new FIDO2 key, it is necessary to provide an already enrolled regular
+ passphrase or recovery key. Thus, if in future key roll-over is desired it's generally recommended to
+ combine TPM2, FIDO2, PKCS#11 key enrollment with enrolling a regular passphrase or recovery key.
+
+ Also note that support for enrolling multiple FIDO2 tokens is currently not too useful, as while
+ unlocking systemd-cryptsetup cannot identify which token is currently plugged in and
+ thus does not know which authentication request to send to the device. This limitation does not apply to
+ tokens enrolled via PKCS#11 — because tokens of this type may be identified immediately, before
+ authentication.
+
+
Options
diff --git a/man/systemd-veritysetup-generator.xml b/man/systemd-veritysetup-generator.xml
index bf5e705f8..3c9ee6788 100644
--- a/man/systemd-veritysetup-generator.xml
+++ b/man/systemd-veritysetup-generator.xml
@@ -17,7 +17,7 @@
systemd-veritysetup-generator
- Unit generator for integrity protected block devices
+ Unit generator for verity protected block devices
@@ -28,7 +28,7 @@
Description
systemd-veritysetup-generator is a generator that translates kernel command line options
- configuring integrity-protected block devices (verity) into native systemd units early at boot and when
+ configuring verity protected block devices into native systemd units early at boot and when
configuration of the system manager is reloaded. This will create
systemd-veritysetup@.service8
units as necessary.
@@ -66,7 +66,7 @@
data devices to use are automatically derived from the specified hash value. Specifically, the data partition
device is looked for under a GPT partition UUID derived from the first 128bit of the root hash, the hash
partition device is looked for under a GPT partition UUID derived from the last 128bit of the root hash. Hence
- it is usually sufficient to specify the root hash to boot from an integrity protected root file system, as
+ it is usually sufficient to specify the root hash to boot from a verity protected root file system, as
device paths are automatically determined from it — as long as the partition table is properly set up.
@@ -76,7 +76,7 @@
systemd.verity_root_hash=
These two settings take block device paths as arguments and may be used to explicitly
- configure the data partition and hash partition to use for setting up the integrity protection for the root file
+ configure the data partition and hash partition to use for setting up the verity protection for the root file
system. If not specified, these paths are automatically derived from the roothash= argument
(see above).
diff --git a/man/systemd-veritysetup@.service.xml b/man/systemd-veritysetup@.service.xml
index 70f08374e..0f21c2fbb 100644
--- a/man/systemd-veritysetup@.service.xml
+++ b/man/systemd-veritysetup@.service.xml
@@ -18,7 +18,7 @@
systemd-veritysetup@.service
systemd-veritysetup
- Disk integrity protection logic
+ Disk verity protection logic
@@ -29,12 +29,12 @@
Description
- systemd-veritysetup@.service is a service responsible for setting up integrity
- protection (verity) block devices. It should be instantiated for each device that requires integrity
+ systemd-veritysetup@.service is a service responsible for setting up verity
+ protection block devices. It should be instantiated for each device that requires verity
protection.
At early boot and when the system manager configuration is reloaded kernel command line configuration for
- integrity protected block devices is translated into systemd-veritysetup@.service units by
+ verity protected block devices is translated into systemd-veritysetup@.service units by
systemd-veritysetup-generator8.
systemd-veritysetup@.service calls systemd-veritysetup.
diff --git a/man/veritytab.xml b/man/veritytab.xml
index d29e9f5f2..28dce1fe3 100644
--- a/man/veritytab.xml
+++ b/man/veritytab.xml
@@ -33,12 +33,12 @@ This is based on crypttab(5).
Description
The /etc/veritytab file describes
- verity integrity protected block devices that are set up during
+ verity protected block devices that are set up during
system boot.
Empty lines and lines starting with the #
character are ignored. Each of the remaining lines describes one
- verity integrity protected block device. Fields are delimited by
+ verity protected block device. Fields are delimited by
white space.
Each line is in the formvolume-name data-device hash-device roothash options
@@ -65,7 +65,7 @@ This is based on crypttab(5).
- Defines what to do if data integrity problem is detected (data corruption). Without these
+ Defines what to do if a data verity problem is detected (data corruption). Without these
options kernel fails the IO operation with I/O error. With --ignore-corruption option the
corruption is only logged. With --restart-on-corruption or
--panic-on-corruption the kernel is restarted (panicked) immediately.
@@ -149,18 +149,18 @@ This is based on crypttab(5).
- Setup this verity integrity protected block device in the initramfs, similarly to
+ Setup this verity protected block device in the initramfs, similarly to
systemd.mount5
units marked with .
Although it's not necessary to mark the mount entry for the root file system with
, is still recommended with
- the verity integrity protected block device containing the root file system as otherwise systemd
+ the verity protected block device containing the root file system as otherwise systemd
will attempt to detach the device during the regular system shutdown while it's still in
use. With this option the device will still be detached but later after the root file
system is unmounted.
- All other verity integrity protected block devices that contain file systems mounted in the
+ All other verity protected block devices that contain file systems mounted in the
initramfs should use this option.
@@ -176,7 +176,7 @@ This is based on crypttab(5).
Examples
/etc/veritytab example
- Set up two verity integrity protected block devices. One using device blocks, another using files.
+ Set up two verity protected block devices. One using device blocks, another using files.
usr PARTUUID=783e45ae-7aa3-484a-beef-a80ff9c19cbb PARTUUID=21dc1dfe-4c33-8b48-98a9-918a22eb3e37 36e3f740ad502e2c25e2a23d9c7c17bf0fdad2300b7580842d4b7ec1fb0fa263 auto
data /etc/data /etc/hash a5ee4b42f70ae1f46a08a7c92c2e0a20672ad2f514792730f5d49d7606ab8fdf auto
diff --git a/meson.build b/meson.build
index b5a51b6d0..5bdfd9753 100644
--- a/meson.build
+++ b/meson.build
@@ -2493,18 +2493,17 @@ endif
if conf.get('ENABLE_LOCALED') == 1
if conf.get('HAVE_XKBCOMMON') == 1
- # logind will load libxkbcommon.so dynamically on its own
- deps = [libdl]
- extra_includes = [libxkbcommon.get_pkgconfig_variable('includedir')]
+ # logind will load libxkbcommon.so dynamically on its own, but we still
+ # need to specify where the headers are
+ deps = [libdl, libxkbcommon.partial_dependency(compile_args: true)]
else
deps = []
- extra_includes = []
endif
executable(
'systemd-localed',
systemd_localed_sources,
- include_directories : includes + extra_includes,
+ include_directories : includes,
link_with : [libshared],
dependencies : deps,
install_rpath : rootlibexecdir,
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 14259ea8d..461bbfe9a 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -858,8 +858,8 @@ int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout) {
void sigkill_wait(pid_t pid) {
assert(pid > 1);
- if (kill(pid, SIGKILL) >= 0)
- (void) wait_for_terminate(pid, NULL);
+ (void) kill(pid, SIGKILL);
+ (void) wait_for_terminate(pid, NULL);
}
void sigkill_waitp(pid_t *pid) {
@@ -876,8 +876,8 @@ void sigkill_waitp(pid_t *pid) {
void sigterm_wait(pid_t pid) {
assert(pid > 1);
- if (kill_and_sigcont(pid, SIGTERM) >= 0)
- (void) wait_for_terminate(pid, NULL);
+ (void) kill_and_sigcont(pid, SIGTERM);
+ (void) wait_for_terminate(pid, NULL);
}
int kill_and_sigcont(pid_t pid, int sig) {
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index 72a7e4a48..56f7652ce 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -79,7 +79,7 @@ int dir_is_empty_at(int dir_fd, const char *path) {
} else {
/* Note that DUPing is not enough, as the internal pointer
* would still be shared and moved by FOREACH_DIRENT. */
- fd = fd_reopen(dir_fd, O_CLOEXEC);
+ fd = fd_reopen(dir_fd, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
if (fd < 0)
return fd;
}
diff --git a/src/basic/virt.c b/src/basic/virt.c
index 7ed01ba3c..cc123a286 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -159,12 +159,13 @@ static int detect_vm_dmi_vendor(void) {
{ "VMware", VIRTUALIZATION_VMWARE }, /* https://kb.vmware.com/s/article/1009458 */
{ "VMW", VIRTUALIZATION_VMWARE },
{ "innotek GmbH", VIRTUALIZATION_ORACLE },
- { "Oracle Corporation", VIRTUALIZATION_ORACLE },
+ { "VirtualBox", VIRTUALIZATION_ORACLE },
{ "Xen", VIRTUALIZATION_XEN },
{ "Bochs", VIRTUALIZATION_BOCHS },
{ "Parallels", VIRTUALIZATION_PARALLELS },
/* https://wiki.freebsd.org/bhyve */
{ "BHYVE", VIRTUALIZATION_BHYVE },
+ { "Microsoft", VIRTUALIZATION_MICROSOFT },
};
int r;
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index 13940a6df..b4f3b9605 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -134,7 +134,7 @@ static BOOLEAN line_edit(
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, print);
uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, cursor, y_pos);
- err = console_key_read(&key, TRUE);
+ err = console_key_read(&key, 0);
if (EFI_ERROR(err))
continue;
@@ -387,7 +387,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
Print(L"OsIndicationsSupported: %d\n", indvar);
Print(L"\n--- press key ---\n\n");
- console_key_read(&key, TRUE);
+ console_key_read(&key, 0);
Print(L"timeout: %u\n", config->timeout_sec);
if (config->timeout_sec_efivar >= 0)
@@ -432,7 +432,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
Print(L"LoaderEntryDefault: %s\n", defaultstr);
Print(L"\n--- press key ---\n\n");
- console_key_read(&key, TRUE);
+ console_key_read(&key, 0);
for (UINTN i = 0; i < config->entry_count; i++) {
ConfigEntry *entry;
@@ -482,7 +482,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
entry->path, entry->next_name);
Print(L"\n--- press key ---\n\n");
- console_key_read(&key, TRUE);
+ console_key_read(&key, 0);
}
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
@@ -509,11 +509,10 @@ static BOOLEAN menu_run(
UINTN y_max;
CHAR16 *status;
CHAR16 *clearline;
- INTN timeout_remain;
+ UINTN timeout_remain = config->timeout_sec;
INT16 idx;
BOOLEAN exit = FALSE;
BOOLEAN run = TRUE;
- BOOLEAN wait = FALSE;
graphics_mode(FALSE);
uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE);
@@ -527,7 +526,7 @@ static BOOLEAN menu_run(
err = console_set_mode(&config->console_mode, config->console_mode_change);
if (EFI_ERROR(err)) {
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- Print(L"Error switching console mode to %ld: %r.\r", (UINT64)config->console_mode, err);
+ log_error_stall(L"Error switching console mode to %lu: %r", (UINT64)config->console_mode, err);
}
} else
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
@@ -538,12 +537,6 @@ static BOOLEAN menu_run(
y_max = 25;
}
- /* we check 10 times per second for a keystroke */
- if (config->timeout_sec > 0)
- timeout_remain = config->timeout_sec * 10;
- else
- timeout_remain = -1;
-
idx_highlight = config->idx_default;
idx_highlight_prev = 0;
@@ -643,7 +636,7 @@ static BOOLEAN menu_run(
if (timeout_remain > 0) {
FreePool(status);
- status = PoolPrint(L"Boot in %d sec.", (timeout_remain + 5) / 10);
+ status = PoolPrint(L"Boot in %d s.", timeout_remain);
}
/* print status at last line of screen */
@@ -664,27 +657,18 @@ static BOOLEAN menu_run(
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, clearline+1 + x + len);
}
- err = console_key_read(&key, wait);
- if (EFI_ERROR(err)) {
- /* timeout reached */
+ err = console_key_read(&key, timeout_remain > 0 ? 1000 * 1000 : 0);
+ if (err == EFI_TIMEOUT) {
+ timeout_remain--;
if (timeout_remain == 0) {
exit = TRUE;
break;
}
- /* sleep and update status */
- if (timeout_remain > 0) {
- uefi_call_wrapper(BS->Stall, 1, 100 * 1000);
- timeout_remain--;
- continue;
- }
-
- /* timeout disabled, wait for next key */
- wait = TRUE;
+ /* update status */
continue;
- }
-
- timeout_remain = -1;
+ } else
+ timeout_remain = 0;
/* clear status after keystroke */
if (status) {
@@ -787,7 +771,7 @@ static BOOLEAN menu_run(
config->timeout_sec_efivar,
EFI_VARIABLE_NON_VOLATILE);
if (config->timeout_sec_efivar > 0)
- status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar);
+ status = PoolPrint(L"Menu timeout set to %d s.", config->timeout_sec_efivar);
else
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
} else if (config->timeout_sec_efivar <= 0){
@@ -795,7 +779,7 @@ static BOOLEAN menu_run(
efivar_set(
LOADER_GUID, L"LoaderConfigTimeout", NULL, EFI_VARIABLE_NON_VOLATILE);
if (config->timeout_sec_config > 0)
- status = PoolPrint(L"Menu timeout of %d sec is defined by configuration file.",
+ status = PoolPrint(L"Menu timeout of %d s is defined by configuration file.",
config->timeout_sec_config);
else
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
@@ -813,7 +797,7 @@ static BOOLEAN menu_run(
config->timeout_sec_efivar,
EFI_VARIABLE_NON_VOLATILE);
if (config->timeout_sec_efivar > 0)
- status = PoolPrint(L"Menu timeout set to %d sec.",
+ status = PoolPrint(L"Menu timeout set to %d s.",
config->timeout_sec_efivar);
else
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
@@ -1221,8 +1205,7 @@ static VOID config_entry_bump_counters(
break;
if (r != EFI_BUFFER_TOO_SMALL || file_info_size * 2 < file_info_size) {
- Print(L"\nFailed to get file info for '%s': %r\n", old_path, r);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+ log_error_stall(L"Failed to get file info for '%s': %r", old_path, r);
return;
}
@@ -1234,8 +1217,7 @@ static VOID config_entry_bump_counters(
StrCpy(file_info->FileName, entry->next_name);
r = uefi_call_wrapper(handle->SetInfo, 4, handle, &EfiFileInfoGuid, file_info_size, file_info);
if (EFI_ERROR(r)) {
- Print(L"\nFailed to rename '%s' to '%s', ignoring: %r\n", old_path, entry->next_name, r);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+ log_error_stall(L"Failed to rename '%s' to '%s', ignoring: %r", old_path, entry->next_name, r);
return;
}
@@ -2165,18 +2147,12 @@ static EFI_STATUS image_start(
EFI_STATUS err;
path = FileDevicePath(entry->device, entry->loader);
- if (!path) {
- Print(L"Error getting device path.");
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return EFI_INVALID_PARAMETER;
- }
+ if (!path)
+ return log_error_status_stall(EFI_INVALID_PARAMETER, L"Error getting device path.");
err = uefi_call_wrapper(BS->LoadImage, 6, FALSE, parent_image, path, NULL, 0, &image);
- if (EFI_ERROR(err)) {
- Print(L"Error loading %s: %r", entry->loader, err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return err;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Error loading %s: %r", entry->loader, err);
if (config->options_edit)
options = config->options_edit;
@@ -2190,8 +2166,7 @@ static EFI_STATUS image_start(
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (EFI_ERROR(err)) {
- Print(L"Error getting LoadedImageProtocol handle: %r", err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+ log_error_stall(L"Error getting LoadedImageProtocol handle: %r", err);
goto out_unload;
}
loaded_image->LoadOptions = options;
@@ -2202,10 +2177,8 @@ static EFI_STATUS image_start(
err = tpm_log_event(SD_TPM_PCR,
(EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions,
loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
- if (EFI_ERROR(err)) {
- Print(L"Unable to add image options measurement: %r", err);
- uefi_call_wrapper(BS->Stall, 1, 200 * 1000);
- }
+ if (EFI_ERROR(err))
+ log_error_stall(L"Unable to add image options measurement: %r", err);
#endif
}
@@ -2231,9 +2204,7 @@ static EFI_STATUS reboot_into_firmware(VOID) {
return err;
err = uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold, EFI_SUCCESS, 0, NULL);
- Print(L"Error calling ResetSystem: %r", err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return err;
+ return log_error_status_stall(err, L"Error calling ResetSystem: %r", err);
}
static VOID config_free(Config *config) {
@@ -2305,30 +2276,21 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (EFI_ERROR(err)) {
- Print(L"Error getting a LoadedImageProtocol handle: %r", err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return err;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
/* export the device path this image is started from */
if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS)
efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, 0);
root_dir = LibOpenRoot(loaded_image->DeviceHandle);
- if (!root_dir) {
- Print(L"Unable to open root directory.");
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return EFI_LOAD_ERROR;
- }
+ if (!root_dir)
+ return log_error_status_stall(EFI_LOAD_ERROR, L"Unable to open root directory.", EFI_LOAD_ERROR);
if (secure_boot_enabled() && shim_loaded()) {
err = security_policy_install();
- if (EFI_ERROR(err)) {
- Print(L"Error installing security policy: %r ", err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return err;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Error installing security policy: %r", err);
}
/* the filesystem path to this image, to prevent adding ourselves to the menu */
@@ -2367,8 +2329,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
}
if (config.entry_count == 0) {
- Print(L"No loader found. Configuration files in \\loader\\entries\\*.conf are needed.");
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+ log_error_stall(L"No loader found. Configuration files in \\loader\\entries\\*.conf are needed.");
goto out;
}
@@ -2392,13 +2353,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
else {
UINT64 key;
- err = console_key_read(&key, FALSE);
-
- if (err == EFI_NOT_READY) {
- uefi_call_wrapper(BS->Stall, 1, 100 * 1000);
- err = console_key_read(&key, FALSE);
- }
-
+ /* Block up to 100ms to give firmware time to get input working. */
+ err = console_key_read(&key, 100 * 1000);
if (!EFI_ERROR(err)) {
INT16 idx;
@@ -2440,8 +2396,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
err = image_start(image, &config, entry);
if (EFI_ERROR(err)) {
graphics_mode(FALSE);
- Print(L"\nFailed to execute %s (%s): %r\n", entry->title, entry->loader, err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+ log_error_stall(L"Failed to execute %s (%s): %r", entry->title, entry->loader, err);
goto out;
}
diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c
index 83619d214..369c549da 100644
--- a/src/boot/efi/console.c
+++ b/src/boot/efi/console.c
@@ -11,61 +11,105 @@
#define EFI_SIMPLE_TEXT_INPUT_EX_GUID &(EFI_GUID) EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID
-EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) {
+static inline void EventClosep(EFI_EVENT *event) {
+ if (!*event)
+ return;
+
+ uefi_call_wrapper(BS->CloseEvent, 1, *event);
+}
+
+/*
+ * Reading input from the console sounds like an easy task to do, but thanks to broken
+ * firmware it is actually a nightmare.
+ *
+ * There is a ConIn and TextInputEx API for this. Ideally we want to use TextInputEx,
+ * because that gives us Ctrl/Alt/Shift key state information. Unfortunately, it is not
+ * always available and sometimes just non-functional.
+ *
+ * On the other hand we have ConIn, where some firmware likes to just freeze on us
+ * if we call ReadKeyStroke on it.
+ *
+ * Therefore, we use WaitForEvent on both ConIn and TextInputEx (if available) along
+ * with a timer event. The timer ensures there is no need to call into functions
+ * that might freeze on us, while still allowing us to show a timeout counter.
+ */
+EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx;
static BOOLEAN checked;
UINTN index;
EFI_INPUT_KEY k;
EFI_STATUS err;
+ _cleanup_(EventClosep) EFI_EVENT timer = NULL;
+ EFI_EVENT events[3] = { ST->ConIn->WaitForKey };
+ UINTN n_events = 1;
if (!checked) {
err = LibLocateProtocol(EFI_SIMPLE_TEXT_INPUT_EX_GUID, (VOID **)&TextInputEx);
- if (EFI_ERROR(err))
+ if (EFI_ERROR(err) ||
+ uefi_call_wrapper(BS->CheckEvent, 1, TextInputEx->WaitForKeyEx) == EFI_INVALID_PARAMETER)
+ /* If WaitForKeyEx fails here, the firmware pretends it talks this
+ * protocol, but it really doesn't. */
TextInputEx = NULL;
+ else
+ events[n_events++] = TextInputEx->WaitForKeyEx;
checked = TRUE;
}
- /* wait until key is pressed */
- if (wait)
- uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &index);
+ if (timeout_usec > 0) {
+ err = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &timer);
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Error creating timer event: %r", err);
- if (TextInputEx) {
- EFI_KEY_DATA keydata;
- UINT64 keypress;
+ /* SetTimer expects 100ns units for some reason. */
+ err = uefi_call_wrapper(BS->SetTimer, 3, timer, TimerRelative, timeout_usec * 10);
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Error arming timer event: %r", err);
- err = uefi_call_wrapper(TextInputEx->ReadKeyStrokeEx, 2, TextInputEx, &keydata);
- if (!EFI_ERROR(err)) {
- UINT32 shift = 0;
-
- /* do not distinguish between left and right keys */
- if (keydata.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) {
- if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_CONTROL_PRESSED|EFI_LEFT_CONTROL_PRESSED))
- shift |= EFI_CONTROL_PRESSED;
- if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_ALT_PRESSED|EFI_LEFT_ALT_PRESSED))
- shift |= EFI_ALT_PRESSED;
- };
-
- /* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */
- keypress = KEYPRESS(shift, keydata.Key.ScanCode, keydata.Key.UnicodeChar);
- if (keypress > 0) {
- *key = keypress;
- return 0;
- }
- }
+ events[n_events++] = timer;
+ }
+
+ err = uefi_call_wrapper(BS->WaitForEvent, 3, n_events, events, &index);
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Error waiting for events: %r", err);
+
+ if (timeout_usec > 0 && timer == events[index])
+ return EFI_TIMEOUT;
+
+ /* TextInputEx might be ready too even if ConIn got to signal first. */
+ if (TextInputEx && !EFI_ERROR(uefi_call_wrapper(BS->CheckEvent, 1, TextInputEx->WaitForKeyEx))) {
+ EFI_KEY_DATA keydata;
+ UINT64 keypress;
+ UINT32 shift = 0;
+
+ err = uefi_call_wrapper(TextInputEx->ReadKeyStrokeEx, 2, TextInputEx, &keydata);
+ if (EFI_ERROR(err))
+ return err;
+
+ /* do not distinguish between left and right keys */
+ if (keydata.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) {
+ if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_CONTROL_PRESSED|EFI_LEFT_CONTROL_PRESSED))
+ shift |= EFI_CONTROL_PRESSED;
+ if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_ALT_PRESSED|EFI_LEFT_ALT_PRESSED))
+ shift |= EFI_ALT_PRESSED;
+ };
+
+ /* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */
+ keypress = KEYPRESS(shift, keydata.Key.ScanCode, keydata.Key.UnicodeChar);
+ if (keypress > 0) {
+ *key = keypress;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_READY;
}
- /* fallback for firmware which does not support SimpleTextInputExProtocol
- *
- * This is also called in case ReadKeyStrokeEx did not return a key, because
- * some broken firmwares offer SimpleTextInputExProtocol, but never actually
- * handle any key. */
err = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &k);
if (EFI_ERROR(err))
return err;
*key = KEYPRESS(0, k.ScanCode, k.UnicodeChar);
- return 0;
+ return EFI_SUCCESS;
}
static EFI_STATUS change_mode(UINTN mode) {
diff --git a/src/boot/efi/console.h b/src/boot/efi/console.h
index 2c69af552..23848a9c5 100644
--- a/src/boot/efi/console.h
+++ b/src/boot/efi/console.h
@@ -16,5 +16,5 @@ enum console_mode_change_type {
CONSOLE_MODE_MAX,
};
-EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait);
+EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec);
EFI_STATUS console_set_mode(UINTN *mode, enum console_mode_change_type how);
diff --git a/src/boot/efi/random-seed.c b/src/boot/efi/random-seed.c
index 3e179851b..939daf3e4 100644
--- a/src/boot/efi/random-seed.c
+++ b/src/boot/efi/random-seed.c
@@ -35,10 +35,8 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) {
return log_oom();
err = uefi_call_wrapper(rng->GetRNG, 3, rng, NULL, size, data);
- if (EFI_ERROR(err)) {
- Print(L"Failed to acquire RNG data: %r\n", err);
- return err;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Failed to acquire RNG data: %r", err);
*ret = TAKE_PTR(data);
return EFI_SUCCESS;
@@ -149,14 +147,12 @@ static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_size) {
err = efivar_get_raw(LOADER_GUID, L"LoaderSystemToken", &data, &size);
if (EFI_ERROR(err)) {
if (err != EFI_NOT_FOUND)
- Print(L"Failed to read LoaderSystemToken EFI variable: %r", err);
+ log_error_stall(L"Failed to read LoaderSystemToken EFI variable: %r", err);
return err;
}
- if (size <= 0) {
- Print(L"System token too short, ignoring.");
- return EFI_NOT_FOUND;
- }
+ if (size <= 0)
+ return log_error_status_stall(EFI_NOT_FOUND, L"System token too short, ignoring.");
*ret = TAKE_PTR(data);
*ret_size = size;
@@ -209,8 +205,7 @@ static VOID validate_sha256(void) {
sha256_finish_ctx(&hash, result);
if (CompareMem(result, array[i].hash, HASH_VALUE_SIZE) != 0) {
- Print(L"SHA256 failed validation.\n");
- uefi_call_wrapper(BS->Stall, 1, 120 * 1000 * 1000);
+ log_error_stall(L"SHA256 failed validation.");
return;
}
}
@@ -246,7 +241,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, (CHAR16*) L"\\loader\\random-seed", EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL);
if (EFI_ERROR(err)) {
if (err != EFI_NOT_FOUND && err != EFI_WRITE_PROTECTED)
- Print(L"Failed to open random seed file: %r\n", err);
+ log_error_stall(L"Failed to open random seed file: %r", err);
return err;
}
@@ -255,15 +250,11 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
return log_oom();
size = info->FileSize;
- if (size < RANDOM_MAX_SIZE_MIN) {
- Print(L"Random seed file is too short?\n");
- return EFI_INVALID_PARAMETER;
- }
+ if (size < RANDOM_MAX_SIZE_MIN)
+ return log_error_status_stall(EFI_INVALID_PARAMETER, L"Random seed file is too short.");
- if (size > RANDOM_MAX_SIZE_MAX) {
- Print(L"Random seed file is too large?\n");
- return EFI_INVALID_PARAMETER;
- }
+ if (size > RANDOM_MAX_SIZE_MAX)
+ return log_error_status_stall(EFI_INVALID_PARAMETER, L"Random seed file is too large.");
seed = AllocatePool(size);
if (!seed)
@@ -271,20 +262,14 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
rsize = size;
err = uefi_call_wrapper(handle->Read, 3, handle, &rsize, seed);
- if (EFI_ERROR(err)) {
- Print(L"Failed to read random seed file: %r\n", err);
- return err;
- }
- if (rsize != size) {
- Print(L"Short read on random seed file\n");
- return EFI_PROTOCOL_ERROR;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Failed to read random seed file: %r", err);
+ if (rsize != size)
+ return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short read on random seed file.");
err = uefi_call_wrapper(handle->SetPosition, 2, handle, 0);
- if (EFI_ERROR(err)) {
- Print(L"Failed to seek to beginning of random seed file: %r\n", err);
- return err;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Failed to seek to beginning of random seed file: %r", err);
/* Request some random data from the UEFI RNG. We don't need this to work safely, but it's a good
* idea to use it because it helps us for cases where users mistakenly include a random seed in
@@ -299,27 +284,19 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
/* Update the random seed on disk before we use it */
wsize = size;
err = uefi_call_wrapper(handle->Write, 3, handle, &wsize, new_seed);
- if (EFI_ERROR(err)) {
- Print(L"Failed to write random seed file: %r\n", err);
- return err;
- }
- if (wsize != size) {
- Print(L"Short write on random seed file\n");
- return EFI_PROTOCOL_ERROR;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Failed to write random seed file: %r", err);
+ if (wsize != size)
+ return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short write on random seed file.");
err = uefi_call_wrapper(handle->Flush, 1, handle);
- if (EFI_ERROR(err)) {
- Print(L"Failed to flush random seed file: %r\n");
- return err;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Failed to flush random seed file: %r", err);
/* We are good to go */
err = efivar_set_raw(LOADER_GUID, L"LoaderRandomSeed", for_kernel, size, 0);
- if (EFI_ERROR(err)) {
- Print(L"Failed to write random seed to EFI variable: %r\n", err);
- return err;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Failed to write random seed to EFI variable: %r", err);
return EFI_SUCCESS;
}
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
index 082fe91c9..82da1d3ec 100644
--- a/src/boot/efi/stub.c
+++ b/src/boot/efi/stub.c
@@ -36,18 +36,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (EFI_ERROR(err)) {
- Print(L"Error getting a LoadedImageProtocol handle: %r ", err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return err;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, offs, szs);
- if (EFI_ERROR(err)) {
- Print(L"Unable to locate embedded .linux section: %r ", err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return err;
- }
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err);
if (szs[0] > 0)
cmdline = (CHAR8 *)(loaded_image->ImageBase) + addrs[0];
@@ -72,10 +66,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
err = tpm_log_event(SD_TPM_PCR,
(EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions,
loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
- if (EFI_ERROR(err)) {
- Print(L"Unable to add image options measurement: %r", err);
- uefi_call_wrapper(BS->Stall, 1, 200 * 1000);
- }
+ if (EFI_ERROR(err))
+ log_error_stall(L"Unable to add image options measurement: %r", err);
#endif
}
@@ -126,7 +118,5 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
(UINTN)loaded_image->ImageBase + addrs[2], szs[2]);
graphics_mode(FALSE);
- Print(L"Execution of embedded linux image failed: %r\n", err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return err;
+ return log_error_status_stall(err, L"Execution of embedded linux image failed: %r", err);
}
diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c
index 6f4e5933d..aee076060 100644
--- a/src/boot/efi/util.c
+++ b/src/boot/efi/util.c
@@ -411,8 +411,21 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN s
return err;
}
+VOID log_error_stall(const CHAR16 *fmt, ...) {
+ va_list args;
+
+ uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTRED|EFI_BACKGROUND_BLACK);
+
+ Print(L"\n");
+ va_start(args, fmt);
+ VPrint(fmt, args);
+ va_end(args);
+ Print(L"\n");
+
+ uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+}
+
EFI_STATUS log_oom(void) {
- Print(L"Out of memory.");
- (void) uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+ log_error_stall(L"Out of memory.");
return EFI_OUT_OF_RESOURCES;
}
diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h
index 1a42b0103..d3bf848a9 100644
--- a/src/boot/efi/util.h
+++ b/src/boot/efi/util.h
@@ -74,4 +74,13 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) {
#define UINT64_MAX ((UINT64) -1)
#endif
+VOID log_error_stall(const CHAR16 *fmt, ...);
EFI_STATUS log_oom(void);
+
+/* This works just like log_error_errno() from userspace, but requires you
+ * to provide err a second time if you want to use %r in the message! */
+#define log_error_status_stall(err, fmt, ...) \
+ ({ \
+ log_error_stall(fmt, ##__VA_ARGS__); \
+ err; \
+ })
diff --git a/src/core/automount.c b/src/core/automount.c
index 0722abef2..edc958816 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -814,6 +814,12 @@ static int automount_start(Unit *u) {
if (r < 0)
return r;
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -1059,21 +1065,6 @@ static bool automount_supported(void) {
return supported;
}
-static int automount_test_start_limit(Unit *u) {
- Automount *a = AUTOMOUNT(u);
- int r;
-
- assert(a);
-
- r = unit_test_start_limit(u);
- if (r < 0) {
- automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
- return 0;
-}
-
static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
[AUTOMOUNT_SUCCESS] = "success",
[AUTOMOUNT_FAILURE_RESOURCES] = "resources",
@@ -1136,6 +1127,4 @@ const UnitVTable automount_vtable = {
[JOB_FAILED] = "Failed to unset automount %s.",
},
},
-
- .test_start_limit = automount_test_start_limit,
};
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 5c07aa71d..51936b7d1 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -2137,7 +2137,7 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
CGroupMask delegated_mask;
const char *p;
void *pidp;
- int r, q;
+ int ret, r;
assert(u);
@@ -2164,16 +2164,16 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
delegated_mask = unit_get_delegate_mask(u);
- r = 0;
+ ret = 0;
SET_FOREACH(pidp, pids) {
pid_t pid = PTR_TO_PID(pidp);
/* First, attach the PID to the main cgroup hierarchy */
- q = cg_attach(SYSTEMD_CGROUP_CONTROLLER, p, pid);
- if (q < 0) {
- bool again = MANAGER_IS_USER(u->manager) && ERRNO_IS_PRIVILEGE(q);
+ r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, p, pid);
+ if (r < 0) {
+ bool again = MANAGER_IS_USER(u->manager) && ERRNO_IS_PRIVILEGE(r);
- log_unit_full_errno(u, again ? LOG_DEBUG : LOG_INFO, q,
+ log_unit_full_errno(u, again ? LOG_DEBUG : LOG_INFO, r,
"Couldn't move process "PID_FMT" to%s requested cgroup '%s': %m",
pid, again ? " directly" : "", empty_to_root(p));
@@ -2192,16 +2192,17 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
continue; /* When the bus thing worked via the bus we are fully done for this PID. */
}
- if (r >= 0)
- r = q; /* Remember first error */
+ if (ret >= 0)
+ ret = r; /* Remember first error */
continue;
- }
+ } else if (ret >= 0)
+ ret++; /* Count successful additions */
- q = cg_all_unified();
- if (q < 0)
- return q;
- if (q > 0)
+ r = cg_all_unified();
+ if (r < 0)
+ return r;
+ if (r > 0)
continue;
/* In the legacy hierarchy, attach the process to the request cgroup if possible, and if not to the
@@ -2216,11 +2217,11 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
/* If this controller is delegated and realized, honour the caller's request for the cgroup suffix. */
if (delegated_mask & u->cgroup_realized_mask & bit) {
- q = cg_attach(cgroup_controller_to_string(c), p, pid);
- if (q >= 0)
+ r = cg_attach(cgroup_controller_to_string(c), p, pid);
+ if (r >= 0)
continue; /* Success! */
- log_unit_debug_errno(u, q, "Failed to attach PID " PID_FMT " to requested cgroup %s in controller %s, falling back to unit's cgroup: %m",
+ log_unit_debug_errno(u, r, "Failed to attach PID " PID_FMT " to requested cgroup %s in controller %s, falling back to unit's cgroup: %m",
pid, empty_to_root(p), cgroup_controller_to_string(c));
}
@@ -2231,14 +2232,14 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
if (!realized)
continue; /* Not even realized in the root slice? Then let's not bother */
- q = cg_attach(cgroup_controller_to_string(c), realized, pid);
- if (q < 0)
- log_unit_debug_errno(u, q, "Failed to attach PID " PID_FMT " to realized cgroup %s in controller %s, ignoring: %m",
+ r = cg_attach(cgroup_controller_to_string(c), realized, pid);
+ if (r < 0)
+ log_unit_debug_errno(u, r, "Failed to attach PID " PID_FMT " to realized cgroup %s in controller %s, ignoring: %m",
pid, realized, cgroup_controller_to_string(c));
}
}
- return r;
+ return ret;
}
static bool unit_has_mask_realized(
diff --git a/src/core/execute.c b/src/core/execute.c
index 2a337b55a..2f2de4d9c 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -4059,13 +4059,17 @@ static int exec_child(
}
}
- if (context->utmp_id)
+ if (context->utmp_id) {
+ const char *line = context->tty_path ?
+ (path_startswith(context->tty_path, "/dev/") ?: context->tty_path) :
+ NULL;
utmp_put_init_process(context->utmp_id, getpid_cached(), getsid(0),
- context->tty_path,
+ line,
context->utmp_mode == EXEC_UTMP_INIT ? INIT_PROCESS :
context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS :
USER_PROCESS,
username);
+ }
if (uid_is_valid(uid)) {
r = chown_terminal(STDIN_FILENO, uid);
@@ -4357,7 +4361,7 @@ static int exec_child(
if (fd >= 0) {
r = mac_selinux_get_child_mls_label(fd, executable, context->selinux_context, &mac_selinux_context_net);
- if (r < 0) {
+ if (r < 0 && !context->selinux_context_ignore) {
*exit_status = EXIT_SELINUX_CONTEXT;
return log_unit_error_errno(unit, r, "Failed to determine SELinux context: %m");
}
@@ -4404,7 +4408,7 @@ static int exec_child(
* process. This is the latest place before dropping capabilities. Other MAC context are set later. */
if (use_smack) {
r = setup_smack(context, executable_fd);
- if (r < 0) {
+ if (r < 0 && !context->smack_process_label_ignore) {
*exit_status = EXIT_SMACK_PROCESS_LABEL;
return log_unit_error_errno(unit, r, "Failed to set SMACK process label: %m");
}
@@ -4491,7 +4495,7 @@ static int exec_child(
if (exec_context) {
r = setexeccon(exec_context);
- if (r < 0) {
+ if (r < 0 && !context->selinux_context_ignore) {
*exit_status = EXIT_SELINUX_CONTEXT;
return log_unit_error_errno(unit, r, "Failed to change SELinux context to %s: %m", exec_context);
}
diff --git a/src/core/mount.c b/src/core/mount.c
index 9bec190cb..af39db214 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1168,6 +1168,12 @@ static int mount_start(Unit *u) {
assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED));
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -2137,21 +2143,6 @@ static int mount_can_clean(Unit *u, ExecCleanMask *ret) {
return exec_context_get_clean_mask(&m->exec_context, ret);
}
-static int mount_test_start_limit(Unit *u) {
- Mount *m = MOUNT(u);
- int r;
-
- assert(m);
-
- r = unit_test_start_limit(u);
- if (r < 0) {
- mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
- return 0;
-}
-
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
[MOUNT_EXEC_MOUNT] = "ExecMount",
[MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
@@ -2249,6 +2240,4 @@ const UnitVTable mount_vtable = {
[JOB_TIMEOUT] = "Timed out unmounting %s.",
},
},
-
- .test_start_limit = mount_test_start_limit,
};
diff --git a/src/core/path.c b/src/core/path.c
index 2b659696a..e098e83a3 100644
--- a/src/core/path.c
+++ b/src/core/path.c
@@ -590,6 +590,12 @@ static int path_start(Unit *u) {
if (r < 0)
return r;
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -805,21 +811,6 @@ static void path_reset_failed(Unit *u) {
p->result = PATH_SUCCESS;
}
-static int path_test_start_limit(Unit *u) {
- Path *p = PATH(u);
- int r;
-
- assert(p);
-
- r = unit_test_start_limit(u);
- if (r < 0) {
- path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
- return 0;
-}
-
static const char* const path_type_table[_PATH_TYPE_MAX] = {
[PATH_EXISTS] = "PathExists",
[PATH_EXISTS_GLOB] = "PathExistsGlob",
@@ -874,6 +865,4 @@ const UnitVTable path_vtable = {
.reset_failed = path_reset_failed,
.bus_set_property = bus_path_set_property,
-
- .test_start_limit = path_test_start_limit,
};
diff --git a/src/core/scope.c b/src/core/scope.c
index af6311bb5..fd4367dbe 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -374,6 +374,12 @@ static int scope_start(Unit *u) {
scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
return r;
}
+ if (r == 0) {
+ log_unit_warning(u, "No PIDs left to attach to the scope's control group, refusing: %m");
+ scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
+ return -ECHILD;
+ }
+ log_unit_debug(u, "%i %s added to scope's control group.", r, r == 1 ? "process" : "processes");
s->result = SCOPE_SUCCESS;
diff --git a/src/core/service.c b/src/core/service.c
index 701c14556..7b90822f6 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -2456,6 +2456,13 @@ static int service_start(Unit *u) {
assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED));
+ /* Make sure we don't enter a busy loop of some kind. */
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false);
+ return r;
+ }
+
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -4451,22 +4458,6 @@ static const char *service_finished_job(Unit *u, JobType t, JobResult result) {
return NULL;
}
-static int service_test_start_limit(Unit *u) {
- Service *s = SERVICE(u);
- int r;
-
- assert(s);
-
- /* Make sure we don't enter a busy loop of some kind. */
- r = unit_test_start_limit(u);
- if (r < 0) {
- service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false);
- return r;
- }
-
- return 0;
-}
-
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
[SERVICE_RESTART_NO] = "no",
[SERVICE_RESTART_ON_SUCCESS] = "on-success",
@@ -4629,6 +4620,4 @@ const UnitVTable service_vtable = {
},
.finished_job = service_finished_job,
},
-
- .test_start_limit = service_test_start_limit,
};
diff --git a/src/core/socket.c b/src/core/socket.c
index 31d88b71f..f362a5baa 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -2515,6 +2515,12 @@ static int socket_start(Unit *u) {
assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED));
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -3423,21 +3429,6 @@ static int socket_can_clean(Unit *u, ExecCleanMask *ret) {
return exec_context_get_clean_mask(&s->exec_context, ret);
}
-static int socket_test_start_limit(Unit *u) {
- Socket *s = SOCKET(u);
- int r;
-
- assert(s);
-
- r = unit_test_start_limit(u);
- if (r < 0) {
- socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
- return 0;
-}
-
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
[SOCKET_EXEC_START_PRE] = "ExecStartPre",
[SOCKET_EXEC_START_CHOWN] = "ExecStartChown",
@@ -3564,6 +3555,4 @@ const UnitVTable socket_vtable = {
[JOB_TIMEOUT] = "Timed out stopping %s.",
},
},
-
- .test_start_limit = socket_test_start_limit,
};
diff --git a/src/core/swap.c b/src/core/swap.c
index b25f68fb7..3843b1950 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -933,6 +933,12 @@ static int swap_start(Unit *u) {
if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING)
return -EAGAIN;
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -1582,21 +1588,6 @@ static int swap_can_clean(Unit *u, ExecCleanMask *ret) {
return exec_context_get_clean_mask(&s->exec_context, ret);
}
-static int swap_test_start_limit(Unit *u) {
- Swap *s = SWAP(u);
- int r;
-
- assert(s);
-
- r = unit_test_start_limit(u);
- if (r < 0) {
- swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
- return 0;
-}
-
static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
[SWAP_EXEC_ACTIVATE] = "ExecActivate",
[SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
@@ -1692,6 +1683,4 @@ const UnitVTable swap_vtable = {
[JOB_TIMEOUT] = "Timed out deactivating swap %s.",
},
},
-
- .test_start_limit = swap_test_start_limit,
};
diff --git a/src/core/timer.c b/src/core/timer.c
index 5ecc9f35c..e064ad9a2 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -635,6 +635,12 @@ static int timer_start(Unit *u) {
if (r < 0)
return r;
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -895,21 +901,6 @@ static int timer_can_clean(Unit *u, ExecCleanMask *ret) {
return 0;
}
-static int timer_test_start_limit(Unit *u) {
- Timer *t = TIMER(u);
- int r;
-
- assert(t);
-
- r = unit_test_start_limit(u);
- if (r < 0) {
- timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
- return 0;
-}
-
static const char* const timer_base_table[_TIMER_BASE_MAX] = {
[TIMER_ACTIVE] = "OnActiveSec",
[TIMER_BOOT] = "OnBootSec",
@@ -969,6 +960,4 @@ const UnitVTable timer_vtable = {
.timezone_change = timer_timezone_change,
.bus_set_property = bus_timer_set_property,
-
- .test_start_limit = timer_test_start_limit,
};
diff --git a/src/core/unit.c b/src/core/unit.c
index 69ed43578..38d3eb703 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1851,13 +1851,6 @@ int unit_start(Unit *u) {
assert(u);
- /* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */
- if (UNIT_VTABLE(u)->test_start_limit) {
- int r = UNIT_VTABLE(u)->test_start_limit(u);
- if (r < 0)
- return r;
- }
-
/* If this is already started, then this will succeed. Note that this will even succeed if this unit
* is not startable by the user. This is relied on to detect when we need to wait for units and when
* waiting is finished. */
diff --git a/src/core/unit.h b/src/core/unit.h
index 9babd0718..759104ffa 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -649,10 +649,6 @@ typedef struct UnitVTable {
* of this type will immediately fail. */
bool (*supported)(void);
- /* If this function is set, it's invoked first as part of starting a unit to allow start rate
- * limiting checks to occur before we do anything else. */
- int (*test_start_limit)(Unit *u);
-
/* The strings to print in status messages */
UnitStatusMessageFormats status_message_formats;
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index 444b9ec37..1e34c4b5b 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -525,6 +525,7 @@ static int save_external_coredump(
if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
return log_error_errno(errno, "Failed to seek on coredump %s: %m", fn);
+ *ret_filename = TAKE_PTR(fn);
*ret_data_fd = TAKE_FD(fd);
*ret_size = (uint64_t) st.st_size;
*ret_truncated = truncated;
diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c
index 3d44e51e3..7eba8330d 100644
--- a/src/coredump/coredumpctl.c
+++ b/src/coredump/coredumpctl.c
@@ -555,6 +555,8 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
assert(file);
assert(j);
+ (void) sd_journal_set_data_threshold(j, 0);
+
SD_JOURNAL_FOREACH_DATA(j, d, l) {
RETRIEVE(d, l, "MESSAGE_ID", mid);
RETRIEVE(d, l, "COREDUMP_PID", pid);
diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c
index 6448883fe..05a0ed861 100644
--- a/src/home/homework-luks.c
+++ b/src/home/homework-luks.c
@@ -8,6 +8,10 @@
#include
#include
+#if HAVE_VALGRIND_MEMCHECK_H
+#include
+#endif
+
#include "blkid-util.h"
#include "blockdev-util.h"
#include "btrfs-util.h"
@@ -1136,6 +1140,10 @@ int home_prepare_luks(
offset *= 512U;
}
} else {
+#if HAVE_VALGRIND_MEMCHECK_H
+ VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
+#endif
+
offset = info.lo_offset;
size = info.lo_sizelimit;
}
@@ -1146,7 +1154,7 @@ int home_prepare_luks(
root_fd = open(user_record_home_directory(h), O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
if (root_fd < 0) {
- r = log_error_errno(r, "Failed to open home directory: %m");
+ r = log_error_errno(errno, "Failed to open home directory: %m");
goto fail;
}
} else {
@@ -1233,7 +1241,7 @@ int home_prepare_luks(
root_fd = open(subdir, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
if (root_fd < 0) {
- r = log_error_errno(r, "Failed to open home directory: %m");
+ r = log_error_errno(errno, "Failed to open home directory: %m");
goto fail;
}
@@ -2813,7 +2821,7 @@ int home_resize_luks(
if (r > 0)
log_info("Growing of partition completed.");
- if (ioctl(image_fd, BLKRRPART, 0) < 0)
+ if (S_ISBLK(st.st_mode) && ioctl(image_fd, BLKRRPART, 0) < 0)
log_debug_errno(errno, "BLKRRPART failed on block device, ignoring: %m");
/* Tell LUKS about the new bigger size too */
@@ -2887,7 +2895,7 @@ int home_resize_luks(
if (r > 0)
log_info("Shrinking of partition completed.");
- if (ioctl(image_fd, BLKRRPART, 0) < 0)
+ if (S_ISBLK(st.st_mode) && ioctl(image_fd, BLKRRPART, 0) < 0)
log_debug_errno(errno, "BLKRRPART failed on block device, ignoring: %m");
} else {
r = home_store_embedded_identity(new_home, setup->root_fd, h->uid, embedded_home);
diff --git a/src/home/homework.c b/src/home/homework.c
index bdd9ac649..b20b4bdf3 100644
--- a/src/home/homework.c
+++ b/src/home/homework.c
@@ -1651,6 +1651,8 @@ static int run(int argc, char *argv[]) {
log_setup();
+ cryptsetup_enable_logging(NULL);
+
umask(0022);
if (argc < 2 || argc > 3)
diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h
index f0f814957..35cafc96e 100644
--- a/src/libsystemd-network/dhcp6-internal.h
+++ b/src/libsystemd-network/dhcp6-internal.h
@@ -104,7 +104,7 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHash
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
size_t *optlen, uint8_t **optvalue);
int dhcp6_option_parse_status(DHCP6Option *option, size_t len);
-int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code);
+int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, be32_t iaid, DHCP6IA *ia, uint16_t *ret_status_code);
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
struct in6_addr **addrs, size_t count);
int dhcp6_option_parse_domainname_list(const uint8_t *optval, uint16_t optlen,
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c
index 97ef03a2d..34d7e997d 100644
--- a/src/libsystemd-network/dhcp6-option.c
+++ b/src/libsystemd-network/dhcp6-option.c
@@ -509,7 +509,13 @@ static int dhcp6_option_parse_pdprefix(sd_dhcp6_client *client, DHCP6Option *opt
return 0;
}
-int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code) {
+int dhcp6_option_parse_ia(
+ sd_dhcp6_client *client,
+ DHCP6Option *iaoption,
+ be32_t iaid,
+ DHCP6IA *ia,
+ uint16_t *ret_status_code) {
+
uint32_t lt_t1, lt_t2, lt_valid = 0, lt_min = UINT32_MAX;
uint16_t iatype, optlen;
size_t iaaddr_offset;
@@ -529,6 +535,14 @@ int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6I
if (len < DHCP6_OPTION_IA_NA_LEN)
return -ENOBUFS;
+ /* According to RFC8415, IAs which do not match the client's IAID should be ignored,
+ * but not necessary to ignore or refuse the whole message. */
+ if (((const struct ia_na*) iaoption->data)->id != iaid)
+ /* ENOANO indicates the option should be ignored. */
+ return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(ENOANO),
+ "Received an IA_NA option with a different IAID "
+ "from the one chosen by the client, ignoring.");
+
iaaddr_offset = DHCP6_OPTION_IA_NA_LEN;
memcpy(&ia->ia_na, iaoption->data, sizeof(ia->ia_na));
@@ -547,6 +561,14 @@ int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6I
if (len < sizeof(ia->ia_pd))
return -ENOBUFS;
+ /* According to RFC8415, IAs which do not match the client's IAID should be ignored,
+ * but not necessary to ignore or refuse the whole message. */
+ if (((const struct ia_pd*) iaoption->data)->id != iaid)
+ /* ENOANO indicates the option should be ignored. */
+ return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(ENOANO),
+ "Received an IA_PD option with a different IAID "
+ "from the one chosen by the client, ignoring.");
+
iaaddr_offset = sizeof(ia->ia_pd);
memcpy(&ia->ia_pd, iaoption->data, sizeof(ia->ia_pd));
@@ -564,13 +586,21 @@ int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6I
if (len < DHCP6_OPTION_IA_TA_LEN)
return -ENOBUFS;
+ /* According to RFC8415, IAs which do not match the client's IAID should be ignored,
+ * but not necessary to ignore or refuse the whole message. */
+ if (((const struct ia_ta*) iaoption->data)->id != iaid)
+ /* ENOANO indicates the option should be ignored. */
+ return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(ENOANO),
+ "Received an IA_TA option with a different IAID "
+ "from the one chosen by the client, ignoring.");
+
iaaddr_offset = DHCP6_OPTION_IA_TA_LEN;
- memcpy(&ia->ia_ta.id, iaoption->data, sizeof(ia->ia_ta));
+ memcpy(&ia->ia_ta, iaoption->data, sizeof(ia->ia_ta));
break;
default:
- return -ENOMSG;
+ return -EINVAL;
}
ia->type = iatype;
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index f99c12620..efbf7d7df 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -1119,7 +1119,6 @@ static int client_parse_message(
while (pos < len) {
DHCP6Option *option = (DHCP6Option *) &message->options[pos];
uint16_t optcode, optlen;
- be32_t iaid_lease;
int status;
uint8_t *optval;
@@ -1198,8 +1197,8 @@ static int client_parse_message(
break;
}
- r = dhcp6_option_parse_ia(client, option, &lease->ia, &ia_na_status);
- if (r < 0 && r != -ENOMSG)
+ r = dhcp6_option_parse_ia(client, option, client->ia_pd.ia_na.id, &lease->ia, &ia_na_status);
+ if (r < 0 && r != -ENOANO)
return r;
if (ia_na_status == DHCP6_STATUS_NO_ADDRS_AVAIL) {
@@ -1207,16 +1206,6 @@ static int client_parse_message(
continue;
}
- r = dhcp6_lease_get_iaid(lease, &iaid_lease);
- if (r < 0)
- return r;
-
- if (client->ia_na.ia_na.id != iaid_lease) {
- log_dhcp6_client(client, "%s has wrong IAID for IA NA",
- dhcp6_message_type_to_string(message->type));
- return -EINVAL;
- }
-
if (lease->ia.addresses) {
lt_t1 = MIN(lt_t1, be32toh(lease->ia.ia_na.lifetime_t1));
lt_t2 = MIN(lt_t2, be32toh(lease->ia.ia_na.lifetime_t2));
@@ -1231,8 +1220,8 @@ static int client_parse_message(
break;
}
- r = dhcp6_option_parse_ia(client, option, &lease->pd, &ia_pd_status);
- if (r < 0 && r != -ENOMSG)
+ r = dhcp6_option_parse_ia(client, option, client->ia_pd.ia_pd.id, &lease->pd, &ia_pd_status);
+ if (r < 0 && r != -ENOANO)
return r;
if (ia_pd_status == DHCP6_STATUS_NO_PREFIX_AVAIL) {
@@ -1240,16 +1229,6 @@ static int client_parse_message(
continue;
}
- r = dhcp6_lease_get_pd_iaid(lease, &iaid_lease);
- if (r < 0)
- return r;
-
- if (client->ia_pd.ia_pd.id != iaid_lease) {
- log_dhcp6_client(client, "%s has wrong IAID for IA PD",
- dhcp6_message_type_to_string(message->type));
- return -EINVAL;
- }
-
if (lease->pd.addresses) {
lt_t1 = MIN(lt_t1, be32toh(lease->pd.ia_pd.lifetime_t1));
lt_t2 = MIN(lt_t2, be32toh(lease->pd.ia_pd.lifetime_t2));
diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c
index a72c13684..5e3b19159 100644
--- a/src/libsystemd-network/test-dhcp6-client.c
+++ b/src/libsystemd-network/test-dhcp6-client.c
@@ -287,25 +287,31 @@ static int test_option_status(sd_event *e) {
};
DHCP6Option *option;
DHCP6IA ia, pd;
+ be32_t iaid;
int r = 0;
log_debug("/* %s */", __func__);
+ memcpy(&iaid, option1 + 4, sizeof(iaid));
+
zero(ia);
option = (DHCP6Option *)option1;
assert_se(sizeof(option1) == sizeof(DHCP6Option) + be16toh(option->len));
- r = dhcp6_option_parse_ia(NULL, option, &ia, NULL);
+ r = dhcp6_option_parse_ia(NULL, option, 0, &ia, NULL);
+ assert_se(r == -ENOANO);
+
+ r = dhcp6_option_parse_ia(NULL, option, iaid, &ia, NULL);
assert_se(r == 0);
assert_se(ia.addresses == NULL);
option->len = htobe16(17);
- r = dhcp6_option_parse_ia(NULL, option, &ia, NULL);
+ r = dhcp6_option_parse_ia(NULL, option, iaid, &ia, NULL);
assert_se(r == -ENOBUFS);
assert_se(ia.addresses == NULL);
option->len = htobe16(sizeof(DHCP6Option));
- r = dhcp6_option_parse_ia(NULL, option, &ia, NULL);
+ r = dhcp6_option_parse_ia(NULL, option, iaid, &ia, NULL);
assert_se(r == -ENOBUFS);
assert_se(ia.addresses == NULL);
@@ -313,7 +319,7 @@ static int test_option_status(sd_event *e) {
option = (DHCP6Option *)option2;
assert_se(sizeof(option2) == sizeof(DHCP6Option) + be16toh(option->len));
- r = dhcp6_option_parse_ia(NULL, option, &ia, NULL);
+ r = dhcp6_option_parse_ia(NULL, option, iaid, &ia, NULL);
assert_se(r >= 0);
assert_se(ia.addresses == NULL);
@@ -321,7 +327,7 @@ static int test_option_status(sd_event *e) {
option = (DHCP6Option *)option3;
assert_se(sizeof(option3) == sizeof(DHCP6Option) + be16toh(option->len));
- r = dhcp6_option_parse_ia(NULL, option, &ia, NULL);
+ r = dhcp6_option_parse_ia(NULL, option, iaid, &ia, NULL);
assert_se(r >= 0);
assert_se(ia.addresses != NULL);
dhcp6_lease_free_ia(&ia);
@@ -330,7 +336,7 @@ static int test_option_status(sd_event *e) {
option = (DHCP6Option *)option4;
assert_se(sizeof(option4) == sizeof(DHCP6Option) + be16toh(option->len));
- r = dhcp6_option_parse_ia(NULL, option, &pd, NULL);
+ r = dhcp6_option_parse_ia(NULL, option, iaid, &pd, NULL);
assert_se(r >= 0);
assert_se(pd.addresses != NULL);
assert_se(memcmp(&pd.ia_pd.id, &option4[4], 4) == 0);
@@ -342,7 +348,7 @@ static int test_option_status(sd_event *e) {
option = (DHCP6Option *)option5;
assert_se(sizeof(option5) == sizeof(DHCP6Option) + be16toh(option->len));
- r = dhcp6_option_parse_ia(NULL, option, &pd, NULL);
+ r = dhcp6_option_parse_ia(NULL, option, iaid, &pd, NULL);
assert_se(r >= 0);
assert_se(pd.addresses != NULL);
dhcp6_lease_free_ia(&pd);
@@ -447,13 +453,14 @@ static int test_advertise_option(sd_event *e) {
opt_clientid = true;
break;
- case SD_DHCP6_OPTION_IA_NA:
+ case SD_DHCP6_OPTION_IA_NA: {
+ be32_t iaid = htobe32(0x0ecfa37d);
+
assert_se(optlen == 94);
assert_se(optval == &msg_advertise[26]);
assert_se(!memcmp(optval, &msg_advertise[26], optlen));
- val = htobe32(0x0ecfa37d);
- assert_se(!memcmp(optval, &val, sizeof(val)));
+ assert_se(!memcmp(optval, &iaid, sizeof(val)));
val = htobe32(80);
assert_se(!memcmp(optval + 4, &val, sizeof(val)));
@@ -461,10 +468,10 @@ static int test_advertise_option(sd_event *e) {
val = htobe32(120);
assert_se(!memcmp(optval + 8, &val, sizeof(val)));
- assert_se(dhcp6_option_parse_ia(NULL, option, &lease->ia, NULL) >= 0);
+ assert_se(dhcp6_option_parse_ia(NULL, option, iaid, &lease->ia, NULL) >= 0);
break;
-
+ }
case SD_DHCP6_OPTION_SERVERID:
assert_se(optlen == 14);
assert_se(optval == &msg_advertise[179]);
@@ -598,6 +605,8 @@ static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
static int test_client_send_reply(DHCP6Message *request) {
DHCP6Message reply;
+ log_debug("/* %s */", __func__);
+
reply.transaction_id = request->transaction_id;
reply.type = DHCP6_REPLY;
@@ -658,7 +667,7 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
assert_se(!memcmp(optval + 8, &val, sizeof(val)));
/* Then, this should refuse all addresses. */
- assert_se(dhcp6_option_parse_ia(NULL, option, &lease->ia, NULL) >= 0);
+ assert_se(dhcp6_option_parse_ia(NULL, option, test_iaid, &lease->ia, NULL) >= 0);
break;
@@ -704,6 +713,8 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
static int test_client_send_advertise(DHCP6Message *solicit) {
DHCP6Message advertise;
+ log_debug("/* %s */", __func__);
+
advertise.transaction_id = solicit->transaction_id;
advertise.type = DHCP6_ADVERTISE;
@@ -899,6 +910,8 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
DHCP6Message *message;
+ log_debug("/* %s */", __func__);
+
assert_se(s == test_dhcp_fd[0]);
assert_se(server_address);
assert_se(packet);
diff --git a/src/libsystemd/sd-device/device-monitor.c b/src/libsystemd/sd-device/device-monitor.c
index b485e3e2b..2cb35951d 100644
--- a/src/libsystemd/sd-device/device-monitor.c
+++ b/src/libsystemd/sd-device/device-monitor.c
@@ -178,7 +178,7 @@ int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group,
netns = ioctl(m->sock, SIOCGSKNS);
if (netns < 0)
- log_debug_errno(errno, "sd-device-monitor: Unable to get network namespace of udev netlink socket, unable to determine if we are in host netns: %m");
+ log_debug_errno(errno, "sd-device-monitor: Unable to get network namespace of udev netlink socket, unable to determine if we are in host netns, ignoring: %m");
else {
struct stat a, b;
@@ -191,9 +191,9 @@ int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group,
if (ERRNO_IS_PRIVILEGE(errno))
/* If we can't access PID1's netns info due to permissions, it's fine, this is a
* safety check only after all. */
- log_debug_errno(errno, "sd-device-monitor: No permission to stat PID1's netns, unable to determine if we are in host netns: %m");
+ log_debug_errno(errno, "sd-device-monitor: No permission to stat PID1's netns, unable to determine if we are in host netns, ignoring: %m");
else
- log_debug_errno(errno, "sd-device-monitor: Failed to stat PID1's netns: %m");
+ log_debug_errno(errno, "sd-device-monitor: Failed to stat PID1's netns, ignoring: %m");
} else if (a.st_dev != b.st_dev || a.st_ino != b.st_ino)
log_debug("sd-device-monitor: Netlink socket we listen on is not from host netns, we won't see device events.");
diff --git a/src/locale/test-keymap-util.c b/src/locale/test-keymap-util.c
index 6f60aba38..a5d40af44 100644
--- a/src/locale/test-keymap-util.c
+++ b/src/locale/test-keymap-util.c
@@ -190,12 +190,17 @@ static void test_x11_convert_to_vconsole(void) {
}
int main(int argc, char **argv) {
+ _cleanup_free_ char *map = NULL;
+
test_setup_logging(LOG_DEBUG);
test_find_language_fallback();
test_find_converted_keymap();
test_find_legacy_keymap();
+ assert_se(get_testdata_dir("test-keymap-util/kbd-model-map", &map) >= 0);
+ assert_se(setenv("SYSTEMD_KBD_MODEL_MAP", map, 1) == 0);
+
test_vconsole_convert_to_x11();
test_x11_convert_to_vconsole();
diff --git a/src/login/70-uaccess.rules.in b/src/login/70-uaccess.rules.in
index 56e1087fe..1b6be8270 100644
--- a/src/login/70-uaccess.rules.in
+++ b/src/login/70-uaccess.rules.in
@@ -33,6 +33,7 @@ SUBSYSTEM=="sound", TAG+="uaccess", \
# Webcams, frame grabber, TV cards
SUBSYSTEM=="video4linux", TAG+="uaccess"
SUBSYSTEM=="dvb", TAG+="uaccess"
+SUBSYSTEM=="media", TAG+="uaccess"
# industrial cameras, some webcams, camcorders, set-top boxes, TV sets, audio devices, and more
SUBSYSTEM=="firewire", TEST=="units", ENV{IEEE1394_UNIT_FUNCTION_MIDI}=="1", TAG+="uaccess"
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 791fd64c3..eeba31c45 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -1537,7 +1537,7 @@ static int route_configure(
if (route->lifetime != USEC_INFINITY && kernel_route_expiration_supported()) {
r = sd_netlink_message_append_u32(req, RTA_EXPIRES,
- DIV_ROUND_UP(usec_sub_unsigned(route->lifetime, now(clock_boottime_or_monotonic())), USEC_PER_SEC));
+ MIN(DIV_ROUND_UP(usec_sub_unsigned(route->lifetime, now(clock_boottime_or_monotonic())), USEC_PER_SEC), UINT32_MAX));
if (r < 0)
return log_link_error_errno(link, r, "Could not append RTA_EXPIRES attribute: %m");
}
diff --git a/src/partition/repart.c b/src/partition/repart.c
index 3c80d1380..7602ac6aa 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -4863,6 +4863,10 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
+#if HAVE_LIBCRYPTSETUP
+ cryptsetup_enable_logging(NULL);
+#endif
+
if (arg_image) {
assert(!arg_root);
diff --git a/src/shared/json.c b/src/shared/json.c
index c52460a3e..d72b1e3a3 100644
--- a/src/shared/json.c
+++ b/src/shared/json.c
@@ -359,6 +359,12 @@ int json_variant_new_real(JsonVariant **ret, long double d) {
}
REENABLE_WARNING;
+ /* JSON doesn't know NaN, +Infinity or -Infinity. Let's silently convert to 'null'. */
+ if (isnan(d) || isinf(d)) {
+ *ret = JSON_VARIANT_MAGIC_NULL;
+ return 0;
+ }
+
r = json_variant_new(&v, JSON_VARIANT_REAL, sizeof(d));
if (r < 0)
return r;
diff --git a/src/shared/varlink.c b/src/shared/varlink.c
index 8da568e20..a57475b5b 100644
--- a/src/shared/varlink.c
+++ b/src/shared/varlink.c
@@ -417,9 +417,10 @@ static int varlink_test_disconnect(Varlink *v) {
if (IN_SET(v->state, VARLINK_IDLE_CLIENT) && (v->write_disconnected || v->got_pollhup))
goto disconnect;
- /* The server is still expecting to write more, but its write end is disconnected and it got a POLLHUP
- * (i.e. from a disconnected client), so disconnect. */
- if (IN_SET(v->state, VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE) && v->write_disconnected && v->got_pollhup)
+ /* We are on the server side and still want to send out more replies, but we saw POLLHUP already, and
+ * either got no buffered bytes to write anymore or already saw a write error. In that case we should
+ * shut down the varlink link. */
+ if (IN_SET(v->state, VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE) && (v->write_disconnected || v->output_buffer_size == 0) && v->got_pollhup)
goto disconnect;
return 0;
diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c
index c2a26242c..1f945b787 100644
--- a/src/shutdown/umount.c
+++ b/src/shutdown/umount.c
@@ -15,6 +15,10 @@
#include
#include
+#if HAVE_VALGRIND_MEMCHECK_H
+#include
+#endif
+
#include "sd-device.h"
#include "alloc-util.h"
@@ -409,6 +413,10 @@ static int delete_loopback(const char *device) {
return -EBUSY; /* propagate original error */
}
+#if HAVE_VALGRIND_MEMCHECK_H
+ VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
+#endif
+
if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR)) /* someone else already set LO_FLAGS_AUTOCLEAR for us? fine by us */
return -EBUSY; /* propagate original error */
@@ -434,6 +442,10 @@ static int delete_loopback(const char *device) {
return 1;
}
+#if HAVE_VALGRIND_MEMCHECK_H
+ VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
+#endif
+
/* Linux makes LOOP_CLR_FD succeed whenever LO_FLAGS_AUTOCLEAR is set without actually doing
* anything. Very confusing. Let's hence not claim we did anything in this case. */
if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR))
diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c
index 1f524626b..dd99bc532 100644
--- a/src/systemctl/systemctl-show.c
+++ b/src/systemctl/systemctl-show.c
@@ -741,7 +741,7 @@ static void print_status_info(
c = 0;
r = unit_show_processes(bus, i->id, i->control_group, prefix, c, get_output_flags(), &error);
- if (r == -EBADR) {
+ if (r == -EBADR && arg_transport == BUS_TRANSPORT_LOCAL) {
unsigned k = 0;
pid_t extra[2];
@@ -1649,11 +1649,13 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
r = sd_bus_message_enter_container(m, 'r', "ssba(ss)");
if (r < 0)
- return r;
+ return bus_log_parse_error(r);
+ if (r == 0)
+ break;
r = sd_bus_message_read(m, "ssb", &source, &destination, &ignore_enoent);
- if (r <= 0)
- break;
+ if (r < 0)
+ return bus_log_parse_error(r);
str = strjoin(ignore_enoent ? "-" : "",
source,
@@ -1664,28 +1666,82 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
r = sd_bus_message_enter_container(m, 'a', "(ss)");
if (r < 0)
- return r;
+ return bus_log_parse_error(r);
while ((r = sd_bus_message_read(m, "(ss)", &partition, &mount_options)) > 0)
- if (!strextend_with_separator(&str, ":", partition, ":", mount_options))
+ if (!strextend_with_separator(&str, ":", partition, mount_options))
return log_oom();
if (r < 0)
- return r;
+ return bus_log_parse_error(r);
if (!strextend_with_separator(&paths, " ", str))
return log_oom();
r = sd_bus_message_exit_container(m);
if (r < 0)
- return r;
+ return bus_log_parse_error(r);
r = sd_bus_message_exit_container(m);
if (r < 0)
- return r;
+ return bus_log_parse_error(r);
}
+
+ r = sd_bus_message_exit_container(m);
if (r < 0)
return bus_log_parse_error(r);
+ bus_print_property_value(name, expected_value, flags, paths);
+
+ return 1;
+
+ } else if (streq(name, "ExtensionImages")) {
+ _cleanup_free_ char *paths = NULL;
+
+ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sba(ss))");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ for (;;) {
+ _cleanup_free_ char *str = NULL;
+ const char *source, *partition, *mount_options;
+ int ignore_enoent;
+
+ r = sd_bus_message_enter_container(m, 'r', "sba(ss)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+ if (r == 0)
+ break;
+
+ r = sd_bus_message_read(m, "sb", &source, &ignore_enoent);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ str = strjoin(ignore_enoent ? "-" : "", source);
+ if (!str)
+ return log_oom();
+
+ r = sd_bus_message_enter_container(m, 'a', "(ss)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_read(m, "(ss)", &partition, &mount_options)) > 0)
+ if (!strextend_with_separator(&str, ":", partition, mount_options))
+ return log_oom();
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ if (!strextend_with_separator(&paths, " ", str))
+ return log_oom();
+
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return bus_log_parse_error(r);
+ }
+
r = sd_bus_message_exit_container(m);
if (r < 0)
return bus_log_parse_error(r);
diff --git a/src/test/meson.build b/src/test/meson.build
index e10605918..64dbb8200 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -13,7 +13,6 @@ test_include_dir = include_directories('.')
path = run_command(sh, '-c', 'echo "$PATH"').stdout().strip()
test_env = environment()
-test_env.set('SYSTEMD_KBD_MODEL_MAP', kbd_model_map)
test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map)
test_env.set('PATH', '@0@:@1@'.format(meson.build_root(), path))
diff --git a/src/test/test-path.c b/src/test/test-path.c
index 490fb136a..88457d177 100644
--- a/src/test/test-path.c
+++ b/src/test/test-path.c
@@ -306,7 +306,7 @@ static void test_path_unit(Manager *m) {
}
static void test_path_directorynotempty(Manager *m) {
- const char *test_path = "/tmp/test-path_directorynotempty/";
+ const char *test_file, *test_path = "/tmp/test-path_directorynotempty/";
Unit *unit = NULL;
Path *path = NULL;
Service *service = NULL;
@@ -328,7 +328,8 @@ static void test_path_directorynotempty(Manager *m) {
assert_se(access(test_path, F_OK) < 0);
assert_se(mkdir_p(test_path, 0755) >= 0);
- assert_se(touch(strjoina(test_path, "test_file")) >= 0);
+ test_file = strjoina(test_path, "test_file");
+ assert_se(touch(test_file) >= 0);
if (check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING) < 0)
return;
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index b28089be7..9854270b2 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -828,6 +828,7 @@ int udev_event_spawn(UdevEvent *event,
static int rename_netif(UdevEvent *event) {
sd_device *dev = event->dev;
const char *oldname;
+ unsigned flags;
int ifindex, r;
if (!event->name)
@@ -855,6 +856,16 @@ static int rename_netif(UdevEvent *event) {
return 0;
}
+ r = rtnl_get_link_info(&event->rtnl, ifindex, NULL, &flags);
+ if (r < 0)
+ return log_device_warning_errno(dev, r, "Failed to get link flags: %m");
+
+ if (FLAGS_SET(flags, IFF_UP)) {
+ log_device_info(dev, "Network interface '%s' is already up, refusing to rename to '%s'.",
+ oldname, event->name);
+ return 0;
+ }
+
/* Set ID_RENAMING boolean property here, and drop it in the corresponding move uevent later. */
r = device_add_property(dev, "ID_RENAMING", "1");
if (r < 0)
diff --git a/src/userdb/userdbctl.c b/src/userdb/userdbctl.c
index 8db0c34fb..9ec0ad6c5 100644
--- a/src/userdb/userdbctl.c
+++ b/src/userdb/userdbctl.c
@@ -512,7 +512,7 @@ static int display_services(int argc, char *argv[], void *userdata) {
if (fd < 0)
return log_error_errno(r, "Failed to allocate AF_UNIX/SOCK_STREAM socket: %m");
- if (connect(fd, &sockaddr.un, sockaddr_len) < 0) {
+ if (connect(fd, &sockaddr.sa, sockaddr_len) < 0) {
no = strjoin("No (", errno_to_name(errno), ")");
if (!no)
return log_oom();
diff --git a/src/veritysetup/veritysetup-generator.c b/src/veritysetup/veritysetup-generator.c
index fd95e6f30..f4d14bcc6 100644
--- a/src/veritysetup/veritysetup-generator.c
+++ b/src/veritysetup/veritysetup-generator.c
@@ -100,7 +100,7 @@ static int create_device(void) {
fprintf(f,
"[Unit]\n"
- "Description=Integrity Protection Setup for %%I\n"
+ "Description=Verity Protection Setup for %%I\n"
"Documentation=man:systemd-veritysetup-generator(8) man:systemd-veritysetup@.service(8)\n"
"SourcePath=/proc/cmdline\n"
"DefaultDependencies=no\n"
diff --git a/src/veritysetup/veritysetup.c b/src/veritysetup/veritysetup.c
index e58bae45d..61973bf37 100644
--- a/src/veritysetup/veritysetup.c
+++ b/src/veritysetup/veritysetup.c
@@ -30,7 +30,7 @@ static int help(void) {
printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH [OPTIONS]\n"
"%s detach VOLUME\n\n"
- "Attach or detach an integrity protected block device.\n"
+ "Attach or detach a verity protected block device.\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
program_invocation_short_name,
diff --git a/test/TEST-63-ISSUE-17433/Makefile b/test/TEST-63-ISSUE-17433/Makefile
deleted file mode 120000
index e9f93b110..000000000
--- a/test/TEST-63-ISSUE-17433/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-63-ISSUE-17433/test.sh b/test/TEST-63-ISSUE-17433/test.sh
deleted file mode 100755
index c595a9f2d..000000000
--- a/test/TEST-63-ISSUE-17433/test.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/17433"
-
-# shellcheck source=test/test-functions
-. "${TEST_BASE_DIR:?}/test-functions"
-
-do_test "$@"
diff --git a/test/meson.build b/test/meson.build
index 6f8f257c2..65d4eb19b 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -33,8 +33,9 @@ if install_tests
install_dir : testdata_dir)
install_subdir('testsuite-52.units',
install_dir : testdata_dir)
- install_subdir('testsuite-63.units',
- install_dir : testdata_dir)
+
+ install_data(kbd_model_map,
+ install_dir : testdata_dir + '/test-keymap-util')
testsuite08_dir = testdata_dir + '/testsuite-08.units'
install_data('testsuite-08.units/-.mount',
diff --git a/test/test-keymap-util/kbd-model-map b/test/test-keymap-util/kbd-model-map
new file mode 120000
index 000000000..3e7c928b2
--- /dev/null
+++ b/test/test-keymap-util/kbd-model-map
@@ -0,0 +1 @@
+../../src/locale/kbd-model-map
\ No newline at end of file
diff --git a/test/testsuite-10.units/test10.service b/test/testsuite-10.units/test10.service
index 2fb476b98..d0be786b0 100644
--- a/test/testsuite-10.units/test10.service
+++ b/test/testsuite-10.units/test10.service
@@ -1,9 +1,6 @@
[Unit]
Requires=test10.socket
ConditionPathExistsGlob=/tmp/nonexistent
-# Make sure we hit the socket trigger limit in the test and not the service start limit.
-StartLimitInterval=1000
-StartLimitBurst=1000
[Service]
ExecStart=true
diff --git a/test/testsuite-63.units/test63.path b/test/testsuite-63.units/test63.path
deleted file mode 100644
index a6573bda0..000000000
--- a/test/testsuite-63.units/test63.path
+++ /dev/null
@@ -1,2 +0,0 @@
-[Path]
-PathExists=/tmp/test63
diff --git a/test/testsuite-63.units/test63.service b/test/testsuite-63.units/test63.service
deleted file mode 100644
index c83801874..000000000
--- a/test/testsuite-63.units/test63.service
+++ /dev/null
@@ -1,5 +0,0 @@
-[Unit]
-ConditionPathExists=!/tmp/nonexistent
-
-[Service]
-ExecStart=true
diff --git a/test/units/testsuite-63.service b/test/units/testsuite-63.service
deleted file mode 100644
index 04122723d..000000000
--- a/test/units/testsuite-63.service
+++ /dev/null
@@ -1,16 +0,0 @@
-[Unit]
-Description=TEST-63-ISSUE-17433
-
-[Service]
-ExecStartPre=rm -f /failed /testok
-Type=oneshot
-ExecStart=rm -f /tmp/nonexistent
-ExecStart=systemctl start test63.path
-ExecStart=touch /tmp/test63
-# Make sure systemd has sufficient time to hit the start limit for test63.service.
-ExecStart=sleep 2
-ExecStart=sh -x -c 'test "$(systemctl show test63.service -P ActiveState)" = failed'
-ExecStart=sh -x -c 'test "$(systemctl show test63.service -P Result)" = start-limit-hit'
-ExecStart=sh -x -c 'test "$(systemctl show test63.path -P ActiveState)" = failed'
-ExecStart=sh -x -c 'test "$(systemctl show test63.path -P Result)" = unit-start-limit-hit'
-ExecStart=sh -x -c 'echo OK >/testok'
diff --git a/units/remote-veritysetup.target b/units/remote-veritysetup.target
index bd9f71ace..bad28c3f0 100644
--- a/units/remote-veritysetup.target
+++ b/units/remote-veritysetup.target
@@ -8,7 +8,7 @@
# (at your option) any later version.
[Unit]
-Description=Remote Verity Integrity Protected Volumes
+Description=Remote Verity Protected Volumes
Documentation=man:systemd.special(7)
After=remote-fs-pre.target veritysetup-pre.target
DefaultDependencies=no
diff --git a/units/veritysetup-pre.target b/units/veritysetup-pre.target
index be065f335..869575a98 100644
--- a/units/veritysetup-pre.target
+++ b/units/veritysetup-pre.target
@@ -8,7 +8,7 @@
# (at your option) any later version.
[Unit]
-Description=Local Verity Integrity Protected Volumes (Pre)
+Description=Local Verity Protected Volumes (Pre)
Documentation=man:systemd.special(7)
RefuseManualStart=yes
Before=veritysetup.target
diff --git a/units/veritysetup.target b/units/veritysetup.target
index 0ac3ad3bd..c75b15375 100644
--- a/units/veritysetup.target
+++ b/units/veritysetup.target
@@ -8,5 +8,5 @@
# (at your option) any later version.
[Unit]
-Description=Local Verity Integrity Protected Volumes
+Description=Local Verity Protected Volumes
Documentation=man:systemd.special(7)