]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Implement postParse callback skipping on config reload
authorPeter Krempa <pkrempa@redhat.com>
Wed, 16 Aug 2017 14:00:25 +0000 (16:00 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 18 Aug 2017 13:07:44 +0000 (15:07 +0200)
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.

src/qemu/qemu_domain.c
src/qemu/qemu_process.c

index e28b373a95cbdae6ebb785dedc2c275183ed835f..e2531cdcfeb8a64cb69eeea0f74436ef3c2338ce 100644 (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;
 }
index fed2bc588270f7addc87fcbe9611f7410ac7d723..589d0ed2cffbabf2b02145484228184737d53f2e 100644 (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,