From e2cda710c1b360cfbea3c43b1fcb49def4cf4678 Mon Sep 17 00:00:00 2001 From: r-vdp Date: Wed, 1 Jul 2026 14:21:43 +0200 Subject: [PATCH] bootctl: accept makeEntryDirectory in Install Varlink method The CLI defaults --make-entry-directory to off and lets callers opt in or request auto mode. The Varlink Install method always ran in auto mode with no way to override it. Expose the tri-state so IPC callers can match the CLI behaviour. --- src/bootctl/bootctl-install.c | 17 +++++++++-------- src/shared/varlink-io.systemd.BootControl.c | 2 ++ test/units/TEST-87-AUX-UTILS-VM.bootctl.sh | 18 +++++++++++++++++- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/bootctl/bootctl-install.c b/src/bootctl/bootctl-install.c index 5015f4c8072..381ee95223a 100644 --- a/src/bootctl/bootctl-install.c +++ b/src/bootctl/bootctl-install.c @@ -2113,14 +2113,15 @@ int vl_method_install( }; static const sd_json_dispatch_field dispatch_table[] = { - { "operation", SD_JSON_VARIANT_STRING, json_dispatch_install_operation, voffsetof(p, context.operation), SD_JSON_MANDATORY }, - { "graceful", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, voffsetof(p, context.graceful), 0 }, - { "rootFileDescriptor", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint, voffsetof(p, root_fd_index), 0 }, - { "rootDirectory", SD_JSON_VARIANT_STRING, json_dispatch_path, voffsetof(p, context.root), 0 }, - { "espPath", SD_JSON_VARIANT_STRING, json_dispatch_path, voffsetof(p, esp_path), 0 }, - { "xbootldrPath", SD_JSON_VARIANT_STRING, json_dispatch_path, voffsetof(p, xbootldr_path), 0 }, - { "bootEntryTokenType", SD_JSON_VARIANT_STRING, json_dispatch_boot_entry_token_type, voffsetof(p, context.entry_token_type), 0 }, - { "touchVariables", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, voffsetof(p, context.touch_variables), 0 }, + { "operation", SD_JSON_VARIANT_STRING, json_dispatch_install_operation, voffsetof(p, context.operation), SD_JSON_MANDATORY }, + { "graceful", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, voffsetof(p, context.graceful), 0 }, + { "rootFileDescriptor", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint, voffsetof(p, root_fd_index), 0 }, + { "rootDirectory", SD_JSON_VARIANT_STRING, json_dispatch_path, voffsetof(p, context.root), 0 }, + { "espPath", SD_JSON_VARIANT_STRING, json_dispatch_path, voffsetof(p, esp_path), 0 }, + { "xbootldrPath", SD_JSON_VARIANT_STRING, json_dispatch_path, voffsetof(p, xbootldr_path), 0 }, + { "bootEntryTokenType", SD_JSON_VARIANT_STRING, json_dispatch_boot_entry_token_type, voffsetof(p, context.entry_token_type), 0 }, + { "makeEntryDirectory", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, voffsetof(p, context.make_entry_directory), 0 }, + { "touchVariables", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, voffsetof(p, context.touch_variables), 0 }, {}, }; diff --git a/src/shared/varlink-io.systemd.BootControl.c b/src/shared/varlink-io.systemd.BootControl.c index 8df9e335e5b..9907a14d50e 100644 --- a/src/shared/varlink-io.systemd.BootControl.c +++ b/src/shared/varlink-io.systemd.BootControl.c @@ -137,6 +137,8 @@ static SD_VARLINK_DEFINE_METHOD( SD_VARLINK_DEFINE_INPUT(xbootldrPath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("Selects how to identify boot entries"), SD_VARLINK_DEFINE_INPUT_BY_TYPE(bootEntryTokenType, BootEntryTokenType, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Whether to create the '$BOOT/ENTRY-TOKEN/' directory for Boot Loader Specification Type #1 snippets. If not specified this is decided automatically."), + SD_VARLINK_DEFINE_INPUT(makeEntryDirectory, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("If true the boot loader will be registered in an EFI boot entry via EFI variables, otherwise this is omitted"), SD_VARLINK_DEFINE_INPUT(touchVariables, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); diff --git a/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh b/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh index 99fa39da40b..c91211e8f8f 100755 --- a/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh +++ b/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh @@ -459,9 +459,25 @@ testcase_install_varlink() { FAKE_BOOT="$(mktemp --directory /tmp/test-bootctl-boot.XXXXXXXXXX)" SYSTEMD_RELAX_ESP_CHECKS=yes SYSTEMD_RELAX_XBOOTLDR_CHECKS=yes SYSTEMD_LOG_TARGET=console \ varlinkctl call --quiet "$(type -p bootctl)" io.systemd.BootControl.Install \ - "{\"operation\":\"new\",\"touchVariables\":false,\"espPath\":\"$FAKE_ESP\",\"xbootldrPath\":\"$FAKE_BOOT\"}" + "{\"operation\":\"new\",\"touchVariables\":false,\"espPath\":\"$FAKE_ESP\",\"xbootldrPath\":\"$FAKE_BOOT\",\"makeEntryDirectory\":false}" test -f "$FAKE_ESP/EFI/systemd/systemd-boot$(bootctl --print-efi-architecture).efi" test -f "$FAKE_BOOT/loader/entries.srel" + # makeEntryDirectory:false means loader.conf must not gain a "default" line and no entry + # token directory is created under $BOOT. + (! grep '^default ' "$FAKE_ESP/loader/loader.conf" >/dev/null) + + # Same again into fresh directories with makeEntryDirectory:true, and check loader.conf now + # gets a "default -*" line and the entry token directory shows up under $BOOT. + rm -rf "$FAKE_ESP" "$FAKE_BOOT" + FAKE_ESP="$(mktemp --directory /tmp/test-bootctl-esp.XXXXXXXXXX)" + FAKE_BOOT="$(mktemp --directory /tmp/test-bootctl-boot.XXXXXXXXXX)" + SYSTEMD_RELAX_ESP_CHECKS=yes SYSTEMD_RELAX_XBOOTLDR_CHECKS=yes SYSTEMD_LOG_TARGET=console \ + varlinkctl call --quiet "$(type -p bootctl)" io.systemd.BootControl.Install \ + "{\"operation\":\"new\",\"touchVariables\":false,\"espPath\":\"$FAKE_ESP\",\"xbootldrPath\":\"$FAKE_BOOT\",\"makeEntryDirectory\":true}" + local TOKEN + TOKEN="$(sed -n 's/^default \(.*\)-\*$/\1/p' "$FAKE_ESP/loader/loader.conf")" + test -n "$TOKEN" + test -d "$FAKE_BOOT/$TOKEN" } cleanup_link() { -- 2.47.3