X Tutup
Skip to content

Commit b64f6d8

Browse files
authored
Merge pull request systemd#22843 from poettering/bootspec-json
bootctl: bootspec improvements and clean-ups
2 parents 2350712 + af9ae75 commit b64f6d8

File tree

7 files changed

+283
-117
lines changed

7 files changed

+283
-117
lines changed

man/bootctl.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@
9292
url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink>, as well as any
9393
other entries discovered or automatically generated by a boot loader implementing the <ulink
9494
url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader
95-
Interface</ulink>.</para></listitem>
95+
Interface</ulink>.</para>
96+
97+
<para>JSON output may be requested with <option>--json=</option>.</para>
98+
</listitem>
9699
</varlistentry>
97100

98101
<varlistentry>
@@ -315,6 +318,7 @@
315318
</varlistentry>
316319

317320
<xi:include href="standard-options.xml" xpointer="no-pager"/>
321+
<xi:include href="standard-options.xml" xpointer="json" />
318322
<xi:include href="standard-options.xml" xpointer="help"/>
319323
<xi:include href="standard-options.xml" xpointer="version"/>
320324
</variablelist>

src/boot/bootctl.c

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static enum {
7070
ARG_ENTRY_TOKEN_AUTO,
7171
} arg_entry_token_type = ARG_ENTRY_TOKEN_AUTO;
7272
static char *arg_entry_token = NULL;
73+
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
7374

