From 3ab7f9502366643f7c7ecfddd158906a2ebba609 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 8 Jun 2021 16:41:57 +0000 Subject: [PATCH] import libvirt-6.0.0-36.module+el8.5.0+11222+c889b3f3 --- ...are-auto-selection-feature-filtering.patch | 415 ++++++++++++++++++ ...uce-virDomainDefParseBootAcpiOptions.patch | 124 ++++++ ...virDomainDefParseBootFirmwareOptions.patch | 86 ++++ ...uce-virDomainDefParseBootInitOptions.patch | 173 ++++++++ ...e-virDomainDefParseBootKernelOptions.patch | 60 +++ ...e-virDomainDefParseBootLoaderOptions.patch | 97 ++++ ...e-duplicated-firmware-type-attribute.patch | 317 +++++++++++++ ...itch-in-virDomainDefParseBootOptions.patch | 89 ++++ ...-secure-attribute-for-loader-element.patch | 47 ++ ...f-Don-t-leak-def-os.firmwareFeatures.patch | 43 ++ ...reference-after-checking-device-type.patch | 50 +++ ...y-sysfs-path-rather-than-mdev-struct.patch | 166 +++++++ ...-private-chains-on-firewalld-restart.patch | 282 ++++++++++++ ...orkSetupPrivateChains-multiple-times.patch | 65 +++ ...are-auto-selection-feature-filtering.patch | 248 +++++++++++ ...or-out-for-unknown-firmware-features.patch | 68 +++ SPECS/libvirt.spec | 36 +- 17 files changed, 2365 insertions(+), 1 deletion(-) create mode 100644 SOURCES/libvirt-conf-introduce-support-for-firmware-auto-selection-feature-filtering.patch create mode 100644 SOURCES/libvirt-conf-introduce-virDomainDefParseBootAcpiOptions.patch create mode 100644 SOURCES/libvirt-conf-introduce-virDomainDefParseBootFirmwareOptions.patch create mode 100644 SOURCES/libvirt-conf-introduce-virDomainDefParseBootInitOptions.patch create mode 100644 SOURCES/libvirt-conf-introduce-virDomainDefParseBootKernelOptions.patch create mode 100644 SOURCES/libvirt-conf-introduce-virDomainDefParseBootLoaderOptions.patch create mode 100644 SOURCES/libvirt-conf-remove-duplicated-firmware-type-attribute.patch create mode 100644 SOURCES/libvirt-conf-use-switch-in-virDomainDefParseBootOptions.patch create mode 100644 SOURCES/libvirt-docs-improve-description-of-secure-attribute-for-loader-element.patch create mode 100644 SOURCES/libvirt-domain_conf-Don-t-leak-def-os.firmwareFeatures.patch create mode 100644 SOURCES/libvirt-hostdev-Update-mdev-pointer-reference-after-checking-device-type.patch create mode 100644 SOURCES/libvirt-hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-mdev-struct.patch create mode 100644 SOURCES/libvirt-network-force-re-creation-of-iptables-private-chains-on-firewalld-restart.patch create mode 100644 SOURCES/libvirt-network-make-it-safe-to-call-networkSetupPrivateChains-multiple-times.patch create mode 100644 SOURCES/libvirt-qemu-implement-support-for-firmware-auto-selection-feature-filtering.patch create mode 100644 SOURCES/libvirt-qemu_firmware-don-t-error-out-for-unknown-firmware-features.patch diff --git a/SOURCES/libvirt-conf-introduce-support-for-firmware-auto-selection-feature-filtering.patch b/SOURCES/libvirt-conf-introduce-support-for-firmware-auto-selection-feature-filtering.patch new file mode 100644 index 0000000..2b876eb --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-support-for-firmware-auto-selection-feature-filtering.patch @@ -0,0 +1,415 @@ +From 6f02748897062d40b411177ef752644505189a72 Mon Sep 17 00:00:00 2001 +Message-Id: <6f02748897062d40b411177ef752644505189a72@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:11 +0200 +Subject: [PATCH] conf: introduce support for firmware auto-selection feature + filtering + +When the firmware auto-selection was introduced it always picked first +usable firmware based on the JSON descriptions on the host. It is +possible to add/remove/change the JSON files but it will always be for +the whole host. + +This patch introduces support for configuring the auto-selection per VM +by adding users an option to limit what features they would like to have +available in the firmware. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit cff524af6c5e1ddc11149394ed7f985242ebea0f) + +Conflicts: + docs/formatdomain.rst + - we still have formatdomain.html.in in downstream + src/conf/domain_conf.c + - missing following upstream commits: + 0280fc72708b9d0f162a808bcc8d78137a68d58d + 104dadcff6023da676df3905d1ed8688aea15e86 + 2d5f7a49ae0780143566932ab38215433982c89f + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <631e05bc5363abb3e48d8b652a806324801cce16.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + docs/formatdomain.html.in | 58 +++++++++++++ + docs/schemas/domaincommon.rng | 23 +++++ + src/conf/domain_conf.c | 83 ++++++++++++++++++- + src/conf/domain_conf.h | 10 +++ + ...os-firmware-invalid-type.x86_64-latest.err | 1 + + .../os-firmware-invalid-type.xml | 28 +++++++ + tests/qemuxml2argvtest.c | 1 + + ...aarch64-os-firmware-efi.aarch64-latest.xml | 1 + + .../os-firmware-bios.x86_64-latest.xml | 1 + + .../os-firmware-efi-secboot.x86_64-latest.xml | 1 + + .../os-firmware-efi.x86_64-latest.xml | 1 + + tests/vmx2xmldata/vmx2xml-firmware-efi.xml | 1 + + 12 files changed, 206 insertions(+), 3 deletions(-) + create mode 100644 tests/qemuxml2argvdata/os-firmware-invalid-type.x86_64-latest.err + create mode 100644 tests/qemuxml2argvdata/os-firmware-invalid-type.xml + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index a40bed347b..11f31618af 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -180,6 +180,64 @@ + ESX and VMWare hypervisor drivers, however, + the i686 arch will always be chosen even on an + x86_64 host. Since 0.0.1 ++
firmware
++
++

Since 7.2.0 QEMU/KVM only

++

++ When used together with firmware attribute of ++ os element the type attribute must ++ have the same value. ++

++

++ List of mandatory attributes: ++

    ++
  • ++ type (accepted values are bios ++ and efi) same as the firmware ++ attribute of os element. ++
  • ++
++

++

++ When using firmware auto-selection there are different features ++ enabled in the firmwares. The list of features can be used to ++ limit what firmware should be automatically selected for the VM. ++ The list of features can be specified using zero or more ++ feature elements. Libvirt will take into consideration ++ only the listed features and ignore the rest when selecting the firmware. ++ ++

++
feature
++
++ The list of mandatory attributes: ++ ++
    ++
  • ++ enabled (accepted values are yes ++ and no) is used to tell libvirt if the feature ++ must be enabled or not in the automatically selected firmware ++
  • ++
  • ++ name the name of the feature, the list of the features: ++
      ++
    • ++ enrolled-keys whether the selected nvram template ++ has default certificate enrolled. Firmware with Secure Boot ++ feature but without enrolled keys will successfully boot ++ non-signed binaries as well. Valid only for firmwares with ++ Secure Boot feature. ++
    • ++
    • ++ secure-boot whether the firmware implements ++ UEFI Secure boot feature. ++
    • ++
    ++
  • ++
++
++
++

