qemu: Add UNDEFINE_TPM and UNDEFINE_KEEP_TPM flags

Add UNDEFINE_TPM and UNDEFINE_KEEP_TPM flags to qemuDomainUndefineFlags()
API and --tpm and --keep-tpm to 'virsh undefine'. Pass the
virDomainUndefineFlagsValues via qemuDomainRemoveInactive()
from qemuDomainUndefineFlags() all the way down to
qemuTPMEmulatorCleanupHost() and delete TPM storage there considering that
the UNDEFINE_TPM flag has priority over the persistent_state attribute
from the domain XML. Pass 0 in all other API call sites to
qemuDomainRemoveInactive() for now.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Stefan Berger 2022-10-04 09:38:13 -04:00 committed by Michal Privoznik
parent 17554563b6
commit 60a06693cc
13 changed files with 85 additions and 35 deletions

View File

@ -4486,6 +4486,7 @@ undefine
[--checkpoints-metadata] [--nvram] [--keep-nvram] [--checkpoints-metadata] [--nvram] [--keep-nvram]
[ {--storage volumes | --remove-all-storage [ {--storage volumes | --remove-all-storage
[--delete-storage-volume-snapshots]} --wipe-storage] [--delete-storage-volume-snapshots]} --wipe-storage]
[--tpm] [--keep-tpm]
Undefine a domain. If the domain is running, this converts it to a Undefine a domain. If the domain is running, this converts it to a
transient domain, without stopping it. If the domain is inactive, transient domain, without stopping it. If the domain is inactive,
@ -4537,6 +4538,11 @@ failure.
The flag *--wipe-storage* specifies that the storage volumes should be The flag *--wipe-storage* specifies that the storage volumes should be
wiped before removal. wiped before removal.
*--tpm* and *--keep-tpm* specify accordingly to delete or keep a TPM's
persistent state directory structure and files. If the flags are omitted
then the persistent_state attribute in the TPM emulator definition in the
domain XML determines whether the TPM state is kept.
NOTE: For an inactive domain, the domain name or UUID must be used as the NOTE: For an inactive domain, the domain name or UUID must be used as the
*domain*. *domain*.

View File

@ -2267,6 +2267,10 @@ typedef enum {
VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA = (1 << 4), /* If last use of domain, VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA = (1 << 4), /* If last use of domain,
then also remove any then also remove any
checkpoint metadata (Since: 5.6.0) */ checkpoint metadata (Since: 5.6.0) */
VIR_DOMAIN_UNDEFINE_TPM = (1 << 5), /* Also remove any
TPM state (Since: 8.9.0) */
VIR_DOMAIN_UNDEFINE_KEEP_TPM = (1 << 6), /* Keep TPM state (Since: 8.9.0) */
/* Future undefine control flags should come here. */
} virDomainUndefineFlagsValues; } virDomainUndefineFlagsValues;

View File

@ -7168,7 +7168,8 @@ qemuDomainSnapshotDiscardAllMetadata(virQEMUDriver *driver,
static void static void
qemuDomainRemoveInactiveCommon(virQEMUDriver *driver, qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
virDomainObj *vm) virDomainObj *vm,
virDomainUndefineFlagsValues flags)
{ {
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
g_autofree char *snapDir = NULL; g_autofree char *snapDir = NULL;
@ -7194,7 +7195,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); qemuExtDevicesCleanupHost(driver, vm->def, flags);
} }
@ -7205,14 +7206,15 @@ qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
*/ */
void void
qemuDomainRemoveInactive(virQEMUDriver *driver, qemuDomainRemoveInactive(virQEMUDriver *driver,
virDomainObj *vm) virDomainObj *vm,
virDomainUndefineFlagsValues flags)
{ {
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); qemuDomainRemoveInactiveCommon(driver, vm, flags);
virDomainObjListRemove(driver->domains, vm); virDomainObjListRemove(driver->domains, vm);
} }
@ -7234,7 +7236,7 @@ qemuDomainRemoveInactiveLocked(virQEMUDriver *driver,
return; return;
} }
qemuDomainRemoveInactiveCommon(driver, vm); qemuDomainRemoveInactiveCommon(driver, vm, 0);
virDomainObjListRemoveLocked(driver->domains, vm); virDomainObjListRemoveLocked(driver->domains, vm);
} }

View File

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

View File

