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@xxxxxxxxxxxxx> --- 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