On 10/4/24 9:32 AM, marcandre.lureau(a)redhat.com wrote:
From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
Learn to parse a file path for the TPM state.
Signed-off-by: Marc-André Lureau <marcandre.lureau(a)redhat.com>
---
docs/formatdomain.rst | 19 ++++++++++++++
src/conf/domain_conf.c | 28 +++++++++++++++++++++
src/conf/domain_conf.h | 9 +++++++
src/conf/schemas/domaincommon.rng | 14 +++++++++++
tests/qemuxmlconfdata/tpm-emulator-tpm2.xml | 1 +
5 files changed, 71 insertions(+)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 4336cff3ac..992bb98730 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -8173,6 +8173,25 @@ Example: usage of the TPM Emulator
The default version used depends on the combination of hypervisor, guest
architecture, TPM model and backend.
+``source``
+ The ``source`` element specifies the location of the TPM state storage . This
+ element only works with the ``emulator`` backend.
+
+ If not specified, the storage configuration is left to libvirt discretion.
+
+ This element requires that swtpm v0.7 or later is installed.
+
+ The following attributes are supported:
+
+ ``type``
+ The type of storage. It's possible to provide "file" to utilize a
single
+ file or block device where the TPM state will be stored.
+
+ ``path``
+ The path to the TPM state storage.
The file backend of swtpm does not do the locking similar to what the
dir backend does because those who added the file backend didn't
need/want it. If we now give full control to the path of the TPM state
file to the user via the domain XML then whose fault is it if two VMs
use the same path to a file backend and stomp on the TPM state file? Is
it the fault of the user because of how he defined the path in the XMLs?
+
+ :since:`Since v10.8.0`
+
> ``persistent_state``
> The ``persistent_state`` attribute indicates whether 'swtpm' TPM state
is
> kept or not when a transient domain is powered off or undefined. This
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 284a3815b3..9dd8b6b55d 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -1322,6 +1322,12 @@ VIR_ENUM_IMPL(virDomainTPMVersion,
> "2.0",
> );
>
> +VIR_ENUM_IMPL(virDomainTPMSourceType,
> + VIR_DOMAIN_TPM_SOURCE_TYPE_LAST,
> + "default",
> + "file",
> +);
> +
> VIR_ENUM_IMPL(virDomainTPMPcrBank,
> VIR_DOMAIN_TPM_PCR_BANK_LAST,
> "sha1",
> @@ -10784,6 +10790,7 @@ virDomainTPMDefParseXML(virDomainXMLOption *xmlopt,
> int nbackends;
> int nnodes;
> size_t i;
> + xmlNodePtr source_node = NULL;
> g_autofree char *path = NULL;
> g_autofree char *secretuuid = NULL;
> g_autofree char *persistent_state = NULL;
> @@ -10857,6 +10864,22 @@ virDomainTPMDefParseXML(virDomainXMLOption *xmlopt,
> def->data.emulator.hassecretuuid = true;
> }
>
> + source_node = virXPathNode("./backend/source", ctxt);
> + if (source_node) {
> + if (virXMLPropEnum(source_node, "type",
> + virDomainTPMSourceTypeTypeFromString,
> + VIR_XML_PROP_NONZERO,
> + &def->data.emulator.source_type) < 0)
> + goto error;
> + path = virXMLPropString(source_node, "path");
> + if (!path) {
> + virReportError(VIR_ERR_XML_ERROR, "%s",
> + _("missing TPM source path"));
> + goto error;
> + }
> + def->data.emulator.source_path = g_steal_pointer(&path);
> + }
> +
> persistent_state = virXMLPropString(backends[0],
"persistent_state");
> if (persistent_state) {
> if (virStringParseYesNo(persistent_state,
> @@ -25070,6 +25093,11 @@ virDomainTPMDefFormat(virBuffer *buf,
>
> virXMLFormatElement(&backendChildBuf, "active_pcr_banks",
NULL, &activePcrBanksBuf);
> }
> + if (def->data.emulator.source_type != VIR_DOMAIN_TPM_SOURCE_TYPE_DEFAULT)
{
> + virBufferAsprintf(&backendChildBuf, "<source
type='%s'",
> +
virDomainTPMSourceTypeTypeToString(def->data.emulator.source_type));
> + virBufferEscapeString(&backendChildBuf, "
path='%s'/>\n", def->data.emulator.source_path);
> + }
> break;
> case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
> if (def->data.external.source->type == VIR_DOMAIN_CHR_TYPE_UNIX) {
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 6b27322e3e..7a70f68177 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -1463,6 +1463,13 @@ typedef enum {
> VIR_DOMAIN_TPM_PCR_BANK_LAST
> } virDomainPcrBank;
>
> +typedef enum {
> + VIR_DOMAIN_TPM_SOURCE_TYPE_DEFAULT = 0,
> + VIR_DOMAIN_TPM_SOURCE_TYPE_FILE,
> +
> + VIR_DOMAIN_TPM_SOURCE_TYPE_LAST
> +} virDomainTPMSourceType;
> +
> #define VIR_DOMAIN_TPM_DEFAULT_DEVICE "/dev/tpm0"
>
> struct _virDomainTPMDef {
> @@ -1478,6 +1485,7 @@ struct _virDomainTPMDef {
> struct {
> virDomainTPMVersion version;
> virDomainChrSourceDef *source;
> + virDomainTPMSourceType source_type;
> char *source_path;
> char *logfile;
> unsigned int debug;
> @@ -4277,6 +4285,7 @@ VIR_ENUM_DECL(virDomainRNGBackend);
> VIR_ENUM_DECL(virDomainTPMModel);
> VIR_ENUM_DECL(virDomainTPMBackend);
> VIR_ENUM_DECL(virDomainTPMVersion);
> +VIR_ENUM_DECL(virDomainTPMSourceType);
> VIR_ENUM_DECL(virDomainTPMPcrBank);
> VIR_ENUM_DECL(virDomainMemoryModel);
> VIR_ENUM_DECL(virDomainMemoryBackingModel);
> diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
> index efb5f00d77..72c8b6c694 100644
> --- a/src/conf/schemas/domaincommon.rng
> +++ b/src/conf/schemas/domaincommon.rng
> @@ -5923,6 +5923,7 @@
> <interleave>
> <ref name="tpm-backend-emulator-encryption"/>
> <ref name="tpm-backend-emulator-active-pcr-banks"/>
> + <ref name="tpm-backend-emulator-source"/>
> </interleave>
> <optional>
> <attribute name="persistent_state">
> @@ -5981,6 +5982,19 @@
> </optional>
> </define>
>
> + <define name="tpm-backend-emulator-source">
> + <optional>
> + <element name="source">
> + <attribute name="type">
> + <value>file</value>
> + </attribute>
> + <attribute name="path">
> + <ref name="filePath"/>
> + </attribute>
> + </element>
> + </optional>
> + </define>
> +
> <define name="tpm-backend-emulator-encryption">
> <optional>
> <element name="encryption">
> diff --git a/tests/qemuxmlconfdata/tpm-emulator-tpm2.xml
b/tests/qemuxmlconfdata/tpm-emulator-tpm2.xml
> index 8a613db456..3d6300f544 100644
> --- a/tests/qemuxmlconfdata/tpm-emulator-tpm2.xml
> +++ b/tests/qemuxmlconfdata/tpm-emulator-tpm2.xml
> @@ -34,6 +34,7 @@
> <sha256/>
> <sha512/>
> </active_pcr_banks>
> + <source type='file' path='/path/to/state'/>
> </backend>
> </tpm>
> <audio id='1' type='none'/>