@ -1626,7 +1626,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); qemuDomainRemoveInactive(driver, vm, 0);
goto cleanup; goto cleanup;
} }
@ -1635,7 +1635,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); qemuDomainRemoveInactive(driver, vm, 0);
qemuProcessEndJob(vm); qemuProcessEndJob(vm);
goto cleanup; goto cleanup;
} }
@ -2118,7 +2118,7 @@ qemuDomainDestroyFlags(virDomainPtr dom,
ret = 0; ret = 0;
endjob: endjob:
if (ret == 0) if (ret == 0)
qemuDomainRemoveInactive(driver, vm); qemuDomainRemoveInactive(driver, vm, 0);
virDomainObjEndJob(vm); virDomainObjEndJob(vm);
cleanup: cleanup:
@ -2738,7 +2738,7 @@ qemuDomainSaveInternal(virQEMUDriver *driver,
} }
virDomainObjEndAsyncJob(vm); virDomainObjEndAsyncJob(vm);
if (ret == 0) if (ret == 0)
qemuDomainRemoveInactive(driver, vm); qemuDomainRemoveInactive(driver, vm, 0);
cleanup: cleanup:
virQEMUSaveDataFree(data); virQEMUSaveDataFree(data);
@ -3278,7 +3278,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); qemuDomainRemoveInactive(driver, vm, 0);
cleanup: cleanup:
virDomainObjEndAPI(&vm); virDomainObjEndAPI(&vm);
@ -3590,7 +3590,7 @@ processGuestPanicEvent(virQEMUDriver *driver,
endjob: endjob:
virDomainObjEndAsyncJob(vm); virDomainObjEndAsyncJob(vm);
if (removeInactive) if (removeInactive)
qemuDomainRemoveInactive(driver, vm); qemuDomainRemoveInactive(driver, vm, 0);
} }
@ -4068,7 +4068,7 @@ processMonitorEOFEvent(virQEMUDriver *driver,
virObjectEventStateQueue(driver->domainEventState, event); virObjectEventStateQueue(driver->domainEventState, event);
endjob: endjob:
qemuDomainRemoveInactive(driver, vm); qemuDomainRemoveInactive(driver, vm, 0);
virDomainObjEndJob(vm); virDomainObjEndJob(vm);
} }
@ -6000,7 +6000,7 @@ qemuDomainRestoreInternal(virConnectPtr conn,
virFileWrapperFdFree(wrapperFd); virFileWrapperFdFree(wrapperFd);
virQEMUSaveDataFree(data); virQEMUSaveDataFree(data);
if (vm && ret < 0) if (vm && ret < 0)
qemuDomainRemoveInactive(driver, vm); qemuDomainRemoveInactive(driver, vm, 0);
virDomainObjEndAPI(&vm); virDomainObjEndAPI(&vm);
return ret; return ret;
} }
@ -6690,7 +6690,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); qemuDomainRemoveInactive(driver, vm, 0);
} }
} }
@ -6723,7 +6723,9 @@ qemuDomainUndefineFlags(virDomainPtr dom,
VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA | VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA |
VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA | VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA |
VIR_DOMAIN_UNDEFINE_NVRAM | VIR_DOMAIN_UNDEFINE_NVRAM |
VIR_DOMAIN_UNDEFINE_KEEP_NVRAM, -1); VIR_DOMAIN_UNDEFINE_KEEP_NVRAM |
VIR_DOMAIN_UNDEFINE_TPM |
VIR_DOMAIN_UNDEFINE_KEEP_TPM, -1);
if ((flags & VIR_DOMAIN_UNDEFINE_NVRAM) && if ((flags & VIR_DOMAIN_UNDEFINE_NVRAM) &&
(flags & VIR_DOMAIN_UNDEFINE_KEEP_NVRAM)) { (flags & VIR_DOMAIN_UNDEFINE_KEEP_NVRAM)) {
@ -6732,6 +6734,13 @@ qemuDomainUndefineFlags(virDomainPtr dom,
return -1; return -1;
} }
if ((flags & VIR_DOMAIN_UNDEFINE_TPM) &&
(flags & VIR_DOMAIN_UNDEFINE_KEEP_TPM)) {
virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("cannot both keep and delete TPM"));
return -1;
}
if (!(vm = qemuDomainObjFromDomain(dom))) if (!(vm = qemuDomainObjFromDomain(dom)))
return -1; return -1;
@ -6830,7 +6839,7 @@ qemuDomainUndefineFlags(virDomainPtr dom,
*/ */
vm->persistent = 0; vm->persistent = 0;
if (!virDomainObjIsActive(vm)) if (!virDomainObjIsActive(vm))
qemuDomainRemoveInactive(driver, vm); qemuDomainRemoveInactive(driver, vm, flags);
ret = 0; ret = 0;
endjob: endjob:

View File

@ -151,7 +151,8 @@ qemuExtDevicesPrepareHost(virQEMUDriver *driver,
void void
qemuExtDevicesCleanupHost(virQEMUDriver *driver, qemuExtDevicesCleanupHost(virQEMUDriver *driver,
virDomainDef *def) virDomainDef *def,
virDomainUndefineFlagsValues flags)
{ {
size_t i; size_t i;
@ -159,7 +160,7 @@ qemuExtDevicesCleanupHost(virQEMUDriver *driver,
return; return;
for (i = 0; i < def->ntpms; i++) { for (i = 0; i < def->ntpms; i++) {
qemuExtTPMCleanupHost(def->tpms[i]); qemuExtTPMCleanupHost(def->tpms[i], flags);
} }
} }

View File

@ -41,7 +41,8 @@ int qemuExtDevicesPrepareHost(virQEMUDriver *driver,
G_GNUC_WARN_UNUSED_RESULT; G_GNUC_WARN_UNUSED_RESULT;
void qemuExtDevicesCleanupHost(virQEMUDriver *driver, void qemuExtDevicesCleanupHost(virQEMUDriver *driver,
virDomainDef *def) virDomainDef *def,
virDomainUndefineFlagsValues flags)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int qemuExtDevicesStart(virQEMUDriver *driver, int qemuExtDevicesStart(virQEMUDriver *driver,

View File

@ -3391,7 +3391,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); qemuDomainRemoveInactive(driver, vm, 0);
} }
virDomainObjEndAPI(&vm); virDomainObjEndAPI(&vm);
virErrorRestore(&origErr); virErrorRestore(&origErr);
@ -4036,7 +4036,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); qemuDomainRemoveInactive(driver, vm, 0);
} }
cleanup: cleanup:
@ -6039,7 +6039,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); qemuDomainRemoveInactive(driver, vm, 0);
} }
virErrorRestore(&orig_err); virErrorRestore(&orig_err);
@ -6166,7 +6166,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriver *driver,
} }
if (!virDomainObjIsActive(vm)) if (!virDomainObjIsActive(vm))
qemuDomainRemoveInactive(driver, vm); qemuDomainRemoveInactive(driver, vm, 0);
return ret; return ret;
} }
@ -6702,7 +6702,7 @@ qemuMigrationDstFinishActive(virQEMUDriver *driver,
} }
if (!virDomainObjIsActive(vm)) if (!virDomainObjIsActive(vm))
qemuDomainRemoveInactive(driver, vm); qemuDomainRemoveInactive(driver, vm, 0);
virErrorRestore(&orig_err); virErrorRestore(&orig_err);
return NULL; return NULL;
@ -6839,7 +6839,7 @@ qemuMigrationProcessUnattended(virQEMUDriver *driver,
qemuMigrationJobFinish(vm); qemuMigrationJobFinish(vm);
if (!virDomainObjIsActive(vm)) if (!virDomainObjIsActive(vm))
qemuDomainRemoveInactive(driver, vm); qemuDomainRemoveInactive(driver, vm, 0);
} }

