vmspawn: Add --firmware=describe
It's useful to be able to check what firmware description vmspawn will select. In particular, this will allow me to figure out the nvram template file that will be picked up so I can pick it up in mkosi and operate on it to pass a modified version of it to vmspawn with --efi-nvram-template=.
This commit is contained in:
committed by
Daan De Meyer
parent
5a7d70e807
commit
d6e5fbca73
@@ -330,7 +330,9 @@
|
||||
<listitem><para>Takes an absolute path, or a relative path beginning with
|
||||
<filename>./</filename>. Specifies a JSON firmware definition file, which allows selecting the
|
||||
firmware to boot in the VM. If not specified, a suitable firmware is automatically discovered. If the
|
||||
special string <literal>list</literal> is specified lists all discovered firmwares.</para>
|
||||
special string <literal>list</literal> is specified lists all discovered firmwares. If the special
|
||||
string <literal>describe</literal> is specified, the firmware that would be selected (taking
|
||||
<option>--firmware-features=</option> into account) is printed and the program exits.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -54,7 +54,7 @@ _systemd_vmspawn() {
|
||||
comps=$(compgen -f -- "$cur" )
|
||||
elif __contains_word "$prev" ${OPTS[FIRMWARE]}; then
|
||||
compopt -o nospace -o filenames
|
||||
comps="list $(compgen -f -- "$cur" )"
|
||||
comps="list describe $(compgen -f -- "$cur" )"
|
||||
elif __contains_word "$prev" ${OPTS[FIRMWARE_FEATURES]}; then
|
||||
comps='list'
|
||||
elif __contains_word "$prev" ${OPTS[BIND]}; then
|
||||
|
||||
@@ -244,7 +244,7 @@ int list_ovmf_config(char ***ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_firmware_data(const char *path, FirmwareData **ret) {
|
||||
static int load_firmware_data(const char *path, FirmwareData **ret, sd_json_variant **ret_json) {
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
@@ -281,6 +281,10 @@ static int load_firmware_data(const char *path, FirmwareData **ret) {
|
||||
return r;
|
||||
|
||||
*ret = TAKE_PTR(fwd);
|
||||
|
||||
if (ret_json)
|
||||
*ret_json = TAKE_PTR(json);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -298,7 +302,7 @@ int list_ovmf_firmware_features(char ***ret) {
|
||||
STRV_FOREACH(file, conf_files) {
|
||||
_cleanup_(firmware_data_freep) FirmwareData *fwd = NULL;
|
||||
|
||||
r = load_firmware_data(*file, &fwd);
|
||||
r = load_firmware_data(*file, &fwd, /* ret_json= */ NULL);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to load JSON file '%s', skipping: %m", *file);
|
||||
continue;
|
||||
@@ -347,14 +351,18 @@ int load_ovmf_config(const char *path, OvmfConfig **ret) {
|
||||
assert(path);
|
||||
assert(ret);
|
||||
|
||||
r = load_firmware_data(path, &fwd);
|
||||
r = load_firmware_data(path, &fwd, /* ret_json= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return ovmf_config_make(fwd, ret);
|
||||
}
|
||||
|
||||
int find_ovmf_config(Set *features_include, Set *features_exclude, OvmfConfig **ret) {
|
||||
int find_ovmf_config(
|
||||
Set *features_include,
|
||||
Set *features_exclude,
|
||||
OvmfConfig **ret,
|
||||
sd_json_variant **ret_firmware_json) {
|
||||
_cleanup_(ovmf_config_freep) OvmfConfig *config = NULL;
|
||||
_cleanup_strv_free_ char **conf_files = NULL;
|
||||
const char* native_arch_qemu;
|
||||
@@ -380,8 +388,9 @@ int find_ovmf_config(Set *features_include, Set *features_exclude, OvmfConfig **
|
||||
|
||||
STRV_FOREACH(file, conf_files) {
|
||||
_cleanup_(firmware_data_freep) FirmwareData *fwd = NULL;
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *json = NULL;
|
||||
|
||||
r = load_firmware_data(*file, &fwd);
|
||||
r = load_firmware_data(*file, &fwd, ret_firmware_json ? &json : NULL);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to load JSON file '%s', skipping: %m", *file);
|
||||
continue;
|
||||
@@ -428,6 +437,10 @@ int find_ovmf_config(Set *features_include, Set *features_exclude, OvmfConfig **
|
||||
return r;
|
||||
|
||||
log_debug("Selected firmware definition %s.", *file);
|
||||
|
||||
if (ret_firmware_json)
|
||||
*ret_firmware_json = TAKE_PTR(json);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ int qemu_check_vsock_support(void);
|
||||
int list_ovmf_config(char ***ret);
|
||||
int list_ovmf_firmware_features(char ***ret);
|
||||
int load_ovmf_config(const char *path, OvmfConfig **ret);
|
||||
int find_ovmf_config(Set *features_include, Set *features_exclude, OvmfConfig **ret);
|
||||
int find_ovmf_config(Set *features_include, Set *features_exclude, OvmfConfig **ret, sd_json_variant **ret_firmware_json);
|
||||
int find_qemu_binary(char **ret_qemu_binary);
|
||||
int vsock_fix_child_cid(int vhost_device_fd, unsigned *machine_cid, const char *machine);
|
||||
|
||||
|
||||
+30
-2
@@ -138,6 +138,7 @@ static MachineCredentialContext arg_credentials = {};
|
||||
static uid_t arg_uid_shift = UID_INVALID, arg_uid_range = 0x10000U;
|
||||
static RuntimeMountContext arg_runtime_mounts = {};
|
||||
static char *arg_firmware = NULL;
|
||||
static bool arg_firmware_describe = false;
|
||||
static Set *arg_firmware_features_include = NULL;
|
||||
static Set *arg_firmware_features_exclude = NULL;
|
||||
static char *arg_forward_journal = NULL;
|
||||
@@ -239,7 +240,9 @@ static int help(void) {
|
||||
" --network-user-mode Use user mode networking\n"
|
||||
" --secure-boot=BOOL|auto\n"
|
||||
" Enable searching for firmware supporting SecureBoot\n"
|
||||
" --firmware=PATH|list Select firmware definition file (or list available)\n"
|
||||
" --firmware=PATH|list|describe\n"
|
||||
" Select firmware definition file (or list/describe\n"
|
||||
" available)\n"
|
||||
" --firmware-features=FEATURE[,FEATURE...]|list\n"
|
||||
" Require/exclude specific firmware features\n"
|
||||
" --discard-disk=BOOL Control processing of discard requests\n"
|
||||
@@ -737,6 +740,16 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(optarg, "describe")) {
|
||||
/* Handled after argument parsing so that --firmware-features= is
|
||||
* taken into account. */
|
||||
arg_firmware = mfree(arg_firmware);
|
||||
arg_firmware_describe = true;
|
||||
break;
|
||||
}
|
||||
|
||||
arg_firmware_describe = false;
|
||||
|
||||
if (!isempty(optarg) && !path_is_absolute(optarg) && !startswith(optarg, "./"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Absolute path or path starting with './' required.");
|
||||
|
||||
@@ -2171,7 +2184,7 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
|
||||
if (arg_firmware)
|
||||
r = load_ovmf_config(arg_firmware, &ovmf_config);
|
||||
else
|
||||
r = find_ovmf_config(arg_firmware_features_include, arg_firmware_features_exclude, &ovmf_config);
|
||||
r = find_ovmf_config(arg_firmware_features_include, arg_firmware_features_exclude, &ovmf_config, /* ret_firmware_json= */ NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to find OVMF config: %m");
|
||||
|
||||
@@ -3637,6 +3650,21 @@ static int run(int argc, char *argv[]) {
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (arg_firmware_describe) {
|
||||
_cleanup_(ovmf_config_freep) OvmfConfig *ovmf_config = NULL;
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *json = NULL;
|
||||
|
||||
r = find_ovmf_config(arg_firmware_features_include, arg_firmware_features_exclude, &ovmf_config, &json);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to find OVMF config: %m");
|
||||
|
||||
r = sd_json_variant_dump(json, SD_JSON_FORMAT_PRETTY|SD_JSON_FORMAT_COLOR_AUTO, stdout, /* prefix= */ NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to output JSON: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = determine_names();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user