++
+
loader
+
The optional loader tag refers to a firmware blob, + which is specified by absolute path, +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index 6671ef3dfa..b7f6a6b494 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -268,6 +268,29 @@ + + + ++ ++ ++ ++ ++ bios ++ efi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ enrolled-keys ++ secure-boot ++ ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 93a78f8277..28c8d0ecbd 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -1240,6 +1240,12 @@ VIR_ENUM_IMPL(virDomainOsDefFirmware, + "efi", + ); + ++VIR_ENUM_IMPL(virDomainOsDefFirmwareFeature, ++ VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST, ++ "enrolled-keys", ++ "secure-boot", ++); ++ + /* Internal mapping: subset of block job types that can be present in + * XML (remaining types are not two-phase). */ + VIR_ENUM_DECL(virDomainBlockJob); +@@ -19382,22 +19388,67 @@ virDomainDefParseBootFirmwareOptions(virDomainDefPtr def, + xmlXPathContextPtr ctxt) + { + g_autofree char *firmware = virXPathString("string(./os/@firmware)", ctxt); ++ g_autofree char *type = virXPathString("string(./os/firmware/@type)", ctxt); ++ g_autofree xmlNodePtr *nodes = NULL; ++ g_autofree int *features = NULL; + int fw = 0; ++ int n = 0; ++ size_t i; + +- if (!firmware) ++ if (!firmware && !type) + return 0; + +- fw = virDomainOsDefFirmwareTypeFromString(firmware); ++ if (firmware && type && STRNEQ(firmware, type)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("firmware attribute and firmware type has to be the same")); ++ return -1; ++ } ++ ++ if (!type) ++ type = g_steal_pointer(&firmware); ++ ++ fw = virDomainOsDefFirmwareTypeFromString(type); + + if (fw <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown firmware value %s"), +- firmware); ++ type); + return -1; + } + + def->os.firmware = fw; + ++ if ((n = virXPathNodeSet("./os/firmware/feature", ctxt, &nodes)) < 0) ++ return -1; ++ ++ if (n > 0) ++ features = g_new0(int, VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST); ++ ++ for (i = 0; i < n; i++) { ++ g_autofree char *name = virXMLPropString(nodes[i], "name"); ++ g_autofree char *enabled = virXMLPropString(nodes[i], "enabled"); ++ int feature = virDomainOsDefFirmwareFeatureTypeFromString(name); ++ int val = virTristateBoolTypeFromString(enabled); ++ ++ if (feature < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("invalid firmware feature name '%s'"), ++ name); ++ return -1; ++ } ++ ++ if (val < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("invalid firmware feature enabled value '%s'"), ++ enabled); ++ return -1; ++ } ++ ++ features[feature] = val; ++ } ++ ++ def->os.firmwareFeatures = g_steal_pointer(&features); ++ + return 0; + } + +@@ -28987,6 +29038,32 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, + virBufferAsprintf(buf, ">%s\n", + virDomainOSTypeToString(def->os.type)); + ++ if (def->os.firmware) { ++ virBufferAsprintf(buf, "os.firmware)); ++ ++ if (def->os.firmwareFeatures) { ++ virBufferAddLit(buf, ">\n"); ++ ++ virBufferAdjustIndent(buf, 2); ++ ++ for (i = 0; i < VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST; i++) { ++ if (def->os.firmwareFeatures[i] == VIR_TRISTATE_BOOL_ABSENT) ++ continue; ++ ++ virBufferAsprintf(buf, "\n", ++ virTristateBoolTypeToString(def->os.firmwareFeatures[i]), ++ virDomainOsDefFirmwareFeatureTypeToString(i)); ++ } ++ ++ virBufferAdjustIndent(buf, -2); ++ ++ virBufferAddLit(buf, "\n"); ++ } else { ++ virBufferAddLit(buf, "/>\n"); ++ } ++ } ++ + virBufferEscapeString(buf, "%s\n", + def->os.init); + for (i = 0; def->os.initargv && def->os.initargv[i]; i++) +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 3aed1fb22a..1ad77ecac6 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -1967,9 +1967,19 @@ G_STATIC_ASSERT((int)VIR_DOMAIN_OS_DEF_FIRMWARE_LAST == (int)VIR_DOMAIN_LOADER_T + + VIR_ENUM_DECL(virDomainOsDefFirmware); + ++typedef enum { ++ VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_ENROLLED_KEYS, ++ VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_SECURE_BOOT, ++ ++ VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST ++} virDomainOsDefFirmwareFeature; ++ ++VIR_ENUM_DECL(virDomainOsDefFirmwareFeature); ++ + struct _virDomainOSDef { + int type; + virDomainOsDefFirmware firmware; ++ int *firmwareFeatures; + virArch arch; + char *machine; + size_t nBootDevs; +diff --git a/tests/qemuxml2argvdata/os-firmware-invalid-type.x86_64-latest.err b/tests/qemuxml2argvdata/os-firmware-invalid-type.x86_64-latest.err +new file mode 100644 +index 0000000000..c8174b1c8b +--- /dev/null ++++ b/tests/qemuxml2argvdata/os-firmware-invalid-type.x86_64-latest.err +@@ -0,0 +1 @@ ++unsupported configuration: firmware attribute and firmware type has to be the same +diff --git a/tests/qemuxml2argvdata/os-firmware-invalid-type.xml b/tests/qemuxml2argvdata/os-firmware-invalid-type.xml +new file mode 100644 +index 0000000000..41360df0f7 +--- /dev/null ++++ b/tests/qemuxml2argvdata/os-firmware-invalid-type.xml +@@ -0,0 +1,28 @@ ++ ++ fedora ++ 63840878-0deb-4095-97e6-fc444d9bc9fa ++ 8192 ++ 8192 ++ 1 ++ ++ hvm ++ ++ ++ /var/lib/libvirt/qemu/nvram/fedora_VARS.fd ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ destroy ++ restart ++ restart ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index a22e3ba157..bc04bea692 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -3094,6 +3094,7 @@ mymain(void) + DO_TEST_CAPS_LATEST("os-firmware-bios"); + DO_TEST_CAPS_LATEST("os-firmware-efi"); + DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); ++ DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-invalid-type"); + DO_TEST_CAPS_ARCH_LATEST("aarch64-os-firmware-efi", "aarch64"); + + DO_TEST_CAPS_LATEST("vhost-user-vga"); +diff --git a/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml b/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml +index 1e51d55305..3cac8fc5c6 100644 +--- a/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml ++++ b/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml +@@ -6,6 +6,7 @@ + 1 + + hvm ++ + /aarch64.kernel + /aarch64.initrd + earlyprintk console=ttyAMA0,115200n8 rw root=/dev/vda rootwait +diff --git a/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml +index 60d3498765..ef24f2fece 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml +@@ -6,6 +6,7 @@ + 1 + + hvm ++ + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml +index 938da73711..3757191e8e 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml +@@ -6,6 +6,7 @@ + 1 + + hvm ++ + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml +index 97ce8a75c7..f2e6b7f36d 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml +@@ -6,6 +6,7 @@ + 1 + + hvm ++ + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/vmx2xmldata/vmx2xml-firmware-efi.xml b/tests/vmx2xmldata/vmx2xml-firmware-efi.xml +index e21158cebf..375c47d281 100644 +--- a/tests/vmx2xmldata/vmx2xml-firmware-efi.xml ++++ b/tests/vmx2xmldata/vmx2xml-firmware-efi.xml +@@ -5,6 +5,7 @@ + 1 + + hvm ++ + + + destroy +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-introduce-virDomainDefParseBootAcpiOptions.patch b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootAcpiOptions.patch new file mode 100644 index 0000000..f3d6fd4 --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootAcpiOptions.patch @@ -0,0 +1,124 @@ +From 7ba2905bfcab4dbe4a491ee8587dd4c9ef457c0b Mon Sep 17 00:00:00 2001 +Message-Id: <7ba2905bfcab4dbe4a491ee8587dd4c9ef457c0b@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:09 +0200 +Subject: [PATCH] conf: introduce virDomainDefParseBootAcpiOptions + +Extract the code to it's own function. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 108cb29c1c7eec7b9089dd431e0bdcd82a0b07f1) + +Conflicts: + src/conf/domain_conf.c + - missing upstream commit d293a556d710754d8aa8d5caac0bb01a365fcbd8 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <5fb7ee0165340ff517b3f7f16ddc542813ac385d.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 71 ++++++++++++++++++++++++------------------ + 1 file changed, 41 insertions(+), 30 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 493700ed6b..f8d8d33245 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19429,13 +19429,51 @@ virDomainDefParseBootLoaderOptions(virDomainDefPtr def, + + + static int +-virDomainDefParseBootOptions(virDomainDefPtr def, +- xmlXPathContextPtr ctxt) ++virDomainDefParseBootAcpiOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) + { + int n; + g_autofree xmlNodePtr *nodes = NULL; + g_autofree char *tmp = NULL; + ++ if ((n = virXPathNodeSet("./os/acpi/table", ctxt, &nodes)) < 0) ++ return -1; ++ ++ if (n > 1) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Only one acpi table is supported")); ++ return -1; ++ } ++ ++ if (n == 1) { ++ tmp = virXMLPropString(nodes[0], "type"); ++ ++ if (!tmp) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Missing acpi table type")); ++ return -1; ++ } ++ ++ if (STREQ_NULLABLE(tmp, "slic")) { ++ VIR_FREE(tmp); ++ tmp = virXMLNodeContentString(nodes[0]); ++ def->os.slic_table = virFileSanitizePath(tmp); ++ } else { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Unknown acpi table type: %s"), ++ tmp); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++static int ++virDomainDefParseBootOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) ++{ + /* + * Booting options for different OS types.... + * +@@ -19467,36 +19505,9 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + } + + if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { +- if ((n = virXPathNodeSet("./os/acpi/table", ctxt, &nodes)) < 0) ++ if (virDomainDefParseBootAcpiOptions(def, ctxt) < 0) + return -1; + +- if (n > 1) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("Only one acpi table is supported")); +- return -1; +- } +- +- if (n == 1) { +- tmp = virXMLPropString(nodes[0], "type"); +- +- if (!tmp) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("Missing acpi table type")); +- return -1; +- } +- +- if (STREQ_NULLABLE(tmp, "slic")) { +- VIR_FREE(tmp); +- tmp = virXMLNodeContentString(nodes[0]); +- def->os.slic_table = virFileSanitizePath(tmp); +- } else { +- virReportError(VIR_ERR_XML_ERROR, +- _("Unknown acpi table type: %s"), +- tmp); +- return -1; +- } +- } +- + if (virDomainDefParseBootXML(ctxt, def) < 0) + return -1; + } +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-introduce-virDomainDefParseBootFirmwareOptions.patch b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootFirmwareOptions.patch new file mode 100644 index 0000000..409c3bd --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootFirmwareOptions.patch @@ -0,0 +1,86 @@ +From 2a019bfa26e697c60893afd09fcc2f0c3218691b Mon Sep 17 00:00:00 2001 +Message-Id: <2a019bfa26e697c60893afd09fcc2f0c3218691b@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:07 +0200 +Subject: [PATCH] conf: introduce virDomainDefParseBootFirmwareOptions + +Extract the code to it's own function. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit bcf97abfc6b45694f0d789ae2bdf87c8d082fddf) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <9a090d9f2a43b261ed1b6db608779a01a7594f4a.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 39 +++++++++++++++++++++++++++------------ + 1 file changed, 27 insertions(+), 12 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 432ad938f9..bb484a57c6 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19377,6 +19377,31 @@ virDomainDefParseBootKernelOptions(virDomainDefPtr def, + } + + ++static int ++virDomainDefParseBootFirmwareOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) ++{ ++ g_autofree char *firmware = virXPathString("string(./os/@firmware)", ctxt); ++ int fw = 0; ++ ++ if (!firmware) ++ return 0; ++ ++ fw = virDomainOsDefFirmwareTypeFromString(firmware); ++ ++ if (fw <= 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("unknown firmware value %s"), ++ firmware); ++ return -1; ++ } ++ ++ def->os.firmware = fw; ++ ++ return 0; ++} ++ ++ + static int + virDomainDefParseBootOptions(virDomainDefPtr def, + xmlXPathContextPtr ctxt) +@@ -19403,23 +19428,13 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + def->os.type == VIR_DOMAIN_OSTYPE_XENPVH || + def->os.type == VIR_DOMAIN_OSTYPE_HVM || + def->os.type == VIR_DOMAIN_OSTYPE_UML) { +- g_autofree char *firmware = NULL; + xmlNodePtr loader_node; + + virDomainDefParseBootKernelOptions(def, ctxt); + +- if (def->os.type == VIR_DOMAIN_OSTYPE_HVM && +- (firmware = virXPathString("string(./os/@firmware)", ctxt))) { +- int fw = virDomainOsDefFirmwareTypeFromString(firmware); +- +- if (fw <= 0) { +- virReportError(VIR_ERR_XML_ERROR, +- _("unknown firmware value %s"), +- firmware); ++ if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { ++ if (virDomainDefParseBootFirmwareOptions(def, ctxt) < 0) + return -1; +- } +- +- def->os.firmware = fw; + } + + if ((loader_node = virXPathNode("./os/loader[1]", ctxt))) { +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-introduce-virDomainDefParseBootInitOptions.patch b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootInitOptions.patch new file mode 100644 index 0000000..4195af7 --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootInitOptions.patch @@ -0,0 +1,173 @@ +From adafaa880b67f1025c64515352e5e851daa62ae9 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:05 +0200 +Subject: [PATCH] conf: introduce virDomainDefParseBootInitOptions + +Extract the code to it's own function. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit b07116438c96fddfa00bdb57878a707240574b42) + +Conflicts: + src/conf/domain_conf.c + - using VIR_ALLOC in downstream instead of g_new0 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 115 +++++++++++++++++++++++------------------ + 1 file changed, 64 insertions(+), 51 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 444657c9a1..9eb418c7c0 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19302,76 +19302,89 @@ virDomainVcpuParse(virDomainDefPtr def, + + + static int +-virDomainDefParseBootOptions(virDomainDefPtr def, +- xmlXPathContextPtr ctxt) ++virDomainDefParseBootInitOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) + { + char *name = NULL; + size_t i; + int n; + g_autofree xmlNodePtr *nodes = NULL; +- g_autofree char *tmp = NULL; + +- /* +- * Booting options for different OS types.... +- * +- * - A bootloader (and optional kernel+initrd) (xen) +- * - A kernel + initrd (xen) +- * - A boot device (and optional kernel+initrd) (hvm) +- * - An init script (exe) +- */ ++ def->os.init = virXPathString("string(./os/init[1])", ctxt); ++ def->os.cmdline = virXPathString("string(./os/cmdline[1])", ctxt); ++ def->os.initdir = virXPathString("string(./os/initdir[1])", ctxt); ++ def->os.inituser = virXPathString("string(./os/inituser[1])", ctxt); ++ def->os.initgroup = virXPathString("string(./os/initgroup[1])", ctxt); + +- if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) { +- def->os.init = virXPathString("string(./os/init[1])", ctxt); +- def->os.cmdline = virXPathString("string(./os/cmdline[1])", ctxt); +- def->os.initdir = virXPathString("string(./os/initdir[1])", ctxt); +- def->os.inituser = virXPathString("string(./os/inituser[1])", ctxt); +- def->os.initgroup = virXPathString("string(./os/initgroup[1])", ctxt); ++ if ((n = virXPathNodeSet("./os/initarg", ctxt, &nodes)) < 0) ++ return -1; + +- if ((n = virXPathNodeSet("./os/initarg", ctxt, &nodes)) < 0) ++ if (VIR_ALLOC_N(def->os.initargv, n+1) < 0) ++ return -1; ++ for (i = 0; i < n; i++) { ++ if (!nodes[i]->children || ++ !nodes[i]->children->content) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("No data supplied for element")); + return -1; ++ } ++ def->os.initargv[i] = g_strdup((const char *)nodes[i]->children->content); ++ } ++ def->os.initargv[n] = NULL; ++ VIR_FREE(nodes); + +- if (VIR_ALLOC_N(def->os.initargv, n+1) < 0) ++ if ((n = virXPathNodeSet("./os/initenv", ctxt, &nodes)) < 0) ++ return -1; ++ ++ if (VIR_ALLOC_N(def->os.initenv, n+1) < 0) ++ return -1; ++ for (i = 0; i < n; i++) { ++ if (!(name = virXMLPropString(nodes[i], "name"))) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("No name supplied for element")); + return -1; +- for (i = 0; i < n; i++) { +- if (!nodes[i]->children || +- !nodes[i]->children->content) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("No data supplied for element")); +- return -1; +- } +- def->os.initargv[i] = g_strdup((const char *)nodes[i]->children->content); + } +- def->os.initargv[n] = NULL; +- VIR_FREE(nodes); + +- if ((n = virXPathNodeSet("./os/initenv", ctxt, &nodes)) < 0) ++ if (!nodes[i]->children || ++ !nodes[i]->children->content) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("No value supplied for element"), ++ name); + return -1; ++ } + +- if (VIR_ALLOC_N(def->os.initenv, n+1) < 0) ++ if (VIR_ALLOC(def->os.initenv[i]) < 0) + return -1; +- for (i = 0; i < n; i++) { +- if (!(name = virXMLPropString(nodes[i], "name"))) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("No name supplied for element")); +- return -1; +- } + +- if (!nodes[i]->children || +- !nodes[i]->children->content) { +- virReportError(VIR_ERR_XML_ERROR, +- _("No value supplied for element"), +- name); +- return -1; +- } ++ def->os.initenv[i]->name = name; ++ def->os.initenv[i]->value = g_strdup((const char *)nodes[i]->children->content); ++ } ++ def->os.initenv[n] = NULL; + +- if (VIR_ALLOC(def->os.initenv[i]) < 0) +- return -1; ++ return 0; ++} + +- def->os.initenv[i]->name = name; +- def->os.initenv[i]->value = g_strdup((const char *)nodes[i]->children->content); +- } +- def->os.initenv[n] = NULL; +- VIR_FREE(nodes); ++ ++static int ++virDomainDefParseBootOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) ++{ ++ int n; ++ g_autofree xmlNodePtr *nodes = NULL; ++ g_autofree char *tmp = NULL; ++ ++ /* ++ * Booting options for different OS types.... ++ * ++ * - A bootloader (and optional kernel+initrd) (xen) ++ * - A kernel + initrd (xen) ++ * - A boot device (and optional kernel+initrd) (hvm) ++ * - An init script (exe) ++ */ ++ ++ if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) { ++ if (virDomainDefParseBootInitOptions(def, ctxt) < 0) ++ return -1; + } + + if (def->os.type == VIR_DOMAIN_OSTYPE_XEN || +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-introduce-virDomainDefParseBootKernelOptions.patch b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootKernelOptions.patch new file mode 100644 index 0000000..a418a03 --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootKernelOptions.patch @@ -0,0 +1,60 @@ +From a62075772680bd30ced25d7177048ab26db8ea09 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:06 +0200 +Subject: [PATCH] conf: introduce virDomainDefParseBootKernelOptions + +Extract the code to it's own function. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit bf9b3f8e573092cc98ea647f25cf116e22bbfe3c) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <936428a5fa6d4104361ac8080639a55111c14965.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 9eb418c7c0..432ad938f9 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19365,6 +19365,18 @@ virDomainDefParseBootInitOptions(virDomainDefPtr def, + } + + ++static void ++virDomainDefParseBootKernelOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) ++{ ++ def->os.kernel = virXPathString("string(./os/kernel[1])", ctxt); ++ def->os.initrd = virXPathString("string(./os/initrd[1])", ctxt); ++ def->os.cmdline = virXPathString("string(./os/cmdline[1])", ctxt); ++ def->os.dtb = virXPathString("string(./os/dtb[1])", ctxt); ++ def->os.root = virXPathString("string(./os/root[1])", ctxt); ++} ++ ++ + static int + virDomainDefParseBootOptions(virDomainDefPtr def, + xmlXPathContextPtr ctxt) +@@ -19394,11 +19406,7 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + g_autofree char *firmware = NULL; + xmlNodePtr loader_node; + +- def->os.kernel = virXPathString("string(./os/kernel[1])", ctxt); +- def->os.initrd = virXPathString("string(./os/initrd[1])", ctxt); +- def->os.cmdline = virXPathString("string(./os/cmdline[1])", ctxt); +- def->os.dtb = virXPathString("string(./os/dtb[1])", ctxt); +- def->os.root = virXPathString("string(./os/root[1])", ctxt); ++ virDomainDefParseBootKernelOptions(def, ctxt); + + if (def->os.type == VIR_DOMAIN_OSTYPE_HVM && + (firmware = virXPathString("string(./os/@firmware)", ctxt))) { +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-introduce-virDomainDefParseBootLoaderOptions.patch b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootLoaderOptions.patch new file mode 100644 index 0000000..599fbfc --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootLoaderOptions.patch @@ -0,0 +1,97 @@ +From 6891ef941e693d86ebbab9e529e908dacf4a7dc6 Mon Sep 17 00:00:00 2001 +Message-Id: <6891ef941e693d86ebbab9e529e908dacf4a7dc6@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:08 +0200 +Subject: [PATCH] conf: introduce virDomainDefParseBootLoaderOptions + +Extract the code to it's own function. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit b8dd70db4ee2f3a5edcbbeb8515830db9652cb59) + +Conflicts: + src/conf/domain_conf.c + - using VIR_ALLOC in downstream instead of g_new0 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 44 +++++++++++++++++++++++++++--------------- + 1 file changed, 28 insertions(+), 16 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index bb484a57c6..493700ed6b 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19402,6 +19402,32 @@ virDomainDefParseBootFirmwareOptions(virDomainDefPtr def, + } + + ++static int ++virDomainDefParseBootLoaderOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) ++{ ++ xmlNodePtr loader_node = virXPathNode("./os/loader[1]", ctxt); ++ const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE; ++ ++ if (!loader_node) ++ return 0; ++ ++ if (VIR_ALLOC(def->os.loader) < 0) ++ return -1; ++ ++ if (virDomainLoaderDefParseXML(loader_node, ++ def->os.loader, ++ fwAutoSelect) < 0) ++ return -1; ++ ++ def->os.loader->nvram = virXPathString("string(./os/nvram[1])", ctxt); ++ if (!fwAutoSelect) ++ def->os.loader->templt = virXPathString("string(./os/nvram[1]/@template)", ctxt); ++ ++ return 0; ++} ++ ++ + static int + virDomainDefParseBootOptions(virDomainDefPtr def, + xmlXPathContextPtr ctxt) +@@ -19428,7 +19454,6 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + def->os.type == VIR_DOMAIN_OSTYPE_XENPVH || + def->os.type == VIR_DOMAIN_OSTYPE_HVM || + def->os.type == VIR_DOMAIN_OSTYPE_UML) { +- xmlNodePtr loader_node; + + virDomainDefParseBootKernelOptions(def, ctxt); + +@@ -19437,21 +19462,8 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + return -1; + } + +- if ((loader_node = virXPathNode("./os/loader[1]", ctxt))) { +- const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE; +- +- if (VIR_ALLOC(def->os.loader) < 0) +- return -1; +- +- if (virDomainLoaderDefParseXML(loader_node, +- def->os.loader, +- fwAutoSelect) < 0) +- return -1; +- +- def->os.loader->nvram = virXPathString("string(./os/nvram[1])", ctxt); +- if (!fwAutoSelect) +- def->os.loader->templt = virXPathString("string(./os/nvram[1]/@template)", ctxt); +- } ++ if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0) ++ return -1; + } + + if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-remove-duplicated-firmware-type-attribute.patch b/SOURCES/libvirt-conf-remove-duplicated-firmware-type-attribute.patch new file mode 100644 index 0000000..3bc500f --- /dev/null +++ b/SOURCES/libvirt-conf-remove-duplicated-firmware-type-attribute.patch @@ -0,0 +1,317 @@ +From 4ca3f2f590fb860b01f1eb5fec8929ceba702dc6 Mon Sep 17 00:00:00 2001 +Message-Id: <4ca3f2f590fb860b01f1eb5fec8929ceba702dc6@dist-git> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 21 May 2021 14:16:14 +0200 +Subject: [PATCH] conf: remove duplicated firmware type attribute +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The + + + + + + + +repeats the firmware attribute twice. This has no functional benefit, as +evidenced by fact that we use a single struct field to store both +attributes, while needlessly introducing an error scenario. The XML can +just be simplified to: + + + + + + + +which also means that we don't need to emit the empty element + for all existing configs too. + +Reviewed-by: Pavel Hrdina +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit a9b1375d7d2f7d240dce09c5f8b62e568e386051) + +Conflicts: + docs/formatdomain.rst + - we still have formatdomain.html.in in downstream + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <299fd16fc3ce632bf25ca55cc4bb65a225437d61.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + docs/formatdomain.html.in | 15 ------ + docs/schemas/domaincommon.rng | 10 +--- + src/conf/domain_conf.c | 48 ++++++------------- + .../os-firmware-efi-no-enrolled-keys.xml | 2 +- + .../os-firmware-invalid-type.xml | 28 ----------- + tests/qemuxml2argvtest.c | 1 - + ...aarch64-os-firmware-efi.aarch64-latest.xml | 1 - + .../os-firmware-bios.x86_64-latest.xml | 1 - + .../os-firmware-efi-secboot.x86_64-latest.xml | 1 - + .../os-firmware-efi.x86_64-latest.xml | 1 - + tests/vmx2xmldata/vmx2xml-firmware-efi.xml | 1 - + 11 files changed, 18 insertions(+), 91 deletions(-) + delete mode 100644 tests/qemuxml2argvdata/os-firmware-invalid-type.xml + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 11f31618af..79e2e51c54 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -183,21 +183,6 @@ +
firmware
+
+

