qemu: tpm: Never remove state on outgoing migration and shared storage

Never remove the TPM state on outgoing migration if the storage setup
has shared storage for the TPM state files. Also, do not do the security
cleanup on outgoing migration if shared storage is detected.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Stefan Berger 2022-10-24 06:28:48 -04:00 committed by Michal Privoznik
parent 2e669ec789
commit 3c9968ec9a
10 changed files with 64 additions and 40 deletions

View File

@ -7250,7 +7250,8 @@ qemuDomainSnapshotDiscardAllMetadata(virQEMUDriver *driver,
static void static void
qemuDomainRemoveInactiveCommon(virQEMUDriver *driver, qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
virDomainObj *vm, virDomainObj *vm,
virDomainUndefineFlagsValues flags) virDomainUndefineFlagsValues flags,
bool outgoingMigration)
{ {
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
g_autofree char *snapDir = NULL; g_autofree char *snapDir = NULL;
@ -7276,7 +7277,7 @@ qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
if (rmdir(chkDir) < 0 && errno != ENOENT) if (rmdir(chkDir) < 0 && errno != ENOENT)
VIR_WARN("unable to remove checkpoint directory %s", chkDir); 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 void
qemuDomainRemoveInactive(virQEMUDriver *driver, qemuDomainRemoveInactive(virQEMUDriver *driver,
virDomainObj *vm, virDomainObj *vm,
virDomainUndefineFlagsValues flags) virDomainUndefineFlagsValues flags,
bool outgoingMigration)
{ {
if (vm->persistent) { if (vm->persistent) {
/* Short-circuit, we don't want to remove a persistent domain */ /* Short-circuit, we don't want to remove a persistent domain */
return; return;
} }
qemuDomainRemoveInactiveCommon(driver, vm, flags); qemuDomainRemoveInactiveCommon(driver, vm, flags, outgoingMigration);
virDomainObjListRemove(driver->domains, vm); virDomainObjListRemove(driver->domains, vm);
} }
@ -7317,7 +7319,7 @@ qemuDomainRemoveInactiveLocked(virQEMUDriver *driver,
return; return;
} }
qemuDomainRemoveInactiveCommon(driver, vm, 0); qemuDomainRemoveInactiveCommon(driver, vm, 0, false);
virDomainObjListRemoveLocked(driver->domains, vm); virDomainObjListRemoveLocked(driver->domains, vm);
} }

View File