7475
STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
7576
STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
@@ -686,7 +687,7 @@ static int status_entries(
686687
const char *xbootldr_path,
687688
sd_id128_t xbootldr_partition_uuid) {
688689

689-
_cleanup_(boot_config_free) BootConfig config = {};
690+
_cleanup_(boot_config_free) BootConfig config = BOOT_CONFIG_NULL;
690691
sd_id128_t dollar_boot_partition_uuid;
691692
const char *dollar_boot_path;
692693
int r;
@@ -708,7 +709,11 @@ static int status_entries(
708709
SD_ID128_FORMAT_VAL(dollar_boot_partition_uuid));
709710
printf("\n\n");
710711

711-
r = boot_entries_load_config(esp_path, xbootldr_path, &config);
712+
r = boot_config_load(&config, esp_path, xbootldr_path);
713+
if (r < 0)
714+
return r;
715+
716+
r = boot_config_select_special_entries(&config);
712717
if (r < 0)
713718
return r;
714719

@@ -718,7 +723,7 @@ static int status_entries(
718723
printf("Default Boot Loader Entry:\n");
719724

720725
r = boot_entry_show(
721-
config.entries + config.default_entry,
726+
boot_config_default_entry(&config),
722727
/* show_as_default= */ false,
723728
/* show_as_selected= */ false,
724729
/* show_discovered= */ false);
@@ -1420,6 +1425,8 @@ static int help(int argc, char *argv[], void *userdata) {
14201425
" Create $BOOT/ENTRY-TOKEN/ directory\n"
14211426
" --entry-token=machine-id|os-id|os-image-id|auto|literal:…\n"
14221427
" Entry token to use for this installation\n"
1428+
" --json=pretty|short|off\n"
1429+
" Generate JSON output\n"
14231430
"\nSee the %2$s for details.\n",
14241431
program_invocation_short_name,
14251432
link,
@@ -1441,6 +1448,7 @@ static int parse_argv(int argc, char *argv[]) {
14411448
ARG_GRACEFUL,
14421449
ARG_MAKE_ENTRY_DIRECTORY,
14431450
ARG_ENTRY_TOKEN,
1451+
ARG_JSON,
14441452
};
14451453

14461454
static const struct option options[] = {
@@ -1458,6 +1466,7 @@ static int parse_argv(int argc, char *argv[]) {
14581466
{ "make-entry-directory", required_argument, NULL, ARG_MAKE_ENTRY_DIRECTORY },
14591467
{ "make-machine-id-directory", required_argument, NULL, ARG_MAKE_ENTRY_DIRECTORY }, /* Compatibility alias */
14601468
{ "entry-token", required_argument, NULL, ARG_ENTRY_TOKEN },
1469+
{ "json", required_argument, NULL, ARG_JSON },
14611470
{}
14621471
};
14631472

@@ -1552,6 +1561,13 @@ static int parse_argv(int argc, char *argv[]) {
15521561
}
15531562
break;
15541563

1564+
case ARG_JSON:
1565+
r = parse_json_argument(optarg, &arg_json_format_flags);
1566+
if (r <= 0)
1567+
return r;
1568+
1569+
break;
1570+
15551571
case '?':
15561572
return -EINVAL;
15571573

@@ -1776,7 +1792,7 @@ static int verb_status(int argc, char *argv[], void *userdata) {
17761792
}
17771793

17781794
static int verb_list(int argc, char *argv[], void *userdata) {
1779-
_cleanup_(boot_config_free) BootConfig config = {};
1795+
_cleanup_(boot_config_free) BootConfig config = BOOT_CONFIG_NULL;
17801796
_cleanup_strv_free_ char **efi_entries = NULL;
17811797
dev_t esp_devid = 0, xbootldr_devid = 0;
17821798
int r;
@@ -1800,7 +1816,7 @@ static int verb_list(int argc, char *argv[], void *userdata) {
18001816
/* If XBOOTLDR and ESP actually refer to the same block device, suppress XBOOTLDR, since it would find the same entries twice */
18011817
bool same = arg_esp_path && arg_xbootldr_path && devid_set_and_equal(esp_devid, xbootldr_devid);
18021818

1803-
r = boot_entries_load_config(arg_esp_path, same ? NULL : arg_xbootldr_path, &config);
1819+
r = boot_config_load(&config, arg_esp_path, same ? NULL : arg_xbootldr_path);
18041820
if (r < 0)
18051821
return r;
18061822

@@ -1810,9 +1826,50 @@ static int verb_list(int argc, char *argv[], void *userdata) {
18101826
else if (r < 0)
18111827
log_warning_errno(r, "Failed to determine entries reported by boot loader, ignoring: %m");
18121828
else
1813-
(void) boot_entries_augment_from_loader(&config, efi_entries, /* only_auto= */ false);
1829+
(void) boot_config_augment_from_loader(&config, efi_entries, /* only_auto= */ false);
1830+
1831+
r = boot_config_select_special_entries(&config);
1832+
if (r < 0)
1833+
return r;
1834+
1835+
if (!FLAGS_SET(arg_json_format_flags, JSON_FORMAT_OFF)) {
1836+
1837+
pager_open(arg_pager_flags);
1838+
1839+
for (size_t i = 0; i < config.n_entries; i++) {
1840+
_cleanup_free_ char *opts = NULL;
1841+
BootEntry *e = config.entries + i;
1842+
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
1843+
1844+
if (!strv_isempty(e->options)) {
1845+
opts = strv_join(e->options, " ");
1846+
if (!opts)
1847+
return log_oom();
1848+
}
1849+
1850+
r = json_build(&v, JSON_BUILD_OBJECT(
1851+
JSON_BUILD_PAIR_CONDITION(e->id, "id", JSON_BUILD_STRING(e->id)),
1852+
JSON_BUILD_PAIR_CONDITION(e->path, "path", JSON_BUILD_STRING(e->path)),
1853+
JSON_BUILD_PAIR_CONDITION(e->root, "root", JSON_BUILD_STRING(e->root)),
1854+
JSON_BUILD_PAIR_CONDITION(e->title, "title", JSON_BUILD_STRING(e->title)),
1855+
JSON_BUILD_PAIR_CONDITION(boot_entry_title(e), "showTitle", JSON_BUILD_STRING(boot_entry_title(e))),
1856+
JSON_BUILD_PAIR_CONDITION(e->sort_key, "sortKey", JSON_BUILD_STRING(e->sort_key)),
1857+
JSON_BUILD_PAIR_CONDITION(e->version, "version", JSON_BUILD_STRING(e->version)),
1858+
JSON_BUILD_PAIR_CONDITION(e->machine_id, "machineId", JSON_BUILD_STRING(e->machine_id)),
1859+
JSON_BUILD_PAIR_CONDITION(e->architecture, "architecture", JSON_BUILD_STRING(e->architecture)),
1860+
JSON_BUILD_PAIR_CONDITION(opts, "options", JSON_BUILD_STRING(opts)),
1861+
JSON_BUILD_PAIR_CONDITION(e->kernel, "linux", JSON_BUILD_STRING(e->kernel)),
1862+
JSON_BUILD_PAIR_CONDITION(e->efi, "efi", JSON_BUILD_STRING(e->efi)),
1863+
JSON_BUILD_PAIR_CONDITION(!strv_isempty(e->initrd), "initrd", JSON_BUILD_STRV(e->initrd)),
1864+
JSON_BUILD_PAIR_CONDITION(e->device_tree, "devicetree", JSON_BUILD_STRING(e->device_tree)),
1865+
JSON_BUILD_PAIR_CONDITION(!strv_isempty(e->device_tree_overlay), "devicetreeOverlay", JSON_BUILD_STRV(e->device_tree_overlay))));
1866+
if (r < 0)
1867+
return log_oom();
1868+
1869+
json_variant_dump(v, arg_json_format_flags, stdout, NULL);
1870+
}
18141871

1815-
if (config.n_entries == 0)
1872+
} else if (config.n_entries == 0)
18161873
log_info("No boot loader entries found.");
18171874
else {
18181875
pager_open(arg_pager_flags);

src/login/logind-dbus.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3002,19 +3002,19 @@ static int property_get_reboot_to_boot_loader_entry(
30023002
}
30033003

30043004
static int boot_loader_entry_exists(Manager *m, const char *id) {
3005-
_cleanup_(boot_config_free) BootConfig config = {};
3005+
_cleanup_(boot_config_free) BootConfig config = BOOT_CONFIG_NULL;
30063006
int r;
30073007

30083008
assert(m);
30093009
assert(id);
30103010

3011-
r = boot_entries_load_config_auto(NULL, NULL, &config);
3011+
r = boot_config_load_auto(&config, NULL, NULL);
30123012
if (r < 0 && r != -ENOKEY) /* don't complain if no GPT is found, hence skip ENOKEY */
30133013
return r;
30143014

30153015
r = manager_read_efi_boot_loader_entries(m);
30163016
if (r >= 0)
3017-
(void) boot_entries_augment_from_loader(&config, m->efi_boot_loader_entries, /* auto_only= */ true);
3017+
(void) boot_config_augment_from_loader(&config, m->efi_boot_loader_entries, /* auto_only= */ true);
30183018

30193019
return !!boot_config_find_entry(&config, id);
30203020
}
@@ -3157,7 +3157,7 @@ static int property_get_boot_loader_entries(
31573157
void *userdata,
31583158
sd_bus_error *error) {
31593159

3160-
_cleanup_(boot_config_free) BootConfig config = {};
3160+
_cleanup_(boot_config_free) BootConfig config = BOOT_CONFIG_NULL;
31613161
Manager *m = userdata;
31623162
size_t i;
31633163
int r;
@@ -3166,13 +3166,13 @@ static int property_get_boot_loader_entries(
31663166
assert(reply);
31673167
assert(m);
31683168

3169-
r = boot_entries_load_config_auto(NULL, NULL, &config);
3169+
r = boot_config_load_auto(&config, NULL, NULL);
31703170
if (r < 0 && r != -ENOKEY) /* don't complain if there's no GPT found */
31713171
return r;
31723172

31733173
r = manager_read_efi_boot_loader_entries(m);
31743174
if (r >= 0)
3175-
(void) boot_entries_augment_from_loader(&config, m->efi_boot_loader_entries, /* auto_only= */ true);
3175+
(void) boot_config_augment_from_loader(&config, m->efi_boot_loader_entries, /* auto_only= */ true);
31763176

31773177
r = sd_bus_message_open_container(reply, 'a', "s");
31783178
if (r < 0)

0 commit comments

Comments
 (0)
X Tutup