diff options
Diffstat (limited to 'src/boot/bootctl-install.c')
-rw-r--r-- | src/boot/bootctl-install.c | 83 |
1 files changed, 62 insertions, 21 deletions
diff --git a/src/boot/bootctl-install.c b/src/boot/bootctl-install.c index bacbbb2..dc46d30 100644 --- a/src/boot/bootctl-install.c +++ b/src/boot/bootctl-install.c @@ -14,6 +14,7 @@ #include "fs-util.h" #include "glyph-util.h" #include "id128-util.h" +#include "kernel-config.h" #include "os-util.h" #include "path-util.h" #include "rm-rf.h" @@ -81,22 +82,22 @@ static int load_etc_machine_info(void) { return 0; } -static int load_etc_kernel_install_conf(void) { - _cleanup_free_ char *layout = NULL, *p = NULL; +static int load_kernel_install_layout(void) { + _cleanup_free_ char *layout = NULL; int r; - p = path_join(arg_root, etc_kernel(), "install.conf"); - if (!p) - return log_oom(); - - r = parse_env_file(NULL, p, "layout", &layout); - if (r == -ENOENT) - return 0; - if (r < 0) - return log_error_errno(r, "Failed to parse %s: %m", p); + r = load_kernel_install_conf(arg_root, + getenv("KERNEL_INSTALL_CONF_ROOT"), + /* ret_machine_id= */ NULL, + /* ret_boot_root= */ NULL, + &layout, + /* ret_initrd_generator= */ NULL, + /* ret_uki_generator= */ NULL); + if (r <= 0) + return r; if (!isempty(layout)) { - log_debug("layout=%s is specified in %s.", layout, p); + log_debug("layout=%s is specified in config.", layout); free_and_replace(arg_install_layout, layout); } @@ -120,7 +121,7 @@ static int settle_make_entry_directory(void) { if (r < 0) return r; - r = load_etc_kernel_install_conf(); + r = load_kernel_install_layout(); if (r < 0) return r; @@ -318,6 +319,46 @@ static int create_subdirs(const char *root, const char * const *subdirs) { return 0; } +static int update_efi_boot_binaries(const char *esp_path, const char *source_path) { + _cleanup_closedir_ DIR *d = NULL; + _cleanup_free_ char *p = NULL; + int r, ret = 0; + + r = chase_and_opendir("/EFI/BOOT", esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, &p, &d); + if (r == -ENOENT) + return 0; + if (r < 0) + return log_error_errno(r, "Failed to open directory \"%s/EFI/BOOT\": %m", esp_path); + + FOREACH_DIRENT(de, d, break) { + _cleanup_close_ int fd = -EBADF; + _cleanup_free_ char *v = NULL; + + if (!endswith_no_case(de->d_name, ".efi")) + continue; + + fd = openat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC); + if (fd < 0) + return log_error_errno(errno, "Failed to open \"%s/%s\" for reading: %m", p, de->d_name); + + r = get_file_version(fd, &v); + if (r == -ESRCH) + continue; /* No version information */ + if (r < 0) + return r; + if (startswith(v, "systemd-boot ")) { + _cleanup_free_ char *dest_path = NULL; + + dest_path = path_join(p, de->d_name); + if (!dest_path) + return log_oom(); + + RET_GATHER(ret, copy_file_with_version_check(source_path, dest_path, /* force = */ false)); + } + } + + return ret; +} static int copy_one_file(const char *esp_path, const char *name, bool force) { char *root = IN_SET(arg_install_source, ARG_INSTALL_SOURCE_AUTO, ARG_INSTALL_SOURCE_IMAGE) ? arg_root : NULL; @@ -371,9 +412,12 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) { if (r < 0) return log_error_errno(r, "Failed to resolve path %s under directory %s: %m", v, esp_path); - r = copy_file_with_version_check(source_path, default_dest_path, force); - if (r < 0 && ret == 0) - ret = r; + RET_GATHER(ret, copy_file_with_version_check(source_path, default_dest_path, force)); + + /* If we were installed under any other name in /EFI/BOOT, make sure we update those binaries + * as well. */ + if (!force) + RET_GATHER(ret, update_efi_boot_binaries(esp_path, source_path)); } return ret; @@ -514,7 +558,7 @@ static int install_entry_token(void) { if (!arg_make_entry_directory && arg_entry_token_type == BOOT_ENTRY_TOKEN_MACHINE_ID) return 0; - p = path_join(arg_root, etc_kernel(), "entry-token"); + p = path_join(arg_root, getenv("KERNEL_INSTALL_CONF_ROOT") ?: "/etc/kernel/", "entry-token"); if (!p) return log_oom(); @@ -845,9 +889,6 @@ static int remove_boot_efi(const char *esp_path) { if (!endswith_no_case(de->d_name, ".efi")) continue; - if (!startswith_no_case(de->d_name, "boot")) - continue; - fd = openat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC); if (fd < 0) return log_error_errno(errno, "Failed to open \"%s/%s\" for reading: %m", p, de->d_name); @@ -978,7 +1019,7 @@ static int remove_loader_variables(void) { EFI_LOADER_VARIABLE(LoaderEntryDefault), EFI_LOADER_VARIABLE(LoaderEntryLastBooted), EFI_LOADER_VARIABLE(LoaderEntryOneShot), - EFI_LOADER_VARIABLE(LoaderSystemToken)){ + EFI_LOADER_VARIABLE(LoaderSystemToken)) { int q; |