@ -703,7 +703,8 @@ int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriver *driver,
void qemuDomainRemoveInactive(virQEMUDriver *driver, void qemuDomainRemoveInactive(virQEMUDriver *driver,
virDomainObj *vm, virDomainObj *vm,
virDomainUndefineFlagsValues flags); virDomainUndefineFlagsValues flags,
bool outgoingMigration);
void void
qemuDomainRemoveInactiveLocked(virQEMUDriver *driver, qemuDomainRemoveInactiveLocked(virQEMUDriver *driver,

View File

@ -1611,7 +1611,7 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
goto cleanup; goto cleanup;
if (qemuProcessBeginJob(vm, VIR_DOMAIN_JOB_OPERATION_START, flags) < 0) { if (qemuProcessBeginJob(vm, VIR_DOMAIN_JOB_OPERATION_START, flags) < 0) {
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
goto cleanup; goto cleanup;
} }
@ -1620,7 +1620,7 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE, VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
start_flags) < 0) { start_flags) < 0) {
virDomainAuditStart(vm, "booted", false); virDomainAuditStart(vm, "booted", false);
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
qemuProcessEndJob(vm); qemuProcessEndJob(vm);
goto cleanup; goto cleanup;
} }
@ -2103,7 +2103,7 @@ qemuDomainDestroyFlags(virDomainPtr dom,
ret = 0; ret = 0;
endjob: endjob:
if (ret == 0) if (ret == 0)
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
virDomainObjEndJob(vm); virDomainObjEndJob(vm);
cleanup: cleanup:
@ -2723,7 +2723,7 @@ qemuDomainSaveInternal(virQEMUDriver *driver,
} }
virDomainObjEndAsyncJob(vm); virDomainObjEndAsyncJob(vm);
if (ret == 0) if (ret == 0)
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
cleanup: cleanup:
virQEMUSaveDataFree(data); virQEMUSaveDataFree(data);
@ -3253,7 +3253,7 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom,
virDomainObjEndAsyncJob(vm); virDomainObjEndAsyncJob(vm);
if (ret == 0 && flags & VIR_DUMP_CRASH) if (ret == 0 && flags & VIR_DUMP_CRASH)
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
cleanup: cleanup:
virDomainObjEndAPI(&vm); virDomainObjEndAPI(&vm);
@ -3565,7 +3565,7 @@ processGuestPanicEvent(virQEMUDriver *driver,
endjob: endjob:
virDomainObjEndAsyncJob(vm); virDomainObjEndAsyncJob(vm);
if (removeInactive) if (removeInactive)
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
} }
@ -3799,7 +3799,7 @@ processMonitorEOFEvent(virQEMUDriver *driver,
virObjectEventStateQueue(driver->domainEventState, event); virObjectEventStateQueue(driver->domainEventState, event);
endjob: endjob:
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
virDomainObjEndJob(vm); virDomainObjEndJob(vm);
} }
@ -5731,7 +5731,7 @@ qemuDomainRestoreInternal(virConnectPtr conn,
virFileWrapperFdFree(wrapperFd); virFileWrapperFdFree(wrapperFd);
virQEMUSaveDataFree(data); virQEMUSaveDataFree(data);
if (vm && ret < 0) if (vm && ret < 0)
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
virDomainObjEndAPI(&vm); virDomainObjEndAPI(&vm);
return ret; return ret;
} }
@ -6421,7 +6421,7 @@ qemuDomainDefineXMLFlags(virConnectPtr conn,
} else { } else {
/* Brand new domain. Remove it */ /* Brand new domain. Remove it */
VIR_INFO("Deleting domain '%s'", vm->def->name); 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; vm->persistent = 0;
if (!virDomainObjIsActive(vm)) if (!virDomainObjIsActive(vm))
qemuDomainRemoveInactive(driver, vm, flags); qemuDomainRemoveInactive(driver, vm, flags, false);
ret = 0; ret = 0;
endjob: endjob:

View File

@ -152,7 +152,8 @@ qemuExtDevicesPrepareHost(virQEMUDriver *driver,
void void
qemuExtDevicesCleanupHost(virQEMUDriver *driver, qemuExtDevicesCleanupHost(virQEMUDriver *driver,
virDomainDef *def, virDomainDef *def,
virDomainUndefineFlagsValues flags) virDomainUndefineFlagsValues flags,
bool outgoingMigration)
{ {
size_t i; size_t i;
@ -160,7 +161,7 @@ qemuExtDevicesCleanupHost(virQEMUDriver *driver,
return; return;
for (i = 0; i < def->ntpms; i++) { 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 void
qemuExtDevicesStop(virQEMUDriver *driver, qemuExtDevicesStop(virQEMUDriver *driver,
virDomainObj *vm) virDomainObj *vm,
bool outgoingMigration)
{ {
virDomainDef *def = vm->def; virDomainDef *def = vm->def;
size_t i; size_t i;
@ -242,7 +244,7 @@ qemuExtDevicesStop(virQEMUDriver *driver,
for (i = 0; i < def->ntpms; i++) { for (i = 0; i < def->ntpms; i++) {
if (def->tpms[i]->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) if (def->tpms[i]->type == VIR_DOMAIN_TPM_TYPE_EMULATOR)
qemuExtTPMStop(driver, vm); qemuExtTPMStop(driver, vm, outgoingMigration);
} }
for (i = 0; i < def->nnets; i++) { for (i = 0; i < def->nnets; i++) {

View File

@ -42,7 +42,8 @@ int qemuExtDevicesPrepareHost(virQEMUDriver *driver,
void qemuExtDevicesCleanupHost(virQEMUDriver *driver, void qemuExtDevicesCleanupHost(virQEMUDriver *driver,
virDomainDef *def, virDomainDef *def,
virDomainUndefineFlagsValues flags) virDomainUndefineFlagsValues flags,
bool outgoingMigration)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int qemuExtDevicesStart(virQEMUDriver *driver, int qemuExtDevicesStart(virQEMUDriver *driver,
@ -52,7 +53,8 @@ int qemuExtDevicesStart(virQEMUDriver *driver,
G_GNUC_WARN_UNUSED_RESULT; G_GNUC_WARN_UNUSED_RESULT;
void qemuExtDevicesStop(virQEMUDriver *driver, void qemuExtDevicesStop(virQEMUDriver *driver,
virDomainObj *vm) virDomainObj *vm,
bool outgoingMigration)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
bool qemuExtDevicesHasDevice(virDomainDef *def); bool qemuExtDevicesHasDevice(virDomainDef *def);

View File

@ -3399,7 +3399,7 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver,
* and there is no 'goto cleanup;' in the middle of those */ * and there is no 'goto cleanup;' in the middle of those */
VIR_FREE(priv->origname); VIR_FREE(priv->origname);
virDomainObjRemoveTransientDef(vm); virDomainObjRemoveTransientDef(vm);
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
} }
virDomainObjEndAPI(&vm); virDomainObjEndAPI(&vm);
virErrorRestore(&origErr); virErrorRestore(&origErr);
@ -4044,7 +4044,7 @@ qemuMigrationSrcConfirm(virQEMUDriver *driver,
virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm); virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
vm->persistent = 0; vm->persistent = 0;
} }
qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM); qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM, true);
} }
cleanup: cleanup:
@ -6055,7 +6055,7 @@ qemuMigrationSrcPerformJob(virQEMUDriver *driver,
virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm); virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
vm->persistent = 0; vm->persistent = 0;
} }
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, true);
} }
virErrorRestore(&orig_err); virErrorRestore(&orig_err);
@ -6182,7 +6182,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriver *driver,
} }
if (!virDomainObjIsActive(vm)) if (!virDomainObjIsActive(vm))
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, true);
return ret; return ret;
} }
@ -6718,7 +6718,7 @@ qemuMigrationDstFinishActive(virQEMUDriver *driver,
} }
if (!virDomainObjIsActive(vm)) if (!virDomainObjIsActive(vm))
qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM); qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM, false);
virErrorRestore(&orig_err); virErrorRestore(&orig_err);
return NULL; return NULL;
@ -6855,7 +6855,7 @@ qemuMigrationProcessUnattended(virQEMUDriver *driver,
qemuMigrationJobFinish(vm); qemuMigrationJobFinish(vm);
if (!virDomainObjIsActive(vm)) if (!virDomainObjIsActive(vm))
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
} }

