From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
When swtpm reports "nvram-backend-dir", it can accepts a single file or
block device where TPM state will be stored. --tpmstate must be
backend-uri=file://<path>.
Signed-off-by: Marc-André Lureau <marcandre.lureau(a)redhat.com>
---
src/qemu/qemu_tpm.c | 74 +++++++++++++++++++++++++++++++++++++--------
1 file changed, 61 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c
index 2f17918cbb..b69706ccc0 100644
--- a/src/qemu/qemu_tpm.c
+++ b/src/qemu/qemu_tpm.c
@@ -340,9 +340,27 @@ qemuTPMVirCommandAddEncryption(virCommand *cmd,
}
+static char *
+qemuTPMGetSwtpmSetupStateArg(const virDomainTPMStorage storage_type,
+ const char *storagepath)
+{
+ switch (storage_type) {
+ case VIR_DOMAIN_TPM_STORAGE_FILE:
+ /* the file:// prefix is supported since swtpm_setup 0.7.0 */
+ /* assume the capability check for swtpm is redundant. */
+ return g_strdup_printf("file://%s", storagepath);
+ case VIR_DOMAIN_TPM_STORAGE_DEFAULT:
+ return g_strdup_printf("%s", storagepath);
+ }
+
+ return NULL;
+}
+
+
/*
* qemuTPMEmulatorRunSetup
*
+ * @storage_type: type of storage
* @storagepath: path to the directory for TPM state
* @vmname: the name of the VM
* @vmuuid: the UUID of the VM
@@ -360,7 +378,8 @@ qemuTPMVirCommandAddEncryption(virCommand *cmd,
* certificates for it.
*/
static int
-qemuTPMEmulatorRunSetup(const char *storagepath,
+qemuTPMEmulatorRunSetup(const virDomainTPMStorage storage_type,
+ const char *storagepath,
const char *vmname,
const unsigned char *vmuuid,
bool privileged,
@@ -376,6 +395,7 @@ qemuTPMEmulatorRunSetup(const char *storagepath,
char uuid[VIR_UUID_STRING_BUFLEN];
g_autofree char *vmid = NULL;
g_autofree char *swtpm_setup = virTPMGetSwtpmSetup();
+ g_autofree char *tpm_state = qemuTPMGetSwtpmSetupStateArg(storage_type,
storagepath);
if (!swtpm_setup)
return -1;
@@ -413,7 +433,7 @@ qemuTPMEmulatorRunSetup(const char *storagepath,
if (!incomingMigration) {
virCommandAddArgList(cmd,
- "--tpm-state", storagepath,
+ "--tpm-state", tpm_state,
"--vmid", vmid,
"--logfile", logfile,
"--createek",
@@ -424,7 +444,7 @@ qemuTPMEmulatorRunSetup(const char *storagepath,
NULL);
} else {
virCommandAddArgList(cmd,
- "--tpm-state", storagepath,
+ "--tpm-state", tpm_state,
"--logfile", logfile,
"--overwrite",
NULL);
@@ -465,6 +485,7 @@ qemuTPMPcrBankBitmapToStr(virBitmap *activePcrBanks)
* qemuTPMEmulatorReconfigure
*
*
+ * @storage_type: type of storage
* @storagepath: path to the directory for TPM state
* @swtpm_user: The userid to switch to when setting up the TPM;
* typically this should be the uid of 'tss' or 'root'
@@ -478,7 +499,8 @@ qemuTPMPcrBankBitmapToStr(virBitmap *activePcrBanks)
* Reconfigure the active PCR banks of a TPM 2.
*/
static int
-qemuTPMEmulatorReconfigure(const char *storagepath,
+qemuTPMEmulatorReconfigure(const virDomainTPMStorage storage_type,
+ const char *storagepath,
uid_t swtpm_user,
gid_t swtpm_group,
virBitmap *activePcrBanks,
@@ -490,6 +512,7 @@ qemuTPMEmulatorReconfigure(const char *storagepath,
int exitstatus;
g_autofree char *activePcrBanksStr = NULL;
g_autofree char *swtpm_setup = virTPMGetSwtpmSetup();
+ g_autofree char *tpm_state = qemuTPMGetSwtpmSetupStateArg(storage_type,
storagepath);
if (!swtpm_setup)
return -1;
@@ -510,7 +533,7 @@ qemuTPMEmulatorReconfigure(const char *storagepath,
return -1;
virCommandAddArgList(cmd,
- "--tpm-state", storagepath,
+ "--tpm-state", tpm_state,
"--logfile", logfile,
"--pcr-banks", activePcrBanksStr,
"--reconfigure",
@@ -555,6 +578,7 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
{
g_autoptr(virCommand) cmd = NULL;
bool created = false;
+ bool run_setup = false;
g_autofree char *swtpm = virTPMGetSwtpm();
int pwdfile_fd = -1;
int migpwdfile_fd = -1;
@@ -565,6 +589,18 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
if (!swtpm)
return NULL;
+ if (tpm->data.emulator.storage_type == VIR_DOMAIN_TPM_STORAGE_FILE) {
+ if (!virTPMSwtpmCapsGet(VIR_TPM_SWTPM_FEATURE_NVRAM_BACKEND_DIR)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
+ _("%1$s does not support file storage"),
+ swtpm);
+ goto error;
+ }
+ create_storage = false;
+ /* setup is run with --not-overwrite */
+ run_setup = true;
+ }
+
/* Do not create storage and run swtpm_setup on incoming migration over
* shared storage
*/
@@ -572,15 +608,18 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
if (incomingMigration && on_shared_storage)
create_storage = false;
- if (create_storage &&
- qemuTPMEmulatorCreateStorage(tpm, &created, swtpm_user, swtpm_group) < 0)
- return NULL;
+ if (create_storage) {
+ if (qemuTPMEmulatorCreateStorage(tpm, &created, swtpm_user, swtpm_group) <
0)
+ return NULL;
+ run_setup = created;
+ }
if (tpm->data.emulator.hassecretuuid)
secretuuid = tpm->data.emulator.secretuuid;
- if (created &&
- qemuTPMEmulatorRunSetup(tpm->data.emulator.storagepath, vmname, vmuuid,
+ if (run_setup &&
+ qemuTPMEmulatorRunSetup(tpm->data.emulator.storage_type,
+ tpm->data.emulator.storagepath, vmname, vmuuid,
privileged, swtpm_user, swtpm_group,
tpm->data.emulator.logfile,
tpm->data.emulator.version,
@@ -588,7 +627,8 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
goto error;
if (!incomingMigration &&
- qemuTPMEmulatorReconfigure(tpm->data.emulator.storagepath,
+ qemuTPMEmulatorReconfigure(tpm->data.emulator.storage_type,
+ tpm->data.emulator.storagepath,
swtpm_user, swtpm_group,
tpm->data.emulator.activePcrBanks,
tpm->data.emulator.logfile,
@@ -607,8 +647,16 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
tpm->data.emulator.source->data.nix.path);
virCommandAddArg(cmd, "--tpmstate");
- virCommandAddArgFormat(cmd, "dir=%s,mode=0600",
- tpm->data.emulator.storagepath);
+ switch (tpm->data.emulator.storage_type) {
+ case VIR_DOMAIN_TPM_STORAGE_FILE:
+ virCommandAddArgFormat(cmd, "backend-uri=file://%s",
+ tpm->data.emulator.storagepath);
+ break;
+ case VIR_DOMAIN_TPM_STORAGE_DEFAULT:
+ virCommandAddArgFormat(cmd, "dir=%s,mode=0600",
+ tpm->data.emulator.storagepath);
+ break;
+ }
virCommandAddArg(cmd, "--log");
if (tpm->data.emulator.debug != 0)
--
2.45.2.827.g557ae147e6