From nobody Mon Feb 9 01:47:26 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1551950999894313.7445680239464; Thu, 7 Mar 2019 01:29:59 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9AFF381E15; Thu, 7 Mar 2019 09:29:57 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 71AC21001E6A; Thu, 7 Mar 2019 09:29:57 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 368483FA4C; Thu, 7 Mar 2019 09:29:57 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x279TafC009383 for ; Thu, 7 Mar 2019 04:29:36 -0500 Received: by smtp.corp.redhat.com (Postfix) id 503771AC1A; Thu, 7 Mar 2019 09:29:36 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.30]) by smtp.corp.redhat.com (Postfix) with ESMTP id A00DC5C5FD; Thu, 7 Mar 2019 09:29:35 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Thu, 7 Mar 2019 10:29:16 +0100 Message-Id: <93e18048e2771f65052d58ded644679bfdc24004.1551950609.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Cc: lersek@redhat.com Subject: [libvirt] [PATCH v2 06/15] conf: Introduce firmware attribute to X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 07 Mar 2019 09:29:58 +0000 (UTC) Content-Type: text/plain; charset="utf-8" The idea is that using this attribute users enable libvirt to automagically select firmware image for their domain. For instance: hvm hvm (The automagic of selecting firmware image will be described in later commits.) Accepted values are 'bios' and 'efi' to let libvirt select corresponding type of firmware. I know it is a good sign to introduce xml2xml test case when changing XML config parser but that will have to come later. Firmware auto selection is not enabled for any driver just yet so any xml2xml test would fail right away. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 --- docs/formatdomain.html.in | 22 +++++++++- docs/schemas/domaincommon.rng | 8 ++++ src/conf/domain_conf.c | 75 ++++++++++++++++++++++++++++------- src/conf/domain_conf.h | 12 ++++++ src/libvirt_private.syms | 2 + 5 files changed, 103 insertions(+), 16 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index eb00c01d96..fedca0eedc 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -128,7 +128,7 @@ =20
 ...
-<os>
+<os firmware=3D'uefi'>
   <type>hvm</type>
   <loader readonly=3D'yes' secure=3D'no' type=3D'rom'>/usr/lib/xen/b=
oot/hvmloader</loader>
   <nvram template=3D'/usr/share/OVMF/OVMF_VARS.fd'>/var/lib/libvirt/=
nvram/guest_VARS.fd</nvram>
@@ -141,6 +141,26 @@
 ...
=20
+
firmware
+
The firmware attribute allows management + applications to automatically fill <loader/> + and <nvram/> elements and possibly enable + some features required by selected firmware. Accepted values are + bios and efi.
+ The selection process scans for files describing installed + firmware images in specified location and uses the most specific + one which fulfils domain requirements. The locations in order of + preference (from generic to most specific one) are: +
    +
  • /usr/share/qemu/firmware
  • +
  • /etc/qemu/firmware
  • +
  • $XDG_CONFIG_HOME/qemu/firmware
  • +