Since 7.2.0 QEMU/KVM only

+-

+- When used together with firmware attribute of +- os element the type attribute must +- have the same value. +-

+-

+- List of mandatory attributes: +-

    +-
  • +- type (accepted values are bios +- and efi) same as the firmware +- attribute of os element. +-
  • +-
+-

+

+ When using firmware auto-selection there are different features + enabled in the firmwares. The list of features can be used to +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index b7f6a6b494..ec8167e588 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -270,13 +270,7 @@ + + + +- +- +- bios +- efi +- +- +- ++ + + + +@@ -288,7 +282,7 @@ + + + +- ++ + + + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 2ffa9c8a2a..6806064016 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19389,31 +19389,21 @@ virDomainDefParseBootFirmwareOptions(virDomainDefPtr def, + xmlXPathContextPtr ctxt) + { + g_autofree char *firmware = virXPathString("string(./os/@firmware)", ctxt); +- g_autofree char *type = virXPathString("string(./os/firmware/@type)", ctxt); + g_autofree xmlNodePtr *nodes = NULL; + g_autofree int *features = NULL; + int fw = 0; + int n = 0; + size_t i; + +- if (!firmware && !type) ++ if (!firmware) + return 0; + +- if (firmware && type && STRNEQ(firmware, type)) { +- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", +- _("firmware attribute and firmware type has to be the same")); +- return -1; +- } +- +- if (!type) +- type = g_steal_pointer(&firmware); +- +- fw = virDomainOsDefFirmwareTypeFromString(type); ++ fw = virDomainOsDefFirmwareTypeFromString(firmware); + + if (fw <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown firmware value %s"), +- type); ++ firmware); + return -1; + } + +@@ -29039,30 +29029,22 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, + virBufferAsprintf(buf, ">%s\n", + virDomainOSTypeToString(def->os.type)); + +- if (def->os.firmware) { +- virBufferAsprintf(buf, "os.firmware)); +- +- if (def->os.firmwareFeatures) { +- virBufferAddLit(buf, ">\n"); +- +- virBufferAdjustIndent(buf, 2); ++ if (def->os.firmwareFeatures) { ++ virBufferAddLit(buf, "\n"); ++ virBufferAdjustIndent(buf, 2); + +- for (i = 0; i < VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST; i++) { +- if (def->os.firmwareFeatures[i] == VIR_TRISTATE_BOOL_ABSENT) +- continue; ++ for (i = 0; i < VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST; i++) { ++ if (def->os.firmwareFeatures[i] == VIR_TRISTATE_BOOL_ABSENT) ++ continue; + +- virBufferAsprintf(buf, "\n", +- virTristateBoolTypeToString(def->os.firmwareFeatures[i]), +- virDomainOsDefFirmwareFeatureTypeToString(i)); +- } ++ virBufferAsprintf(buf, "\n", ++ virTristateBoolTypeToString(def->os.firmwareFeatures[i]), ++ virDomainOsDefFirmwareFeatureTypeToString(i)); ++ } + +- virBufferAdjustIndent(buf, -2); ++ virBufferAdjustIndent(buf, -2); + +- virBufferAddLit(buf, "\n"); +- } else { +- virBufferAddLit(buf, "/>\n"); +- } ++ virBufferAddLit(buf, "\n"); + } + + virBufferEscapeString(buf, "%s\n", +diff --git a/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml +index 7f8f57a859..4999c4f125 100644 +--- a/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml ++++ b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml +@@ -6,7 +6,7 @@ + 1 + + hvm +- ++ + + + +diff --git a/tests/qemuxml2argvdata/os-firmware-invalid-type.xml b/tests/qemuxml2argvdata/os-firmware-invalid-type.xml +deleted file mode 100644 +index 41360df0f7..0000000000 +--- a/tests/qemuxml2argvdata/os-firmware-invalid-type.xml ++++ /dev/null +@@ -1,28 +0,0 @@ +- +- fedora +- 63840878-0deb-4095-97e6-fc444d9bc9fa +- 8192 +- 8192 +- 1 +- +- hvm +- +- +- /var/lib/libvirt/qemu/nvram/fedora_VARS.fd +- +- +- +- +- +- +- +- +- +- destroy +- restart +- restart +- +- /usr/bin/qemu-system-x86_64 +- +- +- +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 5e16d7fd31..be8054fa6a 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -3095,7 +3095,6 @@ mymain(void) + DO_TEST_CAPS_LATEST("os-firmware-efi"); + DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); + DO_TEST_CAPS_LATEST("os-firmware-efi-no-enrolled-keys"); +- DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-invalid-type"); + DO_TEST_CAPS_ARCH_LATEST("aarch64-os-firmware-efi", "aarch64"); + + DO_TEST_CAPS_LATEST("vhost-user-vga"); +diff --git a/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml b/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml +index 3cac8fc5c6..1e51d55305 100644 +--- a/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml ++++ b/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml +@@ -6,7 +6,6 @@ + 1 + + hvm +- + /aarch64.kernel + /aarch64.initrd + earlyprintk console=ttyAMA0,115200n8 rw root=/dev/vda rootwait +diff --git a/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml +index ef24f2fece..60d3498765 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml +@@ -6,7 +6,6 @@ + 1 + + hvm +- + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml +index 3757191e8e..938da73711 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml +@@ -6,7 +6,6 @@ + 1 + + hvm +- + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml +index f2e6b7f36d..97ce8a75c7 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml +@@ -6,7 +6,6 @@ + 1 + + hvm +- + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/vmx2xmldata/vmx2xml-firmware-efi.xml b/tests/vmx2xmldata/vmx2xml-firmware-efi.xml +index 375c47d281..e21158cebf 100644 +--- a/tests/vmx2xmldata/vmx2xml-firmware-efi.xml ++++ b/tests/vmx2xmldata/vmx2xml-firmware-efi.xml +@@ -5,7 +5,6 @@ + 1 + + hvm +- + + + destroy +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-use-switch-in-virDomainDefParseBootOptions.patch b/SOURCES/libvirt-conf-use-switch-in-virDomainDefParseBootOptions.patch new file mode 100644 index 0000000..e4a8822 --- /dev/null +++ b/SOURCES/libvirt-conf-use-switch-in-virDomainDefParseBootOptions.patch @@ -0,0 +1,89 @@ +From 75470b7c297be9bdd712282b89c48465dbe8d400 Mon Sep 17 00:00:00 2001 +Message-Id: <75470b7c297be9bdd712282b89c48465dbe8d400@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:10 +0200 +Subject: [PATCH] conf: use switch in virDomainDefParseBootOptions + +The original code used a lot of conditions and was not that obvious +when each XML bits are parsed. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 6330be1ba3af5c4d2150fe2b831f7bc5d87c6d2a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <900c870b1720688123ed7b69850548ae308ea9a8.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 42 ++++++++++++++++++++++++++---------------- + 1 file changed, 26 insertions(+), 16 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index f8d8d33245..93a78f8277 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19483,33 +19483,43 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + * - An init script (exe) + */ + +- if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) { +- if (virDomainDefParseBootInitOptions(def, ctxt) < 0) +- return -1; +- } +- +- if (def->os.type == VIR_DOMAIN_OSTYPE_XEN || +- def->os.type == VIR_DOMAIN_OSTYPE_XENPVH || +- def->os.type == VIR_DOMAIN_OSTYPE_HVM || +- def->os.type == VIR_DOMAIN_OSTYPE_UML) { +- ++ switch ((virDomainOSType) def->os.type) { ++ case VIR_DOMAIN_OSTYPE_HVM: + virDomainDefParseBootKernelOptions(def, ctxt); + +- if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { +- if (virDomainDefParseBootFirmwareOptions(def, ctxt) < 0) +- return -1; +- } ++ if (virDomainDefParseBootFirmwareOptions(def, ctxt) < 0) ++ return -1; + + if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0) + return -1; +- } + +- if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { + if (virDomainDefParseBootAcpiOptions(def, ctxt) < 0) + return -1; + + if (virDomainDefParseBootXML(ctxt, def) < 0) + return -1; ++ ++ break; ++ ++ case VIR_DOMAIN_OSTYPE_XEN: ++ case VIR_DOMAIN_OSTYPE_XENPVH: ++ case VIR_DOMAIN_OSTYPE_UML: ++ virDomainDefParseBootKernelOptions(def, ctxt); ++ ++ if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0) ++ return -1; ++ ++ break; ++ ++ case VIR_DOMAIN_OSTYPE_EXE: ++ if (virDomainDefParseBootInitOptions(def, ctxt) < 0) ++ return -1; ++ ++ break; ++ ++ case VIR_DOMAIN_OSTYPE_LINUX: ++ case VIR_DOMAIN_OSTYPE_LAST: ++ break; + } + + return 0; +-- +2.31.1 + diff --git a/SOURCES/libvirt-docs-improve-description-of-secure-attribute-for-loader-element.patch b/SOURCES/libvirt-docs-improve-description-of-secure-attribute-for-loader-element.patch new file mode 100644 index 0000000..9114b14 --- /dev/null +++ b/SOURCES/libvirt-docs-improve-description-of-secure-attribute-for-loader-element.patch @@ -0,0 +1,47 @@ +From 3398815aa337278fe4085f06f3586b2a1a98ab3d Mon Sep 17 00:00:00 2001 +Message-Id: <3398815aa337278fe4085f06f3586b2a1a98ab3d@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:04 +0200 +Subject: [PATCH] docs: improve description of secure attribute for loader + element + +The original text was not explaining what this attribute actually +controls and could have been interpreted as a control switch for the +Secure boot feature in firmwares. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Kashyap Chamarthy +Reviewed-by: Michal Privoznik +(cherry picked from commit f47d06260b9698f705ab2c079c573f89f832e376) + +Conflicts: + docs/formatdomain.rst + - we still have formatdomain.html.in in downstream + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Michal Privoznik +--- + docs/formatdomain.html.in | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 7ac9523684..a40bed347b 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -197,7 +197,9 @@ + path points to an UEFI image, type should be + pflash. Moreover, some firmwares may + implement the Secure boot feature. Attribute +- secure can be used then to control it. ++ secure can be used to tell the hypervisor that the ++ firmware is capable of Secure Boot feature. It cannot be used to ++ enable or disable the feature itself in the firmware. + Since 2.1.0

