]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: tpm: Never remove state on outgoing migration and shared storage
authorStefan Berger <stefanb@linux.ibm.com>
Mon, 24 Oct 2022 10:28:48 +0000 (06:28 -0400)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 9 Nov 2022 11:26:42 +0000 (12:26 +0100)
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>
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/qemu/qemu_driver.c
src/qemu/qemu_extdevice.c
src/qemu/qemu_extdevice.h
src/qemu/qemu_migration.c
src/qemu/qemu_process.c
src/qemu/qemu_snapshot.c
src/qemu/qemu_tpm.c
src/qemu/qemu_tpm.h

index ec785af5bba9fb79676821c9907f184155fcb127..41e616ca480ce082bec92f6e0203db82276d1eea 100644 (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);
 }
index 919ce16097b99d7228a30c13a0a5cea7439acbe1..7950c4c2dae164219377bed03929b08337cad8ea 100644 (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,
index d10283f2ea16cd3c4c624314b8a752259369e829..c7c966503e547c9bb97703c5813f191c10f0afeb 100644 (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:
index 24a57b0f74f0c5546640aaa11c85b41bdfcfc6c7..3eaf6571a24f15ba1fee0388a48431547f7b305c 100644 (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++) {
index 6b05b59cd67697b09f95b49fbdde4e85a47fd27b..86e7133a2abf70a8133bc99e907d4b3e8fe64806 100644 (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);
index 02816169cb120af138bc728cb4b371e2871986ee..bba4e1dbf3c9ccf7585177d637cbb220898759ea 100644 (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);
 }
 
 
index 48864a92a5e58953e88fbe91b29751ac7aa8f3ae..40abd306f6692b6f7eb50aecf0de8dad8da0e5c5 100644 (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;
index 06b5c180ff2d22d3f7a027626dfa91296572bdd4..d7983c134ff090f7a87c72927eb21689891ca63f 100644 (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;
index 0c3775a913fe409f5168baddb4e200748d5287c6..dc15514ca6a7724986baa5a1d0286cfa59c72e01 100644 (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);
 }
 
 
index 799ab62f581766b70c4e6cb6e7c7a0454d374316..33ba5d22687b28cbca254de6bf9aa9c17ebbd1c2 100644 (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,