[Libguestfs] [PATCH 3/4] lib: allow to use libvirt firmware autoselection

Pino Toscano ptoscano at redhat.com
Thu Jan 16 12:27:04 UTC 2020


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.
---
 lib/appliance-uefi.c   | 18 ++++++++++++++----
 lib/guestfs-internal.h |  2 +-
 lib/launch-direct.c    |  3 ++-
 lib/launch-libvirt.c   | 10 +++++++++-
 4 files changed, 26 insertions(+), 7 deletions(-)

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<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;
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
                                  * <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);
-- 
2.24.1




More information about the Libguestfs mailing list