mirror of
https://github.com/systemd/systemd.git
synced 2026-08-03 14:40:31 +00:00
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:
@@ -524,6 +524,18 @@
|
||||
<xi:include href="version-info.xml" xpointer="v252"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--efi-boot-option-description-with-device=</option></term>
|
||||
<listitem><para>Takes a boolean, defaults to false. Controls whether to append disk model information
|
||||
to the firmware boot option item description (as configured with
|
||||
<option>--efi-boot-option-description=</option> above). This is useful when installing multiple
|
||||
operating systems on separate disks on the same system, as it ensures the firmware boot options are discernable
|
||||
and give a hint which disk is booted into. Note that this uses hardware model information, and hence
|
||||
might not be too useful in case multiple disks of an identical model are used.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v260"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--dry-run</option></term>
|
||||
<listitem><para>Dry run for <option>unlink</option> and <option>cleanup</option>.</para>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,10 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "shared-forward.h"
|
||||
|
||||
int verb_install(int argc, char *argv[], void *userdata);
|
||||
int verb_remove(int argc, char *argv[], void *userdata);
|
||||
int verb_is_installed(int argc, char *argv[], void *userdata);
|
||||
|
||||
int vl_method_install(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
|
||||
|
||||
@@ -75,6 +75,8 @@ int get_file_version(int fd, char **ret) {
|
||||
assert(fd >= 0);
|
||||
assert(ret);
|
||||
|
||||
/* Does not reposition file offset (as it uses mmap()) */
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return log_error_errno(errno, "Failed to stat EFI binary: %m");
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "parse-argument.h"
|
||||
#include "path-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "utf8.h"
|
||||
@@ -39,12 +40,6 @@
|
||||
#include "verbs.h"
|
||||
#include "virt.h"
|
||||
|
||||
/* EFI_BOOT_OPTION_DESCRIPTION_MAX sets the maximum length for the boot option description
|
||||
* stored in NVRAM. The UEFI spec does not specify a minimum or maximum length for this
|
||||
* string, but we limit the length to something reasonable to prevent from the firmware
|
||||
* having to deal with a potentially too long string. */
|
||||
#define EFI_BOOT_OPTION_DESCRIPTION_MAX ((size_t) 255)
|
||||
|
||||
static GracefulMode _arg_graceful = ARG_GRACEFUL_NO;
|
||||
|
||||
char *arg_esp_path = NULL;
|
||||
@@ -69,6 +64,7 @@ char *arg_root = NULL;
|
||||
char *arg_image = NULL;
|
||||
InstallSource arg_install_source = INSTALL_SOURCE_AUTO;
|
||||
char *arg_efi_boot_option_description = NULL;
|
||||
bool arg_efi_boot_option_description_with_device = false;
|
||||
bool arg_dry_run = false;
|
||||
ImagePolicy *arg_image_policy = NULL;
|
||||
bool arg_varlink = false;
|
||||
@@ -93,6 +89,14 @@ STATIC_DESTRUCTOR_REGISTER(arg_certificate_source, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_private_key, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_private_key_source, freep);
|
||||
|
||||
static const char* const install_source_table[_INSTALL_SOURCE_MAX] = {
|
||||
[INSTALL_SOURCE_IMAGE] = "image",
|
||||
[INSTALL_SOURCE_HOST] = "host",
|
||||
[INSTALL_SOURCE_AUTO] = "auto",
|
||||
};
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(install_source, InstallSource);
|
||||
|
||||
int acquire_esp(
|
||||
int unprivileged_mode,
|
||||
bool graceful,
|
||||
@@ -340,6 +344,8 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" Install all supported EFI architectures\n"
|
||||
" --efi-boot-option-description=DESCRIPTION\n"
|
||||
" Description of the entry in the boot option list\n"
|
||||
" --efi-boot-option-description-with-device=yes\n"
|
||||
" Suffix description with disk vendor/model/serial\n"
|
||||
" --dry-run Dry run (unlink and cleanup)\n"
|
||||
" --secure-boot-auto-enroll=yes|no\n"
|
||||
" Set up secure boot auto-enrollment\n"
|
||||
@@ -389,6 +395,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_JSON,
|
||||
ARG_ARCH_ALL,
|
||||
ARG_EFI_BOOT_OPTION_DESCRIPTION,
|
||||
ARG_EFI_BOOT_OPTION_DESCRIPTION_WITH_DEVICE,
|
||||
ARG_DRY_RUN,
|
||||
ARG_PRINT_LOADER_PATH,
|
||||
ARG_PRINT_STUB_PATH,
|
||||
@@ -400,39 +407,40 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "esp-path", required_argument, NULL, ARG_ESP_PATH },
|
||||
{ "path", required_argument, NULL, ARG_ESP_PATH }, /* Compatibility alias */
|
||||
{ "boot-path", required_argument, NULL, ARG_BOOT_PATH },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{ "image", required_argument, NULL, ARG_IMAGE },
|
||||
{ "image-policy", required_argument, NULL, ARG_IMAGE_POLICY },
|
||||
{ "install-source", required_argument, NULL, ARG_INSTALL_SOURCE },
|
||||
{ "print-esp-path", no_argument, NULL, 'p' },
|
||||
{ "print-path", no_argument, NULL, 'p' }, /* Compatibility alias */
|
||||
{ "print-boot-path", no_argument, NULL, 'x' },
|
||||
{ "print-loader-path", no_argument, NULL, ARG_PRINT_LOADER_PATH },
|
||||
{ "print-stub-path", no_argument, NULL, ARG_PRINT_STUB_PATH },
|
||||
{ "print-root-device", no_argument, NULL, 'R' },
|
||||
{ "variables", required_argument, NULL, ARG_VARIABLES },
|
||||
{ "no-variables", no_argument, NULL, ARG_NO_VARIABLES }, /* Compatibility alias */
|
||||
{ "random-seed", required_argument, NULL, ARG_RANDOM_SEED },
|
||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||
{ "graceful", no_argument, NULL, ARG_GRACEFUL },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "make-entry-directory", required_argument, NULL, ARG_MAKE_ENTRY_DIRECTORY },
|
||||
{ "make-machine-id-directory", required_argument, NULL, ARG_MAKE_ENTRY_DIRECTORY }, /* Compatibility alias */
|
||||
{ "entry-token", required_argument, NULL, ARG_ENTRY_TOKEN },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{ "all-architectures", no_argument, NULL, ARG_ARCH_ALL },
|
||||
{ "efi-boot-option-description", required_argument, NULL, ARG_EFI_BOOT_OPTION_DESCRIPTION },
|
||||
{ "dry-run", no_argument, NULL, ARG_DRY_RUN },
|
||||
{ "secure-boot-auto-enroll", required_argument, NULL, ARG_SECURE_BOOT_AUTO_ENROLL },
|
||||
{ "certificate", required_argument, NULL, ARG_CERTIFICATE },
|
||||
{ "certificate-source", required_argument, NULL, ARG_CERTIFICATE_SOURCE },
|
||||
{ "private-key", required_argument, NULL, ARG_PRIVATE_KEY },
|
||||
{ "private-key-source", required_argument, NULL, ARG_PRIVATE_KEY_SOURCE },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "esp-path", required_argument, NULL, ARG_ESP_PATH },
|
||||
{ "path", required_argument, NULL, ARG_ESP_PATH }, /* Compatibility alias */
|
||||
{ "boot-path", required_argument, NULL, ARG_BOOT_PATH },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{ "image", required_argument, NULL, ARG_IMAGE },
|
||||
{ "image-policy", required_argument, NULL, ARG_IMAGE_POLICY },
|
||||
{ "install-source", required_argument, NULL, ARG_INSTALL_SOURCE },
|
||||
{ "print-esp-path", no_argument, NULL, 'p' },
|
||||
{ "print-path", no_argument, NULL, 'p' }, /* Compatibility alias */
|
||||
{ "print-boot-path", no_argument, NULL, 'x' },
|
||||
{ "print-loader-path", no_argument, NULL, ARG_PRINT_LOADER_PATH },
|
||||
{ "print-stub-path", no_argument, NULL, ARG_PRINT_STUB_PATH },
|
||||
{ "print-root-device", no_argument, NULL, 'R' },
|
||||
{ "variables", required_argument, NULL, ARG_VARIABLES },
|
||||
{ "no-variables", no_argument, NULL, ARG_NO_VARIABLES }, /* Compatibility alias */
|
||||
{ "random-seed", required_argument, NULL, ARG_RANDOM_SEED },
|
||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||
{ "graceful", no_argument, NULL, ARG_GRACEFUL },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "make-entry-directory", required_argument, NULL, ARG_MAKE_ENTRY_DIRECTORY },
|
||||
{ "make-machine-id-directory", required_argument, NULL, ARG_MAKE_ENTRY_DIRECTORY }, /* Compatibility alias */
|
||||
{ "entry-token", required_argument, NULL, ARG_ENTRY_TOKEN },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{ "all-architectures", no_argument, NULL, ARG_ARCH_ALL },
|
||||
{ "efi-boot-option-description", required_argument, NULL, ARG_EFI_BOOT_OPTION_DESCRIPTION },
|
||||
{ "efi-boot-option-description-with-device", required_argument, NULL, ARG_EFI_BOOT_OPTION_DESCRIPTION_WITH_DEVICE },
|
||||
{ "dry-run", no_argument, NULL, ARG_DRY_RUN },
|
||||
{ "secure-boot-auto-enroll", required_argument, NULL, ARG_SECURE_BOOT_AUTO_ENROLL },
|
||||
{ "certificate", required_argument, NULL, ARG_CERTIFICATE },
|
||||
{ "certificate-source", required_argument, NULL, ARG_CERTIFICATE_SOURCE },
|
||||
{ "private-key", required_argument, NULL, ARG_PRIVATE_KEY },
|
||||
{ "private-key-source", required_argument, NULL, ARG_PRIVATE_KEY_SOURCE },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -481,18 +489,14 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return r;
|
||||
break;
|
||||
|
||||
case ARG_INSTALL_SOURCE:
|
||||
if (streq(optarg, "auto"))
|
||||
arg_install_source = INSTALL_SOURCE_AUTO;
|
||||
else if (streq(optarg, "image"))
|
||||
arg_install_source = INSTALL_SOURCE_IMAGE;
|
||||
else if (streq(optarg, "host"))
|
||||
arg_install_source = INSTALL_SOURCE_HOST;
|
||||
else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Unexpected parameter for --install-source=: %s", optarg);
|
||||
case ARG_INSTALL_SOURCE: {
|
||||
InstallSource is = install_source_from_string(optarg);
|
||||
if (is < 0)
|
||||
return log_error_errno(is, "Unexpected parameter for --install-source=: %s", optarg);
|
||||
|
||||
arg_install_source = is;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p':
|
||||
arg_print_esp_path = true;
|
||||
@@ -572,9 +576,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
case ARG_EFI_BOOT_OPTION_DESCRIPTION:
|
||||
if (isempty(optarg) || !(string_is_safe(optarg) && utf8_is_valid(optarg))) {
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
|
||||
escaped = cescape(optarg);
|
||||
_cleanup_free_ char *escaped = cescape(optarg);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Invalid --efi-boot-option-description=: %s", strna(escaped));
|
||||
}
|
||||
@@ -587,6 +589,13 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return r;
|
||||
break;
|
||||
|
||||
case ARG_EFI_BOOT_OPTION_DESCRIPTION_WITH_DEVICE:
|
||||
r = parse_boolean_argument("--efi-boot-option-description-with-device=", optarg, &arg_efi_boot_option_description_with_device);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case ARG_DRY_RUN:
|
||||
arg_dry_run = true;
|
||||
break;
|
||||
@@ -711,7 +720,7 @@ static int vl_server(void) {
|
||||
|
||||
r = varlink_server_new(
|
||||
&varlink_server,
|
||||
SD_VARLINK_SERVER_ROOT_ONLY,
|
||||
SD_VARLINK_SERVER_ROOT_ONLY|SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT,
|
||||
/* userdata= */ NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate Varlink server: %m");
|
||||
@@ -724,7 +733,8 @@ static int vl_server(void) {
|
||||
varlink_server,
|
||||
"io.systemd.BootControl.ListBootEntries", vl_method_list_boot_entries,
|
||||
"io.systemd.BootControl.SetRebootToFirmware", vl_method_set_reboot_to_firmware,
|
||||
"io.systemd.BootControl.GetRebootToFirmware", vl_method_get_reboot_to_firmware);
|
||||
"io.systemd.BootControl.GetRebootToFirmware", vl_method_get_reboot_to_firmware,
|
||||
"io.systemd.BootControl.Install", vl_method_install);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind Varlink methods: %m");
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ extern char *arg_root;
|
||||
extern char *arg_image;
|
||||
extern InstallSource arg_install_source;
|
||||
extern char *arg_efi_boot_option_description;
|
||||
extern bool arg_efi_boot_option_description_with_device;
|
||||
extern bool arg_dry_run;
|
||||
extern ImagePolicy *arg_image_policy;
|
||||
extern bool arg_varlink;
|
||||
@@ -59,3 +60,9 @@ int acquire_esp(int unprivileged_mode, bool graceful, uint32_t *ret_part, uint64
|
||||
int acquire_xbootldr(int unprivileged_mode, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
|
||||
bool touch_variables(void);
|
||||
|
||||
/* EFI_BOOT_OPTION_DESCRIPTION_MAX sets the maximum length for the boot option description
|
||||
* stored in NVRAM. The UEFI spec does not specify a minimum or maximum length for this
|
||||
* string, but we limit the length to something reasonable to prevent from the firmware
|
||||
* having to deal with a potentially too long string. */
|
||||
#define EFI_BOOT_OPTION_DESCRIPTION_MAX ((size_t) 255)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -27,9 +27,11 @@ restore_esp() {
|
||||
fi
|
||||
|
||||
if [ -d /tmp/esp.bak/EFI/ ]; then
|
||||
mkdir -p "$(bootctl --print-esp-path)/EFI/"
|
||||
cp -r /tmp/esp.bak/EFI/* "$(bootctl --print-esp-path)/EFI/"
|
||||
fi
|
||||
if [ -d /tmp/esp.bak/loader/ ]; then
|
||||
mkdir -p "$(bootctl --print-esp-path)/loader/"
|
||||
cp -r /tmp/esp.bak/loader/* "$(bootctl --print-esp-path)/loader/"
|
||||
fi
|
||||
rm -rf /tmp/esp.bak
|
||||
@@ -40,13 +42,19 @@ backup_esp() {
|
||||
return
|
||||
fi
|
||||
|
||||
# make a backup of the two key dirs in the ESP, and delete them
|
||||
|
||||
if [[ -d "$(bootctl --print-esp-path)/EFI" ]]; then
|
||||
mkdir -p /tmp/esp.bak
|
||||
cp -r "$(bootctl --print-esp-path)/EFI/" /tmp/esp.bak/
|
||||
rm -rf "$(bootctl --print-esp-path)/EFI"
|
||||
mkdir "$(bootctl --print-esp-path)/EFI"
|
||||
fi
|
||||
if [[ -d "$(bootctl --print-esp-path)/loader" ]]; then
|
||||
mkdir -p /tmp/esp.bak
|
||||
cp -r "$(bootctl --print-esp-path)/loader/" /tmp/esp.bak/
|
||||
rm -rf "$(bootctl --print-esp-path)/loader"
|
||||
mkdir "$(bootctl --print-esp-path)/loader"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -364,4 +372,22 @@ testcase_00_secureboot() {
|
||||
grep -q addonfoobar /proc/cmdline
|
||||
}
|
||||
|
||||
remove_root_dir() {
|
||||
rm -rf "$ROOTDIR"
|
||||
}
|
||||
|
||||
testcase_install_varlink() {
|
||||
|
||||
varlinkctl introspect "$(type -p bootctl)"
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
backup_esp
|
||||
trap restore_esp RETURN ERR
|
||||
fi
|
||||
|
||||
(! bootctl is-installed )
|
||||
SYSTEMD_LOG_TARGET=console varlinkctl call "$(type -p bootctl)" io.systemd.BootControl.Install "{\"operation\":\"new\",\"touchVariables\":false}"
|
||||
bootctl is-installed
|
||||
}
|
||||
|
||||
run_testcases
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# (at your option) any later version.
|
||||
|
||||
[Unit]
|
||||
Description=Boot Entries Service Socket
|
||||
Description=Boot Loader Control Service Socket
|
||||
Documentation=man:bootctl(1)
|
||||
DefaultDependencies=no
|
||||
After=local-fs.target
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# (at your option) any later version.
|
||||
|
||||
[Unit]
|
||||
Description=Boot Entries Service
|
||||
Description=Boot Loader Control Service
|
||||
Documentation=man:bootctl(1)
|
||||
DefaultDependencies=no
|
||||
Conflicts=shutdown.target
|
||||
|
||||
Reference in New Issue
Block a user