qemu: Implement postParse callback skipping on config reload

Use the new facility which allows to ignore failures in post parse
callbacks if they are not fatal so that VM configs are not lost if the
emulator binary is missing.

If qemuCaps can't be populated on daemon restart skip certain portions
of the post parse callbacks during config reload and re-run the callback
during VM startup.

This fixes VMs vanishing if the emulator binary was broken or
uninstalled and libvirtd was restarted.
This commit is contained in:
Peter Krempa 2017-08-16 16:00:25 +02:00
parent 7808884808
commit 7726d1581f
2 changed files with 27 additions and 2 deletions

View File

@ -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;
}

View File

@ -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,