[PATCH v2 2/4] schema: add TPM emulator <source file='..'>

marcandre.lureau@redhat.com posted 4 patches 1 year, 5 months ago
[PATCH v2 2/4] schema: add TPM emulator <source file='..'>
Posted by marcandre.lureau@redhat.com 1 year, 5 months ago
From: Marc-André Lureau <marcandre.lureau@redhat.com>

Learn to parse a file path for the TPM state.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.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'/>
-- 
2.45.2.827.g557ae147e6
Re: [PATCH v2 2/4] schema: add TPM emulator <source file='..'>
Posted by Martin Kletzander 1 year, 4 months ago
On Tue, Sep 10, 2024 at 11:05:58AM +0400, marcandre.lureau@redhat.com wrote:
>From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
>Learn to parse a file path for the TPM state.
>
>Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.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``

You name it "path" here, but everywhere below it is a "file".
Re: [PATCH v2 2/4] schema: add TPM emulator <source file='..'>
Posted by Marc-André Lureau 1 year, 4 months ago
On Wed, Oct 2, 2024 at 11:18 AM Martin Kletzander <mkletzan@redhat.com> wrote:
>
> On Tue, Sep 10, 2024 at 11:05:58AM +0400, marcandre.lureau@redhat.com wrote:
> >From: Marc-André Lureau <marcandre.lureau@redhat.com>
> >
> >Learn to parse a file path for the TPM state.
> >
> >Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.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``
>
> You name it "path" here, but everywhere below it is a "file".

good catch, fixed
Re: [PATCH v2 2/4] schema: add TPM emulator <source file='..'>
Posted by Stefan Berger 1 year, 4 months ago

On 9/10/24 3:05 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Learn to parse a file path for the TPM state.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Stefan Berger <stefanb@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'/>