mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
bootctl: update/list/remove all instances of systemd-boot in /EFI/BOOT
systemd-boot might be installed in /EFI/BOOT under more names than just /EFI/BOOT/BOOTX64.efi. The prime example is shim which loads its second stage binary from /EFI/BOOT/grubx64.efi. To accomodate use cases where systemd-boot is installed as /EFI/BOOT/grubx64.efi, let's always check the entire /EFI/BOOT directory for binaries that identify as systemd-boot and list/update/remove those as well. Let's keep this somewhat generic though and not install ourselves as grubx64.efi since that would mean having to check for shim which is a can of worms we probably don't want to open.
This commit is contained in:
committed by
Luca Boccassi
parent
3553fddb1e
commit
929f41c652
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user