summaryrefslogtreecommitdiffstats
path: root/src/boot/bootctl-install.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/boot/bootctl-install.c83
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;