bootctl parts of installer PR (#40447)

This contains the "bootctl install" related work from the #38764 split
out, but also includes the preparatory work already split out into
#40446.

I'll rebase this PR once the prep work is merged.

This has a simple CI test already, and has docs
This commit is contained in:
Daan De Meyer
2026-02-09 09:46:39 +01:00
committed by GitHub
13 changed files with 1328 additions and 475 deletions
+8 -6
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();
@@ -291,4 +293,4 @@ static const char *const boot_entry_token_type_table[] = {
[BOOT_ENTRY_TOKEN_AUTO] = "auto",
};
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(boot_entry_token_type, BootEntryTokenType);
DEFINE_STRING_TABLE_LOOKUP(boot_entry_token_type, BootEntryTokenType);
+1 -1
View File
@@ -34,4 +34,4 @@ int boot_entry_token_ensure_at(
int parse_boot_entry_token_type(const char *s, BootEntryTokenType *type, char **token);
DECLARE_STRING_TABLE_LOOKUP_TO_STRING(boot_entry_token_type, BootEntryTokenType);
DECLARE_STRING_TABLE_LOOKUP(boot_entry_token_type, BootEntryTokenType);
+2
View File
@@ -12,6 +12,8 @@
#include "string-table.h"
#include "string-util.h"
/* Note: none of these function change the file position of the provided fd, as they use pread() */
bool pe_header_is_64bit(const PeHeader *h) {
assert(h);
+68 -1
View File
@@ -36,21 +36,37 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
SD_VARLINK_DEFINE_FIELD_BY_TYPE(source, BootEntrySource, 0),
SD_VARLINK_FIELD_COMMENT("The string identifier of the entry"),
SD_VARLINK_DEFINE_FIELD(id, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Path to the primary definition file for the entry"),
SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Directory path of the file system root the entry was found on"),
SD_VARLINK_DEFINE_FIELD(root, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The entry's title string"),
SD_VARLINK_DEFINE_FIELD(title, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The possibly mangled/augmented title to show for the entry"),
SD_VARLINK_DEFINE_FIELD(showTitle, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("An explicitly configured sorting key for the enry"),
SD_VARLINK_DEFINE_FIELD(sortKey, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The version of the entry"),
SD_VARLINK_DEFINE_FIELD(version, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Machine ID of the OS installation belonging to the entry, if known"),
SD_VARLINK_DEFINE_FIELD(machineId, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("EFI architecture name for this entry"),
SD_VARLINK_DEFINE_FIELD(architecture, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Command line options to pass to the invoked kernel or EFI binary"),
SD_VARLINK_DEFINE_FIELD(options, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Path to the Linux kernel to invoke, relative to the root directory of the file system containing the entry file"),
SD_VARLINK_DEFINE_FIELD(linux, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Path to the EFI binary to invoke, relative to the root directory of the file system containing the entry file"),
SD_VARLINK_DEFINE_FIELD(efi, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Path to an UKI EFI binary to invoke, relative to the root directory of the file system containing the entry file"),
SD_VARLINK_DEFINE_FIELD(uki, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("An UKI profile index to invoke. If not specified defaults to the first profile."),
SD_VARLINK_DEFINE_FIELD(profile, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Path to the initrd image to pass to the invoked kernel, relative to the root directory of the file system containing the entry file"),
SD_VARLINK_DEFINE_FIELD(initrd, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY),
SD_VARLINK_FIELD_COMMENT("Devicetree file to pass to the invoked kernel, relative to the root directory of the file system containing the entry file"),
SD_VARLINK_DEFINE_FIELD(devicetree, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Devicetree overlay file to pass to the invoked kernel, relative to the root directory of the file system containing the entry file"),
SD_VARLINK_DEFINE_FIELD(devicetreeOverlay, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY),
SD_VARLINK_FIELD_COMMENT("Indicates whether the boot loader reported this entry on the current boot"),
SD_VARLINK_DEFINE_FIELD(isReported, SD_VARLINK_BOOL, 0),
@@ -83,12 +99,53 @@ static SD_VARLINK_DEFINE_METHOD(
SD_VARLINK_FIELD_COMMENT("The current state of the reboot-to-firmware-UI flag"),
SD_VARLINK_DEFINE_OUTPUT(state, SD_VARLINK_BOOL, 0));
static SD_VARLINK_DEFINE_ENUM_TYPE(
Operation,
SD_VARLINK_FIELD_COMMENT("Install the boot loader afresh, creating everything it needs"),
SD_VARLINK_DEFINE_ENUM_VALUE(new),
SD_VARLINK_FIELD_COMMENT("Just update existing boot loader binaries"),
SD_VARLINK_DEFINE_ENUM_VALUE(update));
static SD_VARLINK_DEFINE_ENUM_TYPE(
BootEntryTokenType,
SD_VARLINK_FIELD_COMMENT("Pick identifiers for type #1 boot entries based on /etc/machine-id"),
SD_VARLINK_DEFINE_ENUM_VALUE(machine_id),
SD_VARLINK_FIELD_COMMENT("Pick identifiers for type #1 boot entries based on the IMAGE_ID= field from /etc/os-release"),
SD_VARLINK_DEFINE_ENUM_VALUE(os_image_id),
SD_VARLINK_FIELD_COMMENT("Pick identifiers for type #1 boot entries based on the ID= field from /etc/os-release"),
SD_VARLINK_DEFINE_ENUM_VALUE(os_id),
SD_VARLINK_FIELD_COMMENT("Pick identifiers for type #1 boot entries based on a manually chosen string"),
SD_VARLINK_DEFINE_ENUM_VALUE(literal),
SD_VARLINK_FIELD_COMMENT("Choose automatically how to pick identifiers for type #1 boot entries"),
SD_VARLINK_DEFINE_ENUM_VALUE(auto));
static SD_VARLINK_DEFINE_METHOD(
Install,
SD_VARLINK_FIELD_COMMENT("Operation, either 'new' or 'update'"),
SD_VARLINK_DEFINE_INPUT_BY_TYPE(operation, Operation, 0),
SD_VARLINK_FIELD_COMMENT("If true, continue on various failures"),
SD_VARLINK_DEFINE_INPUT(graceful, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Index into array of file descriptors passed along with this message, pointing to file descriptor to root file system to operate on"),
SD_VARLINK_DEFINE_INPUT(rootFileDescriptor, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Root directory to operate relative to. If both this and rootFileDescriptor is specified, this is purely informational. If only this is specified, it is what will be used."),
SD_VARLINK_DEFINE_INPUT(rootDirectory, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Selects how to identify boot entries"),
SD_VARLINK_DEFINE_INPUT_BY_TYPE(bootEntryTokenType, BootEntryTokenType, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If true the boot loader will be registered in an EFI boot entry via EFI variables, otherwise this is omitted"),
SD_VARLINK_DEFINE_INPUT(touchVariables, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_ERROR(
RebootToFirmwareNotSupported);
static SD_VARLINK_DEFINE_ERROR(
NoSuchBootEntry);
static SD_VARLINK_DEFINE_ERROR(
NoESPFound);
static SD_VARLINK_DEFINE_ERROR(
BootEntryTokenUnavailable);
SD_VARLINK_DEFINE_INTERFACE(
io_systemd_BootControl,
"io.systemd.BootControl",
@@ -101,13 +158,23 @@ SD_VARLINK_DEFINE_INTERFACE(
&vl_type_BootEntryAddon,
SD_VARLINK_SYMBOL_COMMENT("A structure encapsulating a boot entry"),
&vl_type_BootEntry,
SD_VARLINK_SYMBOL_COMMENT("The operation to execute"),
&vl_type_Operation,
SD_VARLINK_SYMBOL_COMMENT("Enumerates boot entries. Method call must be called with 'more' flag set. Each response returns one entry. If no entries are defined returns the NoSuchBootEntry error."),
&vl_method_ListBootEntries,
SD_VARLINK_SYMBOL_COMMENT("Sets the reboot-to-firmware-UI flag of the firmware, if this concept exists. Returns the RebootToFirmwareNotSupported error if not."),
&vl_method_SetRebootToFirmware,
SD_VARLINK_SYMBOL_COMMENT("Gets the current state of the reboot-to-firmware-UI flag of the firmware, if this concept exists. Returns the RebootToFirmwareNotSupported error if not."),
&vl_method_GetRebootToFirmware,
SD_VARLINK_SYMBOL_COMMENT("The boot entry token type to use."),
&vl_type_BootEntryTokenType,
SD_VARLINK_SYMBOL_COMMENT("Install the boot loader on the ESP."),
&vl_method_Install,
SD_VARLINK_SYMBOL_COMMENT("SetRebootToFirmware() and GetRebootToFirmware() return this if the firmware does not actually support the reboot-to-firmware-UI concept."),
&vl_error_RebootToFirmwareNotSupported,
SD_VARLINK_SYMBOL_COMMENT("No boot entry defined."),
&vl_error_NoSuchBootEntry);
&vl_error_NoSuchBootEntry,
SD_VARLINK_SYMBOL_COMMENT("No EFI System Partition (ESP) found."),
&vl_error_NoESPFound,
SD_VARLINK_SYMBOL_COMMENT("The select boot entry token could not be determined."),
&vl_error_BootEntryTokenUnavailable);