bootctl: move arg_touch_variables checkers to bootctl-util.c

No functional change, just refactoring.
This commit is contained in:
Yu Watanabe
2026-02-13 16:11:30 +09:00
parent 3c5ed73030
commit 28fa318b16
6 changed files with 75 additions and 58 deletions
+1
View File
@@ -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"
+4 -33
View File
@@ -1,18 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <uchar.h>
#include <unistd.h>
#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 *);
+65
View File
@@ -2,17 +2,82 @@
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#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;
+5
View File
@@ -1,6 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
bool touch_variables(void);
int verify_touch_variables_allowed(const char *command);
int sync_everything(void);
const char* get_efi_arch(void);
-23
View File
@@ -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;
-2
View File
@@ -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