/* 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;
}
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);
}
/* 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) {
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;
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)
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.");
(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.");
* 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;
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;
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;
break;
case ARG_GRACEFUL:
- arg_graceful = true;
+ _arg_graceful = ARG_GRACEFUL_YES;
break;
case 'q':
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");
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;
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;
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);