From: Peter Krempa <[email protected]> The current logic in 'qemuTPMEmulatorBuildCommand' skips all setup if the *location* of the data is on what we'd consider shared storage.
This means that if the location is not actually shared (e.g. it's shared betweeh some other hosts than the two doing the migration) and the path wasn't ever used (e.g. by migrating out) from the host where we're migrating into the complete setup of the location would be skipped even when it doesn't exist. Fix the logic by skipping only some of the setup steps so that 'qemuTPMEmulatorCreateStorage' can still create the storage if it doesn't exist. The rest of the code then needs to take the 'created' flag returned from 'qemuTPMEmulatorCreateStorage' into account. Fixes: 68103e9daf633b789428fedef56f816c92f6ee75 Signed-off-by: Peter Krempa <[email protected]> --- src/qemu/qemu_tpm.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c index 4c9445d72c..1ce6390fd5 100644 --- a/src/qemu/qemu_tpm.c +++ b/src/qemu/qemu_tpm.c @@ -158,6 +158,7 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir, /** * qemuTPMEmulatorCreateStorage: * @tpm: TPM definition for an emulator type + * @sharedStorageMigration: VM is being migrated with possibly shared storage * @created: a pointer to a bool that will be set to true if the * storage was created because it did not exist yet * @swtpm_user: The uid that needs to be able to access the directory @@ -169,6 +170,7 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir, */ static int qemuTPMEmulatorCreateStorage(virDomainTPMDef *tpm, + bool sharedStorageMigration, bool *created, uid_t swtpm_user, gid_t swtpm_group) @@ -187,8 +189,14 @@ qemuTPMEmulatorCreateStorage(virDomainTPMDef *tpm, *created = false; if (!virFileExists(source_path) || - virDirIsEmpty(source_path, true) > 0) + virDirIsEmpty(source_path, true) > 0) { *created = true; + } else { + /* If the location exists and is shared, we don't need to create it + * during migration */ + if (sharedStorageMigration) + return 0; + } if (virDirCreate(source_path, 0700, swtpm_user, swtpm_group, VIR_DIR_CREATE_ALLOW_EXIST) < 0) { @@ -809,16 +817,13 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, run_setup = true; } - /* Do not create storage and run swtpm_setup on incoming migration over - * shared storage - */ on_shared_storage = virFileIsSharedFS(tpm->data.emulator.source_path, cfg->sharedFilesystems) == 1; - if (incomingMigration && on_shared_storage) - create_storage = false; if (create_storage) { - if (qemuTPMEmulatorCreateStorage(tpm, &created, + if (qemuTPMEmulatorCreateStorage(tpm, + incomingMigration && on_shared_storage, + &created, cfg->swtpm_user, cfg->swtpm_group) < 0) return NULL; run_setup = created; @@ -885,6 +890,9 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, /* If swtpm supports it and the TPM state is stored on shared storage, * start swtpm with --migration release-lock-outgoing so it can migrate * across shared storage if needed. + * + * Note that if 'created' is true, the location didn't exist so the storage + * is not actually shared. */ QEMU_DOMAIN_TPM_PRIVATE(tpm)->swtpm.can_migrate_shared_storage = false; if (on_shared_storage && @@ -892,13 +900,13 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, virCommandAddArg(cmd, "--migration"); virCommandAddArgFormat(cmd, "release-lock-outgoing%s", - incomingMigration ? ",incoming": ""); + incomingMigration && !created ? ",incoming": ""); QEMU_DOMAIN_TPM_PRIVATE(tpm)->swtpm.can_migrate_shared_storage = true; } else { /* Report an error if there's an incoming migration across shared * storage and swtpm does not support the --migration option. */ - if (incomingMigration && on_shared_storage) { + if (incomingMigration && on_shared_storage && !created) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, _("%1$s (on destination side) does not support the --migration option needed for migration with shared storage"), swtpm); -- 2.52.0
