[libvirt] [PATCH 3/3] Stop accessing driver->caps directly in QEMU driver

Daniel P. Berrange berrange at redhat.com
Wed Feb 6 11:54:51 UTC 2013


From: "Daniel P. Berrange" <berrange at redhat.com>

The 'driver->caps' pointer can be changed on the fly. Accessing
it currently requires the global driver lock. Isolate this
access in a single helper, so a future patch can relax the
locking constraints.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/qemu/qemu_command.c   |  10 +-
 src/qemu/qemu_conf.c      | 100 +++++++++++
 src/qemu/qemu_conf.h      |   8 +-
 src/qemu/qemu_domain.c    |  30 +++-
 src/qemu/qemu_driver.c    | 428 ++++++++++++++++++++++++++++++----------------
 src/qemu/qemu_migration.c |  44 ++++-
 src/qemu/qemu_process.c   | 149 ++++++++++++----
 7 files changed, 567 insertions(+), 202 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ad6c1d8..955c050 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4395,7 +4395,7 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
                    bool *hasHwVirt,
                    bool migrating)
 {
-    const virCPUDefPtr host = driver->caps->host.cpu;
+    virCPUDefPtr host = NULL;
     virCPUDefPtr guest = NULL;
     virCPUDefPtr cpu = NULL;
     size_t ncpus = 0;
@@ -4407,9 +4407,15 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
     int ret = -1;
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     int i;
+    virCapsPtr caps = NULL;
 
     *hasHwVirt = false;
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    host = caps->host.cpu;
+
     if (def->os.arch == VIR_ARCH_I686)
         default_model = "qemu32";
     else
@@ -4594,7 +4600,7 @@ cleanup:
         cpuDataFree(host->arch, data);
     virCPUDefFree(guest);
     virCPUDefFree(cpu);
-
+    virObjectUnref(caps);
     return ret;
 
 no_memory:
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 17f7d45..574d2cb 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -526,6 +526,106 @@ virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver)
     return virObjectRef(driver->config);
 }
 
+
+virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver)
+{
+    size_t i;
+    virCapsPtr caps;
+    virSecurityManagerPtr *sec_managers = NULL;
+    /* Security driver data */
+    const char *doi, *model;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
+    /* Basic host arch / guest machine capabilities */
+    if (!(caps = virQEMUCapsInit(driver->qemuCapsCache))) {
+        virReportOOMError();
+        virObjectUnref(cfg);
+        return NULL;
+    }
+
+    if (cfg->allowDiskFormatProbing) {
+        caps->defaultDiskDriverName = NULL;
+        caps->defaultDiskDriverType = VIR_STORAGE_FILE_AUTO;
+    } else {
+        caps->defaultDiskDriverName = "qemu";
+        caps->defaultDiskDriverType = VIR_STORAGE_FILE_RAW;
+    }
+
+    qemuDomainSetPrivateDataHooks(caps);
+    qemuDomainSetNamespaceHooks(caps);
+
+    if (virGetHostUUID(caps->host.host_uuid)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("cannot get the host uuid"));
+        goto err_exit;
+    }
+
+    /* access sec drivers and create a sec model for each one */
+    sec_managers = virSecurityManagerGetNested(driver->securityManager);
+    if (sec_managers == NULL) {
+        goto err_exit;
+    }
+
+    /* calculate length */
+    for (i = 0; sec_managers[i]; i++)
+        ;
+    caps->host.nsecModels = i;
+
+    if (VIR_ALLOC_N(caps->host.secModels, caps->host.nsecModels) < 0)
+        goto no_memory;
+
+    for (i = 0; sec_managers[i]; i++) {
+        doi = virSecurityManagerGetDOI(sec_managers[i]);
+        model = virSecurityManagerGetModel(sec_managers[i]);
+        if (!(caps->host.secModels[i].model = strdup(model)))
+            goto no_memory;
+        if (!(caps->host.secModels[i].doi = strdup(doi)))
+            goto no_memory;
+        VIR_DEBUG("Initialized caps for security driver \"%s\" with "
+                  "DOI \"%s\"", model, doi);
+    }
+    VIR_FREE(sec_managers);
+
+    virObjectUnref(cfg);
+    return caps;
+
+no_memory:
+    virReportOOMError();
+err_exit:
+    VIR_FREE(sec_managers);
+    virObjectUnref(caps);
+    virObjectUnref(cfg);
+    return NULL;
+}
+
+
+/**
+ * virQEMUDriverGetCapabilities:
+ *
+ * Get a reference to the virCapsPtr instance for the
+ * driver. If @refresh is true, the capabilities will be
+ * rebuilt first
+ *
+ * The caller must release the reference with virObjetUnref
+ *
+ * Returns: a reference to a virCapsPtr instance or NULL
+ */
+virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver,
+                                        bool refresh)
+{
+    if (refresh) {
+        virCapsPtr caps = NULL;
+        if ((caps = virQEMUDriverCreateCapabilities(driver)) == NULL)
+            return NULL;
+
+        virObjectUnref(driver->caps);
+        driver->caps = caps;
+    }
+
+    return virObjectRef(driver->caps);
+}
+
+
 static void
 qemuDriverCloseCallbackFree(void *payload,
                             const void *name ATTRIBUTE_UNUSED)
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 14680b1..9ff1c5a 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -183,7 +183,9 @@ struct _virQEMUDriver {
     /* Immutable pointer, lockless APIs. Pointless abstraction */
     ebtablesContext *ebtables;
 
-    /* Require lock while using. Unsafe. XXX */
+    /* Require lock to get a reference on the object,
+     * lockless access thereafter
+     */
     virCapsPtr caps;
 
     /* Immutable pointer, self-locking APIs */
@@ -244,6 +246,10 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
 
 virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver);
 
+virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver);
+virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver,
+                                        bool refresh);
+
 struct qemuDomainDiskInfo {
     bool removable;
     bool locked;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 5410ef0..ecf3be0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -664,13 +664,19 @@ static void
 qemuDomainObjSaveJob(virQEMUDriverPtr driver, virDomainObjPtr obj)
 {
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     if (virDomainObjIsActive(obj)) {
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, obj) < 0)
+        if (virDomainSaveStatus(caps, cfg->stateDir, obj) < 0)
             VIR_WARN("Failed to save status on vm %s", obj->def->name);
     }
 
+cleanup:
     virObjectUnref(cfg);
+    virObjectUnref(caps);
 }
 
 void
@@ -1244,21 +1250,24 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
     virCPUDefPtr def_cpu = def->cpu;
     virDomainControllerDefPtr *controllers = NULL;
     int ncontrollers = 0;
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     /* Update guest CPU requirements according to host CPU */
     if ((flags & VIR_DOMAIN_XML_UPDATE_CPU) &&
         def_cpu &&
         (def_cpu->mode != VIR_CPU_MODE_CUSTOM || def_cpu->model)) {
-        if (!driver->caps ||
-            !driver->caps->host.cpu ||
-            !driver->caps->host.cpu->model) {
+        if (!caps->host.cpu ||
+            !caps->host.cpu->model) {
             virReportError(VIR_ERR_OPERATION_FAILED,
                            "%s", _("cannot get host CPU capabilities"));
             goto cleanup;
         }
 
         if (!(cpu = virCPUDefCopy(def_cpu)) ||
-            cpuUpdate(cpu, driver->caps->host.cpu) < 0)
+            cpuUpdate(cpu, caps->host.cpu) < 0)
             goto cleanup;
         def->cpu = cpu;
     }
@@ -1310,6 +1319,7 @@ cleanup:
         def->controllers = controllers;
         def->ncontrollers = ncontrollers;
     }
+    virObjectUnref(caps);
     return ret;
 }
 
