From 9b29d38c33dcdb56a51d0baf577a8d6d4afde4e4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 23 Jan 2026 21:04:55 +0100 Subject: [PATCH] bootctl: return recognizable Varlink error when we cannot determine the boot entry token When running "bootctl install" on an empty --root= dir, we don't know which token to use, and the operation will fail. Make sure to return an explicit error about this. This introduces a recognizable low-level error for this (EUNATCH), and then turns this into a recognizable Varlink error. (I made sure that the old low-level error EINVAL wasn't load-bearing, and it is safe to change this.) --- src/bootctl/bootctl-install.c | 2 ++ src/shared/boot-entry.c | 12 +++++++----- src/shared/varlink-io.systemd.BootControl.c | 7 ++++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/bootctl/bootctl-install.c b/src/bootctl/bootctl-install.c index 976c5380e1f..2d9a151212d 100644 --- a/src/bootctl/bootctl-install.c +++ b/src/bootctl/bootctl-install.c @@ -2087,6 +2087,8 @@ int vl_method_install( return r; r = run_install(&p.context); + if (r == -EUNATCH) /* no boot entry token is set */ + return sd_varlink_error(link, "io.systemd.BootControl.BootEntryTokenUnavailable", NULL); if (r < 0) return r; diff --git a/src/shared/boot-entry.c b/src/shared/boot-entry.c index 042522951cc..0f1d8090247 100644 --- a/src/shared/boot-entry.c +++ b/src/shared/boot-entry.c @@ -155,6 +155,8 @@ int boot_entry_token_ensure_at( assert(type); assert(token); + /* Returns -EUNATCH if the selected token is not set */ + if (*token) return 0; /* Already set. */ @@ -181,7 +183,7 @@ int boot_entry_token_ensure_at( return r; } - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + return log_error_errno(SYNTHETIC_ERRNO(EUNATCH), "No machine ID set, and /etc/os-release carries no ID=/IMAGE_ID= fields."); case BOOT_ENTRY_TOKEN_MACHINE_ID: @@ -189,14 +191,14 @@ int boot_entry_token_ensure_at( if (r != 0) return r; - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No machine ID set."); + return log_error_errno(SYNTHETIC_ERRNO(EUNATCH), "No machine ID set."); case BOOT_ENTRY_TOKEN_OS_IMAGE_ID: r = entry_token_from_os_release(rfd, type, token); if (r != 0) return r; - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + return log_error_errno(SYNTHETIC_ERRNO(EUNATCH), "IMAGE_ID= field not set in /etc/os-release."); case BOOT_ENTRY_TOKEN_OS_ID: @@ -204,12 +206,12 @@ int boot_entry_token_ensure_at( if (r != 0) return r; - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + return log_error_errno(SYNTHETIC_ERRNO(EUNATCH), "ID= field not set in /etc/os-release."); case BOOT_ENTRY_TOKEN_LITERAL: /* In this case, the token should be already set by the user input. */ - return -EINVAL; + return log_error_errno(SYNTHETIC_ERRNO(EUNATCH), "Literal token indicated but not specified."); default: assert_not_reached(); diff --git a/src/shared/varlink-io.systemd.BootControl.c b/src/shared/varlink-io.systemd.BootControl.c index 453002aaa9f..a24b4b076e0 100644 --- a/src/shared/varlink-io.systemd.BootControl.c +++ b/src/shared/varlink-io.systemd.BootControl.c @@ -143,6 +143,9 @@ static SD_VARLINK_DEFINE_ERROR( static SD_VARLINK_DEFINE_ERROR( NoESPFound); +static SD_VARLINK_DEFINE_ERROR( + BootEntryTokenUnavailable); + SD_VARLINK_DEFINE_INTERFACE( io_systemd_BootControl, "io.systemd.BootControl", @@ -172,4 +175,6 @@ SD_VARLINK_DEFINE_INTERFACE( SD_VARLINK_SYMBOL_COMMENT("No boot entry defined."), &vl_error_NoSuchBootEntry, SD_VARLINK_SYMBOL_COMMENT("No EFI System Partition (ESP) found."), - &vl_error_NoESPFound); + &vl_error_NoESPFound, + SD_VARLINK_SYMBOL_COMMENT("The select boot entry token could not be determined."), + &vl_error_BootEntryTokenUnavailable); -- 2.47.3