From: Yu Watanabe Date: Wed, 21 Jan 2026 10:36:10 +0000 (+0900) Subject: bootctl: move arg_touch_variables checkers to bootctl-util.c X-Git-Tag: v260-rc1~7^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=28fa318b16d8ba30e51f38c98e332ee8a5610d66;p=thirdparty%2Fsystemd.git bootctl: move arg_touch_variables checkers to bootctl-util.c No functional change, just refactoring. --- diff --git a/src/bootctl/bootctl-random-seed.c b/src/bootctl/bootctl-random-seed.c index 8abb6c19697..a193b3a2f82 100644 --- a/src/bootctl/bootctl-random-seed.c +++ b/src/bootctl/bootctl-random-seed.c @@ -5,6 +5,7 @@ #include "alloc-util.h" #include "bootctl.h" #include "bootctl-random-seed.h" +#include "bootctl-util.h" #include "efivars.h" #include "env-util.h" #include "fd-util.h" diff --git a/src/bootctl/bootctl-set-efivar.c b/src/bootctl/bootctl-set-efivar.c index 82770dd6c6c..7c3a18e1207 100644 --- a/src/bootctl/bootctl-set-efivar.c +++ b/src/bootctl/bootctl-set-efivar.c @@ -1,18 +1,17 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include #include "alloc-util.h" #include "bootctl.h" #include "bootctl-set-efivar.h" +#include "bootctl-util.h" #include "efi-loader.h" #include "efivars.h" #include "log.h" #include "stdio-util.h" #include "time-util.h" #include "utf8.h" -#include "virt.h" static int parse_timeout(const char *arg1, char16_t **ret_timeout, size_t *ret_timeout_size) { char buf[DECIMAL_STR_MAX(usec_t)]; @@ -133,37 +132,9 @@ static int parse_loader_entry_target_arg(const char *arg1, char16_t **ret_target int verb_set_efivar(int argc, char *argv[], void *userdata) { int r; - /* Note: changing EFI variables is the primary purpose of these verbs, hence unlike in the other - * verbs that might touch EFI variables where we skip things gracefully, here we fail loudly if we - * are not run on EFI or EFI variable modifications were turned off. */ - - if (arg_touch_variables < 0) { - if (arg_root) - return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "Acting on %s, refusing EFI variable setup.", - arg_image ? "image" : "root directory"); - - if (detect_container() > 0) - return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "'%s' operation not supported in a container.", - argv[0]); - if (!is_efi_boot()) - return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "Not booted with UEFI."); - - if (access(EFIVAR_PATH(EFI_LOADER_VARIABLE_STR("LoaderInfo")), F_OK) < 0) { - if (errno == ENOENT) { - log_error_errno(errno, "Not booted with a supported boot loader."); - return -EOPNOTSUPP; - } - - return log_error_errno(errno, "Failed to detect whether boot loader supports '%s' operation: %m", argv[0]); - } - - } else if (!arg_touch_variables) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "'%s' operation cannot be combined with --variables=no.", - argv[0]); + r = verify_touch_variables_allowed(argv[0]); + if (r < 0) + return r; const char *variable; int (* arg_parser)(const char *, char16_t **, size_t *); diff --git a/src/bootctl/bootctl-util.c b/src/bootctl/bootctl-util.c index 071accb77d6..19a7f47b8a0 100644 --- a/src/bootctl/bootctl-util.c +++ b/src/bootctl/bootctl-util.c @@ -2,17 +2,82 @@ #include #include +#include #include "alloc-util.h" #include "boot-entry.h" #include "bootctl.h" #include "bootctl-util.h" +#include "efivars.h" #include "errno-util.h" #include "fileio.h" #include "log.h" #include "stat-util.h" #include "string-util.h" #include "sync-util.h" +#include "virt.h" + +bool touch_variables(void) { + /* If we run in a container or on a non-EFI system, automatically turn off EFI file system access, + * unless explicitly overridden. */ + + if (arg_touch_variables >= 0) + return arg_touch_variables; + + if (arg_root) { + log_once(LOG_NOTICE, + "Operating on %s, skipping EFI variable modifications.", + arg_image ? "image" : "root directory"); + return false; + } + + if (!is_efi_boot()) { /* NB: this internally checks if we run in a container */ + log_once(LOG_NOTICE, + "Not booted with EFI or running in a container, skipping EFI variable modifications."); + return false; + } + + return true; +} + +int verify_touch_variables_allowed(const char *command) { + /* Note: changing EFI variables is the primary purpose of these verbs, hence unlike in the other + * verbs that might touch EFI variables where we skip things gracefully, here we fail loudly if we + * are not run on EFI or EFI variable modifications were turned off. */ + + if (arg_touch_variables > 0) + return 0; + + if (arg_touch_variables == 0) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "'%s' operation cannot be combined with --variables=no.", + command); + + if (arg_root) + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), + "Acting on %s, refusing EFI variable setup.", + arg_image ? "image" : "root directory"); + + if (detect_container() > 0) + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), + "'%s' operation not supported in a container.", + command); + + if (!is_efi_boot()) + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), + "Not booted with UEFI."); + + if (access(EFIVAR_PATH(EFI_LOADER_VARIABLE_STR("LoaderInfo")), F_OK) < 0) { + if (errno == ENOENT) { + log_error_errno(errno, "Not booted with a supported boot loader."); + return -EOPNOTSUPP; + } + + return log_error_errno(errno, "Failed to detect whether boot loader supports '%s' operation: %m", command); + } + + return 0; +} int sync_everything(void) { int r = 0, k; diff --git a/src/bootctl/bootctl-util.h b/src/bootctl/bootctl-util.h index 4abd4a303be..25b4451d92f 100644 --- a/src/bootctl/bootctl-util.h +++ b/src/bootctl/bootctl-util.h @@ -1,6 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include + +bool touch_variables(void); +int verify_touch_variables_allowed(const char *command); + int sync_everything(void); const char* get_efi_arch(void); diff --git a/src/bootctl/bootctl.c b/src/bootctl/bootctl.c index 77a4d555932..b0c1fb29341 100644 --- a/src/bootctl/bootctl.c +++ b/src/bootctl/bootctl.c @@ -229,29 +229,6 @@ static int print_loader_or_stub_path(void) { return 0; } -bool touch_variables(void) { - /* If we run in a container or on a non-EFI system, automatically turn off EFI file system access, - * unless explicitly overridden. */ - - if (arg_touch_variables >= 0) - return arg_touch_variables; - - if (arg_root) { - log_once(LOG_NOTICE, - "Operating on %s, skipping EFI variable modifications.", - arg_image ? "image" : "root directory"); - return false; - } - - if (!is_efi_boot()) { /* NB: this internally checks if we run in a container */ - log_once(LOG_NOTICE, - "Not booted with EFI or running in a container, skipping EFI variable modifications."); - return false; - } - - return true; -} - GracefulMode arg_graceful(void) { static bool chroot_checked = false; diff --git a/src/bootctl/bootctl.h b/src/bootctl/bootctl.h index 93a1ca733b6..d979411c782 100644 --- a/src/bootctl/bootctl.h +++ b/src/bootctl/bootctl.h @@ -59,8 +59,6 @@ GracefulMode arg_graceful(void); int acquire_esp(int unprivileged_mode, bool graceful, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid); 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