diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e28b373a95..e2531cdcfe 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2932,7 +2932,7 @@ qemuDomainDefPostParseBasic(virDomainDefPtr def, /* check for emulator and create a default one if needed */ if (!def->emulator && !(def->emulator = virDomainDefGetDefaultEmulator(def, caps))) - return -1; + return 1; return 0; } @@ -2947,6 +2947,9 @@ qemuDomainDefPostParse(virDomainDefPtr def, { virQEMUDriverPtr driver = opaque; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + /* Note that qemuCaps may be NULL when this function is called. This + * function shall not fail in that case. It will be re-run on VM startup + * with the capabilities populated. */ virQEMUCapsPtr qemuCaps = parseOpaque; int ret = -1; @@ -3575,6 +3578,9 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, void *parseOpaque) { virQEMUDriverPtr driver = opaque; + /* Note that qemuCaps may be NULL when this function is called. This + * function shall not fail in that case. It will be re-run on VM startup + * with the capabilities populated. */ virQEMUCapsPtr qemuCaps = parseOpaque; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); int ret = -1; @@ -3700,9 +3706,19 @@ qemuDomainDefAssignAddresses(virDomainDef *def, void *parseOpaque) { virQEMUDriverPtr driver = opaque; + /* Note that qemuCaps may be NULL when this function is called. This + * function shall not fail in that case. It will be re-run on VM startup + * with the capabilities populated. */ virQEMUCapsPtr qemuCaps = parseOpaque; bool newDomain = parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE; + /* Skip address assignment if @qemuCaps is not present. In such case devices + * which are automatically added may be missing. Additionally @qemuCaps should + * only be missing when reloading configs, thus addresses were already + * assigned. */ + if (!qemuCaps) + return 1; + return qemuDomainAssignAddresses(def, qemuCaps, driver, NULL, newDomain); } @@ -3718,7 +3734,7 @@ qemuDomainPostParseDataAlloc(const virDomainDef *def, if (!(*parseOpaque = virQEMUCapsCacheLookup(driver->qemuCapsCache, def->emulator))) - return -1; + return 1; return 0; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index fed2bc5882..589d0ed2cf 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4691,6 +4691,15 @@ qemuProcessInit(virQEMUDriverPtr driver, if (!(caps = virQEMUDriverGetCapabilities(driver, false))) goto cleanup; + /* in case when the post parse callback failed we need to re-run it on the + * old config prior we start the VM */ + if (vm->def->postParseFailed) { + VIR_DEBUG("re-running the post parse callback"); + + if (virDomainDefPostParse(vm->def, caps, 0, driver->xmlopt, NULL) < 0) + goto cleanup; + } + VIR_DEBUG("Determining emulator version"); virObjectUnref(priv->qemuCaps); if (!(priv->qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,