diff --git a/src/boot/bootctl-install.c b/src/boot/bootctl-install.c index bacbbb2939..d1bd3c681c 100644 --- a/src/boot/bootctl-install.c +++ b/src/boot/bootctl-install.c @@ -318,6 +318,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 +411,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; @@ -845,9 +888,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); diff --git a/src/boot/bootctl-status.c b/src/boot/bootctl-status.c index 16b2eaed07..c8041c4bd1 100644 --- a/src/boot/bootctl-status.c +++ b/src/boot/bootctl-status.c @@ -187,7 +187,6 @@ static int status_variables(void) { static int enumerate_binaries( const char *esp_path, const char *path, - const char *prefix, char **previous, bool *is_first) { @@ -213,9 +212,6 @@ static int enumerate_binaries( if (!endswith_no_case(de->d_name, ".efi")) continue; - if (prefix && !startswith_no_case(de->d_name, prefix)) - continue; - filename = path_join(p, de->d_name); if (!filename) return log_oom(); @@ -272,11 +268,11 @@ static int status_binaries(const char *esp_path, sd_id128_t partition) { printf(" (/dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR ")", SD_ID128_FORMAT_VAL(partition)); printf("\n"); - r = enumerate_binaries(esp_path, "EFI/systemd", NULL, &last, &is_first); + r = enumerate_binaries(esp_path, "EFI/systemd", &last, &is_first); if (r < 0) goto fail; - k = enumerate_binaries(esp_path, "EFI/BOOT", "boot", &last, &is_first); + k = enumerate_binaries(esp_path, "EFI/BOOT", &last, &is_first); if (k < 0) { r = k; goto fail;