View File

@ -8442,7 +8442,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); qemuDomainRemoveInactive(driver, dom, 0);
virDomainObjEndJob(dom); virDomainObjEndJob(dom);
@ -8905,7 +8905,7 @@ qemuProcessReconnect(void *opaque)
if (jobStarted) if (jobStarted)
virDomainObjEndJob(obj); virDomainObjEndJob(obj);
if (!virDomainObjIsActive(obj)) if (!virDomainObjIsActive(obj))
qemuDomainRemoveInactive(driver, obj); qemuDomainRemoveInactive(driver, obj, 0);
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); qemuDomainRemoveInactive(driver, vm, 0);
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); qemuDomainRemoveInactive(driver, vm, 0);
return -1; return -1;
} }
detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT; detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;

View File

@ -693,14 +693,23 @@ qemuTPMEmulatorInitPaths(virDomainTPMDef *tpm,
/** /**
* qemuTPMEmulatorCleanupHost: * qemuTPMEmulatorCleanupHost:
* @tpm: TPM definition * @tpm: TPM definition
* @flags: flags indicating whether to keep or remove TPM persistent state
* *
* 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)
{ {
if (!tpm->data.emulator.persistent_state) /*
* remove TPM state if:
* - persistent_state flag is set and the UNDEFINE_TPM flag is set
* - persistent_state flag is not set and the KEEP_TPM flag is not set
*/
if ((tpm->data.emulator.persistent_state && (flags & VIR_DOMAIN_UNDEFINE_TPM)) ||
(!tpm->data.emulator.persistent_state && !(flags & VIR_DOMAIN_UNDEFINE_KEEP_TPM))) {
qemuTPMEmulatorDeleteStorage(tpm); qemuTPMEmulatorDeleteStorage(tpm);
}
} }
@ -991,9 +1000,10 @@ qemuExtTPMPrepareHost(virQEMUDriver *driver,
void void
qemuExtTPMCleanupHost(virDomainTPMDef *tpm) qemuExtTPMCleanupHost(virDomainTPMDef *tpm,
virDomainUndefineFlagsValues flags)
{ {
qemuTPMEmulatorCleanupHost(tpm); qemuTPMEmulatorCleanupHost(tpm, flags);
} }

View File

@ -35,7 +35,8 @@ int qemuExtTPMPrepareHost(virQEMUDriver *driver,
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(3)
G_GNUC_WARN_UNUSED_RESULT; G_GNUC_WARN_UNUSED_RESULT;
void qemuExtTPMCleanupHost(virDomainTPMDef *tpm) void qemuExtTPMCleanupHost(virDomainTPMDef *tpm,
virDomainUndefineFlagsValues flags)
ATTRIBUTE_NONNULL(1); ATTRIBUTE_NONNULL(1);
int qemuExtTPMStart(virQEMUDriver *driver, int qemuExtTPMStart(virQEMUDriver *driver,

View File

@ -3650,6 +3650,14 @@ static const vshCmdOptDef opts_undefine[] = {
.type = VSH_OT_BOOL, .type = VSH_OT_BOOL,
.help = N_("keep nvram file") .help = N_("keep nvram file")
}, },
{.name = "tpm",
.type = VSH_OT_BOOL,
.help = N_("remove TPM state")
},
{.name = "keep-tpm",
.type = VSH_OT_BOOL,
.help = N_("keep TPM state")
},
{.name = NULL} {.name = NULL}
}; };
@ -3677,6 +3685,8 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
bool delete_snapshots = vshCommandOptBool(cmd, "delete-storage-volume-snapshots"); bool delete_snapshots = vshCommandOptBool(cmd, "delete-storage-volume-snapshots");
bool nvram = vshCommandOptBool(cmd, "nvram"); bool nvram = vshCommandOptBool(cmd, "nvram");
bool keep_nvram = vshCommandOptBool(cmd, "keep-nvram"); bool keep_nvram = vshCommandOptBool(cmd, "keep-nvram");
bool tpm = vshCommandOptBool(cmd, "tpm");
bool keep_tpm = vshCommandOptBool(cmd, "keep-tpm");
/* Positive if these items exist. */ /* Positive if these items exist. */
int has_managed_save = 0; int has_managed_save = 0;
int has_snapshots_metadata = 0; int has_snapshots_metadata = 0;
@ -3702,6 +3712,7 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
VSH_REQUIRE_OPTION("delete-storage-volume-snapshots", "remove-all-storage"); VSH_REQUIRE_OPTION("delete-storage-volume-snapshots", "remove-all-storage");
VSH_EXCLUSIVE_OPTIONS("nvram", "keep-nvram"); VSH_EXCLUSIVE_OPTIONS("nvram", "keep-nvram");
VSH_EXCLUSIVE_OPTIONS("tpm", "keep-tpm");
ignore_value(vshCommandOptStringQuiet(ctl, cmd, "storage", &vol_string)); ignore_value(vshCommandOptStringQuiet(ctl, cmd, "storage", &vol_string));
@ -3729,6 +3740,10 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
flags |= VIR_DOMAIN_UNDEFINE_NVRAM; flags |= VIR_DOMAIN_UNDEFINE_NVRAM;
if (keep_nvram) if (keep_nvram)
flags |= VIR_DOMAIN_UNDEFINE_KEEP_NVRAM; flags |= VIR_DOMAIN_UNDEFINE_KEEP_NVRAM;
if (tpm)
flags |= VIR_DOMAIN_UNDEFINE_TPM;
if (keep_tpm)
flags |= VIR_DOMAIN_UNDEFINE_KEEP_TPM;
if (!(dom = virshCommandOptDomain(ctl, cmd, &name))) if (!(dom = virshCommandOptDomain(ctl, cmd, &name)))
return false; return false;