[PATCH v4 7/7] qemu: tpm: Never remove state on outgoing migration and shared storage

Stefan Berger stefanb at linux.ibm.com
Mon Oct 24 10:28:48 UTC 2022


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 at linux.ibm.com>
---
 src/qemu/qemu_domain.c    | 12 +++++++-----
 src/qemu/qemu_domain.h    |  3 ++-
 src/qemu/qemu_driver.c    | 20 ++++++++++----------
 src/qemu/qemu_extdevice.c | 10 ++++++----
 src/qemu/qemu_extdevice.h |  6 ++++--
 src/qemu/qemu_migration.c | 12 ++++++------
 src/qemu/qemu_process.c   |  9 ++++++---
 src/qemu/qemu_snapshot.c  |  4 ++--
 src/qemu/qemu_tpm.c       | 22 +++++++++++++++++-----
 src/qemu/qemu_tpm.h       |  6 ++++--
 10 files changed, 64 insertions(+), 40 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 41333f1725..acfa60bc2c 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7257,7 +7257,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;
@@ -7283,7 +7284,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);
 }
 
 
@@ -7295,14 +7296,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);
 }
@@ -7324,7 +7326,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 59a3b37b98..a4a5970b8c 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);
@@ -3263,7 +3263,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);
@@ -3575,7 +3575,7 @@ processGuestPanicEvent(virQEMUDriver *driver,
  endjob:
     virDomainObjEndAsyncJob(vm);
     if (removeInactive)
-        qemuDomainRemoveInactive(driver, vm, 0);
+        qemuDomainRemoveInactive(driver, vm, 0, false);
 }
 
 
@@ -3809,7 +3809,7 @@ processMonitorEOFEvent(virQEMUDriver *driver,
     virObjectEventStateQueue(driver->domainEventState, event);
 
  endjob:
-    qemuDomainRemoveInactive(driver, vm, 0);
+    qemuDomainRemoveInactive(driver, vm, 0, false);
     virDomainObjEndJob(vm);
 }
 
@@ -5741,7 +5741,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;
 }
@@ -6431,7 +6431,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);
         }
     }
 
@@ -6580,7 +6580,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 2aa0b6e89e..c47fdce253 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3407,7 +3407,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);
@@ -4052,7 +4052,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 f405326312..14adba255b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8209,6 +8209,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",
@@ -8306,7 +8307,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);
 
@@ -8572,7 +8575,7 @@ qemuProcessAutoDestroy(virDomainObj *dom,
                                      VIR_DOMAIN_EVENT_STOPPED,
                                      VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
 
-    qemuDomainRemoveInactive(driver, dom, 0);
+    qemuDomainRemoveInactive(driver, dom, 0, false);
 
     virDomainObjEndJob(dom);
 
@@ -9038,7 +9041,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 5a0d298052..ec78697c38 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
@@ -1091,9 +1100,10 @@ qemuExtTPMPrepareHost(virQEMUDriver *driver,
 
 void
 qemuExtTPMCleanupHost(virDomainTPMDef *tpm,
-                      virDomainUndefineFlagsValues flags)
+                      virDomainUndefineFlagsValues flags,
+                      bool outgoingMigration)
 {
-    qemuTPMEmulatorCleanupHost(tpm, flags);
+    qemuTPMEmulatorCleanupHost(tpm, flags, outgoingMigration);
 }
 
 
@@ -1114,7 +1124,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);
@@ -1123,7 +1134,8 @@ qemuExtTPMStop(virQEMUDriver *driver,
         return;
 
     qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName);
-    qemuSecurityCleanupTPMEmulator(driver, vm);
+    if (!(outgoingMigration && qemuTPMHasSharedStorage(driver, vm->def) == 1))
+        qemuSecurityCleanupTPMEmulator(driver, vm);
 }
 
 
diff --git a/src/qemu/qemu_tpm.h b/src/qemu/qemu_tpm.h
index e6e32a0c4a..0e99cfb3e6 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,
-- 
2.37.3



More information about the libvir-list mailing list