View File

@ -8207,6 +8207,7 @@ void qemuProcessStop(virQEMUDriver *driver,
g_autofree char *timestamp = NULL; g_autofree char *timestamp = NULL;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
g_autoptr(virConnect) conn = NULL; g_autoptr(virConnect) conn = NULL;
bool outgoingMigration;
VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%lld, " VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%lld, "
"reason=%s, asyncJob=%s, flags=0x%x", "reason=%s, asyncJob=%s, flags=0x%x",
@ -8304,7 +8305,9 @@ void qemuProcessStop(virQEMUDriver *driver,
qemuDomainCleanupRun(driver, vm); 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); qemuDBusStop(driver, vm);
@ -8570,7 +8573,7 @@ qemuProcessAutoDestroy(virDomainObj *dom,
VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_DESTROYED); VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
qemuDomainRemoveInactive(driver, dom, 0); qemuDomainRemoveInactive(driver, dom, 0, false);
virDomainObjEndJob(dom); virDomainObjEndJob(dom);
@ -9036,7 +9039,7 @@ qemuProcessReconnect(void *opaque)
if (jobStarted) if (jobStarted)
virDomainObjEndJob(obj); virDomainObjEndJob(obj);
if (!virDomainObjIsActive(obj)) if (!virDomainObjIsActive(obj))
qemuDomainRemoveInactive(driver, obj, 0); qemuDomainRemoveInactive(driver, obj, 0, false);
virDomainObjEndAPI(&obj); virDomainObjEndAPI(&obj);
virIdentitySetCurrent(NULL); virIdentitySetCurrent(NULL);
return; return;

View File

@ -2103,7 +2103,7 @@ qemuSnapshotRevertInactive(virDomainObj *vm,
} }
if (qemuSnapshotInternalRevertInactive(driver, vm, snap) < 0) { if (qemuSnapshotInternalRevertInactive(driver, vm, snap) < 0) {
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
return -1; return -1;
} }
@ -2125,7 +2125,7 @@ qemuSnapshotRevertInactive(virDomainObj *vm,
start_flags); start_flags);
virDomainAuditStart(vm, "from-snapshot", rc >= 0); virDomainAuditStart(vm, "from-snapshot", rc >= 0);
if (rc < 0) { if (rc < 0) {
qemuDomainRemoveInactive(driver, vm, 0); qemuDomainRemoveInactive(driver, vm, 0, false);
return -1; return -1;
} }
detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT; detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;