@@ -1888,16 +1898,22 @@ qemuDomainSetFakeReboot(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     if (priv->fakeReboot == value)
-        return;
+        goto cleanup;
 
     priv->fakeReboot = value;
 
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+    if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
         VIR_WARN("Failed to save status on vm %s", vm->def->name);
 
+cleanup:
     virObjectUnref(cfg);
+    virObjectUnref(caps);
 }
 
 int
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 18c4d3c..7ada7c3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -416,79 +416,6 @@ error:
 }
 
 
-static virCapsPtr
-qemuCreateCapabilities(virQEMUDriverPtr driver)
-{
-    size_t i;
-    virCapsPtr caps;
-    virSecurityManagerPtr *sec_managers = NULL;
-    /* Security driver data */
-    const char *doi, *model;
-    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
-
-    /* Basic host arch / guest machine capabilities */
-    if (!(caps = virQEMUCapsInit(driver->qemuCapsCache))) {
-        virReportOOMError();
-        virObjectUnref(cfg);
-        return NULL;
-    }
-
-    if (cfg->allowDiskFormatProbing) {
-        caps->defaultDiskDriverName = NULL;
-        caps->defaultDiskDriverType = VIR_STORAGE_FILE_AUTO;
-    } else {
-        caps->defaultDiskDriverName = "qemu";
-        caps->defaultDiskDriverType = VIR_STORAGE_FILE_RAW;
-    }
-
-    qemuDomainSetPrivateDataHooks(caps);
-    qemuDomainSetNamespaceHooks(caps);
-
-    if (virGetHostUUID(caps->host.host_uuid)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("cannot get the host uuid"));
-        goto err_exit;
-    }
-
-    /* access sec drivers and create a sec model for each one */
-    sec_managers = virSecurityManagerGetNested(driver->securityManager);
-    if (sec_managers == NULL) {
-        goto err_exit;
-    }
-
-    /* calculate length */
-    for (i = 0; sec_managers[i]; i++)
-        ;
-    caps->host.nsecModels = i;
-
-    if (VIR_ALLOC_N(caps->host.secModels, caps->host.nsecModels) < 0)
-        goto no_memory;
-
-    for (i = 0; sec_managers[i]; i++) {
-        doi = virSecurityManagerGetDOI(sec_managers[i]);
-        model = virSecurityManagerGetModel(sec_managers[i]);
-        if (!(caps->host.secModels[i].model = strdup(model)))
-            goto no_memory;
-        if (!(caps->host.secModels[i].doi = strdup(doi)))
-            goto no_memory;
-        VIR_DEBUG("Initialized caps for security driver \"%s\" with "
-                  "DOI \"%s\"", model, doi);
-    }
-    VIR_FREE(sec_managers);
-
-    virObjectUnref(cfg);
-    return caps;
-
-no_memory:
-    virReportOOMError();
-err_exit:
-    VIR_FREE(sec_managers);
-    virObjectUnref(caps);
-    virObjectUnref(cfg);
-    return NULL;
-}
-
-
 static int
 qemuDomainSnapshotLoad(virDomainObjPtr vm,
                        void *data)
@@ -507,6 +434,7 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm,
                           VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
                           VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL);
     int ret = -1;
+    virCapsPtr caps = NULL;
 
     virObjectLock(vm);
     if (virAsprintf(&snapDir, "%s/%s", baseDir, vm->def->name) < 0) {
@@ -515,6 +443,9 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm,
         goto cleanup;
     }
 
+    if (!(caps = virQEMUDriverGetCapabilities(qemu_driver, false)))
+        goto cleanup;
+
     VIR_INFO("Scanning for snapshots for domain %s in %s", vm->def->name,
              snapDir);
 
@@ -547,7 +478,7 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm,
             continue;
         }
 
