diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 6673a323c6..d60ef81061 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -31430,3 +31430,59 @@ virDomainGraphicsNeedsAutoRenderNode(const virDomainGraphicsDef *graphics) return true; } + + +static int +virDomainCheckTPMChanges(virDomainDefPtr def, + virDomainDefPtr newDef) +{ + bool oldEnc, newEnc; + + if (!def->tpm) + return 0; + + switch (def->tpm->type) { + case VIR_DOMAIN_TPM_TYPE_EMULATOR: + if (virFileExists(def->tpm->data.emulator.storagepath)) { + /* VM has been started */ + /* Once a VM was started with an encrypted state we allow + * less configuration changes. + */ + oldEnc = def->tpm->data.emulator.hassecretuuid; + if (oldEnc && def->tpm->type != newDef->tpm->type) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Changing the type of TPM is not allowed")); + return -1; + } + if (oldEnc && !newDef->tpm) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Removing an encrypted TPM is not allowed")); + return -1; + } + newEnc = newDef->tpm->data.emulator.hassecretuuid; + if (oldEnc != newEnc) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("TPM state encryption cannot be changed " + "once VM was started")); + return -1; + } + } + break; + case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: + case VIR_DOMAIN_TPM_TYPE_LAST: + break; + } + + return 0; +} + + +int +virDomainCheckDeviceChanges(virDomainDefPtr def, + virDomainDefPtr newDef) +{ + if (!def || !newDef) + return 0; + + return virDomainCheckTPMChanges(def, newDef); +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8092893c2a..285fa6c496 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3636,3 +3636,7 @@ virDomainGraphicsGetRenderNode(const virDomainGraphicsDef *graphics); bool virDomainGraphicsNeedsAutoRenderNode(const virDomainGraphicsDef *graphics); + +int +virDomainCheckDeviceChanges(virDomainDefPtr def, virDomainDefPtr newDef) + ATTRIBUTE_NONNULL(2); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a8d65e4318..e1526031a5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -205,6 +205,7 @@ virDomainBootTypeFromString; virDomainBootTypeToString; virDomainCapabilitiesPolicyTypeToString; virDomainCapsFeatureTypeToString; +virDomainCheckDeviceChanges; virDomainChrConsoleTargetTypeFromString; virDomainChrConsoleTargetTypeToString; virDomainChrDefForeach; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e7720fbd99..9110d15cca 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -52,6 +52,7 @@ #include "qemu_migration_params.h" #include "qemu_blockjob.h" #include "qemu_security.h" +#include "qemu_extdevice.h" #include "virerror.h" #include "virlog.h" @@ -7600,6 +7601,30 @@ qemuDomainCreate(virDomainPtr dom) return qemuDomainCreateWithFlags(dom, 0); } +static int +qemuDomainCheckDeviceChanges(virQEMUDriverPtr driver, + virDomainDefPtr def) +{ + virDomainObjPtr vm; + int ret; + + vm = virDomainObjListFindByUUID(driver->domains, def->uuid); + if (!vm) + return 0; + + if (qemuExtDevicesInitPaths(driver, vm->def) < 0) { + ret = -1; + goto cleanup; + } + + ret = virDomainCheckDeviceChanges(vm->def, def); + + cleanup: + virDomainObjEndAPI(&vm); + + return ret; +} + static virDomainPtr qemuDomainDefineXMLFlags(virConnectPtr conn, const char *xml, @@ -7636,6 +7661,9 @@ qemuDomainDefineXMLFlags(virConnectPtr conn, if (virDomainDefineXMLFlagsEnsureACL(conn, def) < 0) goto cleanup; + if (qemuDomainCheckDeviceChanges(driver, def) < 0) + goto cleanup; + if (!(vm = virDomainObjListAdd(driver->domains, def, driver->xmlopt, 0, &oldDef))) diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c index a21caefaba..e576bca165 100644 --- a/src/qemu/qemu_extdevice.c +++ b/src/qemu/qemu_extdevice.c @@ -79,7 +79,7 @@ qemuExtDeviceLogCommand(qemuDomainLogContextPtr logCtxt, * stored and we can remove directories and files in case of domain XML * changes. */ -static int +int qemuExtDevicesInitPaths(virQEMUDriverPtr driver, virDomainDefPtr def) { diff --git a/src/qemu/qemu_extdevice.h b/src/qemu/qemu_extdevice.h index a72e05ce63..bbdb9a1cc2 100644 --- a/src/qemu/qemu_extdevice.h +++ b/src/qemu/qemu_extdevice.h @@ -53,3 +53,6 @@ bool qemuExtDevicesHasDevice(virDomainDefPtr def); int qemuExtDevicesSetupCgroup(virQEMUDriverPtr driver, virDomainDefPtr def, virCgroupPtr cgroup); + +int qemuExtDevicesInitPaths(virQEMUDriverPtr driver, + virDomainDefPtr def);