diff options
author | Lennart Poettering <lennart@poettering.net> | 2022-12-19 11:04:17 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2022-12-19 12:08:02 +0100 |
commit | da36788f650def6e1ba3d371d1084d017545588f (patch) | |
tree | 029b11ac3a32eddd940117e61772ac5e62e4cdab /src/boot/bootctl-util.c | |
parent | 6d8ca2576629edb2f492f2479dfd0b97d37bac11 (diff) | |
download | systemd-da36788f650def6e1ba3d371d1084d017545588f.tar.gz |
bootctl: split out "status" verb too
Diffstat (limited to 'src/boot/bootctl-util.c')
-rw-r--r-- | src/boot/bootctl-util.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/boot/bootctl-util.c b/src/boot/bootctl-util.c index 2d3f7d4537..c994f5f952 100644 --- a/src/boot/bootctl-util.c +++ b/src/boot/bootctl-util.c @@ -1,7 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include <sys/mman.h> + #include "bootctl.h" #include "bootctl-util.h" +#include "fileio.h" +#include "stat-util.h" #include "sync-util.h" int sync_everything(void) { @@ -21,3 +25,87 @@ int sync_everything(void) { return ret; } + +const char *get_efi_arch(void) { + /* Detect EFI firmware architecture of the running system. On mixed mode systems, it could be 32bit + * while the kernel is running in 64bit. */ + +#ifdef __x86_64__ + _cleanup_free_ char *platform_size = NULL; + int r; + + r = read_one_line_file("/sys/firmware/efi/fw_platform_size", &platform_size); + if (r == -ENOENT) + return EFI_MACHINE_TYPE_NAME; + if (r < 0) { + log_warning_errno(r, "Error reading EFI firmware word size, assuming '%i': %m", __WORDSIZE); + return EFI_MACHINE_TYPE_NAME; + } + + if (streq(platform_size, "64")) + return EFI_MACHINE_TYPE_NAME; + if (streq(platform_size, "32")) + return "ia32"; + + log_warning( + "Unknown EFI firmware word size '%s', using default word size '%i' instead.", + platform_size, + __WORDSIZE); +#endif + + return EFI_MACHINE_TYPE_NAME; +} + +/* search for "#### LoaderInfo: systemd-boot 218 ####" string inside the binary */ +int get_file_version(int fd, char **ret) { + struct stat st; + char *buf; + const char *s, *e; + char *x = NULL; + int r; + + assert(fd >= 0); + assert(ret); + + if (fstat(fd, &st) < 0) + return log_error_errno(errno, "Failed to stat EFI binary: %m"); + + r = stat_verify_regular(&st); + if (r < 0) + return log_error_errno(r, "EFI binary is not a regular file: %m"); + + if (st.st_size < 27 || file_offset_beyond_memory_size(st.st_size)) { + *ret = NULL; + return 0; + } + + buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (buf == MAP_FAILED) + return log_error_errno(errno, "Failed to memory map EFI binary: %m"); + + s = mempmem_safe(buf, st.st_size - 8, "#### LoaderInfo: ", 17); + if (!s) { + r = -ESRCH; + goto finish; + } + + e = memmem_safe(s, st.st_size - (s - buf), " ####", 5); + if (!e || e - s < 3) { + r = log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Malformed version string."); + goto finish; + } + + x = strndup(s, e - s); + if (!x) { + r = log_oom(); + goto finish; + } + r = 1; + +finish: + (void) munmap(buf, st.st_size); + if (r >= 0) + *ret = x; + + return r; +} |