-        def = virDomainSnapshotDefParseString(xmlStr, qemu_driver->caps,
+        def = virDomainSnapshotDefParseString(xmlStr, caps,
                                               QEMU_EXPECTED_VIRT_TYPES,
                                               flags);
         if (def == NULL) {
@@ -598,6 +529,7 @@ cleanup:
     if (dir)
         closedir(dir);
     VIR_FREE(snapDir);
+    virObjectUnref(caps);
     virObjectUnlock(vm);
     return ret;
 }
@@ -822,7 +754,7 @@ qemuStartup(bool privileged,
     if (!qemu_driver->qemuCapsCache)
         goto error;
 
-    if ((qemu_driver->caps = qemuCreateCapabilities(qemu_driver)) == NULL)
+    if ((qemu_driver->caps = virQEMUDriverCreateCapabilities(qemu_driver)) == NULL)
         goto error;
 
     /* If hugetlbfs is present, then we need to create a sub-directory within
@@ -956,20 +888,25 @@ static void qemuNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque)
 static int
 qemuReload(void) {
     virQEMUDriverConfigPtr cfg;
+    virCapsPtr caps;
 
     if (!qemu_driver)
         return 0;
 
+    if (!(caps = virQEMUDriverGetCapabilities(qemu_driver, false)))
+        return -1;
+
     qemuDriverLock(qemu_driver);
     cfg = virQEMUDriverGetConfig(qemu_driver);
     virDomainObjListLoadAllConfigs(qemu_driver->domains,
-                                   qemu_driver->caps,
+                                   caps,
                                    cfg->configDir,
                                    cfg->autostartDir,
                                    0, QEMU_EXPECTED_VIRT_TYPES,
                                    qemuNotifyLoadDomain, qemu_driver);
     qemuDriverUnlock(qemu_driver);
     virObjectUnref(cfg);
+    virObjectUnref(caps);
     return 0;
 }
 
@@ -1281,14 +1218,12 @@ static char *qemuGetCapabilities(virConnectPtr conn) {
 
     qemuDriverLock(driver);
 
-    if ((caps = qemuCreateCapabilities(qemu_driver)) == NULL)
+    if (!(caps = virQEMUDriverGetCapabilities(qemu_driver, true)))
         goto cleanup;
 
-    virObjectUnref(qemu_driver->caps);
-    qemu_driver->caps = caps;
-
-    if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
+    if ((xml = virCapabilitiesFormatXML(caps)) == NULL)
         virReportOOMError();
+    virObjectUnref(caps);
 
 cleanup:
     qemuDriverUnlock(driver);
@@ -1503,9 +1438,13 @@ static int qemuGetVersion(virConnectPtr conn, unsigned long *version) {
     virQEMUDriverPtr driver = conn->privateData;
     int ret = -1;
     unsigned int qemuVersion;
+    virCapsPtr caps = NULL;
 
     qemuDriverLock(driver);
-    if (virQEMUCapsGetDefaultVersion(driver->caps,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virQEMUCapsGetDefaultVersion(caps,
                                      driver->qemuCapsCache,
                                      &qemuVersion) < 0)
         goto cleanup;
@@ -1514,6 +1453,7 @@ static int qemuGetVersion(virConnectPtr conn, unsigned long *version) {
     ret = 0;
 
 cleanup:
+    virObjectUnref(caps);
     qemuDriverUnlock(driver);
     return ret;
 }
@@ -1566,13 +1506,14 @@ qemuCanonicalizeMachine(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
 static virDomainPtr qemuDomainCreate(virConnectPtr conn, const char *xml,
                                      unsigned int flags) {
     virQEMUDriverPtr driver = conn->privateData;
-    virDomainDefPtr def;
+    virDomainDefPtr def = NULL;
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
     virDomainEventPtr event2 = NULL;
     unsigned int start_flags = VIR_QEMU_PROCESS_START_COLD;
     virQEMUCapsPtr qemuCaps = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_START_PAUSED |
                   VIR_DOMAIN_START_AUTODESTROY, NULL);
@@ -1583,7 +1524,11 @@ static virDomainPtr qemuDomainCreate(virConnectPtr conn, const char *xml,
         start_flags |= VIR_QEMU_PROCESS_START_AUTODESROY;
 
     qemuDriverLock(driver);
-    if (!(def = virDomainDefParseString(driver->caps, xml,
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (!(def = virDomainDefParseString(caps, xml,
                                         QEMU_EXPECTED_VIRT_TYPES,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
@@ -1601,7 +1546,7 @@ static virDomainPtr qemuDomainCreate(virConnectPtr conn, const char *xml,
         goto cleanup;
 
     if (!(vm = virDomainObjListAdd(driver->domains,
-                                   driver->caps,
+                                   caps,
                                    def,
                                    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
                                    NULL)))
@@ -1653,6 +1598,7 @@ cleanup:
         if (event2)
             qemuDomainEventQueue(driver, event2);
     }
+    virObjectUnref(caps);
     virObjectUnref(qemuCaps);
     qemuDriverUnlock(driver);
     return dom;
@@ -1669,6 +1615,7 @@ static int qemuDomainSuspend(virDomainPtr dom) {
     int eventDetail;
     int state;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     qemuDriverLock(driver);
     vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
@@ -1725,7 +1672,9 @@ static int qemuDomainSuspend(virDomainPtr dom) {
                                              eventDetail);
         }
     }
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto endjob;
+    if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
         goto endjob;
     ret = 0;
 
@@ -1740,6 +1689,7 @@ cleanup:
     if (event)
         qemuDomainEventQueue(driver, event);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -1752,6 +1702,7 @@ static int qemuDomainResume(virDomainPtr dom) {
     virDomainEventPtr event = NULL;
     int state;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     qemuDriverLock(driver);
     vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
@@ -1793,7 +1744,9 @@ static int qemuDomainResume(virDomainPtr dom) {
                                          VIR_DOMAIN_EVENT_RESUMED,
                                          VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
     }
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto endjob;
+    if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
         goto endjob;
     ret = 0;
 
@@ -1807,6 +1760,7 @@ cleanup:
     if (event)
         qemuDomainEventQueue(driver, event);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -2171,6 +2125,7 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
     virDomainDefPtr persistentDef = NULL;
     int ret = -1, r;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -2184,7 +2139,9 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
     if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
         goto cleanup;
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto endjob;
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto endjob;
 
@@ -2252,6 +2209,7 @@ endjob:
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -2880,6 +2838,10 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom,
     int rc;
     virDomainEventPtr event = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virCapsPtr caps;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     if (!qemuMigrationIsAllowed(driver, vm, vm->def, false))
         goto cleanup;
@@ -2917,7 +2879,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom,
     if (xmlin) {
         virDomainDefPtr def = NULL;
 
-        if (!(def = virDomainDefParseString(driver->caps, xmlin,
+        if (!(def = virDomainDefParseString(caps, xmlin,
                                             QEMU_EXPECTED_VIRT_TYPES,
                                             VIR_DOMAIN_XML_INACTIVE))) {
             goto endjob;
@@ -2978,6 +2940,7 @@ cleanup:
         qemuDomainEventQueue(driver, event);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     return ret;
 }
 
@@ -3809,13 +3772,14 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
                         unsigned int flags)
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
-    virDomainObjPtr vm;
+    virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef;
     const char * type;
     int max;
     int ret = -1;
     bool maximum;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -3828,6 +3792,8 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
     }
 
     cfg = virQEMUDriverGetConfig(driver);
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
@@ -3838,7 +3804,7 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
     maximum = (flags & VIR_DOMAIN_VCPU_MAXIMUM) != 0;
     flags &= ~VIR_DOMAIN_VCPU_MAXIMUM;
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto endjob;
 
@@ -3900,6 +3866,7 @@ endjob:
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -3930,6 +3897,7 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
     virDomainVcpuPinDefPtr *newVcpuPin = NULL;
     virBitmapPtr pcpumap = NULL;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -3939,7 +3907,10 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -4030,7 +4001,7 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
         if (newVcpuPin)
             virDomainVcpuPinDefArrayFree(newVcpuPin, newVcpuPinNum);
 
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
             goto cleanup;
     }
 
@@ -4077,6 +4048,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     virBitmapFree(pcpumap);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -4107,6 +4079,7 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom,
     virBitmapPtr cpumask = NULL;
     unsigned char *cpumap;
     bool pinned;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -4114,7 +4087,10 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom,
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &targetDef) < 0)
         goto cleanup;
 
@@ -4167,6 +4143,7 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom,
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     return ret;
 }
 
@@ -4189,6 +4166,7 @@ qemuDomainPinEmulator(virDomainPtr dom,
     virDomainVcpuPinDefPtr *newVcpuPin = NULL;
     virBitmapPtr pcpumap = NULL;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -4198,6 +4176,9 @@ qemuDomainPinEmulator(virDomainPtr dom,
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                        _("Changing affinity for emulator thread dynamically "
@@ -4205,7 +4186,7 @@ qemuDomainPinEmulator(virDomainPtr dom,
         goto cleanup;
     }
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -4286,7 +4267,7 @@ qemuDomainPinEmulator(virDomainPtr dom,
             goto cleanup;
         }
 
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
             goto cleanup;
     }
 
@@ -4320,7 +4301,7 @@ cleanup:
     if (cgroup_dom)
         virCgroupFree(&cgroup_dom);
     virBitmapFree(pcpumap);
-
+    virObjectUnref(caps);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(cfg);
@@ -4340,6 +4321,7 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom,
     int maxcpu, hostcpus, pcpu;
     virBitmapPtr cpumask = NULL;
     bool pinned;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -4347,7 +4329,10 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom,
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &targetDef) < 0)
         goto cleanup;
 
@@ -4391,6 +4376,7 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom,
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     return ret;
 }
 
@@ -4491,6 +4477,7 @@ qemuDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
     virDomainObjPtr vm;
     virDomainDefPtr def;
     int ret = -1;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -4499,7 +4486,10 @@ qemuDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &def) < 0)
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &def) < 0)
         goto cleanup;
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
@@ -4511,6 +4501,7 @@ qemuDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     return ret;
 }
 
@@ -4657,16 +4648,20 @@ static int qemuNodeGetSecurityModel(virConnectPtr conn,
     virQEMUDriverPtr driver = conn->privateData;
     char *p;
     int ret = 0;
+    virCapsPtr caps = NULL;
 
     qemuDriverLock(driver);
     memset(secmodel, 0, sizeof(*secmodel));
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     /* We treat no driver as success, but simply return no data in *secmodel */
-    if (driver->caps->host.nsecModels == 0 ||
-        driver->caps->host.secModels[0].model == NULL)
+    if (caps->host.nsecModels == 0 ||
+        caps->host.secModels[0].model == NULL)
         goto cleanup;
 
-    p = driver->caps->host.secModels[0].model;
+    p = caps->host.secModels[0].model;
     if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("security model string exceeds max %d bytes"),
@@ -4676,7 +4671,7 @@ static int qemuNodeGetSecurityModel(virConnectPtr conn,
     }
     strcpy(secmodel->model, p);
 
-    p = driver->caps->host.secModels[0].doi;
+    p = caps->host.secModels[0].doi;
     if (strlen(p) >= VIR_SECURITY_DOI_BUFLEN-1) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("security DOI string exceeds max %d bytes"),
@@ -4688,6 +4683,7 @@ static int qemuNodeGetSecurityModel(virConnectPtr conn,
 
 cleanup:
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     return ret;
 }
 
@@ -4710,6 +4706,7 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver,
     char *xml = NULL;
     virDomainDefPtr def = NULL;
     int oflags = edit ? O_RDWR : O_RDONLY;
+    virCapsPtr caps = NULL;
 
     if (bypass_cache) {
         int directFlag = virFileDirectFdFlag();
@@ -4721,6 +4718,9 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver,
         oflags |= directFlag;
     }
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto error;
+
     if ((fd = qemuOpenFile(driver, path, oflags, NULL, NULL)) < 0)
         goto error;
     if (bypass_cache &&
@@ -4805,14 +4805,14 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver,
         header.was_running = state;
 
     /* Create a domain from this XML */
-    if (!(def = virDomainDefParseString(driver->caps, xml,
+    if (!(def = virDomainDefParseString(caps, xml,
                                         QEMU_EXPECTED_VIRT_TYPES,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto error;
     if (xmlin) {
         virDomainDefPtr def2 = NULL;
 
-        if (!(def2 = virDomainDefParseString(driver->caps, xmlin,
+        if (!(def2 = virDomainDefParseString(caps, xmlin,
                                              QEMU_EXPECTED_VIRT_TYPES,
                                              VIR_DOMAIN_XML_INACTIVE)))
             goto error;
@@ -4829,12 +4829,15 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver,
     *ret_def = def;
     *ret_header = header;
 
+    virObjectUnref(caps);
+
     return fd;
 
 error:
     virDomainDefFree(def);
     VIR_FREE(xml);
     VIR_FORCE_CLOSE(fd);
+    virObjectUnref(caps);
 
     return -1;
 }
@@ -4854,6 +4857,10 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
     virCommandPtr cmd = NULL;
     char *errbuf = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     if (header->version == 2) {
         const char *prog = qemuSaveCompressionTypeToString(header->compressed);
@@ -4861,7 +4868,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
             virReportError(VIR_ERR_OPERATION_FAILED,
                            _("Invalid compressed save format %d"),
                            header->compressed);
-            goto out;
+            goto cleanup;
         }
 
         if (header->compressed != QEMU_SAVE_FORMAT_RAW) {
@@ -4879,7 +4886,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
                                _("Failed to start decompression binary %s"),
                                prog);
                 *fd = intermediatefd;
-                goto out;
+                goto cleanup;
             }
         }
     }
@@ -4914,7 +4921,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
 
     if (ret < 0) {
         virDomainAuditStart(vm, "restored", false);
-        goto out;
+        goto cleanup;
     }
 
     event = virDomainEventNewFromObj(vm,
@@ -4933,11 +4940,11 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
             if (virGetLastError() == NULL)
                 virReportError(VIR_ERR_OPERATION_FAILED,
                                "%s", _("failed to resume domain"));
-            goto out;
+            goto cleanup;
         }
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Failed to save status on vm %s", vm->def->name);
-            goto out;
+            goto cleanup;
         }
     } else {
         int detail = (start_paused ? VIR_DOMAIN_EVENT_SUSPENDED_PAUSED :
@@ -4951,12 +4958,13 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
 
     ret = 0;
 
-out:
+cleanup:
     virCommandFree(cmd);
     VIR_FREE(errbuf);
     if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
                                                  vm->def, path) < 0)
         VIR_WARN("failed to restore save state label on %s", path);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -4975,6 +4983,7 @@ qemuDomainRestoreFlags(virConnectPtr conn,
     virQEMUSaveHeader header;
     virFileWrapperFdPtr wrapperFd = NULL;
     int state = -1;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
                   VIR_DOMAIN_SAVE_RUNNING |
@@ -4987,6 +4996,9 @@ qemuDomainRestoreFlags(virConnectPtr conn,
     else if (flags & VIR_DOMAIN_SAVE_PAUSED)
         state = 0;
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     fd = qemuDomainSaveImageOpen(driver, path, &def, &header,
                                  (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
                                  &wrapperFd, dxml, state, false, false);
@@ -4994,7 +5006,7 @@ qemuDomainRestoreFlags(virConnectPtr conn,
         goto cleanup;
 
     if (!(vm = virDomainObjListAdd(driver->domains,
-                                   driver->caps,
+                                   caps,
                                    def,
                                    VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
                                    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
@@ -5023,6 +5035,7 @@ cleanup:
     virFileWrapperFdFree(wrapperFd);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     qemuDriverUnlock(driver);
     return ret;
 }
@@ -5271,6 +5284,7 @@ static char *qemuDomainXMLFromNative(virConnectPtr conn,
     virQEMUDriverPtr driver = conn->privateData;
     virDomainDefPtr def = NULL;
     char *xml = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(0, NULL);
 
@@ -5281,7 +5295,11 @@ static char *qemuDomainXMLFromNative(virConnectPtr conn,
     }
 
     qemuDriverLock(driver);
-    def = qemuParseCommandLineString(driver->caps, config,
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    def = qemuParseCommandLineString(caps, config,
                                      NULL, NULL, NULL);
     qemuDriverUnlock(driver);
     if (!def)
@@ -5297,6 +5315,7 @@ static char *qemuDomainXMLFromNative(virConnectPtr conn,
 
 cleanup:
     virDomainDefFree(def);
+    virObjectUnref(caps);
     return xml;
 }
 
@@ -5314,6 +5333,7 @@ static char *qemuDomainXMLToNative(virConnectPtr conn,
     char *ret = NULL;
     int i;
     virQEMUDriverConfigPtr cfg;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(0, NULL);
 
@@ -5326,7 +5346,10 @@ static char *qemuDomainXMLToNative(virConnectPtr conn,
         goto cleanup;
     }
 
-    def = virDomainDefParseString(driver->caps, xmlData,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    def = virDomainDefParseString(caps, xmlData,
                                   QEMU_EXPECTED_VIRT_TYPES, 0);
     if (!def)
         goto cleanup;
@@ -5427,6 +5450,7 @@ cleanup:
     virObjectUnref(qemuCaps);
     virCommandFree(cmd);
     virDomainDefFree(def);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -5588,17 +5612,22 @@ qemuDomainStart(virDomainPtr dom)
 
 static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
     virQEMUDriverPtr driver = conn->privateData;
-    virDomainDefPtr def;
+    virDomainDefPtr def = NULL;
     virDomainDefPtr oldDef = NULL;
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
     virQEMUCapsPtr qemuCaps = NULL;
     virQEMUDriverConfigPtr cfg;
+    virCapsPtr caps = NULL;
 
     qemuDriverLock(driver);
     cfg = virQEMUDriverGetConfig(driver);
-    if (!(def = virDomainDefParseString(driver->caps, xml,
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (!(def = virDomainDefParseString(caps, xml,
                                         QEMU_EXPECTED_VIRT_TYPES,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
@@ -5616,7 +5645,7 @@ static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
         goto cleanup;
 
     if (!(vm = virDomainObjListAdd(driver->domains,
-                                   driver->caps,
+                                   caps,
                                    def,
                                    0,
                                    &oldDef)))
@@ -5670,6 +5699,7 @@ cleanup:
         qemuDomainEventQueue(driver, event);
     virObjectUnref(qemuCaps);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return dom;
 }
@@ -6406,6 +6436,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
     virQEMUCapsPtr qemuCaps = NULL;
     qemuDomainObjPrivatePtr priv;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -6417,6 +6448,9 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
     affect = flags & (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG);
 
     qemuDriverLock(driver);
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
     if (!vm) {
         char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -6451,7 +6485,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
          goto endjob;
     }
 
-    dev = dev_copy = virDomainDeviceDefParse(driver->caps, vm->def, xml,
+    dev = dev_copy = virDomainDeviceDefParse(caps, vm->def, xml,
                                              VIR_DOMAIN_XML_INACTIVE);
     if (dev == NULL)
         goto endjob;
@@ -6462,7 +6496,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
          * create a deep copy of device as adding
          * to CONFIG takes one instance.
          */
-        dev_copy = virDomainDeviceDefCopy(driver->caps, vm->def, dev);
+        dev_copy = virDomainDeviceDefCopy(caps, vm->def, dev);
         if (!dev_copy)
             goto endjob;
     }
@@ -6477,7 +6511,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
             goto endjob;
 
         /* Make a copy for updated domain. */
-        vmdef = virDomainObjCopyPersistentDef(driver->caps, vm);
+        vmdef = virDomainObjCopyPersistentDef(caps, vm);
         if (!vmdef)
             goto endjob;
         switch (action) {
@@ -6528,7 +6562,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
          * changed even if we failed to attach the device. For example,
          * a new controller may be created.
          */
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             ret = -1;
             goto endjob;
         }
@@ -6556,6 +6590,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -6887,6 +6922,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
     virDomainDefPtr persistentDef = NULL;
     int ret = -1;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -6906,8 +6942,10 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
         goto cleanup;
     }
     cfg = virQEMUDriverGetConfig(driver);
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -7025,6 +7063,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -7043,6 +7082,7 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
     unsigned int val;
     int ret = -1;
     int rc;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -7062,6 +7102,9 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
         goto cleanup;
     }
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     if ((*nparams) == 0) {
         /* Current number of blkio parameters supported by cgroups */
         *nparams = QEMU_NB_BLKIO_PARAM;
@@ -7069,7 +7112,7 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
         goto cleanup;
     }
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -7211,6 +7254,7 @@ cleanup:
         virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     qemuDriverUnlock(driver);
     return ret;
 }
@@ -7234,6 +7278,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
     virQEMUDriverConfigPtr cfg = NULL;
     int ret = -1;
     int rc;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -7260,7 +7305,10 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
 
     cfg = virQEMUDriverGetConfig(driver);
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -7383,6 +7431,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -7400,6 +7449,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
     virDomainDefPtr persistentDef = NULL;
     int ret = -1;
     int rc;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -7418,7 +7468,10 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
         goto cleanup;
     }
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -7543,6 +7596,7 @@ cleanup:
         virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     qemuDriverUnlock(driver);
     return ret;
 }
@@ -7560,6 +7614,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
     virDomainObjPtr vm = NULL;
     int ret = -1;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -7582,7 +7637,10 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
     }
     cfg = virQEMUDriverGetConfig(driver);
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -7695,6 +7753,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -7713,6 +7772,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
     char *nodeset = NULL;
     int ret = -1;
     int rc;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -7733,7 +7793,10 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
         goto cleanup;
     }
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -7808,6 +7871,7 @@ cleanup:
     virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     qemuDriverUnlock(driver);
     return ret;
 }
@@ -7912,6 +7976,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
     int ret = -1;
     int rc;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -7941,13 +8006,16 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
 
     cfg = virQEMUDriverGetConfig(driver);
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &vmdef) < 0)
         goto cleanup;
 
     if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
         /* Make a copy for updated domain. */
-        vmdef = virDomainObjCopyPersistentDef(driver->caps, vm);
+        vmdef = virDomainObjCopyPersistentDef(caps, vm);
         if (!vmdef)
             goto cleanup;
     }
@@ -8042,7 +8110,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
         }
     }
 
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+    if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
         goto cleanup;
 
 
@@ -8063,6 +8131,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -8200,6 +8269,7 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
     bool cpu_bw_status = false;
     int saved_nparams = 0;
     virDomainDefPtr persistentDef;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -8225,7 +8295,10 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
         goto cleanup;
     }
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -8322,6 +8395,7 @@ cleanup:
     virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     qemuDriverUnlock(driver);
     return ret;
 }
@@ -8728,6 +8802,7 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
     virDomainNetDefPtr net = NULL, persistentNet = NULL;
     virNetDevBandwidthPtr bandwidth = NULL, newBandwidth = NULL;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -8758,7 +8833,10 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
 
     cfg = virQEMUDriverGetConfig(driver);
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -8886,6 +8964,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -8905,6 +8984,7 @@ qemuDomainGetInterfaceParameters(virDomainPtr dom,
     virDomainDefPtr persistentDef = NULL;
     virDomainNetDefPtr net = NULL;
     int ret = -1;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -8922,7 +9002,10 @@ qemuDomainGetInterfaceParameters(virDomainPtr dom,
         goto cleanup;
     }
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -9008,6 +9091,7 @@ cleanup:
         virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     qemuDriverUnlock(driver);
     return ret;
 }
@@ -10141,24 +10225,26 @@ qemuCPUCompare(virConnectPtr conn,
 {
     virQEMUDriverPtr driver = conn->privateData;
     int ret = VIR_CPU_COMPARE_ERROR;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(0, VIR_CPU_COMPARE_ERROR);
 
     qemuDriverLock(driver);
 
-    if (!driver->caps) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("cannot get host capabilities"));
-    } else if (!driver->caps->host.cpu ||
-               !driver->caps->host.cpu->model) {
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (!caps->host.cpu ||
+        !caps->host.cpu->model) {
         VIR_WARN("cannot get host CPU capabilities");
         ret = VIR_CPU_COMPARE_INCOMPATIBLE;
     } else {
-        ret = cpuCompareXML(driver->caps->host.cpu, xmlDesc);
+        ret = cpuCompareXML(caps->host.cpu, xmlDesc);
     }
 
+cleanup:
+    virObjectUnref(caps);
     qemuDriverUnlock(driver);
-
     return ret;
 }
 
@@ -11022,6 +11108,10 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
     bool reuse = (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT) != 0;
     virCgroupPtr cgroup = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
@@ -11116,10 +11206,11 @@ cleanup:
     virCgroupFree(&cgroup);
 
     if (ret == 0 || !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_TRANSACTION)) {
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0 ||
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0 ||
             (persist && virDomainSaveConfig(cfg->configDir, vm->newDef) < 0))
             ret = -1;
     }
+    virObjectUnref(caps);
     virObjectUnref(cfg);
 
     return ret;
@@ -11325,6 +11416,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
     int align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL;
     int align_match = true;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
                   VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT |
@@ -11361,6 +11453,9 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 
     cfg = virQEMUDriverGetConfig(driver);
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     if (qemuProcessAutoDestroyActive(driver, vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("domain is marked for auto destroy"));
@@ -11381,7 +11476,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
         !virDomainObjIsActive(vm))
         parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_OFFLINE;
 
-    if (!(def = virDomainSnapshotDefParseString(xmlDesc, driver->caps,
+    if (!(def = virDomainSnapshotDefParseString(xmlDesc, caps,
                                                 QEMU_EXPECTED_VIRT_TYPES,
                                                 parse_flags)))
         goto cleanup;
@@ -11557,7 +11652,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
         /* Easiest way to clone inactive portion of vm->def is via
          * conversion in and back out of xml.  */
         if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, true)) ||
-            !(def->dom = virDomainDefParseString(driver->caps, xml,
+            !(def->dom = virDomainDefParseString(caps, xml,
                                                  QEMU_EXPECTED_VIRT_TYPES,
                                                  VIR_DOMAIN_XML_INACTIVE)))
             goto cleanup;
@@ -11683,6 +11778,7 @@ cleanup:
     virDomainSnapshotDefFree(def);
     VIR_FREE(xml);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return snapshot;
 }
@@ -12034,6 +12130,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
     int rc;
     virDomainDefPtr config = NULL;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
                   VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED |
@@ -12064,6 +12161,9 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
 
     cfg = virQEMUDriverGetConfig(driver);
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     if (virDomainHasDiskMirror(vm)) {
         virReportError(VIR_ERR_BLOCK_COPY_ACTIVE, "%s",
                        _("domain has active block copy job"));
@@ -12125,7 +12225,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
      * than inactive xml?  */
     snap->def->current = true;
     if (snap->def->dom) {
-        config = virDomainDefCopy(driver->caps, snap->def->dom, true);
+        config = virDomainDefCopy(caps, snap->def->dom, true);
         if (!config)
             goto cleanup;
     }
@@ -12353,6 +12453,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
 
     return ret;
@@ -12580,12 +12681,16 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn,
     pid_t pid = pid_value;
     char *pidfile = NULL;
     virQEMUCapsPtr qemuCaps = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(0, NULL);
 
     qemuDriverLock(driver);
 
-    if (!(def = qemuParseCommandLinePid(driver->caps, pid,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (!(def = qemuParseCommandLinePid(caps, pid,
                                         &pidfile, &monConfig, &monJSON)))
         goto cleanup;
 
@@ -12619,7 +12724,7 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn,
         goto cleanup;
 
     if (!(vm = virDomainObjListAdd(driver->domains,
-                                   driver->caps,
+                                   caps,
                                    def,
                                    VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
                                    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
@@ -12656,6 +12761,7 @@ cleanup:
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
     VIR_FREE(pidfile);
+    virObjectUnref(caps);
     return dom;
 }
 
@@ -13655,6 +13761,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
     bool set_bytes = false;
     bool set_iops = false;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -13687,6 +13794,9 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
     priv = vm->privateData;
     cfg = virQEMUDriverGetConfig(driver);
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("block I/O throttling not supported with this "
@@ -13702,7 +13812,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
     if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
         goto cleanup;
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto endjob;
 
@@ -13806,6 +13916,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 }
@@ -13826,6 +13937,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom,
     const char *device = NULL;
     int ret = -1;
     int i;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -13843,6 +13955,9 @@ qemuDomainGetBlockIoTune(virDomainPtr dom,
         goto cleanup;
     }
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     if ((*nparams) == 0) {
         /* Current number of parameters supported by QEMU Block I/O Throttling */
         *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM;
@@ -13859,7 +13974,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom,
     if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
         goto cleanup;
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto endjob;
 
@@ -13942,6 +14057,7 @@ cleanup:
     VIR_FREE(device);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     qemuDriverUnlock(driver);
     return ret;
 }
@@ -14035,6 +14151,7 @@ qemuDomainSetMetadata(virDomainPtr dom,
     virDomainDefPtr persistentDef;
     int ret = -1;
     virQEMUDriverConfigPtr cfg = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -14044,7 +14161,10 @@ qemuDomainSetMetadata(virDomainPtr dom,
 
     cfg = virQEMUDriverGetConfig(driver);
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
 
@@ -14111,6 +14231,7 @@ qemuDomainSetMetadata(virDomainPtr dom,
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return ret;
 no_memory:
@@ -14129,6 +14250,7 @@ qemuDomainGetMetadata(virDomainPtr dom,
     virDomainDefPtr def;
     char *ret = NULL;
     char *field = NULL;
+    virCapsPtr caps = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, NULL);
@@ -14136,7 +14258,10 @@ qemuDomainGetMetadata(virDomainPtr dom,
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
-    if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &def) < 0)
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (virDomainLiveConfigHelperMethod(caps, vm, &flags, &def) < 0)
         goto cleanup;
 
     /* use correct domain definition according to flags */
@@ -14177,6 +14302,7 @@ qemuDomainGetMetadata(virDomainPtr dom,
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(caps);
     return ret;
 }
 
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 82d2699..815f7a5 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -742,9 +742,13 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
                             unsigned int flags)
 {
     char uuidstr[VIR_UUID_STRING_BUFLEN];
-    char *tmp;
+    char *tmp = NULL;
     xmlNodePtr *nodes = NULL;
     int i, n;
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto error;
 
     /* We don't store the uuid, name, hostname, or hostuuid
      * values. We just compare them to local data to do some
@@ -870,7 +874,7 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
                            n);
             goto error;
         }
-        mig->persistent = virDomainDefParseNode(driver->caps, doc, nodes[0],
+        mig->persistent = virDomainDefParseNode(caps, doc, nodes[0],
                                                 -1, VIR_DOMAIN_XML_INACTIVE);
         if (!mig->persistent) {
             /* virDomainDefParseNode already reported
@@ -885,11 +889,13 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
         (!(mig->network = qemuMigrationCookieNetworkXMLParse(ctxt))))
         goto error;
 
+    virObjectUnref(caps);
     return 0;
 
 error:
     VIR_FREE(tmp);
     VIR_FREE(nodes);
+    virObjectUnref(caps);
     return -1;
 }
 
@@ -1434,12 +1440,16 @@ char *qemuMigrationBegin(virQEMUDriverPtr driver,
     qemuMigrationCookiePtr mig = NULL;
     virDomainDefPtr def = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virCapsPtr caps = NULL;
 
     VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s,"
               " cookieout=%p, cookieoutlen=%p, flags=%lx",
               driver, vm, NULLSTR(xmlin), NULLSTR(dname),
               cookieout, cookieoutlen, flags);
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     /* Only set the phase if we are inside QEMU_ASYNC_JOB_MIGRATION_OUT.
      * Otherwise we will start the async job later in the perform phase losing
      * change protection.
@@ -1484,7 +1494,7 @@ char *qemuMigrationBegin(virQEMUDriverPtr driver,
     }
 
     if (xmlin) {
-        if (!(def = virDomainDefParseString(driver->caps, xmlin,
+        if (!(def = virDomainDefParseString(caps, xmlin,
                                             QEMU_EXPECTED_VIRT_TYPES,
                                             VIR_DOMAIN_XML_INACTIVE)))
             goto cleanup;
@@ -1505,6 +1515,7 @@ char *qemuMigrationBegin(virQEMUDriverPtr driver,
 
 cleanup:
     qemuMigrationCookieFree(mig);
+    virObjectUnref(caps);
     virDomainDefFree(def);
     return rv;
 }
@@ -1555,6 +1566,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
     char *origname = NULL;
     char *xmlout = NULL;
     unsigned int cookieFlags;
+    virCapsPtr caps = NULL;
 
     if (virTimeMillisNow(&now) < 0)
         return -1;
@@ -1581,7 +1593,10 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
         }
     }
 
-    if (!(def = virDomainDefParseString(driver->caps, dom_xml,
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    if (!(def = virDomainDefParseString(caps, dom_xml,
                                         QEMU_EXPECTED_VIRT_TYPES,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
@@ -1622,7 +1637,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
                 virDomainDefPtr newdef;
 
                 VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
-                newdef = virDomainDefParseString(driver->caps, xmlout,
+                newdef = virDomainDefParseString(caps, xmlout,
                                                  QEMU_EXPECTED_VIRT_TYPES,
                                                  VIR_DOMAIN_XML_INACTIVE);
                 if (!newdef)
@@ -1640,7 +1655,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
     }
 
     if (!(vm = virDomainObjListAdd(driver->domains,
-                                   driver->caps,
+                                   caps,
                                    def,
                                    VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
                                    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
@@ -1760,6 +1775,7 @@ cleanup:
     if (event)
         qemuDomainEventQueue(driver, event);
     qemuMigrationCookieFree(mig);
+    virObjectUnref(caps);
     return ret;
 
 endjob:
@@ -3323,12 +3339,16 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
     int cookie_flags = 0;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
 
     VIR_DEBUG("driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
               "cookieout=%p, cookieoutlen=%p, flags=%lx, retcode=%d",
               driver, dconn, vm, NULLSTR(cookiein), cookieinlen,
               cookieout, cookieoutlen, flags, retcode);
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_IN))
         goto cleanup;
 
@@ -3379,7 +3399,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
             if (mig->persistent)
                 vm->newDef = vmdef = mig->persistent;
             else
-                vmdef = virDomainObjGetPersistentDef(driver->caps, vm);
+                vmdef = virDomainObjGetPersistentDef(caps, vm);
             if (!vmdef || virDomainSaveConfig(cfg->configDir, vmdef) < 0) {
                 /* Hmpf.  Migration was successful, but making it persistent
                  * was not.  If we report successful, then when this domain
@@ -3474,7 +3494,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
         }
 
         if (virDomainObjIsActive(vm) &&
-            virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+            virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Failed to save status on vm %s", vm->def->name);
             goto endjob;
         }
@@ -3513,6 +3533,7 @@ cleanup:
         virSetError(orig_err);
         virFreeError(orig_err);
     }
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return dom;
 }
@@ -3530,6 +3551,7 @@ int qemuMigrationConfirm(virQEMUDriverPtr driver,
     virDomainEventPtr event = NULL;
     int rv = -1;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
 
     VIR_DEBUG("driver=%p, conn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
               "flags=%x, retcode=%d",
@@ -3538,6 +3560,9 @@ int qemuMigrationConfirm(virQEMUDriverPtr driver,
 
     virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     qemuMigrationJobSetPhase(driver, vm,
                              retcode == 0
                              ? QEMU_MIGRATION_PHASE_CONFIRM3
@@ -3578,7 +3603,7 @@ int qemuMigrationConfirm(virQEMUDriverPtr driver,
         event = virDomainEventNewFromObj(vm,
                                          VIR_DOMAIN_EVENT_RESUMED,
                                          VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Failed to save status on vm %s", vm->def->name);
             goto cleanup;
         }
@@ -3591,6 +3616,7 @@ done:
 cleanup:
     if (event)
         qemuDomainEventQueue(driver, event);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return rv;
 }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e632615..24073aa 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -660,9 +660,13 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     qemuDomainObjPrivatePtr priv;
     virDomainEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
 
     VIR_DEBUG("vm=%p", vm);
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     virObjectLock(vm);
 
     priv = vm->privateData;
@@ -686,7 +690,7 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                      VIR_DOMAIN_EVENT_SHUTDOWN,
                                      VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED);
 
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+    if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
         VIR_WARN("Unable to save status on vm %s after state change",
                  vm->def->name);
     }
@@ -698,12 +702,13 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 
 unlock:
     virObjectUnlock(vm);
-
+cleanup:
     if (event) {
         qemuDriverLock(driver);
         qemuDomainEventQueue(driver, event);
         qemuDriverUnlock(driver);
     }
+    virObjectUnref(caps);
     virObjectUnref(cfg);
 
     return 0;
@@ -717,6 +722,10 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     virObjectLock(vm);
     if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
@@ -740,7 +749,7 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
             VIR_WARN("Unable to release lease on %s", vm->def->name);
         VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
 
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after state change",
                      vm->def->name);
         }
@@ -749,11 +758,13 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 unlock:
     virObjectUnlock(vm);
 
+cleanup:
     if (event) {
         qemuDriverLock(driver);
         qemuDomainEventQueue(driver, event);
         qemuDriverUnlock(driver);
     }
+    virObjectUnref(caps);
     virObjectUnref(cfg);
 
     return 0;
@@ -767,6 +778,10 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     virObjectLock(vm);
     if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
@@ -797,7 +812,7 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         }
         VIR_FREE(priv->lockState);
 
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after state change",
                      vm->def->name);
         }
@@ -805,12 +820,13 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 
 unlock:
     virObjectUnlock(vm);
-
+cleanup:
     if (event) {
         qemuDriverLock(driver);
         qemuDomainEventQueue(driver, event);
         qemuDriverUnlock(driver);
     }
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return 0;
 }
@@ -822,8 +838,12 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                            long long offset)
 {
     virQEMUDriverPtr driver = qemu_driver;
-    virDomainEventPtr event;
+    virDomainEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     virObjectLock(vm);
     event = virDomainEventRTCChangeNewFromObj(vm, offset);
@@ -831,17 +851,18 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     if (vm->def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE)
         vm->def->clock.data.variable.adjustment = offset;
 
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+    if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
         VIR_WARN("unable to save domain status with RTC change");
 
     virObjectUnlock(vm);
 
+cleanup:
     if (event) {
         qemuDriverLock(driver);
         qemuDomainEventQueue(driver, event);
         qemuDriverUnlock(driver);
     }
-
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return 0;
 }
@@ -856,6 +877,10 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virDomainEventPtr watchdogEvent = NULL;
     virDomainEventPtr lifecycleEvent = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     virObjectLock(vm);
     watchdogEvent = virDomainEventWatchdogNewFromObj(vm, action);
@@ -875,7 +900,7 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
             VIR_WARN("Unable to release lease on %s", vm->def->name);
         VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
 
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after watchdog event",
                      vm->def->name);
         }
@@ -903,6 +928,7 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     if (vm)
         virObjectUnlock(vm);
 
+cleanup:
     if (watchdogEvent || lifecycleEvent) {
         qemuDriverLock(driver);
         if (watchdogEvent)
@@ -912,6 +938,7 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         qemuDriverUnlock(driver);
     }
 
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return 0;
 }
@@ -932,6 +959,10 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     const char *devAlias;
     virDomainDiskDefPtr disk;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     virObjectLock(vm);
     disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);
@@ -962,11 +993,12 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
             VIR_WARN("Unable to release lease on %s", vm->def->name);
         VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
 
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
             VIR_WARN("Unable to save status on vm %s after IO error", vm->def->name);
     }
     virObjectUnlock(vm);
 
+cleanup:
     if (ioErrorEvent || ioErrorEvent2 || lifecycleEvent) {
         qemuDriverLock(driver);
         if (ioErrorEvent)
@@ -977,7 +1009,7 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
             qemuDomainEventQueue(driver, lifecycleEvent);
         qemuDriverUnlock(driver);
     }
-
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return 0;
 }
@@ -1134,6 +1166,10 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virDomainEventPtr event = NULL;
     virDomainDiskDefPtr disk;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     virObjectLock(vm);
     disk = qemuProcessFindDomainDiskByAlias(vm, devAlias);
@@ -1148,19 +1184,20 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         else if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE)
             disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
 
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after tray moved event",
                      vm->def->name);
         }
     }
 
     virObjectUnlock(vm);
-
+cleanup:
     if (event) {
         qemuDriverLock(driver);
         qemuDomainEventQueue(driver, event);
         qemuDriverUnlock(driver);
     }
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return 0;
 }
@@ -1173,6 +1210,10 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virDomainEventPtr event = NULL;
     virDomainEventPtr lifecycleEvent = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     virObjectLock(vm);
     event = virDomainEventPMWakeupNewFromObj(vm);
@@ -1190,7 +1231,7 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                                   VIR_DOMAIN_EVENT_STARTED,
                                                   VIR_DOMAIN_EVENT_STARTED_WAKEUP);
 
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after wakeup event",
                      vm->def->name);
         }
@@ -1198,6 +1239,7 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 
     virObjectUnlock(vm);
 
+cleanup:
     if (event || lifecycleEvent) {
         qemuDriverLock(driver);
         if (event)
@@ -1206,7 +1248,7 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
             qemuDomainEventQueue(driver, lifecycleEvent);
         qemuDriverUnlock(driver);
     }
-
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return 0;
 }
@@ -1219,6 +1261,10 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virDomainEventPtr event = NULL;
     virDomainEventPtr lifecycleEvent = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     virObjectLock(vm);
     event = virDomainEventPMSuspendNewFromObj(vm);
@@ -1235,7 +1281,7 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                      VIR_DOMAIN_EVENT_PMSUSPENDED,
                                      VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY);
 
-        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after suspend event",
                      vm->def->name);
         }
@@ -1246,6 +1292,7 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 
     virObjectUnlock(vm);
 
+cleanup:
     if (event || lifecycleEvent) {
         qemuDriverLock(driver);
         if (event)
@@ -1254,6 +1301,7 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
             qemuDomainEventQueue(driver, lifecycleEvent);
         qemuDriverUnlock(driver);
     }
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return 0;
 }
@@ -1264,8 +1312,12 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                unsigned long long actual)
 {
     virQEMUDriverPtr driver = qemu_driver;
-    virDomainEventPtr event;
+    virDomainEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     virObjectLock(vm);
     event = virDomainEventBalloonChangeNewFromObj(vm, actual);
@@ -1274,17 +1326,18 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
               vm->def->mem.cur_balloon, actual);
     vm->def->mem.cur_balloon = actual;
 
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+    if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
         VIR_WARN("unable to save domain status with balloon change");
 
     virObjectUnlock(vm);
 
+cleanup:
     if (event) {
         qemuDriverLock(driver);
         qemuDomainEventQueue(driver, event);
         qemuDriverUnlock(driver);
     }
-
+    virObjectUnref(caps);
     virObjectUnref(cfg);
     return 0;
 }
@@ -1297,6 +1350,10 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virDomainEventPtr event = NULL;
     virDomainEventPtr lifecycleEvent = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
 
     virObjectLock(vm);
     event = virDomainEventPMSuspendDiskNewFromObj(vm);
@@ -1313,7 +1370,7 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                      VIR_DOMAIN_EVENT_PMSUSPENDED,
                                      VIR_DOMAIN_EVENT_PMSUSPENDED_DISK);
 
-        if (virDomainSaveStatus(driver->caps,cfg->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after suspend event",
                      vm->def->name);
         }
@@ -1324,6 +1381,7 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 
     virObjectUnlock(vm);
 
+cleanup:
     if (event || lifecycleEvent) {
         qemuDriverLock(driver);
         if (event)
@@ -1332,7 +1390,7 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
             qemuDomainEventQueue(driver, lifecycleEvent);
         qemuDriverUnlock(driver);
     }
-
+    virObjectUnref(caps);
     virObjectUnref(cfg);
 
     return 0;
@@ -2029,6 +2087,7 @@ qemuPrepareCpumap(virQEMUDriverPtr driver,
 {
     int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN;
     virBitmapPtr cpumap = NULL;
+    virCapsPtr caps = NULL;
 
     /* setaffinity fails if you set bits for CPUs which
      * aren't present, so we have to limit ourselves */
@@ -2044,24 +2103,33 @@ qemuPrepareCpumap(virQEMUDriverPtr driver,
     }
 
     if (nodemask) {
-        for (i = 0; i < driver->caps->host.nnumaCell; i++) {
+        if (!(caps = virQEMUDriverGetCapabilities(driver, false))) {
+            virBitmapFree(cpumap);
+            cpumap = NULL;
+            goto cleanup;
+        }
+
+        for (i = 0; i < caps->host.nnumaCell; i++) {
             int j;
-            int cur_ncpus = driver->caps->host.numaCell[i]->ncpus;
+            int cur_ncpus = caps->host.numaCell[i]->ncpus;
             bool result;
             if (virBitmapGetBit(nodemask, i, &result) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                _("Failed to convert nodeset to cpuset"));
                 virBitmapFree(cpumap);
-                return NULL;
+                cpumap = NULL;
+                goto cleanup;
             }
             if (result) {
                 for (j = 0; j < cur_ncpus; j++)
                     ignore_value(virBitmapSetBit(cpumap,
-                                                 driver->caps->host.numaCell[i]->cpus[j].id));
+                                                 caps->host.numaCell[i]->cpus[j].id));
             }
         }
     }
 
+cleanup:
+    virObjectUnref(caps);
     return cpumap;
 }
 
@@ -3185,6 +3253,7 @@ qemuProcessReconnect(void *opaque)
     int state;
     int reason;
     virQEMUDriverConfigPtr cfg;
+    virCapsPtr caps = NULL;
 
     memcpy(&oldjob, &data->oldjob, sizeof(oldjob));
 
@@ -3205,6 +3274,9 @@ qemuProcessReconnect(void *opaque)
      * deleted if qemuConnectMonitor() failed */
     virObjectRef(obj);
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto error;
+
     /* XXX check PID liveliness & EXE path */
     if (qemuConnectMonitor(driver, obj) < 0)
         goto error;
@@ -3275,7 +3347,7 @@ qemuProcessReconnect(void *opaque)
         goto error;
 
     /* update domain state XML with possibly updated state in virDomainObj */
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, obj) < 0)
+    if (virDomainSaveStatus(caps, cfg->stateDir, obj) < 0)
         goto error;
 
     /* Run an hook to allow admins to do some magic */
@@ -3310,6 +3382,7 @@ endjob:
 
     virConnectClose(conn);
     virObjectUnref(cfg);
+    virObjectUnref(caps);
 
     return;
 
@@ -3348,8 +3421,8 @@ error:
         }
     }
     qemuDriverUnlock(driver);
-
     virConnectClose(conn);
+    virObjectUnref(caps);
     virObjectUnref(cfg);
 }
 
@@ -3550,6 +3623,7 @@ int qemuProcessStart(virConnectPtr conn,
     virBitmapPtr nodemask = NULL;
     unsigned int stop_flags;
     virQEMUDriverConfigPtr cfg;
+    virCapsPtr caps = NULL;
 
     /* Okay, these are just internal flags,
      * but doesn't hurt to check */
@@ -3578,12 +3652,15 @@ int qemuProcessStart(virConnectPtr conn,
         return -1;
     }
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     /* Do this upfront, so any part of the startup process can add
      * runtime state to vm->def that won't be persisted. This let's us
      * report implicit runtime defaults in the XML, like vnc listen/socket
      */
     VIR_DEBUG("Setting current domain def as transient");
-    if (virDomainObjSetDefTransient(driver->caps, vm, true) < 0)
+    if (virDomainObjSetDefTransient(caps, vm, true) < 0)
         goto cleanup;
 
     vm->def->id = qemuDriverAllocateID(driver);
@@ -3925,7 +4002,7 @@ int qemuProcessStart(virConnectPtr conn,
     }
 
     VIR_DEBUG("Writing early domain status to disk");
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
+    if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0) {
         goto cleanup;
     }
 
@@ -4076,7 +4153,7 @@ int qemuProcessStart(virConnectPtr conn,
         goto cleanup;
 
     VIR_DEBUG("Writing domain status to disk");
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+    if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
         goto cleanup;
 
     /* finally we can call the 'started' hook script if any */
@@ -4099,6 +4176,7 @@ int qemuProcessStart(virConnectPtr conn,
     virCommandFree(cmd);
     VIR_FORCE_CLOSE(logfile);
     virObjectUnref(cfg);
+    virObjectUnref(caps);
 
     return 0;
 
@@ -4112,6 +4190,7 @@ cleanup:
     VIR_FORCE_CLOSE(logfile);
     qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags);
     virObjectUnref(cfg);
+    virObjectUnref(caps);
 
     return -1;
 }
@@ -4420,6 +4499,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
     virSecurityManagerPtr* sec_managers = NULL;
     const char *model;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
 
     VIR_DEBUG("Beginning VM attach process");
 
@@ -4430,12 +4510,15 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
         return -1;
     }
 
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
     /* Do this upfront, so any part of the startup process can add
      * runtime state to vm->def that won't be persisted. This let's us
      * report implicit runtime defaults in the XML, like vnc listen/socket
      */
     VIR_DEBUG("Setting current domain def as transient");
-    if (virDomainObjSetDefTransient(driver->caps, vm, true) < 0)
+    if (virDomainObjSetDefTransient(caps, vm, true) < 0)
         goto cleanup;
 
     vm->def->id = qemuDriverAllocateID(driver);
@@ -4580,7 +4663,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
         virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
 
     VIR_DEBUG("Writing domain status to disk");
-    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
+    if (virDomainSaveStatus(caps, cfg->stateDir, vm) < 0)
         goto cleanup;
 
     /* Run an hook to allow admins to do some magic */
@@ -4604,6 +4687,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
     VIR_FREE(seclabel);
     VIR_FREE(sec_managers);
     virObjectUnref(cfg);
+    virObjectUnref(caps);
 
     return 0;
 
@@ -4618,6 +4702,7 @@ cleanup:
     VIR_FREE(sec_managers);
     virDomainChrSourceDefFree(monConfig);
     virObjectUnref(cfg);
+    virObjectUnref(caps);
     return -1;
 }
 
-- 
1.8.1




More information about the libvir-list mailing list