lib: allow to use libvirt firmware autoselection

Enhance the UEFI firmware lookup function with the information on the
libvirt firmware autoselection, allowing it to return a value to use for
the appliance.

At the moment no firmware is selected this way, so there is no behaviour
change.
This commit is contained in:
Pino Toscano
2020-01-15 17:24:03 +01:00
parent 777a21b16b
commit 029901113c
4 changed files with 26 additions and 7 deletions

View File

@@ -38,14 +38,20 @@
* is aarch64 only currently, since that's the only architecture where
* UEFI is mandatory (and that only for RHEL).
*
* C<firmwares> is an optional list of allowed values for the firmware
* autoselection of libvirt. It is C<NULL> to indicate it is not
* supported. C<*firmware> is set to one of the strings in
* C<firmwares> 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<NULL> then no UEFI firmware is
* available.
* In case a UEFI firmare is available, either C<*firmware> is set to
* a non-C<NULL> 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<must> 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<virt-v2v.git/v2v/utils.ml>: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;

View File

@@ -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);

View File

@@ -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.

View File

@@ -140,6 +140,10 @@ struct backend_libvirt_data {
* contains a list with supported values for
* <os firmware='...'>
*/
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);