bootctl: make sure install verb also honors implied --graceful

Follow-up for bcc73cafdb
This commit is contained in:
Mike Yuan
2025-09-05 04:45:33 +09:00
committed by Yu Watanabe
parent ebcb0a07d3
commit 1bc82e0c97
5 changed files with 35 additions and 15 deletions
+6 -4
View File
@@ -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;
+2 -2
View File
@@ -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.");
+1 -1
View File
@@ -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.");
+18 -7
View File
@@ -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");
+8 -1
View File
@@ -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);