mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
Merge pull request #31286 from poettering/bootctl-varlink
bootctl: add simple varlink IPC interface
This commit is contained in:
commit
76995e7dc4
@ -2,6 +2,7 @@
|
||||
|
||||
#include "bootctl-reboot-to-firmware.h"
|
||||
#include "efi-api.h"
|
||||
#include "errno-util.h"
|
||||
#include "parse-util.h"
|
||||
|
||||
int verb_reboot_to_firmware(int argc, char *argv[], void *userdata) {
|
||||
@ -17,7 +18,7 @@ int verb_reboot_to_firmware(int argc, char *argv[], void *userdata) {
|
||||
puts("supported");
|
||||
return 1; /* recognizable error #1 */
|
||||
}
|
||||
if (r == -EOPNOTSUPP) {
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) {
|
||||
puts("not supported");
|
||||
return 2; /* recognizable error #2 */
|
||||
}
|
||||
@ -36,3 +37,39 @@ int verb_reboot_to_firmware(int argc, char *argv[], void *userdata) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int vl_method_set_reboot_to_firmware(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
|
||||
static const JsonDispatch dispatch_table[] = {
|
||||
{ "state", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, 0, 0 },
|
||||
{}
|
||||
};
|
||||
bool b;
|
||||
int r;
|
||||
|
||||
r = varlink_dispatch(link, parameters, dispatch_table, &b);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = efi_set_reboot_to_firmware(b);
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
|
||||
return varlink_error(link, "io.systemd.BootControl.RebootToFirmwareNotSupported", NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return varlink_reply(link, NULL);
|
||||
}
|
||||
|
||||
int vl_method_get_reboot_to_firmware(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
|
||||
int r;
|
||||
|
||||
if (json_variant_elements(parameters) > 0)
|
||||
return varlink_error_invalid_parameter(link, parameters);
|
||||
|
||||
r = efi_get_reboot_to_firmware();
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
|
||||
return varlink_error(link, "io.systemd.BootControl.RebootToFirmwareNotSupported", NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return varlink_replyb(link, JSON_BUILD_OBJECT(JSON_BUILD_PAIR_BOOLEAN("state", r)));
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "varlink.h"
|
||||
|
||||
int verb_reboot_to_firmware(int argc, char *argv[], void *userdata);
|
||||
|
||||
int vl_method_set_reboot_to_firmware(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata);
|
||||
int vl_method_get_reboot_to_firmware(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata);
|
||||
|
@ -318,7 +318,13 @@ int verb_status(int argc, char *argv[], void *userdata) {
|
||||
dev_t esp_devid = 0, xbootldr_devid = 0;
|
||||
int r, k;
|
||||
|
||||
r = acquire_esp(/* unprivileged_mode= */ -1, /* graceful= */ false, NULL, NULL, NULL, &esp_uuid, &esp_devid);
|
||||
r = acquire_esp(/* unprivileged_mode= */ -1,
|
||||
/* graceful= */ false,
|
||||
/* ret_part= */ NULL,
|
||||
/* ret_pstart= */ NULL,
|
||||
/* ret_psize= */ NULL,
|
||||
&esp_uuid,
|
||||
&esp_devid);
|
||||
if (arg_print_esp_path) {
|
||||
if (r == -EACCES) /* If we couldn't acquire the ESP path, log about access errors (which is the only
|
||||
* error the find_esp_and_warn() won't log on its own) */
|
||||
@ -330,7 +336,10 @@ int verb_status(int argc, char *argv[], void *userdata) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = acquire_xbootldr(/* unprivileged_mode= */ -1, &xbootldr_uuid, &xbootldr_devid);
|
||||
r = acquire_xbootldr(
|
||||
/* unprivileged_mode= */ -1,
|
||||
&xbootldr_uuid,
|
||||
&xbootldr_devid);
|
||||
if (arg_print_dollar_boot_path) {
|
||||
if (r == -EACCES)
|
||||
return log_error_errno(r, "Failed to determine XBOOTLDR partition: %m");
|
||||
@ -825,3 +834,58 @@ int verb_list(int argc, char *argv[], void *userdata) {
|
||||
int verb_unlink(int argc, char *argv[], void *userdata) {
|
||||
return verb_list(argc, argv, userdata);
|
||||
}
|
||||
|
||||
int vl_method_list_boot_entries(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
|
||||
_cleanup_(boot_config_free) BootConfig config = BOOT_CONFIG_NULL;
|
||||
dev_t esp_devid = 0, xbootldr_devid = 0;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
if (json_variant_elements(parameters) > 0)
|
||||
return varlink_error_invalid_parameter(link, parameters);
|
||||
|
||||
r = acquire_esp(/* unprivileged_mode= */ false,
|
||||
/* graceful= */ false,
|
||||
/* ret_part= */ NULL,
|
||||
/* ret_pstart= */ NULL,
|
||||
/* ret_psize= */ NULL,
|
||||
/* ret_uuid=*/ NULL,
|
||||
&esp_devid);
|
||||
if (r == -EACCES) /* We really need the ESP path for this call, hence also log about access errors */
|
||||
return log_error_errno(r, "Failed to determine ESP location: %m");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = acquire_xbootldr(
|
||||
/* unprivileged_mode= */ false,
|
||||
/* ret_uuid= */ NULL,
|
||||
&xbootldr_devid);
|
||||
if (r == -EACCES)
|
||||
return log_error_errno(r, "Failed to determine XBOOTLDR partition: %m");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = boot_config_load_and_select(&config, arg_esp_path, esp_devid, arg_xbootldr_path, xbootldr_devid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_(json_variant_unrefp) JsonVariant *previous = NULL;
|
||||
for (size_t i = 0; i < config.n_entries; i++) {
|
||||
if (previous) {
|
||||
r = varlink_notifyb(link, JSON_BUILD_OBJECT(
|
||||
JSON_BUILD_PAIR_VARIANT("entry", previous)));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
previous = json_variant_unref(previous);
|
||||
}
|
||||
|
||||
r = boot_entry_to_json(&config, i, &previous);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return varlink_replyb(link, JSON_BUILD_OBJECT(
|
||||
JSON_BUILD_PAIR_CONDITION(previous, "entry", JSON_BUILD_VARIANT(previous))));
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "varlink.h"
|
||||
|
||||
int verb_status(int argc, char *argv[], void *userdata);
|
||||
int verb_list(int argc, char *argv[], void *userdata);
|
||||
int verb_unlink(int argc, char *argv[], void *userdata);
|
||||
|
||||
int vl_method_list_boot_entries(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata);
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "parse-argument.h"
|
||||
#include "pretty-print.h"
|
||||
#include "utf8.h"
|
||||
#include "varlink.h"
|
||||
#include "varlink-io.systemd.BootControl.h"
|
||||
#include "verbs.h"
|
||||
#include "virt.h"
|
||||
|
||||
@ -53,6 +55,7 @@ InstallSource arg_install_source = ARG_INSTALL_SOURCE_AUTO;
|
||||
char *arg_efi_boot_option_description = NULL;
|
||||
bool arg_dry_run = false;
|
||||
ImagePolicy *arg_image_policy = NULL;
|
||||
bool arg_varlink = false;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
|
||||
@ -418,6 +421,14 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (arg_dry_run && argv[optind] && !STR_IN_SET(argv[optind], "unlink", "cleanup"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--dry is only supported with --unlink or --cleanup");
|
||||
|
||||
r = varlink_invocation(VARLINK_ALLOW_ACCEPT);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to check if invoked in Varlink mode: %m");
|
||||
if (r > 0) {
|
||||
arg_varlink = true;
|
||||
arg_pager_flags |= PAGER_DISABLE;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -462,6 +473,34 @@ static int run(int argc, char *argv[]) {
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (arg_varlink) {
|
||||
_cleanup_(varlink_server_unrefp) VarlinkServer *varlink_server = NULL;
|
||||
|
||||
/* Invocation as Varlink service */
|
||||
|
||||
r = varlink_server_new(&varlink_server, VARLINK_SERVER_ROOT_ONLY);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate Varlink server: %m");
|
||||
|
||||
r = varlink_server_add_interface(varlink_server, &vl_interface_io_systemd_BootControl);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add Varlink interface: %m");
|
||||
|
||||
r = varlink_server_bind_method_many(
|
||||
varlink_server,
|
||||
"io.systemd.BootControl.ListBootEntries", vl_method_list_boot_entries,
|
||||
"io.systemd.BootControl.SetRebootToFirmware", vl_method_set_reboot_to_firmware,
|
||||
"io.systemd.BootControl.GetRebootToFirmware", vl_method_get_reboot_to_firmware);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind Varlink methods: %m");
|
||||
|
||||
r = varlink_server_loop_auto(varlink_server);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to run Varlink event loop: %m");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (arg_print_root_device > 0) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
dev_t devno;
|
||||
|
@ -36,6 +36,7 @@ extern InstallSource arg_install_source;
|
||||
extern char *arg_efi_boot_option_description;
|
||||
extern bool arg_dry_run;
|
||||
extern ImagePolicy *arg_image_policy;
|
||||
extern bool arg_varlink;
|
||||
|
||||
static inline const char *arg_dollar_boot_path(void) {
|
||||
/* $BOOT shall be the XBOOTLDR partition if it exists, and otherwise the ESP */
|
||||
|
@ -1668,17 +1668,20 @@ int show_boot_entry(
|
||||
return -status;
|
||||
}
|
||||
|
||||
int show_boot_entries(const BootConfig *config, JsonFormatFlags json_format) {
|
||||
int boot_entry_to_json(const BootConfig *c, size_t i, JsonVariant **ret) {
|
||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
||||
const BootEntry *e;
|
||||
int r;
|
||||
|
||||
assert(config);
|
||||
assert(c);
|
||||
assert(ret);
|
||||
|
||||
if (!FLAGS_SET(json_format, JSON_FORMAT_OFF)) {
|
||||
_cleanup_(json_variant_unrefp) JsonVariant *array = NULL;
|
||||
if (i >= c->n_entries) {
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < config->n_entries; i++) {
|
||||
const BootEntry *e = config->entries + i;
|
||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
||||
e = c->entries + i;
|
||||
|
||||
r = json_variant_merge_objectb(
|
||||
&v, JSON_BUILD_OBJECT(
|
||||
@ -1700,10 +1703,6 @@ int show_boot_entries(const BootConfig *config, JsonFormatFlags json_format) {
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = json_cmdline(e, &config->global_addons, &v);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
/* Sanitizers (only memory sanitizer?) do not like function call with too many
|
||||
* arguments and trigger false positive warnings. Let's not add too many json objects
|
||||
* at once. */
|
||||
@ -1712,19 +1711,41 @@ int show_boot_entries(const BootConfig *config, JsonFormatFlags json_format) {
|
||||
JSON_BUILD_PAIR("isReported", JSON_BUILD_BOOLEAN(e->reported_by_loader)),
|
||||
JSON_BUILD_PAIR_CONDITION(e->tries_left != UINT_MAX, "triesLeft", JSON_BUILD_UNSIGNED(e->tries_left)),
|
||||
JSON_BUILD_PAIR_CONDITION(e->tries_done != UINT_MAX, "triesDone", JSON_BUILD_UNSIGNED(e->tries_done)),
|
||||
JSON_BUILD_PAIR_CONDITION(config->default_entry >= 0, "isDefault", JSON_BUILD_BOOLEAN(i == (size_t) config->default_entry)),
|
||||
JSON_BUILD_PAIR_CONDITION(config->selected_entry >= 0, "isSelected", JSON_BUILD_BOOLEAN(i == (size_t) config->selected_entry))));
|
||||
JSON_BUILD_PAIR_CONDITION(c->default_entry >= 0, "isDefault", JSON_BUILD_BOOLEAN(i == (size_t) c->default_entry)),
|
||||
JSON_BUILD_PAIR_CONDITION(c->selected_entry >= 0, "isSelected", JSON_BUILD_BOOLEAN(i == (size_t) c->selected_entry))));
|
||||
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = json_cmdline(e, &c->global_addons, &v);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int show_boot_entries(const BootConfig *config, JsonFormatFlags json_format) {
|
||||
int r;
|
||||
|
||||
assert(config);
|
||||
|
||||
if (!FLAGS_SET(json_format, JSON_FORMAT_OFF)) {
|
||||
_cleanup_(json_variant_unrefp) JsonVariant *array = NULL;
|
||||
|
||||
for (size_t i = 0; i < config->n_entries; i++) {
|
||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
||||
|
||||
r = boot_entry_to_json(config, i, &v);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = json_variant_append_array(&array, v);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
json_variant_dump(array, json_format | JSON_FORMAT_EMPTY_ARRAY, NULL, NULL);
|
||||
|
||||
return json_variant_dump(array, json_format | JSON_FORMAT_EMPTY_ARRAY, NULL, NULL);
|
||||
} else {
|
||||
for (size_t n = 0; n < config->n_entries; n++) {
|
||||
r = show_boot_entry(
|
||||
|
@ -143,3 +143,5 @@ int show_boot_entries(
|
||||
JsonFormatFlags json_format);
|
||||
|
||||
int boot_filename_extract_tries(const char *fname, char **ret_stripped, unsigned *ret_tries_left, unsigned *ret_tries_done);
|
||||
|
||||
int boot_entry_to_json(const BootConfig *c, size_t i, JsonVariant **ret);
|
||||
|
@ -102,7 +102,8 @@ int efi_loader_get_entries(char ***ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* The variable contains a series of individually NUL terminated UTF-16 strings. */
|
||||
/* The variable contains a series of individually NUL terminated UTF-16 strings. We gracefully
|
||||
* consider the final NUL byte optional (i.e. the last string may or may not end in a NUL byte).*/
|
||||
|
||||
for (size_t i = 0, start = 0;; i++) {
|
||||
_cleanup_free_ char *decoded = NULL;
|
||||
@ -116,6 +117,11 @@ int efi_loader_get_entries(char ***ret) {
|
||||
if (!end && entries[i] != 0)
|
||||
continue;
|
||||
|
||||
/* Empty string at the end of variable? That's the trailer, we are done (i.e. we have a final
|
||||
* NUL terminator). */
|
||||
if (end && start == i)
|
||||
break;
|
||||
|
||||
/* 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)
|
||||
@ -128,7 +134,8 @@ int efi_loader_get_entries(char ***ret) {
|
||||
} else
|
||||
log_debug("Ignoring invalid loader entry '%s'.", decoded);
|
||||
|
||||
/* We reached the end of the variable */
|
||||
/* Exit the loop if we reached the end of the variable (i.e. we do not have a final NUL
|
||||
* terminator) */
|
||||
if (end)
|
||||
break;
|
||||
|
||||
|
@ -174,6 +174,7 @@ shared_sources = files(
|
||||
'varlink.c',
|
||||
'varlink-idl.c',
|
||||
'varlink-io.systemd.c',
|
||||
'varlink-io.systemd.BootControl.c',
|
||||
'varlink-io.systemd.Credentials.c',
|
||||
'varlink-io.systemd.Hostname.c',
|
||||
'varlink-io.systemd.Journal.c',
|
||||
|
59
src/shared/varlink-io.systemd.BootControl.c
Normal file
59
src/shared/varlink-io.systemd.BootControl.c
Normal file
@ -0,0 +1,59 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "varlink-io.systemd.BootControl.h"
|
||||
|
||||
static VARLINK_DEFINE_ENUM_TYPE(
|
||||
BootEntryType,
|
||||
VARLINK_DEFINE_ENUM_VALUE(type1),
|
||||
VARLINK_DEFINE_ENUM_VALUE(type2),
|
||||
VARLINK_DEFINE_ENUM_VALUE(loader),
|
||||
VARLINK_DEFINE_ENUM_VALUE(auto));
|
||||
|
||||
static VARLINK_DEFINE_STRUCT_TYPE(
|
||||
BootEntry,
|
||||
VARLINK_DEFINE_FIELD_BY_TYPE(type, BootEntryType, 0),
|
||||
VARLINK_DEFINE_FIELD(id, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(path, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(root, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(title, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(showTitle, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(sortKey, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(version, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(machineId, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(architecture, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(options, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(linux, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(efi, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(initrd, VARLINK_STRING, VARLINK_NULLABLE|VARLINK_ARRAY),
|
||||
VARLINK_DEFINE_FIELD(devicetree, VARLINK_STRING, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(devicetreeOverlay, VARLINK_STRING, VARLINK_NULLABLE|VARLINK_ARRAY),
|
||||
VARLINK_DEFINE_FIELD(isReported, VARLINK_BOOL, 0),
|
||||
VARLINK_DEFINE_FIELD(triesLeft, VARLINK_INT, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(triesDone, VARLINK_INT, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(isDefault, VARLINK_BOOL, VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_FIELD(isSelected, VARLINK_BOOL, VARLINK_NULLABLE));
|
||||
|
||||
static VARLINK_DEFINE_METHOD(
|
||||
ListBootEntries,
|
||||
VARLINK_DEFINE_OUTPUT_BY_TYPE(entry, BootEntry, VARLINK_NULLABLE));
|
||||
|
||||
static VARLINK_DEFINE_METHOD(
|
||||
SetRebootToFirmware,
|
||||
VARLINK_DEFINE_INPUT(state, VARLINK_BOOL, 0));
|
||||
|
||||
static VARLINK_DEFINE_METHOD(
|
||||
GetRebootToFirmware,
|
||||
VARLINK_DEFINE_OUTPUT(state, VARLINK_BOOL, 0));
|
||||
|
||||
static VARLINK_DEFINE_ERROR(
|
||||
RebootToFirmwareNotSupported);
|
||||
|
||||
VARLINK_DEFINE_INTERFACE(
|
||||
io_systemd_BootControl,
|
||||
"io.systemd.BootControl",
|
||||
&vl_type_BootEntryType,
|
||||
&vl_type_BootEntry,
|
||||
&vl_method_ListBootEntries,
|
||||
&vl_method_SetRebootToFirmware,
|
||||
&vl_method_GetRebootToFirmware,
|
||||
&vl_error_RebootToFirmwareNotSupported);
|
6
src/shared/varlink-io.systemd.BootControl.h
Normal file
6
src/shared/varlink-io.systemd.BootControl.h
Normal file
@ -0,0 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "varlink-idl.h"
|
||||
|
||||
extern const VarlinkInterface vl_interface_io_systemd_BootControl;
|
@ -8,6 +8,7 @@
|
||||
#include "varlink.h"
|
||||
#include "varlink-idl.h"
|
||||
#include "varlink-io.systemd.h"
|
||||
#include "varlink-io.systemd.BootControl.h"
|
||||
#include "varlink-io.systemd.Credentials.h"
|
||||
#include "varlink-io.systemd.Journal.h"
|
||||
#include "varlink-io.systemd.ManagedOOM.h"
|
||||
@ -152,6 +153,8 @@ TEST(parse_format) {
|
||||
print_separator();
|
||||
test_parse_format_one(&vl_interface_io_systemd_Credentials);
|
||||
print_separator();
|
||||
test_parse_format_one(&vl_interface_io_systemd_BootControl);
|
||||
print_separator();
|
||||
test_parse_format_one(&vl_interface_xyz_test);
|
||||
}
|
||||
|
||||
|
@ -263,4 +263,13 @@ EOF
|
||||
SYSTEMD_RELAX_ESP_CHECKS=yes SYSTEMD_RELAX_XBOOTLDR_CHECKS=yes basic_tests --root "${IMAGE_DIR}/root"
|
||||
}
|
||||
|
||||
testcase_bootctl_varlink() {
|
||||
varlinkctl call --collect /run/systemd/io.systemd.BootControl io.systemd.BootControl.ListBootEntries '{}'
|
||||
|
||||
# We have no UEFI in the test environment, hence just check that this fails cleanly
|
||||
( SYSTEMD_LOG_TARGET=console varlinkctl call --json=short /run/systemd/io.systemd.BootControl io.systemd.BootControl.GetRebootToFirmware '{}' 2>&1 || true ) | grep -q io.systemd.BootControl.RebootToFirmwareNotSupported
|
||||
( SYSTEMD_LOG_TARGET=console varlinkctl call --json=short /run/systemd/io.systemd.BootControl io.systemd.BootControl.SetRebootToFirmware '{"state":true}' 2>&1 || true ) | grep -q io.systemd.BootControl.RebootToFirmwareNotSupported
|
||||
( SYSTEMD_LOG_TARGET=console varlinkctl call --json=short /run/systemd/io.systemd.BootControl io.systemd.BootControl.SetRebootToFirmware '{"state":false}' 2>&1 || true ) | grep -q io.systemd.BootControl.RebootToFirmwareNotSupported
|
||||
}
|
||||
|
||||
run_testcases
|
||||
|
@ -267,6 +267,15 @@ units = [
|
||||
'file' : 'systemd-boot-update.service',
|
||||
'conditions' : ['ENABLE_BOOTLOADER'],
|
||||
},
|
||||
{
|
||||
'file' : 'systemd-bootctl@.service.in',
|
||||
'conditions' : ['ENABLE_BOOTLOADER'],
|
||||
},
|
||||
{
|
||||
'file' : 'systemd-bootctl.socket',
|
||||
'conditions' : ['ENABLE_BOOTLOADER'],
|
||||
'symlinks' : ['sockets.target.wants/'],
|
||||
},
|
||||
{
|
||||
'file' : 'systemd-confext.service',
|
||||
'conditions' : ['ENABLE_SYSEXT'],
|
||||
|
21
units/systemd-bootctl.socket
Normal file
21
units/systemd-bootctl.socket
Normal file
@ -0,0 +1,21 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
[Unit]
|
||||
Description=Boot Control (Varlink)
|
||||
Documentation=man:bootctl(1)
|
||||
DefaultDependencies=no
|
||||
After=local-fs.target
|
||||
Before=sockets.target
|
||||
|
||||
[Socket]
|
||||
ListenStream=/run/systemd/io.systemd.BootControl
|
||||
FileDescriptorName=varlink
|
||||
SocketMode=0600
|
||||
Accept=yes
|
20
units/systemd-bootctl@.service.in
Normal file
20
units/systemd-bootctl@.service.in
Normal file
@ -0,0 +1,20 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
[Unit]
|
||||
Description=Boot Control (Varlink)
|
||||
Documentation=man:bootctl(1)
|
||||
DefaultDependencies=no
|
||||
Conflicts=shutdown.target
|
||||
After=local-fs.target
|
||||
Before=shutdown.target
|
||||
|
||||
[Service]
|
||||
Environment=LISTEN_FDNAMES=varlink
|
||||
ExecStart={{BINDIR}}/bootctl
|
Loading…
Reference in New Issue
Block a user