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
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);
}

View File

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

View File

@ -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:

View File

@ -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++) {

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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,