diff --git a/lib/appliance-uefi.c b/lib/appliance-uefi.c index 138a8d2f9..d2908867c 100644 --- a/lib/appliance-uefi.c +++ b/lib/appliance-uefi.c @@ -38,14 +38,20 @@ * is aarch64 only currently, since that's the only architecture where * UEFI is mandatory (and that only for RHEL). * + * C is an optional list of allowed values for the firmware + * autoselection of libvirt. It is C to indicate it is not + * supported. C<*firmware> is set to one of the strings in + * C in case one can be used. + * * C<*code> is initialized with the path to the read-only UEFI code * file. C<*vars> is initialized with the path to a copy of the UEFI * vars file (which is cleaned up automatically on exit). * - * If C<*code> == C<*vars> == C then no UEFI firmware is - * available. + * In case a UEFI firmare is available, either C<*firmware> is set to + * a non-C value, or C<*code> and C<*vars> are. * - * C<*code> and C<*vars> should be freed by the caller. + * C<*code> and C<*vars> should be freed by the caller, and + * C<*firmware> B not. * * If the function returns C<-1> then there was a real error which * should cause appliance building to fail (no UEFI firmware is not an @@ -54,10 +60,14 @@ * See also F:find_uefi_firmware */ int -guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars, int *flags) +guestfs_int_get_uefi (guestfs_h *g, char *const *firmwares, + const char **firmware, char **code, char **vars, + int *flags) { *code = *vars = NULL; *flags = 0; + if (firmware) + *firmware = NULL; #ifdef __aarch64__ size_t i; diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h index 75b8a5c8e..6799c265d 100644 --- a/lib/guestfs-internal.h +++ b/lib/guestfs-internal.h @@ -691,7 +691,7 @@ extern char *guestfs_int_appliance_command_line (guestfs_h *g, const char *appli #define APPLIANCE_COMMAND_LINE_IS_TCG 1 /* appliance-uefi.c */ -extern int guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars, int *flags); +extern int guestfs_int_get_uefi (guestfs_h *g, char *const *firmwares, const char **firmware, char **code, char **vars, int *flags); /* launch.c */ extern int64_t guestfs_int_timeval_diff (const struct timeval *x, const struct timeval *y); diff --git a/lib/launch-direct.c b/lib/launch-direct.c index ee2dcb884..ae6ca093b 100644 --- a/lib/launch-direct.c +++ b/lib/launch-direct.c @@ -533,7 +533,8 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) #endif /* UEFI (firmware) if required. */ - if (guestfs_int_get_uefi (g, &uefi_code, &uefi_vars, &uefi_flags) == -1) + if (guestfs_int_get_uefi (g, NULL, NULL, &uefi_code, &uefi_vars, + &uefi_flags) == -1) goto cleanup0; if (uefi_flags & UEFI_FLAG_SECURE_BOOT_REQUIRED) { /* Implementing this requires changes to the qemu command line. diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c index fa7b6987c..864eae314 100644 --- a/lib/launch-libvirt.c +++ b/lib/launch-libvirt.c @@ -140,6 +140,10 @@ struct backend_libvirt_data { * contains a list with supported values for * */ + const char *firmware; /* firmware to set in autoselection mode; + * points to one of the elements in + * "firmware_autoselect" + */ char guestfsd_path[UNIX_PATH_MAX]; /* paths to sockets */ char console_path[UNIX_PATH_MAX]; }; @@ -442,7 +446,8 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) goto cleanup; /* UEFI code and variables, on architectures where that is required. */ - if (guestfs_int_get_uefi (g, &data->uefi_code, &data->uefi_vars, + if (guestfs_int_get_uefi (g, data->firmware_autoselect, &data->firmware, + &data->uefi_code, &data->uefi_vars, &uefi_flags) == -1) goto cleanup; if (uefi_flags & UEFI_FLAG_SECURE_BOOT_REQUIRED) { @@ -1207,6 +1212,9 @@ construct_libvirt_xml_boot (guestfs_h *g, cmdline = guestfs_int_appliance_command_line (g, params->appliance_dev, flags); start_element ("os") { + if (params->data->firmware) + attribute ("firmware", params->data->firmware); + start_element ("type") { #ifdef MACHINE_TYPE attribute ("machine", MACHINE_TYPE);