+ For more information refer to firmware metadata specification as + described in docs/interop/firmware.json in QEMU + repository. Regular users do not need to bother. + Since 5.2.0 (QEMU and KVM only) +
type
The content of the type element specifies the type of operating system to be booted in the virtual machine. diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index c8d63c4912..87ba9daeda 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -256,6 +256,14 @@ + + + + bios + efi + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fbfdd57224..f92ebeb892 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1079,6 +1079,13 @@ VIR_ENUM_IMPL(virDomainHPTResizing, "required", ); =20 +VIR_ENUM_IMPL(virDomainOsDefFirmware, + VIR_DOMAIN_OS_DEF_FIRMWARE_LAST, + "none", + "bios", + "efi", +); + /* Internal mapping: subset of block job types that can be present in * XML (remaining types are not two-phase). */ VIR_ENUM_DECL(virDomainBlockJob); @@ -6608,14 +6615,23 @@ virDomainDefMemtuneValidate(const virDomainDef *def) =20 =20 static int -virDomainDefOSValidate(const virDomainDef *def) +virDomainDefOSValidate(const virDomainDef *def, + virDomainXMLOptionPtr xmlopt) { if (!def->os.loader) return 0; =20 - if (!def->os.loader->path) { + if (def->os.firmware && + !(xmlopt->config.features & VIR_DOMAIN_DEF_FEATURE_FW_AUTOSELECT))= { virReportError(VIR_ERR_XML_DETAIL, "%s", - _("no loader path specified")); + _("firmware auto selection not implemented for this= driver")); + return -1; + } + + if (!def->os.loader->path && + def->os.firmware =3D=3D VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("no loader path specified and firmware auto selec= tion disabled")); return -1; } =20 @@ -6624,7 +6640,8 @@ virDomainDefOSValidate(const virDomainDef *def) =20 =20 static int -virDomainDefValidateInternal(const virDomainDef *def) +virDomainDefValidateInternal(const virDomainDef *def, + virDomainXMLOptionPtr xmlopt) { if (virDomainDefCheckDuplicateDiskInfo(def) < 0) return -1; @@ -6661,7 +6678,7 @@ virDomainDefValidateInternal(const virDomainDef *def) if (virDomainDefMemtuneValidate(def) < 0) return -1; =20 - if (virDomainDefOSValidate(def) < 0) + if (virDomainDefOSValidate(def, xmlopt) < 0) return -1; =20 return 0; @@ -6712,7 +6729,7 @@ virDomainDefValidate(virDomainDefPtr def, &data) < 0) return -1; =20 - if (virDomainDefValidateInternal(def) < 0) + if (virDomainDefValidateInternal(def, xmlopt) < 0) return -1; =20 return 0; @@ -18271,19 +18288,22 @@ virDomainDefMaybeAddHostdevSCSIcontroller(virDoma= inDefPtr def) =20 static int virDomainLoaderDefParseXML(xmlNodePtr node, - virDomainLoaderDefPtr loader) + virDomainLoaderDefPtr loader, + bool fwAutoSelect) { VIR_AUTOFREE(char *) readonly_str =3D NULL; VIR_AUTOFREE(char *) secure_str =3D NULL; VIR_AUTOFREE(char *) type_str =3D NULL; =20 - readonly_str =3D virXMLPropString(node, "readonly"); secure_str =3D virXMLPropString(node, "secure"); - type_str =3D virXMLPropString(node, "type"); - loader->path =3D (char *) xmlNodeGetContent(node); =20 - if (STREQ_NULLABLE(loader->path, "")) - VIR_FREE(loader->path); + if (!fwAutoSelect) { + readonly_str =3D virXMLPropString(node, "readonly"); + type_str =3D virXMLPropString(node, "type"); + loader->path =3D (char *) xmlNodeGetContent(node); + if (STREQ_NULLABLE(loader->path, "")) + VIR_FREE(loader->path); + } =20 if (readonly_str && (loader->readonly =3D virTristateBoolTypeFromString(readonly_str))= <=3D 0) { @@ -18678,6 +18698,7 @@ virDomainDefParseBootOptions(virDomainDefPtr def, def->os.type =3D=3D VIR_DOMAIN_OSTYPE_XENPVH || def->os.type =3D=3D VIR_DOMAIN_OSTYPE_HVM || def->os.type =3D=3D VIR_DOMAIN_OSTYPE_UML) { + VIR_AUTOFREE(char *) firmware =3D NULL; xmlNodePtr loader_node; =20 def->os.kernel =3D virXPathString("string(./os/kernel[1])", ctxt); @@ -18685,15 +18706,35 @@ virDomainDefParseBootOptions(virDomainDefPtr def, def->os.cmdline =3D virXPathString("string(./os/cmdline[1])", ctxt= ); def->os.dtb =3D virXPathString("string(./os/dtb[1])", ctxt); def->os.root =3D virXPathString("string(./os/root[1])", ctxt); + + if (def->os.type =3D=3D VIR_DOMAIN_OSTYPE_HVM && + (firmware =3D virXPathString("string(./os/@firmware)", ctxt)))= { + int fw =3D virDomainOsDefFirmwareTypeFromString(firmware); + + if (fw <=3D 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown firmware value %s"), + firmware); + return -1; + } + + def->os.firmware =3D fw; + } + if ((loader_node =3D virXPathNode("./os/loader[1]", ctxt))) { + const bool fwAutoSelect =3D def->os.firmware !=3D VIR_DOMAIN_O= S_DEF_FIRMWARE_NONE; + if (VIR_ALLOC(def->os.loader) < 0) return -1; =20 - if (virDomainLoaderDefParseXML(loader_node, def->os.loader) < = 0) + if (virDomainLoaderDefParseXML(loader_node, + def->os.loader, + fwAutoSelect) < 0) return -1; =20 def->os.loader->nvram =3D virXPathString("string(./os/nvram[1]= )", ctxt); - def->os.loader->templt =3D virXPathString("string(./os/nvram[1= ]/@template)", ctxt); + if (!fwAutoSelect) + def->os.loader->templt =3D virXPathString("string(./os/nvr= am[1]/@template)", ctxt); } } =20 @@ -28082,7 +28123,11 @@ virDomainDefFormatInternal(virDomainDefPtr def, def->os.bootloaderArgs); } =20 - virBufferAddLit(buf, "\n"); + virBufferAddLit(buf, "os.firmware) + virBufferAsprintf(buf, " firmware=3D'%s'", + virDomainOsDefFirmwareTypeToString(def->os.firmw= are)); + virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); virBufferAddLit(buf, "os.arch) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ed5d00c399..fe9d4fb81a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2005,10 +2005,21 @@ struct _virDomainOSEnv { char *value; }; =20 +typedef enum { + VIR_DOMAIN_OS_DEF_FIRMWARE_NONE =3D 0, + VIR_DOMAIN_OS_DEF_FIRMWARE_BIOS, + VIR_DOMAIN_OS_DEF_FIRMWARE_EFI, + + VIR_DOMAIN_OS_DEF_FIRMWARE_LAST +} virDomainOsDefFirmware; + +VIR_ENUM_DECL(virDomainOsDefFirmware); + typedef struct _virDomainOSDef virDomainOSDef; typedef virDomainOSDef *virDomainOSDefPtr; struct _virDomainOSDef { int type; + virDomainOsDefFirmware firmware; virArch arch; char *machine; size_t nBootDevs; @@ -2729,6 +2740,7 @@ typedef enum { VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS =3D (1 << 4), VIR_DOMAIN_DEF_FEATURE_USER_ALIAS =3D (1 << 5), VIR_DOMAIN_DEF_FEATURE_NO_BOOT_ORDER =3D (1 << 6), + VIR_DOMAIN_DEF_FEATURE_FW_AUTOSELECT =3D (1 << 7), } virDomainDefFeatures; =20 =20 diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d2a240fc7a..e8bb0d8bc4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -509,6 +509,8 @@ virDomainObjTaint; virDomainObjUpdateModificationImpact; virDomainObjWait; virDomainObjWaitUntil; +virDomainOsDefFirmwareTypeFromString; +virDomainOsDefFirmwareTypeToString; virDomainOSTypeFromString; virDomainOSTypeToString; virDomainParseMemory; --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list