Extend the domain XML with a 'shared_storage' attribute for the TPM to
support migration when the TPM's state directory is setup as shared
storage between hosts. Document the shared_storage attribute.
For libvirt to be able to correctly handle migration and the removal and
security-labeling of TPM state files, it is necessary that the domain XML
indicates whether shared stored has been set up for TPM state files. If
shared storage is used the TPM domain XML must indicate this as follows:
<tpm model='tpm-crb'>
<backend type='emulator' version='2.0'
shared_storage='yes'/>
</tpm>
Signed-off-by: Stefan Berger <stefanb(a)linux.ibm.com>
---
docs/formatdomain.rst | 16 ++++++++++++++++
src/conf/domain_conf.c | 13 +++++++++++++
src/conf/schemas/domaincommon.rng | 5 +++++
3 files changed, 34 insertions(+)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 212104fe1f..f6eb126617 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -7775,6 +7775,22 @@ Example: usage of the TPM Emulator
This attribute only works with the ``emulator`` backend. The accepted values
are ``yes`` and ``no``. :since:`Since 7.0.0`
+``shared_storage``
+ The ``shared_storage`` attribute indicates whether shared storage is
+ setup for storing 'swtpm' TPM state. It must be set to ``yes`` if shared
+ storage is used and must be omitted or set to ``no`` otherwise. The
+ default value is ``no``. This attribute is important for migrating
+ 'swtpm' state between hosts and managing the TPM state files.
+ :since:`Since 8.8.0`
+
+ Note: All hosts sharing the storage must be configured to run swtpm
+ with the same account (see ``swtpm_user`` and ``swtpm_group`` in qemu.conf).
+ Further, any Linux security module used for file labeling, such as SELinux,
+ must be supported by the shared storage technology and be the same on all
+ hosts or otherwise may need to be turned off. For example, when NFS is used
+ for shared storage, SELinux must be turned off or put into permissive mode
+ since sVirt's MLS range labeling is not supported by NFS.
+
``active_pcr_banks``
The ``active_pcr_banks`` node is used to define which of the PCR banks
of a TPM 2.0 to activate. Valid names are for example sha1, sha256, sha384,
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2fc94b40ef..9de23d6530 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -10418,6 +10418,7 @@ virDomainTPMDefParseXML(virDomainXMLOption *xmlopt,
g_autofree char *path = NULL;
g_autofree char *secretuuid = NULL;
g_autofree char *persistent_state = NULL;
+ g_autofree char *shared_storage = NULL;
g_autofree xmlNodePtr *backends = NULL;
g_autofree xmlNodePtr *nodes = NULL;
int bank;
@@ -10492,6 +10493,16 @@ virDomainTPMDefParseXML(virDomainXMLOption *xmlopt,
}
}
+ shared_storage = virXMLPropString(backends[0], "shared_storage");
+ if (shared_storage) {
+ if (virStringParseYesNo(shared_storage,
+ &def->data.emulator.shared_storage) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Invalid shared_storage value, either 'yes'
or 'no'"));
+ goto error;
+ }
+ }
+
if ((nnodes = virXPathNodeSet("./backend/active_pcr_banks/*", ctxt,
&nodes)) < 0)
break;
if (nnodes > 0)
@@ -24301,6 +24312,8 @@ virDomainTPMDefFormat(virBuffer *buf,
}
if (def->data.emulator.persistent_state)
virBufferAddLit(&backendAttrBuf, "
persistent_state='yes'");
+ if (def->data.emulator.shared_storage)
+ virBufferAddLit(&backendAttrBuf, "
shared_storage='yes'");
if (def->data.emulator.hassecretuuid) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 7f6ea1d888..27000670b1 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -5541,6 +5541,11 @@
<ref name="virYesNo"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="shared_storage">
+ <ref name="virYesNo"/>
+ </attribute>
+ </optional>
</group>
</choice>
<optional>
--
2.37.1