mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-24 21:34:08 +03:00
bootctl: include boot entries discovered by the boot loader but not in $BOOT in the "list" output
Let's use the new LoaderEntries efi var for this, and show all entries we couldn't find via the config snippets.
This commit is contained in:
parent
d88c96ffe5
commit
bd2865caf6
@ -115,7 +115,8 @@
|
||||
|
||||
<listitem><para>Shows all available boot loader entries implementing the <ulink
|
||||
url="https://github.com/systemd/systemd/blob/master/docs/BOOT_LOADER_SPECIFICATION.md">Boot Loader
|
||||
Specification</ulink></para></listitem>
|
||||
Specification</ulink>, as well as any other entries discovered or automatically generated by the boot
|
||||
loader.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -1027,6 +1027,7 @@ static int verb_status(int argc, char *argv[], void *userdata) {
|
||||
|
||||
static int verb_list(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(boot_config_free) BootConfig config = {};
|
||||
_cleanup_free_ char **found_by_loader = NULL;
|
||||
sd_id128_t uuid = SD_ID128_NULL;
|
||||
int r;
|
||||
|
||||
@ -1044,6 +1045,10 @@ static int verb_list(int argc, char *argv[], void *userdata) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = efi_loader_get_entries(&found_by_loader);
|
||||
if (r < 0 && !IN_SET(r, -ENOENT, -EOPNOTSUPP))
|
||||
log_debug_errno(r, "Failed to acquire boot loader discovered entries: %m");
|
||||
|
||||
if (config.n_entries == 0)
|
||||
log_info("No boot loader entries found.");
|
||||
else {
|
||||
@ -1059,9 +1064,20 @@ static int verb_list(int argc, char *argv[], void *userdata) {
|
||||
return r;
|
||||
|
||||
puts("");
|
||||
|
||||
strv_remove(found_by_loader, config.entries[n].id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!strv_isempty(found_by_loader)) {
|
||||
char **i;
|
||||
|
||||
printf("Automatic/Other Entries Found by Boot Loader:\n\n");
|
||||
|
||||
STRV_FOREACH(i, found_by_loader)
|
||||
puts(*i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "macro.h"
|
||||
#include "parse-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "strv.h"
|
||||
#include "time-util.h"
|
||||
#include "utf8.h"
|
||||
#include "util.h"
|
||||
@ -753,6 +754,56 @@ int efi_loader_get_device_part_uuid(sd_id128_t *u) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int efi_loader_get_entries(char ***ret) {
|
||||
_cleanup_free_ char16_t *entries = NULL;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
size_t size, i, start;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (!is_efi_boot())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderEntries", NULL, (void**) &entries, &size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* The variable contains a series of individually NUL terminated UTF-16 strings. */
|
||||
|
||||
for (i = 0, start = 0;; i++) {
|
||||
char *decoded;
|
||||
bool end;
|
||||
|
||||
/* Is this the end of the variable's data? */
|
||||
end = i * sizeof(char16_t) >= size;
|
||||
|
||||
/* Are we in the middle of a string? (i.e. not at the end of the variable, nor at a NUL terminator?) If
|
||||
* so, let's go to the next entry. */
|
||||
if (!end && entries[i] != 0)
|
||||
continue;
|
||||
|
||||
/* We reached the end of a string, let's decode it into UTF-8 */
|
||||
decoded = utf16_to_utf8(entries + start, (i - start) * sizeof(char16_t));
|
||||
if (!decoded)
|
||||
return -ENOMEM;
|
||||
|
||||
r = strv_consume(&l, decoded);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* We reached the end of the variable */
|
||||
if (end)
|
||||
break;
|
||||
|
||||
/* Continue after the NUL byte */
|
||||
start = i + 1;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *efi_tilt_backslashes(char *s) {
|
||||
|
@ -41,6 +41,8 @@ int efi_get_boot_options(uint16_t **options);
|
||||
int efi_loader_get_device_part_uuid(sd_id128_t *u);
|
||||
int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader);
|
||||
|
||||
int efi_loader_get_entries(char ***ret);
|
||||
|
||||
#else
|
||||
|
||||
static inline bool is_efi_boot(void) {
|
||||
@ -111,6 +113,10 @@ static inline int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int efi_loader_get_entries(char ***ret) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *efi_tilt_backslashes(char *s);
|
||||
|
Loading…
Reference in New Issue
Block a user