View File

@ -728,13 +728,22 @@ qemuTPMEmulatorInitPaths(virDomainTPMDef *tpm,
* qemuTPMEmulatorCleanupHost: * qemuTPMEmulatorCleanupHost:
* @tpm: TPM definition * @tpm: TPM definition
* @flags: flags indicating whether to keep or remove TPM persistent state * @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. * Clean up persistent storage for the swtpm.
*/ */
static void static void
qemuTPMEmulatorCleanupHost(virDomainTPMDef *tpm, 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: * remove TPM state if:
* - persistent_state flag is set and the UNDEFINE_TPM flag is set * - persistent_state flag is set and the UNDEFINE_TPM flag is set
@ -1082,9 +1091,10 @@ qemuExtTPMPrepareHost(virQEMUDriver *driver,
void void
qemuExtTPMCleanupHost(virDomainTPMDef *tpm, qemuExtTPMCleanupHost(virDomainTPMDef *tpm,
virDomainUndefineFlagsValues flags) virDomainUndefineFlagsValues flags,
bool outgoingMigration)
{ {
qemuTPMEmulatorCleanupHost(tpm, flags); qemuTPMEmulatorCleanupHost(tpm, flags, outgoingMigration);
} }
@ -1105,7 +1115,8 @@ qemuExtTPMStart(virQEMUDriver *driver,
void void
qemuExtTPMStop(virQEMUDriver *driver, qemuExtTPMStop(virQEMUDriver *driver,
virDomainObj *vm) virDomainObj *vm,
bool outgoingMigration)
{ {
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
g_autofree char *shortName = virDomainDefGetShortName(vm->def); g_autofree char *shortName = virDomainDefGetShortName(vm->def);
@ -1114,6 +1125,7 @@ qemuExtTPMStop(virQEMUDriver *driver,
return; return;
qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName); qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName);
if (!(outgoingMigration && qemuTPMHasSharedStorage(vm->def)))
qemuSecurityCleanupTPMEmulator(driver, vm); qemuSecurityCleanupTPMEmulator(driver, vm);
} }

View File

@ -36,7 +36,8 @@ int qemuExtTPMPrepareHost(virQEMUDriver *driver,
G_GNUC_WARN_UNUSED_RESULT; G_GNUC_WARN_UNUSED_RESULT;
void qemuExtTPMCleanupHost(virDomainTPMDef *tpm, void qemuExtTPMCleanupHost(virDomainTPMDef *tpm,
virDomainUndefineFlagsValues flags) virDomainUndefineFlagsValues flags,
bool outgoingMigration)
ATTRIBUTE_NONNULL(1); ATTRIBUTE_NONNULL(1);
int qemuExtTPMStart(virQEMUDriver *driver, int qemuExtTPMStart(virQEMUDriver *driver,
@ -48,7 +49,8 @@ int qemuExtTPMStart(virQEMUDriver *driver,
G_GNUC_WARN_UNUSED_RESULT; G_GNUC_WARN_UNUSED_RESULT;
void qemuExtTPMStop(virQEMUDriver *driver, void qemuExtTPMStop(virQEMUDriver *driver,
virDomainObj *vm) virDomainObj *vm,
bool outgoingMigration)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int qemuExtTPMSetupCgroup(virQEMUDriver *driver, int qemuExtTPMSetupCgroup(virQEMUDriver *driver,