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.)
This commit is contained in:
Lennart Poettering
2026-01-23 21:04:55 +01:00
parent 91b3620b07
commit 9b29d38c33
3 changed files with 15 additions and 6 deletions

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);