diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ec785af5bb..41e616ca48 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -7250,7 +7250,8 @@ qemuDomainSnapshotDiscardAllMetadata(virQEMUDriver *driver, static void qemuDomainRemoveInactiveCommon(virQEMUDriver *driver, virDomainObj *vm, - virDomainUndefineFlagsValues flags) + virDomainUndefineFlagsValues flags, + bool outgoingMigration) { g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autofree char *snapDir = NULL; @@ -7276,7 +7277,7 @@ qemuDomainRemoveInactiveCommon(virQEMUDriver *driver, if (rmdir(chkDir) < 0 && errno != ENOENT) VIR_WARN("unable to remove checkpoint directory %s", chkDir); } - qemuExtDevicesCleanupHost(driver, vm->def, flags); + qemuExtDevicesCleanupHost(driver, vm->def, flags, outgoingMigration); } @@ -7288,14 +7289,15 @@ qemuDomainRemoveInactiveCommon(virQEMUDriver *driver, void qemuDomainRemoveInactive(virQEMUDriver *driver, virDomainObj *vm, - virDomainUndefineFlagsValues flags) + virDomainUndefineFlagsValues flags, + bool outgoingMigration) { if (vm->persistent) { /* Short-circuit, we don't want to remove a persistent domain */ return; } - qemuDomainRemoveInactiveCommon(driver, vm, flags); + qemuDomainRemoveInactiveCommon(driver, vm, flags, outgoingMigration); virDomainObjListRemove(driver->domains, vm); } @@ -7317,7 +7319,7 @@ qemuDomainRemoveInactiveLocked(virQEMUDriver *driver, return; } - qemuDomainRemoveInactiveCommon(driver, vm, 0); + qemuDomainRemoveInactiveCommon(driver, vm, 0, false); virDomainObjListRemoveLocked(driver->domains, vm); } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 919ce16097..7950c4c2da 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -703,7 +703,8 @@ int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriver *driver, void qemuDomainRemoveInactive(virQEMUDriver *driver, virDomainObj *vm, - virDomainUndefineFlagsValues flags); + virDomainUndefineFlagsValues flags, + bool outgoingMigration); void qemuDomainRemoveInactiveLocked(virQEMUDriver *driver, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d10283f2ea..c7c966503e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1611,7 +1611,7 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn, goto cleanup; if (qemuProcessBeginJob(vm, VIR_DOMAIN_JOB_OPERATION_START, flags) < 0) { - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); goto cleanup; } @@ -1620,7 +1620,7 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn, VIR_NETDEV_VPORT_PROFILE_OP_CREATE, start_flags) < 0) { virDomainAuditStart(vm, "booted", false); - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); qemuProcessEndJob(vm); goto cleanup; } @@ -2103,7 +2103,7 @@ qemuDomainDestroyFlags(virDomainPtr dom, ret = 0; endjob: if (ret == 0) - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); virDomainObjEndJob(vm); cleanup: @@ -2723,7 +2723,7 @@ qemuDomainSaveInternal(virQEMUDriver *driver, } virDomainObjEndAsyncJob(vm); if (ret == 0) - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); cleanup: virQEMUSaveDataFree(data); @@ -3253,7 +3253,7 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom, virDomainObjEndAsyncJob(vm); if (ret == 0 && flags & VIR_DUMP_CRASH) - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); cleanup: virDomainObjEndAPI(&vm); @@ -3565,7 +3565,7 @@ processGuestPanicEvent(virQEMUDriver *driver, endjob: virDomainObjEndAsyncJob(vm); if (removeInactive) - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); } @@ -3799,7 +3799,7 @@ processMonitorEOFEvent(virQEMUDriver *driver, virObjectEventStateQueue(driver->domainEventState, event); endjob: - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); virDomainObjEndJob(vm); } @@ -5731,7 +5731,7 @@ qemuDomainRestoreInternal(virConnectPtr conn, virFileWrapperFdFree(wrapperFd); virQEMUSaveDataFree(data); if (vm && ret < 0) - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); virDomainObjEndAPI(&vm); return ret; } @@ -6421,7 +6421,7 @@ qemuDomainDefineXMLFlags(virConnectPtr conn, } else { /* Brand new domain. Remove it */ VIR_INFO("Deleting domain '%s'", vm->def->name); - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); } } @@ -6570,7 +6570,7 @@ qemuDomainUndefineFlags(virDomainPtr dom, */ vm->persistent = 0; if (!virDomainObjIsActive(vm)) - qemuDomainRemoveInactive(driver, vm, flags); + qemuDomainRemoveInactive(driver, vm, flags, false); ret = 0; endjob: diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c index 24a57b0f74..3eaf6571a2 100644 --- a/src/qemu/qemu_extdevice.c +++ b/src/qemu/qemu_extdevice.c @@ -152,7 +152,8 @@ qemuExtDevicesPrepareHost(virQEMUDriver *driver, void qemuExtDevicesCleanupHost(virQEMUDriver *driver, virDomainDef *def, - virDomainUndefineFlagsValues flags) + virDomainUndefineFlagsValues flags, + bool outgoingMigration) { size_t i; @@ -160,7 +161,7 @@ qemuExtDevicesCleanupHost(virQEMUDriver *driver, return; for (i = 0; i < def->ntpms; i++) { - qemuExtTPMCleanupHost(def->tpms[i], flags); + qemuExtTPMCleanupHost(def->tpms[i], flags, outgoingMigration); } } @@ -225,7 +226,8 @@ qemuExtDevicesStart(virQEMUDriver *driver, void qemuExtDevicesStop(virQEMUDriver *driver, - virDomainObj *vm) + virDomainObj *vm, + bool outgoingMigration) { virDomainDef *def = vm->def; size_t i; @@ -242,7 +244,7 @@ qemuExtDevicesStop(virQEMUDriver *driver, for (i = 0; i < def->ntpms; i++) { if (def->tpms[i]->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) - qemuExtTPMStop(driver, vm); + qemuExtTPMStop(driver, vm, outgoingMigration); } for (i = 0; i < def->nnets; i++) { diff --git a/src/qemu/qemu_extdevice.h b/src/qemu/qemu_extdevice.h index 6b05b59cd6..86e7133a2a 100644 --- a/src/qemu/qemu_extdevice.h +++ b/src/qemu/qemu_extdevice.h @@ -42,7 +42,8 @@ int qemuExtDevicesPrepareHost(virQEMUDriver *driver, void qemuExtDevicesCleanupHost(virQEMUDriver *driver, virDomainDef *def, - virDomainUndefineFlagsValues flags) + virDomainUndefineFlagsValues flags, + bool outgoingMigration) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); int qemuExtDevicesStart(virQEMUDriver *driver, @@ -52,7 +53,8 @@ int qemuExtDevicesStart(virQEMUDriver *driver, G_GNUC_WARN_UNUSED_RESULT; void qemuExtDevicesStop(virQEMUDriver *driver, - virDomainObj *vm) + virDomainObj *vm, + bool outgoingMigration) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); bool qemuExtDevicesHasDevice(virDomainDef *def); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 02816169cb..bba4e1dbf3 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3399,7 +3399,7 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver, * and there is no 'goto cleanup;' in the middle of those */ VIR_FREE(priv->origname); virDomainObjRemoveTransientDef(vm); - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); } virDomainObjEndAPI(&vm); virErrorRestore(&origErr); @@ -4044,7 +4044,7 @@ qemuMigrationSrcConfirm(virQEMUDriver *driver, virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm); vm->persistent = 0; } - qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM); + qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM, true); } cleanup: @@ -6055,7 +6055,7 @@ qemuMigrationSrcPerformJob(virQEMUDriver *driver, virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm); vm->persistent = 0; } - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, true); } virErrorRestore(&orig_err); @@ -6182,7 +6182,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriver *driver, } if (!virDomainObjIsActive(vm)) - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, true); return ret; } @@ -6718,7 +6718,7 @@ qemuMigrationDstFinishActive(virQEMUDriver *driver, } if (!virDomainObjIsActive(vm)) - qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM); + qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM, false); virErrorRestore(&orig_err); return NULL; @@ -6855,7 +6855,7 @@ qemuMigrationProcessUnattended(virQEMUDriver *driver, qemuMigrationJobFinish(vm); if (!virDomainObjIsActive(vm)) - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 48864a92a5..40abd306f6 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -8207,6 +8207,7 @@ void qemuProcessStop(virQEMUDriver *driver, g_autofree char *timestamp = NULL; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autoptr(virConnect) conn = NULL; + bool outgoingMigration; VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%lld, " "reason=%s, asyncJob=%s, flags=0x%x", @@ -8304,7 +8305,9 @@ void qemuProcessStop(virQEMUDriver *driver, qemuDomainCleanupRun(driver, vm); - qemuExtDevicesStop(driver, vm); + outgoingMigration = (flags & VIR_QEMU_PROCESS_STOP_MIGRATED) && + (asyncJob != VIR_ASYNC_JOB_MIGRATION_IN); + qemuExtDevicesStop(driver, vm, outgoingMigration); qemuDBusStop(driver, vm); @@ -8570,7 +8573,7 @@ qemuProcessAutoDestroy(virDomainObj *dom, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); - qemuDomainRemoveInactive(driver, dom, 0); + qemuDomainRemoveInactive(driver, dom, 0, false); virDomainObjEndJob(dom); @@ -9036,7 +9039,7 @@ qemuProcessReconnect(void *opaque) if (jobStarted) virDomainObjEndJob(obj); if (!virDomainObjIsActive(obj)) - qemuDomainRemoveInactive(driver, obj, 0); + qemuDomainRemoveInactive(driver, obj, 0, false); virDomainObjEndAPI(&obj); virIdentitySetCurrent(NULL); return; diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index 06b5c180ff..d7983c134f 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -2103,7 +2103,7 @@ qemuSnapshotRevertInactive(virDomainObj *vm, } if (qemuSnapshotInternalRevertInactive(driver, vm, snap) < 0) { - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); return -1; } @@ -2125,7 +2125,7 @@ qemuSnapshotRevertInactive(virDomainObj *vm, start_flags); virDomainAuditStart(vm, "from-snapshot", rc >= 0); if (rc < 0) { - qemuDomainRemoveInactive(driver, vm, 0); + qemuDomainRemoveInactive(driver, vm, 0, false); return -1; } detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT; diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c index 0c3775a913..dc15514ca6 100644 --- a/src/qemu/qemu_tpm.c +++ b/src/qemu/qemu_tpm.c @@ -728,13 +728,22 @@ qemuTPMEmulatorInitPaths(virDomainTPMDef *tpm, * qemuTPMEmulatorCleanupHost: * @tpm: TPM definition * @flags: flags indicating whether to keep or remove TPM persistent state + * @outgoingMigration: whether cleanup is due to an outgoing migration * * Clean up persistent storage for the swtpm. */ static void qemuTPMEmulatorCleanupHost(virDomainTPMDef *tpm, - virDomainUndefineFlagsValues flags) + virDomainUndefineFlagsValues flags, + bool outgoingMigration) { + /* Never remove the state in case of outgoing migration with shared + * storage. + */ + if (outgoingMigration && + virFileIsSharedFS(tpm->data.emulator.storagepath) == 1) + return; + /* * remove TPM state if: * - persistent_state flag is set and the UNDEFINE_TPM flag is set @@ -1082,9 +1091,10 @@ qemuExtTPMPrepareHost(virQEMUDriver *driver, void qemuExtTPMCleanupHost(virDomainTPMDef *tpm, - virDomainUndefineFlagsValues flags) + virDomainUndefineFlagsValues flags, + bool outgoingMigration) { - qemuTPMEmulatorCleanupHost(tpm, flags); + qemuTPMEmulatorCleanupHost(tpm, flags, outgoingMigration); } @@ -1105,7 +1115,8 @@ qemuExtTPMStart(virQEMUDriver *driver, void qemuExtTPMStop(virQEMUDriver *driver, - virDomainObj *vm) + virDomainObj *vm, + bool outgoingMigration) { g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autofree char *shortName = virDomainDefGetShortName(vm->def); @@ -1114,7 +1125,8 @@ qemuExtTPMStop(virQEMUDriver *driver, return; qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName); - qemuSecurityCleanupTPMEmulator(driver, vm); + if (!(outgoingMigration && qemuTPMHasSharedStorage(vm->def))) + qemuSecurityCleanupTPMEmulator(driver, vm); } diff --git a/src/qemu/qemu_tpm.h b/src/qemu/qemu_tpm.h index 799ab62f58..33ba5d2268 100644 --- a/src/qemu/qemu_tpm.h +++ b/src/qemu/qemu_tpm.h @@ -36,7 +36,8 @@ int qemuExtTPMPrepareHost(virQEMUDriver *driver, G_GNUC_WARN_UNUSED_RESULT; void qemuExtTPMCleanupHost(virDomainTPMDef *tpm, - virDomainUndefineFlagsValues flags) + virDomainUndefineFlagsValues flags, + bool outgoingMigration) ATTRIBUTE_NONNULL(1); int qemuExtTPMStart(virQEMUDriver *driver, @@ -48,7 +49,8 @@ int qemuExtTPMStart(virQEMUDriver *driver, G_GNUC_WARN_UNUSED_RESULT; void qemuExtTPMStop(virQEMUDriver *driver, - virDomainObj *vm) + virDomainObj *vm, + bool outgoingMigration) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); int qemuExtTPMSetupCgroup(virQEMUDriver *driver,