+
nvram
+
Some UEFI firmwares may want to use a non-volatile memory to store +-- +2.31.1 + diff --git a/SOURCES/libvirt-domain_conf-Don-t-leak-def-os.firmwareFeatures.patch b/SOURCES/libvirt-domain_conf-Don-t-leak-def-os.firmwareFeatures.patch new file mode 100644 index 0000000..431bb2f --- /dev/null +++ b/SOURCES/libvirt-domain_conf-Don-t-leak-def-os.firmwareFeatures.patch @@ -0,0 +1,43 @@ +From 8ad6e3bc6d3e9e55093b546ee886a2a2d9e875f5 Mon Sep 17 00:00:00 2001 +Message-Id: <8ad6e3bc6d3e9e55093b546ee886a2a2d9e875f5@dist-git> +From: Michal Privoznik +Date: Fri, 21 May 2021 14:16:13 +0200 +Subject: [PATCH] domain_conf: Don't leak def->os.firmwareFeatures + +The firmwareFeatures member of virDomainOSDef struct is allocated +in virDomainDefParseBootFirmwareOptions() but never freed. + +Signed-off-by: Michal Privoznik +Reviewed-by: Pavel Hrdina +(cherry picked from commit c116b9481426f86188c71f340d5e3db103120bf8) + +Conflicts: + src/conf/domain_conf.c + - missing upstream commits: + 77f8e48fc35eaf867eae4f623e381f87f6e29930 + f9f81f1c8f855b8c21aeae4441abfc877ff2bfc3 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <82f4beea71e682c43ec10370d5a43a608d1cb411.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 28c8d0ecbd..2ffa9c8a2a 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -3431,6 +3431,7 @@ void virDomainDefFree(virDomainDefPtr def) + VIR_FREE(def->idmap.uidmap); + VIR_FREE(def->idmap.gidmap); + ++ VIR_FREE(def->os.firmwareFeatures); + VIR_FREE(def->os.machine); + VIR_FREE(def->os.init); + for (i = 0; def->os.initargv && def->os.initargv[i]; i++) +-- +2.31.1 + diff --git a/SOURCES/libvirt-hostdev-Update-mdev-pointer-reference-after-checking-device-type.patch b/SOURCES/libvirt-hostdev-Update-mdev-pointer-reference-after-checking-device-type.patch new file mode 100644 index 0000000..96deffe --- /dev/null +++ b/SOURCES/libvirt-hostdev-Update-mdev-pointer-reference-after-checking-device-type.patch @@ -0,0 +1,50 @@ +From bad40f7148a5849e84e9cdc341ff1fa03dc94fc6 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Thomas Huth +Date: Tue, 11 May 2021 14:10:27 +0200 +Subject: [PATCH] hostdev: Update mdev pointer reference after checking device + type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We set the pointer to some garbage packed structure data without +knowing whether we were actually handling the type of device we +expected to be handling. On its own, this was harmless, because we'd +never use the pointer as we'd skip the device if it were not the +expected type. However, it's better to make the logic even more +explicit - we first check the device and only when we're sure we have +the expected type we then update the pointer shortcut. + +Signed-off-by: Erik Skultety +Reviewed-by: Ján Tomko +(cherry picked from commit 964738cff3d949d90fc5c3317a2618fcd8d217b4) +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940449 +Signed-off-by: Thomas Huth +Message-Id: <20210511121028.304070-2-thuth@redhat.com> +Reviewed-by: Erik Skultety +--- + src/util/virhostdev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c +index 9596482146..b7050e99e4 100644 +--- a/src/util/virhostdev.c ++++ b/src/util/virhostdev.c +@@ -2030,11 +2030,11 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr, + virDomainHostdevSubsysMediatedDevPtr mdevsrc; + virDomainHostdevDefPtr hostdev = hostdevs[i]; + +- mdevsrc = &hostdev->source.subsys.u.mdev; +- + if (!virHostdevIsMdevDevice(hostdev)) + continue; + ++ mdevsrc = &hostdev->source.subsys.u.mdev; ++ + if (!(mdev = virMediatedDeviceNew(mdevsrc->uuidstr, + mdevsrc->model))) + continue; +-- +2.31.1 + diff --git a/SOURCES/libvirt-hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-mdev-struct.patch b/SOURCES/libvirt-hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-mdev-struct.patch new file mode 100644 index 0000000..3b68fb0 --- /dev/null +++ b/SOURCES/libvirt-hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-mdev-struct.patch @@ -0,0 +1,166 @@ +From 9e97e35031572e0f6ace32e2fb094f0f358f0391 Mon Sep 17 00:00:00 2001 +Message-Id: <9e97e35031572e0f6ace32e2fb094f0f358f0391@dist-git> +From: Thomas Huth +Date: Tue, 11 May 2021 14:10:28 +0200 +Subject: [PATCH] hostdev: mdev: Lookup mdevs by sysfs path rather than mdev + struct +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The lookup didn't do anything apart from comparing the sysfs paths +anyway since that's what makes each mdev unique. +The most ridiculous usage of the old logic was in +virHostdevReAttachMediatedDevices where in order to drop an mdev +hostdev from the list of active devices we first had to create a new +mdev and use it in the lookup call. Why couldn't we have used the +hostdev directly? Because the hostdev and mdev structures are +incompatible. + +The way mdevs are currently removed is via a write to a specific sysfs +attribute. If you do it while the machine which has the mdev assigned +is running, the write call may block (with a new enough kernel, with +older kernels it would return a write error!) until the device +is no longer in use which is when the QEMU process exits. + +The interesting part here comes afterwards when we're cleaning up and +call virHostdevReAttachMediatedDevices. The domain doesn't exist +anymore, so the list of active hostdevs needs to be updated and the +respective hostdevs removed from the list, but remember we had to +create an mdev object in the memory in order to find it in the list +first which will fail because the write to sysfs had already removed +the mdev instance from the host system. +And so the next time you try to start the same domain you'll get: + +"Requested operation is not valid: mediated device is in use by +driver QEMU, domain " + +Fixes: https://gitlab.com/libvirt/libvirt/-/issues/119 + +Signed-off-by: Erik Skultety +Reviewed-by: Ján Tomko +(cherry picked from commit 49cb59778a4e6c2d04bb9383a9d97fbbc83f9fce) +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940449 +Signed-off-by: Thomas Huth +Message-Id: <20210511121028.304070-3-thuth@redhat.com> +Reviewed-by: Erik Skultety +--- + src/util/virhostdev.c | 10 ++++------ + src/util/virmdev.c | 16 ++++++++-------- + src/util/virmdev.h | 4 ++-- + 3 files changed, 14 insertions(+), 16 deletions(-) + +diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c +index b7050e99e4..392e94307c 100644 +--- a/src/util/virhostdev.c ++++ b/src/util/virhostdev.c +@@ -2025,7 +2025,7 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr, + + virObjectLock(mgr->activeMediatedHostdevs); + for (i = 0; i < nhostdevs; i++) { +- g_autoptr(virMediatedDevice) mdev = NULL; ++ g_autofree char *sysfspath = NULL; + virMediatedDevicePtr tmp; + virDomainHostdevSubsysMediatedDevPtr mdevsrc; + virDomainHostdevDefPtr hostdev = hostdevs[i]; +@@ -2034,14 +2034,12 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr, + continue; + + mdevsrc = &hostdev->source.subsys.u.mdev; +- +- if (!(mdev = virMediatedDeviceNew(mdevsrc->uuidstr, +- mdevsrc->model))) +- continue; ++ sysfspath = virMediatedDeviceGetSysfsPath(mdevsrc->uuidstr); + + /* Remove from the list only mdevs assigned to @drv_name/@dom_name */ + +- tmp = virMediatedDeviceListFind(mgr->activeMediatedHostdevs, mdev); ++ tmp = virMediatedDeviceListFind(mgr->activeMediatedHostdevs, ++ sysfspath); + + /* skip inactive devices */ + if (!tmp) +diff --git a/src/util/virmdev.c b/src/util/virmdev.c +index c2499c0a20..bae4a7d2c1 100644 +--- a/src/util/virmdev.c ++++ b/src/util/virmdev.c +@@ -312,7 +312,7 @@ int + virMediatedDeviceListAdd(virMediatedDeviceListPtr list, + virMediatedDevicePtr *dev) + { +- if (virMediatedDeviceListFind(list, *dev)) { ++ if (virMediatedDeviceListFind(list, (*dev)->path)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("device %s is already in use"), (*dev)->path); + return -1; +@@ -358,7 +358,7 @@ virMediatedDevicePtr + virMediatedDeviceListSteal(virMediatedDeviceListPtr list, + virMediatedDevicePtr dev) + { +- int idx = virMediatedDeviceListFindIndex(list, dev); ++ int idx = virMediatedDeviceListFindIndex(list, dev->path); + + return virMediatedDeviceListStealIndex(list, idx); + } +@@ -374,13 +374,13 @@ virMediatedDeviceListDel(virMediatedDeviceListPtr list, + + int + virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev) ++ const char *sysfspath) + { + size_t i; + + for (i = 0; i < list->count; i++) { +- virMediatedDevicePtr other = list->devs[i]; +- if (STREQ(other->path, dev->path)) ++ virMediatedDevicePtr dev = list->devs[i]; ++ if (STREQ(sysfspath, dev->path)) + return i; + } + return -1; +@@ -389,11 +389,11 @@ virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list, + + virMediatedDevicePtr + virMediatedDeviceListFind(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev) ++ const char *sysfspath) + { + int idx; + +- if ((idx = virMediatedDeviceListFindIndex(list, dev)) >= 0) ++ if ((idx = virMediatedDeviceListFindIndex(list, sysfspath)) >= 0) + return list->devs[idx]; + else + return NULL; +@@ -407,7 +407,7 @@ virMediatedDeviceIsUsed(virMediatedDevicePtr dev, + const char *drvname, *domname; + virMediatedDevicePtr tmp = NULL; + +- if ((tmp = virMediatedDeviceListFind(list, dev))) { ++ if ((tmp = virMediatedDeviceListFind(list, dev->path))) { + virMediatedDeviceGetUsedBy(tmp, &drvname, &domname); + virReportError(VIR_ERR_OPERATION_INVALID, + _("mediated device %s is in use by " +diff --git a/src/util/virmdev.h b/src/util/virmdev.h +index e0905a3f6e..3022ab9948 100644 +--- a/src/util/virmdev.h ++++ b/src/util/virmdev.h +@@ -120,11 +120,11 @@ virMediatedDeviceListDel(virMediatedDeviceListPtr list, + + virMediatedDevicePtr + virMediatedDeviceListFind(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev); ++ const char *sysfspath); + + int + virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev); ++ const char *sysfspath); + + int + virMediatedDeviceListMarkDevices(virMediatedDeviceListPtr dst, +-- +2.31.1 + diff --git a/SOURCES/libvirt-network-force-re-creation-of-iptables-private-chains-on-firewalld-restart.patch b/SOURCES/libvirt-network-force-re-creation-of-iptables-private-chains-on-firewalld-restart.patch new file mode 100644 index 0000000..f35830d --- /dev/null +++ b/SOURCES/libvirt-network-force-re-creation-of-iptables-private-chains-on-firewalld-restart.patch @@ -0,0 +1,282 @@ +From 021167719bebe7fb7a0e366c371b6c7057ebed7e Mon Sep 17 00:00:00 2001 +Message-Id: <021167719bebe7fb7a0e366c371b6c7057ebed7e@dist-git> +From: Laine Stump +Date: Wed, 14 Apr 2021 23:25:34 -0400 +Subject: [PATCH] network: force re-creation of iptables private chains on + firewalld restart +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When firewalld is stopped, it removes *all* iptables rules and chains, +including those added by libvirt. Since restarting firewalld means +stopping and then starting it, any time it is restarted, libvirt needs +to recreate all the private iptables chains it uses, along with all +the rules it adds. + +We already have code in place to call networkReloadFirewallRules() any +time we're notified of a firewalld start, and +networkReloadFirewallRules() will call +networkPreReloadFirewallRules(), which calls +networkSetupPrivateChains(); unfortunately that last call is called +using virOnce(), meaning that it will only be called the first time +through networkPreReloadFirewallRules() after libvirtd starts - so of +course when firewalld is later restarted, the call to +networkSetupPrivateChains() is skipped. + +The neat and tidy way to fix this would be if there was a standard way +to reset a pthread_once_t object so that the next time virOnce was +called, it would think the function hadn't been called, and call it +again. Unfortunately, there isn't any official way of doing that (we +*could* just fill it with 0 and hope for the best, but that doesn't +seem very safe. + +So instead, this patch just adds a static variable called +chainInitDone, which is set to true after networkSetupPrivateChains() +is called for the first time, and then during calls to +networkPreReloadFirewallRules(), if chainInitDone is set, we call +networkSetupPrivateChains() directly instead of via virOnce(). + +It may seem unsafe to directly call a function that is meant to be +called only once, but I think in this case we're safe - there's +nothing in the function that is inherently "once only" - it doesn't +initialize anything that can't safely be re-initialized (as long as +two threads don't try to do it at the same time), and it only happens +when responding to a dbus message that firewalld has been started (and +I don't think it's possible for us to be processing two of those at +once), and even then only if the initial call to the function has +already been completed (so we're safe if we receive a firewalld +restart call at a time when we haven't yet called it, or even if +another thread is already in the process of executing it. The only +problematic bit I can think of is if another thread is in the process +of adding an iptable rule at the time we're executing this function, +but 1) none of those threads will be trying to add chains, and 2) if +there was a concurrency problem with other threads adding iptables +rules while firewalld was being restarted, it would still be a problem +even without this change. + +This is yet another patch that fixes an occurrence of this error: + +COMMAND_FAILED: '/usr/sbin/iptables -w10 -w --table filter --insert LIBVIRT_INP --in-interface virbr0 --protocol tcp --destination-port 67 --jump ACCEPT' failed: iptables: No chain/target/match by that name. + +Signed-off-by: Laine Stump +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit f5418b427e7d2f26803880309478de9103680826) + +https://bugzilla.redhat.com/1942805 +(cloned from the RHEL-AV version: https://bugzilla.redhat.com/1813830 ) + +Conflicts: + src/network/bridge_driver.c: + In one place a later commit was backported prior to this commit, + removing a VIR_DEBUG line and some { }. (see upstream commit + c102bbd3efc35, which was backported for + https://bugzilla.redhat.com/1607929 + +Signed-off-by: Laine Stump +Message-Id: <20210415032534.723202-3-laine@redhat.com> +Reviewed-by: Pavel Hrdina +--- + src/network/bridge_driver.c | 16 ++++--- + src/network/bridge_driver_linux.c | 69 ++++++++++++++++++---------- + src/network/bridge_driver_nop.c | 3 +- + src/network/bridge_driver_platform.h | 2 +- + 4 files changed, 58 insertions(+), 32 deletions(-) + +diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c +index 5995396f78..b8118067d1 100644 +--- a/src/network/bridge_driver.c ++++ b/src/network/bridge_driver.c +@@ -271,7 +271,9 @@ static int + networkShutdownNetworkExternal(virNetworkObjPtr obj); + + static void +-networkReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup); ++networkReloadFirewallRules(virNetworkDriverStatePtr driver, ++ bool startup, ++ bool force); + + static void + networkRefreshDaemons(virNetworkDriverStatePtr driver); +@@ -690,7 +692,7 @@ firewalld_dbus_filter_bridge(DBusConnection *connection G_GNUC_UNUSED, + } + + if (reload) +- networkReloadFirewallRules(driver, false); ++ networkReloadFirewallRules(driver, false, true); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } +@@ -791,7 +793,7 @@ networkStateInitialize(bool privileged, + virNetworkObjListPrune(network_driver->networks, + VIR_CONNECT_LIST_NETWORKS_INACTIVE | + VIR_CONNECT_LIST_NETWORKS_TRANSIENT); +- networkReloadFirewallRules(network_driver, true); ++ networkReloadFirewallRules(network_driver, true, false); + networkRefreshDaemons(network_driver); + + if (virDriverShouldAutostart(network_driver->stateDir, &autostart) < 0) +@@ -861,7 +863,7 @@ networkStateReload(void) + network_driver->networkConfigDir, + network_driver->networkAutostartDir, + network_driver->xmlopt); +- networkReloadFirewallRules(network_driver, false); ++ networkReloadFirewallRules(network_driver, false, false); + networkRefreshDaemons(network_driver); + virNetworkObjListForEach(network_driver->networks, + networkAutostartConfig, +@@ -2229,14 +2231,16 @@ networkReloadFirewallRulesHelper(virNetworkObjPtr obj, + + + static void +-networkReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup) ++networkReloadFirewallRules(virNetworkDriverStatePtr driver, ++ bool startup, ++ bool force) + { + VIR_INFO("Reloading iptables rules"); + /* Ideally we'd not even register the driver when unprivilegd + * but until we untangle the virt driver that's not viable */ + if (!driver->privileged) + return; +- networkPreReloadFirewallRules(driver, startup); ++ networkPreReloadFirewallRules(driver, startup, force); + virNetworkObjListForEach(driver->networks, + networkReloadFirewallRulesHelper, + NULL); +diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c +index b6b324d1d5..f707bf8e47 100644 +--- a/src/network/bridge_driver_linux.c ++++ b/src/network/bridge_driver_linux.c +@@ -36,11 +36,14 @@ VIR_LOG_INIT("network.bridge_driver_linux"); + #define PROC_NET_ROUTE "/proc/net/route" + + static virOnceControl createdOnce; +-static bool createdChains; ++static bool chainInitDone; /* true iff networkSetupPrivateChains was ever called */ ++static bool createdChains; /* true iff networkSetupPrivateChains created chains during most recent call */ + static virErrorPtr errInitV4; + static virErrorPtr errInitV6; + +-/* Only call via virOnce */ ++/* Usually only called via virOnce, but can also be called directly in ++ * response to firewalld reload (if chainInitDone == true) ++ */ + static void networkSetupPrivateChains(void) + { + int rc; +@@ -82,6 +85,8 @@ static void networkSetupPrivateChains(void) + VIR_DEBUG("Global IPv6 chains already exist"); + } + } ++ ++ chainInitDone = true; + } + + +@@ -111,7 +116,10 @@ networkHasRunningNetworks(virNetworkDriverStatePtr driver) + } + + +-void networkPreReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup) ++void ++networkPreReloadFirewallRules(virNetworkDriverStatePtr driver, ++ bool startup, ++ bool force) + { + /* + * If there are any running networks, we need to +@@ -130,29 +138,42 @@ void networkPreReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup + * of starting the network though as that makes them + * more likely to be seen by a human + */ +- if (!networkHasRunningNetworks(driver)) { +- VIR_DEBUG("Delayed global rule setup as no networks are running"); +- return; +- } ++ if (chainInitDone && force) { ++ /* The Private chains have already been initialized once ++ * during this run of libvirtd, so 1) we can't do it again via ++ * virOnce(), and 2) we need to re-add the private chains even ++ * if there are currently no running networks, because the ++ * next time a network is started, libvirt will expect that ++ * the chains have already been added. So we call directly ++ * instead of via virOnce(). ++ */ ++ networkSetupPrivateChains(); + +- ignore_value(virOnce(&createdOnce, networkSetupPrivateChains)); ++ } else { ++ if (!networkHasRunningNetworks(driver)) { ++ VIR_DEBUG("Delayed global rule setup as no networks are running"); ++ return; ++ } + +- /* +- * If this is initial startup, and we just created the +- * top level private chains we either +- * +- * - upgraded from old libvirt +- * - freshly booted from clean state +- * +- * In the first case we must delete the old rules from +- * the built-in chains, instead of our new private chains. +- * In the second case it doesn't matter, since no existing +- * rules will be present. Thus we can safely just tell it +- * to always delete from the builin chain +- */ +- if (startup && createdChains) { +- VIR_DEBUG("Requesting cleanup of legacy firewall rules"); +- iptablesSetDeletePrivate(false); ++ ignore_value(virOnce(&createdOnce, networkSetupPrivateChains)); ++ ++ /* ++ * If this is initial startup, and we just created the ++ * top level private chains we either ++ * ++ * - upgraded from old libvirt ++ * - freshly booted from clean state ++ * ++ * In the first case we must delete the old rules from ++ * the built-in chains, instead of our new private chains. ++ * In the second case it doesn't matter, since no existing ++ * rules will be present. Thus we can safely just tell it ++ * to always delete from the builin chain ++ */ ++ if (startup && createdChains) { ++ VIR_DEBUG("Requesting cleanup of legacy firewall rules"); ++ iptablesSetDeletePrivate(false); ++ } + } + } + +diff --git a/src/network/bridge_driver_nop.c b/src/network/bridge_driver_nop.c +index 08d737511f..db89c10023 100644 +--- a/src/network/bridge_driver_nop.c ++++ b/src/network/bridge_driver_nop.c +@@ -20,7 +20,8 @@ + #include + + void networkPreReloadFirewallRules(virNetworkDriverStatePtr driver G_GNUC_UNUSED, +- bool startup G_GNUC_UNUSED) ++ bool startup G_GNUC_UNUSED, ++ bool force G_GNUC_UNUSED) + { + } + +diff --git a/src/network/bridge_driver_platform.h b/src/network/bridge_driver_platform.h +index 169417a6c0..48ab52c160 100644 +--- a/src/network/bridge_driver_platform.h ++++ b/src/network/bridge_driver_platform.h +@@ -62,7 +62,7 @@ struct _virNetworkDriverState { + typedef struct _virNetworkDriverState virNetworkDriverState; + typedef virNetworkDriverState *virNetworkDriverStatePtr; + +-void networkPreReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup); ++void networkPreReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup, bool force); + void networkPostReloadFirewallRules(bool startup); + + int networkCheckRouteCollision(virNetworkDefPtr def); +-- +2.31.1 + diff --git a/SOURCES/libvirt-network-make-it-safe-to-call-networkSetupPrivateChains-multiple-times.patch b/SOURCES/libvirt-network-make-it-safe-to-call-networkSetupPrivateChains-multiple-times.patch new file mode 100644 index 0000000..b07b70d --- /dev/null +++ b/SOURCES/libvirt-network-make-it-safe-to-call-networkSetupPrivateChains-multiple-times.patch @@ -0,0 +1,65 @@ +From 4792bd80c542f7af373bc939492017bd420a3f3b Mon Sep 17 00:00:00 2001 +Message-Id: <4792bd80c542f7af373bc939492017bd420a3f3b@dist-git> +From: Laine Stump +Date: Wed, 14 Apr 2021 23:25:33 -0400 +Subject: [PATCH] network: make it safe to call networkSetupPrivateChains() + multiple times +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +networkSetupPrivateChains() is currently called only once per run of +libvirtd, so it can assume that errInitV4 and errInitV6 are empty/null +when it is called. In preparation for potentially calling this +function multiple times during one run, this patch moves the reset of +errInitV[46] to the top of the function, to assure no memory is +leaked. + +Signed-off-by: Laine Stump +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit de110f110fb917a31b9f33ad8e4b3c1d3284766a) + +https://bugzilla.redhat.com/1942805 + +Message-Id: <20210415032534.723202-2-laine@redhat.com> +Reviewed-by: Pavel Hrdina +--- + src/network/bridge_driver_linux.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c +index 9de8e93c60..b6b324d1d5 100644 +--- a/src/network/bridge_driver_linux.c ++++ b/src/network/bridge_driver_linux.c +@@ -48,6 +48,10 @@ static void networkSetupPrivateChains(void) + VIR_DEBUG("Setting up global firewall chains"); + + createdChains = false; ++ virFreeError(errInitV4); ++ errInitV4 = NULL; ++ virFreeError(errInitV6); ++ errInitV6 = NULL; + + rc = iptablesSetupPrivateChains(VIR_FIREWALL_LAYER_IPV4); + if (rc < 0) { +@@ -56,8 +60,6 @@ static void networkSetupPrivateChains(void) + errInitV4 = virSaveLastError(); + virResetLastError(); + } else { +- virFreeError(errInitV4); +- errInitV4 = NULL; + if (rc) { + VIR_DEBUG("Created global IPv4 chains"); + createdChains = true; +@@ -73,8 +75,6 @@ static void networkSetupPrivateChains(void) + errInitV6 = virSaveLastError(); + virResetLastError(); + } else { +- virFreeError(errInitV6); +- errInitV6 = NULL; + if (rc) { + VIR_DEBUG("Created global IPv6 chains"); + createdChains = true; +-- +2.31.1 + diff --git a/SOURCES/libvirt-qemu-implement-support-for-firmware-auto-selection-feature-filtering.patch b/SOURCES/libvirt-qemu-implement-support-for-firmware-auto-selection-feature-filtering.patch new file mode 100644 index 0000000..f780cd6 --- /dev/null +++ b/SOURCES/libvirt-qemu-implement-support-for-firmware-auto-selection-feature-filtering.patch @@ -0,0 +1,248 @@ +From d1c5d166a891a2abf408a5879b95bded23b45825 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:12 +0200 +Subject: [PATCH] qemu: implement support for firmware auto-selection feature + filtering + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit c91fa273062ec388385bf8cc081117c78c2f7af5) + +Conflicts: + tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.args + - missing upstream commits: + d96fb5cb31b870e1539bd8ee95fb27dbe461a357 + 43c9c0859f2d53321ccc646ab905beec0740490b + 88957116c9d3cb4705380c3702c9d4315fb500bb + + tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml + - missing upstream commits: + e88367095f3cad2cf80a687fd599dfaeb3073841 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Michal Privoznik +--- + src/qemu/qemu_firmware.c | 40 +++++++++++++++ + ...re-efi-no-enrolled-keys.x86_64-latest.args | 47 ++++++++++++++++++ + .../os-firmware-efi-no-enrolled-keys.xml | 49 +++++++++++++++++++ + tests/qemuxml2argvtest.c | 1 + + ...are-efi-no-enrolled-keys.x86_64-latest.xml | 1 + + tests/qemuxml2xmltest.c | 1 + + 6 files changed, 139 insertions(+) + create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.args + create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml + create mode 120000 tests/qemuxml2xmloutdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.xml + +diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c +index 8ef515ca57..e875e355c7 100644 +--- a/src/qemu/qemu_firmware.c ++++ b/src/qemu/qemu_firmware.c +@@ -952,6 +952,10 @@ qemuFirmwareMatchDomain(const virDomainDef *def, + bool supportsS4 = false; + bool requiresSMM = false; + bool supportsSEV = false; ++ bool supportsSecureBoot = false; ++ bool hasEnrolledKeys = false; ++ int reqSecureBoot; ++ int reqEnrolledKeys; + + want = qemuFirmwareOSInterfaceTypeFromOsDefFirmware(def->os.firmware); + +@@ -1001,7 +1005,13 @@ qemuFirmwareMatchDomain(const virDomainDef *def, + break; + + case QEMU_FIRMWARE_FEATURE_SECURE_BOOT: ++ supportsSecureBoot = true; ++ break; ++ + case QEMU_FIRMWARE_FEATURE_ENROLLED_KEYS: ++ hasEnrolledKeys = true; ++ break; ++ + case QEMU_FIRMWARE_FEATURE_VERBOSE_DYNAMIC: + case QEMU_FIRMWARE_FEATURE_VERBOSE_STATIC: + case QEMU_FIRMWARE_FEATURE_NONE: +@@ -1022,6 +1032,36 @@ qemuFirmwareMatchDomain(const virDomainDef *def, + return false; + } + ++ if (def->os.firmwareFeatures) { ++ reqSecureBoot = def->os.firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_SECURE_BOOT]; ++ if (reqSecureBoot != VIR_TRISTATE_BOOL_ABSENT) { ++ if (reqSecureBoot == VIR_TRISTATE_BOOL_YES && !supportsSecureBoot) { ++ VIR_DEBUG("User requested Secure Boot, firmware '%s' doesn't support it", ++ path); ++ return false; ++ } ++ ++ if (reqSecureBoot == VIR_TRISTATE_BOOL_NO && supportsSecureBoot) { ++ VIR_DEBUG("User refused Secure Boot, firmware '%s' supports it", path); ++ return false; ++ } ++ } ++ ++ reqEnrolledKeys = def->os.firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_ENROLLED_KEYS]; ++ if (reqEnrolledKeys != VIR_TRISTATE_BOOL_ABSENT) { ++ if (reqEnrolledKeys == VIR_TRISTATE_BOOL_YES && !hasEnrolledKeys) { ++ VIR_DEBUG("User requested Enrolled keys, firmware '%s' doesn't have them", ++ path); ++ return false; ++ } ++ ++ if (reqEnrolledKeys == VIR_TRISTATE_BOOL_NO && hasEnrolledKeys) { ++ VIR_DEBUG("User refused Enrolled keys, firmware '%s' has them", path); ++ return false; ++ } ++ } ++ } ++ + if (def->os.loader && + def->os.loader->secure == VIR_TRISTATE_BOOL_YES && + !requiresSMM) { +diff --git a/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.args b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.args +new file mode 100644 +index 0000000000..c3c838fb1a +--- /dev/null ++++ b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.args +@@ -0,0 +1,47 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/tmp/lib/domain--1-fedora \ ++USER=test \ ++LOGNAME=test \ ++XDG_DATA_HOME=/tmp/lib/domain--1-fedora/.local/share \ ++XDG_CACHE_HOME=/tmp/lib/domain--1-fedora/.cache \ ++XDG_CONFIG_HOME=/tmp/lib/domain--1-fedora/.config \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-x86_64 \ ++-name guest=fedora,debug-threads=on \ ++-S \ ++-object secret,id=masterKey0,format=raw,\ ++file=/tmp/lib/domain--1-fedora/master-key.aes \ ++-blockdev '{"driver":"file","filename":"/usr/share/OVMF/OVMF_CODE.fd",\ ++"node-name":"libvirt-pflash0-storage","auto-read-only":true,\ ++"discard":"unmap"}' \ ++-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,\ ++"driver":"raw","file":"libvirt-pflash0-storage"}' \ ++-blockdev '{"driver":"file",\ ++"filename":"/var/lib/libvirt/qemu/nvram/fedora_VARS.fd",\ ++"node-name":"libvirt-pflash1-storage","auto-read-only":true,\ ++"discard":"unmap"}' \ ++-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,\ ++"driver":"raw","file":"libvirt-pflash1-storage"}' \ ++-machine pc-q35-4.0,accel=kvm,usb=off,dump-guest-core=off,\ ++pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format \ ++-cpu qemu64 \ ++-m 8 \ ++-overcommit mem-lock=off \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,fd=1729,server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot strict=on \ ++-device pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ ++addr=0x1 \ ++-device pcie-root-port,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ ++-device qemu-xhci,id=usb,bus=pci.1,addr=0x0 \ ++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ ++resourcecontrol=deny \ ++-msg timestamp=on +diff --git a/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml +new file mode 100644 +index 0000000000..7f8f57a859 +--- /dev/null ++++ b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml +@@ -0,0 +1,49 @@ ++ ++ fedora ++ 63840878-0deb-4095-97e6-fc444d9bc9fa ++ 8192 ++ 8192 ++ 1 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ qemu64 ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ ++ ++
++ ++ ++ ++ ++
++ ++ ++
++ ++ ++
++ ++ ++ ++ ++ ++ +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index bc04bea692..5e16d7fd31 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -3094,6 +3094,7 @@ mymain(void) + DO_TEST_CAPS_LATEST("os-firmware-bios"); + DO_TEST_CAPS_LATEST("os-firmware-efi"); + DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); ++ DO_TEST_CAPS_LATEST("os-firmware-efi-no-enrolled-keys"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-invalid-type"); + DO_TEST_CAPS_ARCH_LATEST("aarch64-os-firmware-efi", "aarch64"); + +diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.xml +new file mode 120000 +index 0000000000..902ccb783b +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.xml +@@ -0,0 +1 @@ ++../qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml +\ No newline at end of file +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index 461b5bc68f..9e5747290a 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -1122,6 +1122,7 @@ mymain(void) + DO_TEST_CAPS_LATEST("os-firmware-bios"); + DO_TEST_CAPS_LATEST("os-firmware-efi"); + DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); ++ DO_TEST_CAPS_LATEST("os-firmware-efi-no-enrolled-keys"); + + DO_TEST("aarch64-aavmf-virtio-mmio", + QEMU_CAPS_DEVICE_VIRTIO_MMIO, +-- +2.31.1 + diff --git a/SOURCES/libvirt-qemu_firmware-don-t-error-out-for-unknown-firmware-features.patch b/SOURCES/libvirt-qemu_firmware-don-t-error-out-for-unknown-firmware-features.patch new file mode 100644 index 0000000..6cab919 --- /dev/null +++ b/SOURCES/libvirt-qemu_firmware-don-t-error-out-for-unknown-firmware-features.patch @@ -0,0 +1,68 @@ +From c8ede44db2e94444e5a8ee38e21eda2b42717879 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Tue, 18 May 2021 15:03:02 +0200 +Subject: [PATCH] qemu_firmware: don't error out for unknown firmware features +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When QEMU introduces new firmware features libvirt will fail until we +list that feature in our code as well which doesn't sound right. + +We should simply ignore the new feature until we add a proper support +for it. + +Reported-by: Laszlo Ersek +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 61d95a1073833ec4323c1ef28e71e913c55aa7b9) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1961562 + +Signed-off-by: Pavel Hrdina +Message-Id: <8989d70d49d8a720532a8c25e3e73d9b3bf2a495.1621342722.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/qemu/qemu_firmware.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c +index c84d03f0a8..8ef515ca57 100644 +--- a/src/qemu/qemu_firmware.c ++++ b/src/qemu/qemu_firmware.c +@@ -570,6 +570,7 @@ qemuFirmwareFeatureParse(const char *path, + virJSONValuePtr featuresJSON; + g_autoptr(qemuFirmwareFeature) features = NULL; + size_t nfeatures; ++ size_t nparsed = 0; + size_t i; + + if (!(featuresJSON = virJSONValueObjectGetArray(doc, "features"))) { +@@ -590,17 +591,16 @@ qemuFirmwareFeatureParse(const char *path, + int tmp; + + if ((tmp = qemuFirmwareFeatureTypeFromString(tmpStr)) <= 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("unknown feature %s"), +- tmpStr); +- return -1; ++ VIR_DEBUG("ignoring unknown QEMU firmware feature '%s'", tmpStr); ++ continue; + } + +- features[i] = tmp; ++ features[nparsed] = tmp; ++ nparsed++; + } + + fw->features = g_steal_pointer(&features); +- fw->nfeatures = nfeatures; ++ fw->nfeatures = nparsed; + return 0; + } + +-- +2.31.1 + diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index e3acab3..ea3958c 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -219,7 +219,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.0.0 -Release: 35%{?dist}%{?extra_release} +Release: 36%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -754,6 +754,22 @@ Patch522: libvirt-cpumap-Add-support-for-svme-addr-check-CPU-feature.patch Patch523: libvirt-cpu_map-Add-EPYC-Milan-x86-CPU-model.patch Patch524: libvirt-cpu_map-Install-x86_EPYC-Milan.xml.patch Patch525: libvirt-cpu_map-Fix-spelling-of-svme-addr-chk-feature.patch +Patch526: libvirt-network-make-it-safe-to-call-networkSetupPrivateChains-multiple-times.patch +Patch527: libvirt-network-force-re-creation-of-iptables-private-chains-on-firewalld-restart.patch +Patch528: libvirt-hostdev-Update-mdev-pointer-reference-after-checking-device-type.patch +Patch529: libvirt-hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-mdev-struct.patch +Patch530: libvirt-qemu_firmware-don-t-error-out-for-unknown-firmware-features.patch +Patch531: libvirt-docs-improve-description-of-secure-attribute-for-loader-element.patch +Patch532: libvirt-conf-introduce-virDomainDefParseBootInitOptions.patch +Patch533: libvirt-conf-introduce-virDomainDefParseBootKernelOptions.patch +Patch534: libvirt-conf-introduce-virDomainDefParseBootFirmwareOptions.patch +Patch535: libvirt-conf-introduce-virDomainDefParseBootLoaderOptions.patch +Patch536: libvirt-conf-introduce-virDomainDefParseBootAcpiOptions.patch +Patch537: libvirt-conf-use-switch-in-virDomainDefParseBootOptions.patch +Patch538: libvirt-conf-introduce-support-for-firmware-auto-selection-feature-filtering.patch +Patch539: libvirt-qemu-implement-support-for-firmware-auto-selection-feature-filtering.patch +Patch540: libvirt-domain_conf-Don-t-leak-def-os.firmwareFeatures.patch +Patch541: libvirt-conf-remove-duplicated-firmware-type-attribute.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2530,6 +2546,24 @@ exit 0 %changelog +* Tue Jun 1 2021 Jiri Denemark - 6.0.0-36 +- network: make it safe to call networkSetupPrivateChains() multiple times (rhbz#1942805) +- network: force re-creation of iptables private chains on firewalld restart (rhbz#1942805) +- hostdev: Update mdev pointer reference after checking device type (rhbz#1940449) +- hostdev: mdev: Lookup mdevs by sysfs path rather than mdev struct (rhbz#1940449) +- qemu_firmware: don't error out for unknown firmware features (rhbz#1961562) +- docs: improve description of secure attribute for loader element (rhbz#1929357) +- conf: introduce virDomainDefParseBootInitOptions (rhbz#1929357) +- conf: introduce virDomainDefParseBootKernelOptions (rhbz#1929357) +- conf: introduce virDomainDefParseBootFirmwareOptions (rhbz#1929357) +- conf: introduce virDomainDefParseBootLoaderOptions (rhbz#1929357) +- conf: introduce virDomainDefParseBootAcpiOptions (rhbz#1929357) +- conf: use switch in virDomainDefParseBootOptions (rhbz#1929357) +- conf: introduce support for firmware auto-selection feature filtering (rhbz#1929357) +- qemu: implement support for firmware auto-selection feature filtering (rhbz#1929357) +- domain_conf: Don't leak def->os.firmwareFeatures (rhbz#1929357) +- conf: remove duplicated firmware type attribute (rhbz#1929357) + * Thu Mar 4 2021 Jiri Denemark - 6.0.0-35 - vircgroupv2: properly detect placement of running VM (rhbz#1798463) - virsystemd: export virSystemdHasMachined (rhbz#1798463)