On 12/1/25 15:25, Peter Krempa via Devel wrote:
> 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)
Can you please put a short VIR_DEBUG("Skipping TPM creation due to
shared storage migration"); here? Or something among those lines. I feel
this is something we might find useful later when reading logs from a
migration.
> + 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);
Reviewed-by: Michal Privoznik <[email protected]>
Michal