bootctl: accept espPath/xbootldrPath in Varlink methods
The CLI verbs have --esp-path/--boot-path but the Varlink methods always auto-discover the partitions, so callers that mount the ESP or XBOOTLDR at a non-standard location have to fall back to the SYSTEMD_ESP_PATH/SYSTEMD_XBOOTLDR_PATH environment variables. Allow to specify the paths when calling Install/Unlink/Link/LinkAuto so the Varlink API is on par with the CLI.
This commit is contained in:
@@ -2085,12 +2085,16 @@ static JSON_DISPATCH_ENUM_DEFINE(json_dispatch_boot_entry_token_type, BootEntryT
|
||||
typedef struct InstallParameters {
|
||||
InstallContext context;
|
||||
unsigned root_fd_index;
|
||||
char *esp_path;
|
||||
char *xbootldr_path;
|
||||
} InstallParameters;
|
||||
|
||||
static void install_parameters_done(InstallParameters *p) {
|
||||
assert(p);
|
||||
|
||||
install_context_done(&p->context);
|
||||
free(p->esp_path);
|
||||
free(p->xbootldr_path);
|
||||
}
|
||||
|
||||
int vl_method_install(
|
||||
@@ -2113,6 +2117,8 @@ int vl_method_install(
|
||||
{ "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 },
|
||||
{},
|
||||
@@ -2162,7 +2168,7 @@ int vl_method_install(
|
||||
|
||||
r = find_esp_and_warn_at_full(
|
||||
p.context.root_fd,
|
||||
/* path= */ NULL,
|
||||
p.esp_path,
|
||||
/* unprivileged_mode= */ false,
|
||||
&p.context.esp_path,
|
||||
&p.context.esp_fd,
|
||||
@@ -2178,7 +2184,7 @@ int vl_method_install(
|
||||
|
||||
r = find_xbootldr_and_warn_at(
|
||||
p.context.root_fd,
|
||||
/* path= */ NULL,
|
||||
p.xbootldr_path,
|
||||
/* unprivileged_mode= */ false,
|
||||
&p.context.xbootldr_path,
|
||||
&p.context.xbootldr_fd);
|
||||
|
||||
@@ -1355,6 +1355,8 @@ typedef struct LinkParameters {
|
||||
LinkContext context;
|
||||
unsigned root_fd_index;
|
||||
unsigned kernel_fd_index;
|
||||
char *esp_path;
|
||||
char *xbootldr_path;
|
||||
sd_varlink *link;
|
||||
} LinkParameters;
|
||||
|
||||
@@ -1362,6 +1364,8 @@ static void link_parameters_done(LinkParameters *p) {
|
||||
assert(p);
|
||||
|
||||
link_context_done(&p->context);
|
||||
free(p->esp_path);
|
||||
free(p->xbootldr_path);
|
||||
}
|
||||
|
||||
typedef struct ExtraParameters {
|
||||
@@ -1509,7 +1513,7 @@ static int vl_link_finish(sd_varlink *link, LinkParameters *p, bool with_ids) {
|
||||
|
||||
r = find_xbootldr_and_warn_at(
|
||||
p->context.root_fd,
|
||||
/* path= */ NULL,
|
||||
p->xbootldr_path,
|
||||
/* unprivileged_mode= */ false,
|
||||
&p->context.dollar_boot_path,
|
||||
&p->context.dollar_boot_fd);
|
||||
@@ -1521,7 +1525,7 @@ static int vl_link_finish(sd_varlink *link, LinkParameters *p, bool with_ids) {
|
||||
|
||||
r = find_esp_and_warn_at(
|
||||
p->context.root_fd,
|
||||
/* path= */ NULL,
|
||||
p->esp_path,
|
||||
/* unprivileged_mode= */ false,
|
||||
&p->context.dollar_boot_path,
|
||||
&p->context.dollar_boot_fd);
|
||||
@@ -1566,6 +1570,8 @@ int vl_method_link(
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "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 },
|
||||
{ "entryTitle", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, voffsetof(p, context.entry_title), 0 },
|
||||
{ "entryVersion", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, voffsetof(p, context.entry_version), 0 },
|
||||
@@ -1634,6 +1640,8 @@ int vl_method_link_auto(
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "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 },
|
||||
{ "entryTitle", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, voffsetof(p, context.entry_title), 0 },
|
||||
{ "entryVersion", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, voffsetof(p, context.entry_version), 0 },
|
||||
|
||||
@@ -550,6 +550,8 @@ static JSON_DISPATCH_ENUM_DEFINE(json_dispatch_boot_entry_token_type, BootEntryT
|
||||
typedef struct UnlinkParameters {
|
||||
UnlinkContext context;
|
||||
unsigned root_fd_index;
|
||||
char *esp_path;
|
||||
char *xbootldr_path;
|
||||
const char *id;
|
||||
bool oldest;
|
||||
} UnlinkParameters;
|
||||
@@ -558,6 +560,8 @@ static void unlink_parameters_done(UnlinkParameters *p) {
|
||||
assert(p);
|
||||
|
||||
unlink_context_done(&p->context);
|
||||
free(p->esp_path);
|
||||
free(p->xbootldr_path);
|
||||
}
|
||||
|
||||
int vl_method_unlink(
|
||||
@@ -578,6 +582,8 @@ int vl_method_unlink(
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "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 },
|
||||
{ "id", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, voffsetof(p, id), 0 },
|
||||
{ "oldest", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, voffsetof(p, oldest), 0 },
|
||||
@@ -631,7 +637,7 @@ int vl_method_unlink(
|
||||
|
||||
r = find_esp_and_warn_at_full(
|
||||
p.context.root_fd,
|
||||
/* path= */ NULL,
|
||||
p.esp_path,
|
||||
/* unprivileged_mode= */ false,
|
||||
&p.context.esp_path,
|
||||
&p.context.esp_fd,
|
||||
@@ -644,7 +650,7 @@ int vl_method_unlink(
|
||||
return r;
|
||||
r = find_xbootldr_and_warn_at_full(
|
||||
p.context.root_fd,
|
||||
/* path= */ NULL,
|
||||
p.xbootldr_path,
|
||||
/* unprivileged_mode= */ false,
|
||||
&p.context.xbootldr_path,
|
||||
&p.context.xbootldr_fd,
|
||||
|
||||
@@ -131,6 +131,10 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
SD_VARLINK_DEFINE_INPUT(rootFileDescriptor, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Root directory to operate relative to. If both this and rootFileDescriptor is specified, this is purely informational. If only this is specified, it is what will be used."),
|
||||
SD_VARLINK_DEFINE_INPUT(rootDirectory, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the EFI System Partition mount point, resolved relative to rootDirectory/rootFileDescriptor if either is set. If not specified the ESP is auto-discovered."),
|
||||
SD_VARLINK_DEFINE_INPUT(espPath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the XBOOTLDR partition mount point, resolved relative to rootDirectory/rootFileDescriptor if either is set. If not specified the XBOOTLDR partition is auto-discovered."),
|
||||
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("If true the boot loader will be registered in an EFI boot entry via EFI variables, otherwise this is omitted"),
|
||||
@@ -142,6 +146,10 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
SD_VARLINK_DEFINE_INPUT(rootFileDescriptor, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Root directory to operate relative to. If both this and rootFileDescriptor is specified, this is purely informational. If only this is specified, it is what will be used."),
|
||||
SD_VARLINK_DEFINE_INPUT(rootDirectory, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the EFI System Partition mount point, resolved relative to rootDirectory/rootFileDescriptor if either is set. If not specified the ESP is auto-discovered."),
|
||||
SD_VARLINK_DEFINE_INPUT(espPath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the XBOOTLDR partition mount point, resolved relative to rootDirectory/rootFileDescriptor if either is set. If not specified the XBOOTLDR partition is auto-discovered."),
|
||||
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("The ID of the boot loader entry to remove."),
|
||||
@@ -164,6 +172,10 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
SD_VARLINK_DEFINE_INPUT(rootFileDescriptor, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Root directory to operate relative to. If both this and rootFileDescriptor is specified, this is purely informational. If only this is specified, it is what will be used."),
|
||||
SD_VARLINK_DEFINE_INPUT(rootDirectory, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the EFI System Partition mount point, resolved relative to rootDirectory/rootFileDescriptor if either is set. If not specified the ESP is auto-discovered."),
|
||||
SD_VARLINK_DEFINE_INPUT(espPath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the XBOOTLDR partition mount point, resolved relative to rootDirectory/rootFileDescriptor if either is set. If not specified the XBOOTLDR partition is auto-discovered."),
|
||||
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("The entry title for the newly created boot menu entry"),
|
||||
@@ -191,6 +203,10 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
SD_VARLINK_DEFINE_INPUT(rootFileDescriptor, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Root directory to operate relative to. If both this and rootFileDescriptor is specified, this is purely informational. If only this is specified, it is what will be used."),
|
||||
SD_VARLINK_DEFINE_INPUT(rootDirectory, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the EFI System Partition mount point, resolved relative to rootDirectory/rootFileDescriptor if either is set. If not specified the ESP is auto-discovered."),
|
||||
SD_VARLINK_DEFINE_INPUT(espPath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the XBOOTLDR partition mount point, resolved relative to rootDirectory/rootFileDescriptor if either is set. If not specified the XBOOTLDR partition is auto-discovered."),
|
||||
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("The entry title for the newly created boot menu entry"),
|
||||
|
||||
@@ -425,18 +425,43 @@ remove_root_dir() {
|
||||
rm -rf "$ROOTDIR"
|
||||
}
|
||||
|
||||
cleanup_install_varlink() {
|
||||
if [[ -n "${FAKE_ESP:-}" ]]; then
|
||||
rm -rf "$FAKE_ESP"
|
||||
unset FAKE_ESP
|
||||
fi
|
||||
if [[ -n "${FAKE_BOOT:-}" ]]; then
|
||||
rm -rf "$FAKE_BOOT"
|
||||
unset FAKE_BOOT
|
||||
fi
|
||||
restore_esp
|
||||
}
|
||||
|
||||
testcase_install_varlink() {
|
||||
|
||||
varlinkctl introspect "$(type -p bootctl)"
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
backup_esp
|
||||
trap restore_esp RETURN ERR
|
||||
trap cleanup_install_varlink RETURN ERR
|
||||
fi
|
||||
|
||||
(! bootctl is-installed )
|
||||
SYSTEMD_LOG_TARGET=console varlinkctl call "$(type -p bootctl)" io.systemd.BootControl.Install "{\"operation\":\"new\",\"touchVariables\":false}"
|
||||
bootctl is-installed
|
||||
|
||||
# Verify that espPath/xbootldrPath override auto-discovery: install into fresh empty
|
||||
# directories (with relaxed checks so verify_esp()/verify_xbootldr() accept a non-vfat
|
||||
# non-mountpoint path) and check the loader files land there. If the parameters were ignored
|
||||
# the call would auto-discover the real partitions instead and the directories would stay
|
||||
# empty.
|
||||
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\"}"
|
||||
test -f "$FAKE_ESP/EFI/systemd/systemd-boot$(bootctl --print-efi-architecture).efi"
|
||||
test -f "$FAKE_BOOT/loader/entries.srel"
|
||||
}
|
||||
|
||||
cleanup_link() {
|
||||
|
||||
Reference in New Issue
Block a user