On 9/10/24 3:05 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>
Reviewed-by: Stefan Berger <stefanb(a)linux.ibm.com>
> ---
> docs/formatdomain.rst | 15 +++++++++++++++
> src/conf/domain_conf.c | 21 +++++++++++++++++++++
> src/conf/domain_conf.h | 6 ++++++
> src/conf/schemas/domaincommon.rng | 11 +++++++++++
> tests/qemuxmlconfdata/tpm-emulator-tpm2.xml | 1 +
> 5 files changed, 54 insertions(+)
>
> diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
> index 47d3e2125e..4818113bc2 100644
> --- a/docs/formatdomain.rst
> +++ b/docs/formatdomain.rst
> @@ -8170,6 +8170,21 @@ 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.
> +
> + The following attributes are supported:
> +
> + ``path``
> + The path to the TPM state storage file.
> +
> + This attribute requires that swtpm v0.7 or later is installed.
> +
> + :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 a263612ef7..18c58d16dc 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -10789,6 +10789,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;
> @@ -10862,6 +10863,18 @@ virDomainTPMDefParseXML(virDomainXMLOption *xmlopt,
> def->data.emulator.hassecretuuid = true;
> }
>
> + source_node = virXPathNode("./backend/source", ctxt);
> + if (source_node) {
> + path = virXMLPropString(source_node, "file");
> + if (!path) {
> + virReportError(VIR_ERR_XML_ERROR, "%s",
> + _("missing TPM file source"));
> + goto error;
> + }
> + def->data.emulator.storage_type = VIR_DOMAIN_TPM_STORAGE_FILE;
> + def->data.emulator.storagepath = g_steal_pointer(&path);
> + }
> +
> persistent_state = virXMLPropString(backends[0],
"persistent_state");
> if (persistent_state) {
> if (virStringParseYesNo(persistent_state,
> @@ -25066,6 +25079,14 @@ virDomainTPMDefFormat(virBuffer *buf,
>
> virXMLFormatElement(&backendChildBuf, "active_pcr_banks",
NULL, &activePcrBanksBuf);
> }
> + switch (def->data.emulator.storage_type) {
> + case VIR_DOMAIN_TPM_STORAGE_FILE:
> + virBufferAsprintf(&backendChildBuf, "<source
file='%s'/>\n",
> + def->data.emulator.storagepath);
> + break;
> + case VIR_DOMAIN_TPM_STORAGE_DEFAULT:
> + break;
> + }
> 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 659299bdd1..371e6ecf6c 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -1463,6 +1463,11 @@ typedef enum {
> VIR_DOMAIN_TPM_PCR_BANK_LAST
> } virDomainPcrBank;
>
> +typedef enum {
> + VIR_DOMAIN_TPM_STORAGE_DEFAULT,
> + VIR_DOMAIN_TPM_STORAGE_FILE,
> +} virDomainTPMStorage;
> +
> #define VIR_DOMAIN_TPM_DEFAULT_DEVICE "/dev/tpm0"
>
> struct _virDomainTPMDef {
> @@ -1478,6 +1483,7 @@ struct _virDomainTPMDef {
> struct {
> virDomainTPMVersion version;
> virDomainChrSourceDef *source;
> + virDomainTPMStorage storage_type;
> char *storagepath;
> char *logfile;
> unsigned int debug;
> diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
> index efb5f00d77..62d3f0e6fe 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,16 @@
> </optional>
> </define>
>
> + <define name="tpm-backend-emulator-source">
> + <optional>
> + <element name="source">
> + <attribute name="file">
> + <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..4c61e2645b 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 file='/path/to/state'/>
> </backend>
> </tpm>
> <audio id='1' type='none'/>