From: Mike Yuan Date: Wed, 3 Sep 2025 14:44:32 +0000 (+0200) Subject: bootctl: make sure install verb also honors implied --graceful X-Git-Tag: v258-rc4~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1bc82e0c974fc3cf3b35dc47abfbd0838302c125;p=thirdparty%2Fsystemd.git bootctl: make sure install verb also honors implied --graceful Follow-up for bcc73cafdbd9c3947c53e4cff3498f8a73e56d9d --- diff --git a/src/bootctl/bootctl-install.c b/src/bootctl/bootctl-install.c index 27ec4cf0fea..197c9d5bd63 100644 --- a/src/bootctl/bootctl-install.c +++ b/src/bootctl/bootctl-install.c @@ -453,7 +453,7 @@ static int install_binaries(const char *esp_path, const char *arch, bool force) /* If we had a root directory to try, we didn't find it and we are in auto mode, retry on the host */ if (r == -ENOENT && root && arg_install_source == ARG_INSTALL_SOURCE_AUTO) r = chase_and_opendir(BOOTLIBDIR, NULL, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_TRIGGER_AUTOFS, &path, &d); - if (r == -ENOENT && arg_graceful) { + if (r == -ENOENT && arg_graceful() != ARG_GRACEFUL_NO) { log_debug("Source directory does not exist, ignoring."); return 0; } @@ -481,7 +481,7 @@ static int install_binaries(const char *esp_path, const char *arch, bool force) k = copy_one_file(esp_path, de->d_name, force); /* Don't propagate an error code if no update necessary, installed version already equal or * newer version, or other boot loader in place. */ - if (arg_graceful && IN_SET(k, -ESTALE, -ESRCH)) + if (arg_graceful() != ARG_GRACEFUL_NO && IN_SET(k, -ESTALE, -ESRCH)) continue; RET_GATHER(r, k); } @@ -961,7 +961,9 @@ int verb_install(int argc, char *argv[], void *userdata) { /* Invoked for both "update" and "install" */ install = streq(argv[0], "install"); - graceful = !install && arg_graceful; /* support graceful mode for updates */ + + /* Support graceful mode only for updates, unless forcibly enabled in chroot environments */ + graceful = arg_graceful() == ARG_GRACEFUL_FORCE || (!install && arg_graceful() != ARG_GRACEFUL_NO); if (arg_secure_boot_auto_enroll) { if (arg_certificate_source_type == OPENSSL_CERTIFICATE_SOURCE_FILE) { @@ -1365,7 +1367,7 @@ int verb_is_installed(int argc, char *argv[], void *userdata) { int r; r = acquire_esp(/* unprivileged_mode= */ false, - /* graceful= */ arg_graceful, + /* graceful= */ arg_graceful() != ARG_GRACEFUL_NO, NULL, NULL, NULL, NULL, NULL); if (r < 0) return r; diff --git a/src/bootctl/bootctl-random-seed.c b/src/bootctl/bootctl-random-seed.c index a9826ca9e6b..7cd39624c11 100644 --- a/src/bootctl/bootctl-random-seed.c +++ b/src/bootctl/bootctl-random-seed.c @@ -96,7 +96,7 @@ static int set_system_token(void) { WITH_UMASK(0077) { r = efi_set_variable(EFI_LOADER_VARIABLE_STR("LoaderSystemToken"), buffer, sizeof(buffer)); if (r < 0) { - if (!arg_graceful) + if (arg_graceful() == ARG_GRACEFUL_NO) return log_error_errno(r, "Failed to write 'LoaderSystemToken' EFI variable: %m"); if (r == -EINVAL) @@ -213,7 +213,7 @@ int verb_random_seed(int argc, char *argv[], void *userdata) { r = find_esp_and_warn(arg_root, arg_esp_path, false, &arg_esp_path, NULL, NULL, NULL, NULL, NULL); if (r == -ENOKEY) { /* find_esp_and_warn() doesn't warn about ENOKEY, so let's do that on our own */ - if (!arg_graceful) + if (arg_graceful() == ARG_GRACEFUL_NO) return log_error_errno(r, "Unable to find ESP."); log_notice("No ESP found, not initializing random seed."); diff --git a/src/bootctl/bootctl-set-efivar.c b/src/bootctl/bootctl-set-efivar.c index c989f73aee4..b102d6600ea 100644 --- a/src/bootctl/bootctl-set-efivar.c +++ b/src/bootctl/bootctl-set-efivar.c @@ -40,7 +40,7 @@ static int parse_timeout(const char *arg1, char16_t **ret_timeout, size_t *ret_t (void) efi_loader_get_features(&loader_features); if (!(loader_features & EFI_LOADER_FEATURE_MENU_DISABLE)) { - if (!arg_graceful) + if (arg_graceful() == ARG_GRACEFUL_NO) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Loader does not support 'menu-disabled'."); log_warning("Loader does not support 'menu-disabled', setting anyway."); diff --git a/src/bootctl/bootctl.c b/src/bootctl/bootctl.c index 2f86e87476e..192f9ddb603 100644 --- a/src/bootctl/bootctl.c +++ b/src/bootctl/bootctl.c @@ -45,6 +45,8 @@ * 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; char *arg_xbootldr_path = NULL; bool arg_print_esp_path = false; @@ -55,7 +57,6 @@ unsigned arg_print_root_device = 0; int arg_touch_variables = -1; bool arg_install_random_seed = true; PagerFlags arg_pager_flags = 0; -bool arg_graceful = false; bool arg_quiet = false; int arg_make_entry_directory = false; /* tri-state: < 0 for automatic logic */ sd_id128_t arg_machine_id = SD_ID128_NULL; @@ -245,6 +246,21 @@ bool touch_variables(void) { return true; } +GracefulMode arg_graceful(void) { + static bool chroot_checked = false; + + if (!chroot_checked && running_in_chroot() > 0) { + if (_arg_graceful == ARG_GRACEFUL_NO) + log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, "Running in a chroot, enabling --graceful."); + + _arg_graceful = ARG_GRACEFUL_FORCE; + } + + chroot_checked = true; + + return _arg_graceful; +} + static int help(int argc, char *argv[], void *userdata) { _cleanup_free_ char *link = NULL; int r; @@ -519,7 +535,7 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_GRACEFUL: - arg_graceful = true; + _arg_graceful = ARG_GRACEFUL_YES; break; case 'q': @@ -644,11 +660,6 @@ static int parse_argv(int argc, char *argv[]) { if (arg_secure_boot_auto_enroll && !arg_private_key) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Secure boot auto-enrollment requested but no private key provided"); - if (!arg_graceful && running_in_chroot() > 0) { - log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, "Running in a chroot, enabling --graceful."); - arg_graceful = true; - } - r = sd_varlink_invocation(SD_VARLINK_ALLOW_ACCEPT); if (r < 0) return log_error_errno(r, "Failed to check if invoked in Varlink mode: %m"); diff --git a/src/bootctl/bootctl.h b/src/bootctl/bootctl.h index 8d064f5de24..7504d5715cf 100644 --- a/src/bootctl/bootctl.h +++ b/src/bootctl/bootctl.h @@ -9,6 +9,12 @@ typedef enum InstallSource { ARG_INSTALL_SOURCE_AUTO, } InstallSource; +typedef enum GracefulMode { + ARG_GRACEFUL_NO, + ARG_GRACEFUL_YES, + ARG_GRACEFUL_FORCE, +} GracefulMode; + extern char *arg_esp_path; extern char *arg_xbootldr_path; extern bool arg_print_esp_path; @@ -17,7 +23,6 @@ extern unsigned arg_print_root_device; extern int arg_touch_variables; extern bool arg_install_random_seed; extern PagerFlags arg_pager_flags; -extern bool arg_graceful; extern bool arg_quiet; extern int arg_make_entry_directory; /* tri-state: < 0 for automatic logic */ extern sd_id128_t arg_machine_id; @@ -46,6 +51,8 @@ static inline const char* arg_dollar_boot_path(void) { return arg_xbootldr_path ?: arg_esp_path; } +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);