import libvirt-6.0.0-36.module+el8.5.0+11222+c889b3f3

This commit is contained in:
CentOS Sources 2021-06-08 16:41:57 +00:00 committed by Andrew Lukoshko
parent cf63038957
commit 3ab7f95023
17 changed files with 2365 additions and 1 deletions

View File

@ -0,0 +1,415 @@
From 6f02748897062d40b411177ef752644505189a72 Mon Sep 17 00:00:00 2001
Message-Id: <6f02748897062d40b411177ef752644505189a72@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
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 <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(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 <phrdina@redhat.com>
Message-Id: <631e05bc5363abb3e48d8b652a806324801cce16.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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 @@
<code>ESX</code> and <code>VMWare</code> hypervisor drivers, however,
the <code>i686</code> arch will always be chosen even on an
<code>x86_64</code> host. <span class="since">Since 0.0.1</span></dd>
+ <dt><a id="elementFirmware"><code>firmware</code></a></dt>
+ <dd>
+ <p><span class="since">Since 7.2.0 QEMU/KVM only</span></p>
+ <p>
+ When used together with <code>firmware</code> attribute of
+ <code>os</code> element the <code>type</code> attribute must
+ have the same value.
+ </p>
+ <p>
+ List of mandatory attributes:
+ <ul>
+ <li>
+ <code>type</code> (accepted values are <code>bios</code>
+ and <code>efi</code>) same as the <code>firmware</code>
+ attribute of <code>os</code> element.
+ </li>
+ </ul>
+ </p>
+ <p>
+ 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
+ <code>feature</code> elements. Libvirt will take into consideration
+ only the listed features and ignore the rest when selecting the firmware.
+
+ <dl>
+ <dt><code>feature</code></dt>
+ <dd>
+ The list of mandatory attributes:
+
+ <ul>
+ <li>
+ <code>enabled</code> (accepted values are <code>yes</code>
+ and <code>no</code>) is used to tell libvirt if the feature
+ must be enabled or not in the automatically selected firmware
+ </li>
+ <li>
+ <code>name</code> the name of the feature, the list of the features:
+ <ul>
+ <li>
+ <code>enrolled-keys</code> 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.
+ </li>
+ <li>
+ <code>secure-boot</code> whether the firmware implements
+ UEFI Secure boot feature.
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </dd>
+ </dl>
+ </p>
+ </dd>
<dt><a id="elementLoader"><code>loader</code></a></dt>
<dd>The optional <code>loader</code> 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 @@
</attribute>
</optional>
<ref name="ostypehvm"/>
+ <optional>
+ <element name="firmware">
+ <attribute name="type">
+ <choice>
+ <value>bios</value>
+ <value>efi</value>
+ </choice>
+ </attribute>
+ <zeroOrMore>
+ <element name="feature">
+ <attribute name="enabled">
+ <ref name="virYesNo"/>
+ </attribute>
+ <attribute name="name">
+ <choice>
+ <value>enrolled-keys</value>
+ <value>secure-boot</value>
+ </choice>
+ </attribute>
+ </element>
+ </zeroOrMore>
+ </element>
+ </optional>
<optional>
<element name="loader">
<optional>
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
* <mirror> 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</type>\n",
virDomainOSTypeToString(def->os.type));
+ if (def->os.firmware) {
+ virBufferAsprintf(buf, "<firmware type='%s'",
+ virDomainOsDefFirmwareTypeToString(def->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, "<feature enabled='%s' name='%s'/>\n",
+ virTristateBoolTypeToString(def->os.firmwareFeatures[i]),
+ virDomainOsDefFirmwareFeatureTypeToString(i));
+ }
+
+ virBufferAdjustIndent(buf, -2);
+
+ virBufferAddLit(buf, "</firmware>\n");
+ } else {
+ virBufferAddLit(buf, "/>\n");
+ }
+ }
+
virBufferEscapeString(buf, "<init>%s</init>\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 @@
+<domain type='kvm'>
+ <name>fedora</name>
+ <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
+ <memory unit='KiB'>8192</memory>
+ <currentMemory unit='KiB'>8192</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os firmware='efi'>
+ <type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
+ <firmware type='bios'/>
+ <loader secure='no'/>
+ <nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram>
+ <boot dev='hd'/>
+ <bootmenu enable='yes'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <memballoon model='none'/>
+ </devices>
+</domain>
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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='efi'>
<type arch='aarch64' machine='virt-4.0'>hvm</type>
+ <firmware type='efi'/>
<kernel>/aarch64.kernel</kernel>
<initrd>/aarch64.initrd</initrd>
<cmdline>earlyprintk console=ttyAMA0,115200n8 rw root=/dev/vda rootwait</cmdline>
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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='bios'>
<type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
+ <firmware type='bios'/>
<loader secure='no'/>
<nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram>
<boot dev='hd'/>
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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='efi'>
<type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
+ <firmware type='efi'/>
<loader secure='yes'/>
<nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram>
<boot dev='hd'/>
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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='efi'>
<type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
+ <firmware type='efi'/>
<loader secure='no'/>
<nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram>
<boot dev='hd'/>
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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='efi'>
<type arch='i686'>hvm</type>
+ <firmware type='efi'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
--
2.31.1

View File

@ -0,0 +1,124 @@
From 7ba2905bfcab4dbe4a491ee8587dd4c9ef457c0b Mon Sep 17 00:00:00 2001
Message-Id: <7ba2905bfcab4dbe4a491ee8587dd4c9ef457c0b@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
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 <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(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 <phrdina@redhat.com>
Message-Id: <5fb7ee0165340ff517b3f7f16ddc542813ac385d.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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

View File

@ -0,0 +1,86 @@
From 2a019bfa26e697c60893afd09fcc2f0c3218691b Mon Sep 17 00:00:00 2001
Message-Id: <2a019bfa26e697c60893afd09fcc2f0c3218691b@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
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 <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit bcf97abfc6b45694f0d789ae2bdf87c8d082fddf)
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Message-Id: <9a090d9f2a43b261ed1b6db608779a01a7594f4a.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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

View File

@ -0,0 +1,173 @@
From adafaa880b67f1025c64515352e5e851daa62ae9 Mon Sep 17 00:00:00 2001
Message-Id: <adafaa880b67f1025c64515352e5e851daa62ae9@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
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 <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(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 <phrdina@redhat.com>
Message-Id: <cb7f11437bdbc14b0791645c39c963118d0f9806.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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 <initarg> 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 <initenv> 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 <initarg> 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 <initenv name='%s'> 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 <initenv> element"));
- return -1;
- }
- if (!nodes[i]->children ||
- !nodes[i]->children->content) {
- virReportError(VIR_ERR_XML_ERROR,
- _("No value supplied for <initenv name='%s'> 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

View File

@ -0,0 +1,60 @@
From a62075772680bd30ced25d7177048ab26db8ea09 Mon Sep 17 00:00:00 2001
Message-Id: <a62075772680bd30ced25d7177048ab26db8ea09@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
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 <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit bf9b3f8e573092cc98ea647f25cf116e22bbfe3c)
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Message-Id: <936428a5fa6d4104361ac8080639a55111c14965.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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

View File

@ -0,0 +1,97 @@
From 6891ef941e693d86ebbab9e529e908dacf4a7dc6 Mon Sep 17 00:00:00 2001
Message-Id: <6891ef941e693d86ebbab9e529e908dacf4a7dc6@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
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 <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(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 <phrdina@redhat.com>
Message-Id: <e9d0f563b055b415deb7718d33f7661a797a48f1.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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

View File

@ -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?= <berrange@redhat.com>
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
<os firmware='efi'>
<firmware type='efi'>
<feature enabled='no' name='enrolled-keys'/>
</firmware>
</os>
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:
<os firmware='efi'>
<firmware>
<feature enabled='no' name='enrolled-keys'/>
</firmware>
</os>
which also means that we don't need to emit the empty element
<firmware type='efi'/> for all existing configs too.
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(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 <phrdina@redhat.com>
Message-Id: <299fd16fc3ce632bf25ca55cc4bb65a225437d61.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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 @@
<dt><a id="elementFirmware"><code>firmware</code></a></dt>
<dd>
<p><span class="since">Since 7.2.0 QEMU/KVM only</span></p>
- <p>
- When used together with <code>firmware</code> attribute of
- <code>os</code> element the <code>type</code> attribute must
- have the same value.
- </p>
- <p>
- List of mandatory attributes:
- <ul>
- <li>
- <code>type</code> (accepted values are <code>bios</code>
- and <code>efi</code>) same as the <code>firmware</code>
- attribute of <code>os</code> element.
- </li>
- </ul>
- </p>
<p>
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 @@
<ref name="ostypehvm"/>
<optional>
<element name="firmware">
- <attribute name="type">
- <choice>
- <value>bios</value>
- <value>efi</value>
- </choice>
- </attribute>
- <zeroOrMore>
+ <oneOrMore>
<element name="feature">
<attribute name="enabled">
<ref name="virYesNo"/>
@@ -288,7 +282,7 @@
</choice>
</attribute>
</element>
- </zeroOrMore>
+ </oneOrMore>
</element>
</optional>
<optional>
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</type>\n",
virDomainOSTypeToString(def->os.type));
- if (def->os.firmware) {
- virBufferAsprintf(buf, "<firmware type='%s'",
- virDomainOsDefFirmwareTypeToString(def->os.firmware));
-
- if (def->os.firmwareFeatures) {
- virBufferAddLit(buf, ">\n");
-
- virBufferAdjustIndent(buf, 2);
+ if (def->os.firmwareFeatures) {
+ virBufferAddLit(buf, "<firmware>\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, "<feature enabled='%s' name='%s'/>\n",
- virTristateBoolTypeToString(def->os.firmwareFeatures[i]),
- virDomainOsDefFirmwareFeatureTypeToString(i));
- }
+ virBufferAsprintf(buf, "<feature enabled='%s' name='%s'/>\n",
+ virTristateBoolTypeToString(def->os.firmwareFeatures[i]),
+ virDomainOsDefFirmwareFeatureTypeToString(i));
+ }
- virBufferAdjustIndent(buf, -2);
+ virBufferAdjustIndent(buf, -2);
- virBufferAddLit(buf, "</firmware>\n");
- } else {
- virBufferAddLit(buf, "/>\n");
- }
+ virBufferAddLit(buf, "</firmware>\n");
}
virBufferEscapeString(buf, "<init>%s</init>\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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='efi'>
<type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
- <firmware type='efi'>
+ <firmware>
<feature enabled='no' name='enrolled-keys'/>
</firmware>
<boot dev='hd'/>
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 @@
-<domain type='kvm'>
- <name>fedora</name>
- <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
- <memory unit='KiB'>8192</memory>
- <currentMemory unit='KiB'>8192</currentMemory>
- <vcpu placement='static'>1</vcpu>
- <os firmware='efi'>
- <type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
- <firmware type='bios'/>
- <loader secure='no'/>
- <nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram>
- <boot dev='hd'/>
- <bootmenu enable='yes'/>
- </os>
- <features>
- <acpi/>
- <apic/>
- <pae/>
- </features>
- <clock offset='utc'/>
- <on_poweroff>destroy</on_poweroff>
- <on_reboot>restart</on_reboot>
- <on_crash>restart</on_crash>
- <devices>
- <emulator>/usr/bin/qemu-system-x86_64</emulator>
- <memballoon model='none'/>
- </devices>
-</domain>
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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='efi'>
<type arch='aarch64' machine='virt-4.0'>hvm</type>
- <firmware type='efi'/>
<kernel>/aarch64.kernel</kernel>
<initrd>/aarch64.initrd</initrd>
<cmdline>earlyprintk console=ttyAMA0,115200n8 rw root=/dev/vda rootwait</cmdline>
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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='bios'>
<type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
- <firmware type='bios'/>
<loader secure='no'/>
<nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram>
<boot dev='hd'/>
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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='efi'>
<type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
- <firmware type='efi'/>
<loader secure='yes'/>
<nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram>
<boot dev='hd'/>
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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='efi'>
<type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
- <firmware type='efi'/>
<loader secure='no'/>
<nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram>
<boot dev='hd'/>
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 @@
<vcpu placement='static'>1</vcpu>
<os firmware='efi'>
<type arch='i686'>hvm</type>
- <firmware type='efi'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
--
2.31.1

View File

@ -0,0 +1,89 @@
From 75470b7c297be9bdd712282b89c48465dbe8d400 Mon Sep 17 00:00:00 2001
Message-Id: <75470b7c297be9bdd712282b89c48465dbe8d400@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
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 <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 6330be1ba3af5c4d2150fe2b831f7bc5d87c6d2a)
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Message-Id: <900c870b1720688123ed7b69850548ae308ea9a8.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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

View File

@ -0,0 +1,47 @@
From 3398815aa337278fe4085f06f3586b2a1a98ab3d Mon Sep 17 00:00:00 2001
Message-Id: <3398815aa337278fe4085f06f3586b2a1a98ab3d@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
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 <phrdina@redhat.com>
Reviewed-by: Kashyap Chamarthy <kchamart@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(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 <phrdina@redhat.com>
Message-Id: <e2c4f2faa7f2a525b4d3ea5608a1b305cf18712b.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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, <code>type</code> should be
<code>pflash</code>. Moreover, some firmwares may
implement the Secure boot feature. Attribute
- <code>secure</code> can be used then to control it.
+ <code>secure</code> 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.
<span class="since">Since 2.1.0</span></dd>
<dt><code>nvram</code></dt>
<dd>Some UEFI firmwares may want to use a non-volatile memory to store
--
2.31.1

View File

@ -0,0 +1,43 @@
From 8ad6e3bc6d3e9e55093b546ee886a2a2d9e875f5 Mon Sep 17 00:00:00 2001
Message-Id: <8ad6e3bc6d3e9e55093b546ee886a2a2d9e875f5@dist-git>
From: Michal Privoznik <mprivozn@redhat.com>
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 <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(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 <phrdina@redhat.com>
Message-Id: <82f4beea71e682c43ec10370d5a43a608d1cb411.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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

View File

@ -0,0 +1,50 @@
From bad40f7148a5849e84e9cdc341ff1fa03dc94fc6 Mon Sep 17 00:00:00 2001
Message-Id: <bad40f7148a5849e84e9cdc341ff1fa03dc94fc6@dist-git>
From: Thomas Huth <thuth@redhat.com>
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 <eskultet@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 964738cff3d949d90fc5c3317a2618fcd8d217b4)
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940449
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210511121028.304070-2-thuth@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
---
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

View File

@ -0,0 +1,166 @@
From 9e97e35031572e0f6ace32e2fb094f0f358f0391 Mon Sep 17 00:00:00 2001
Message-Id: <9e97e35031572e0f6ace32e2fb094f0f358f0391@dist-git>
From: Thomas Huth <thuth@redhat.com>
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 <path> is in use by
driver QEMU, domain <name>"
Fixes: https://gitlab.com/libvirt/libvirt/-/issues/119
Signed-off-by: Erik Skultety <eskultet@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 49cb59778a4e6c2d04bb9383a9d97fbbc83f9fce)
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940449
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210511121028.304070-3-thuth@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
---
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

View File

@ -0,0 +1,282 @@
From 021167719bebe7fb7a0e366c371b6c7057ebed7e Mon Sep 17 00:00:00 2001
Message-Id: <021167719bebe7fb7a0e366c371b6c7057ebed7e@dist-git>
From: Laine Stump <laine@redhat.com>
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 <laine@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(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 <laine@redhat.com>
Message-Id: <20210415032534.723202-3-laine@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
---
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 <config.h>
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

View File

@ -0,0 +1,65 @@
From 4792bd80c542f7af373bc939492017bd420a3f3b Mon Sep 17 00:00:00 2001
Message-Id: <4792bd80c542f7af373bc939492017bd420a3f3b@dist-git>
From: Laine Stump <laine@redhat.com>
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 <laine@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit de110f110fb917a31b9f33ad8e4b3c1d3284766a)
https://bugzilla.redhat.com/1942805
Message-Id: <20210415032534.723202-2-laine@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
---
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

View File

@ -0,0 +1,248 @@
From d1c5d166a891a2abf408a5879b95bded23b45825 Mon Sep 17 00:00:00 2001
Message-Id: <d1c5d166a891a2abf408a5879b95bded23b45825@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
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 <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(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 <phrdina@redhat.com>
Message-Id: <de1971688ed4bf1556d669973e60de6e3c76b4c1.1621599207.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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 @@
+<domain type='kvm'>
+ <name>fedora</name>
+ <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
+ <memory unit='KiB'>8192</memory>
+ <currentMemory unit='KiB'>8192</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os firmware='efi'>
+ <type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
+ <firmware type='efi'>
+ <feature enabled='no' name='enrolled-keys'/>
+ </firmware>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='1' port='0x8'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='2' port='0x9'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='qemu-xhci'>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
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

View File

@ -0,0 +1,68 @@
From c8ede44db2e94444e5a8ee38e21eda2b42717879 Mon Sep 17 00:00:00 2001
Message-Id: <c8ede44db2e94444e5a8ee38e21eda2b42717879@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
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 <lersek@redhat.com>
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 61d95a1073833ec4323c1ef28e71e913c55aa7b9)
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1961562
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Message-Id: <8989d70d49d8a720532a8c25e3e73d9b3bf2a495.1621342722.git.phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
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

View File

@ -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 <jdenemar@redhat.com> - 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 <jdenemar@redhat.com> - 6.0.0-35
- vircgroupv2: properly detect placement of running VM (rhbz#1798463)
- virsystemd: export virSystemdHasMachined (rhbz#1798463)