[PATCH v3 01/13] Introduce a virQEMUDriverConfigPtr object

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Daniel P. Berrange" <berrange@xxxxxxxxxx>

Currently the virQEMUDriverPtr struct contains an wide variety
of data with varying access needs. Move all the static config
data into a dedicated virQEMUDriverConfigPtr object. The only
locking requirement is to hold the driver lock, while obtaining
an instance of virQEMUDriverConfigPtr. Once a reference is held
on the config object, it can be used completely lockless since
it is immutable.

NB, not all APIs correctly hold the driver lock while getting
a reference to the config object in this patch. This is safe
for now since the config is never updated on the fly. Later
patches will address this fully.

Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx>
---
 src/qemu/qemu_cgroup.c                             |  28 +-
 src/qemu/qemu_command.c                            |  75 +--
 src/qemu/qemu_conf.c                               | 402 ++++++++-----
 src/qemu/qemu_conf.h                               | 136 +++--
 src/qemu/qemu_domain.c                             | 104 ++--
 src/qemu/qemu_driver.c                             | 635 +++++++++++----------
 src/qemu/qemu_hostdev.c                            |  17 +-
 src/qemu/qemu_hotplug.c                            | 185 +++---
 src/qemu/qemu_migration.c                          |  49 +-
 src/qemu/qemu_process.c                            | 154 +++--
 src/qemu/qemu_process.h                            |   2 +-
 tests/qemuargv2xmltest.c                           |  14 +-
 .../qemuxml2argv-graphics-vnc-tls.args             |   2 +-
 tests/qemuxml2argvtest.c                           |  37 +-
 tests/qemuxmlnstest.c                              |  14 +-
 15 files changed, 1099 insertions(+), 755 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 6527146..482989f 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -48,15 +48,20 @@ static const char *const defaultDeviceACL[] = {
 bool qemuCgroupControllerActive(virQEMUDriverPtr driver,
                                 int controller)
 {
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    bool ret = false;
     if (driver->cgroup == NULL)
-        return false;
+        goto cleanup;
     if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST)
-        return false;
+        goto cleanup;
     if (!virCgroupMounted(driver->cgroup, controller))
-        return false;
-    if (driver->cgroupControllers & (1 << controller))
-        return true;
-    return false;
+        goto cleanup;
+    if (cfg->cgroupControllers & (1 << controller))
+        ret = true;
+
+cleanup:
+    virObjectUnref(cfg);
+    return ret;
 }
 
 static int
@@ -195,13 +200,14 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
     virCgroupPtr cgroup = NULL;
     int rc;
     unsigned int i;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     const char *const *deviceACL =
-        driver->cgroupDeviceACL ?
-        (const char *const *)driver->cgroupDeviceACL :
+        cfg->cgroupDeviceACL ?
+        (const char *const *)cfg->cgroupDeviceACL :
         defaultDeviceACL;
 
     if (driver->cgroup == NULL)
-        return 0; /* Not supported, so claim success */
+        goto done; /* Not supported, so claim success */
 
     rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 1);
     if (rc != 0) {
@@ -246,7 +252,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
         if (vm->def->nsounds &&
             (!vm->def->ngraphics ||
              ((vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
-               driver->vncAllowHostAudio) ||
+               cfg->vncAllowHostAudio) ||
               (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL)))) {
             rc = virCgroupAllowDeviceMajor(cgroup, 'c', DEVICE_SND_MAJOR,
                                            VIR_CGROUP_DEVICE_RW);
@@ -434,10 +440,12 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
         }
     }
 done:
+    virObjectUnref(cfg);
     virCgroupFree(&cgroup);
     return 0;
 
 cleanup:
+    virObjectUnref(cfg);
     if (cgroup) {
         virCgroupRemove(cgroup);
         virCgroupFree(&cgroup);
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f6273c1..ef04634 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -152,6 +152,7 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
     int rc;
     char *res_ifname = NULL;
     int vnet_hdr = 0;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (qemuCapsGet(caps, QEMU_CAPS_VNET_HDR) &&
         net->model && STREQ(net->model, "virtio"))
@@ -164,7 +165,7 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
         true, vnet_hdr, def->uuid,
         virDomainNetGetActualVirtPortProfile(net),
         &res_ifname,
-        vmop, driver->stateDir,
+        vmop, cfg->stateDir,
         virDomainNetGetActualBandwidth(net));
     if (rc >= 0) {
         if (virSecurityManagerSetTapFDLabel(driver->securityManager,
@@ -176,6 +177,7 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
         net->ifname = res_ifname;
     }
 
+    virObjectUnref(cfg);
     return rc;
 
 error:
@@ -184,8 +186,9 @@ error:
                      virDomainNetGetActualDirectDev(net),
                      virDomainNetGetActualDirectMode(net),
                      virDomainNetGetActualVirtPortProfile(net),
-                     driver->stateDir));
+                     cfg->stateDir));
     VIR_FREE(res_ifname);
+    virObjectUnref(cfg);
     return -1;
 }
 
@@ -203,6 +206,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
     unsigned int tap_create_flags = VIR_NETDEV_TAP_CREATE_IFUP;
     bool template_ifname = false;
     int actualType = virDomainNetGetActualType(net);
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
         int active, fail = 0;
@@ -278,7 +282,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
         tapfd = -1;
     }
 
-    if (driver->macFilter) {
+    if (cfg->macFilter) {
         if ((err = networkAllowMacOnPort(driver, net->ifname, &net->mac))) {
             virReportSystemError(err,
                  _("failed to add ebtables rule to allow MAC address on '%s'"),
@@ -306,6 +310,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
 
 cleanup:
     VIR_FREE(brname);
+    virObjectUnref(cfg);
 
     return tapfd;
 }
@@ -3283,6 +3288,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     enum virDomainNetType netType = virDomainNetGetActualType(net);
     const char *brname = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -3298,7 +3304,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
      * through, -net tap,fd
      */
     case VIR_DOMAIN_NET_TYPE_BRIDGE:
-        if (!driver->privileged &&
+        if (!cfg->privileged &&
             qemuCapsGet(caps, QEMU_CAPS_NETDEV_BRIDGE)) {
             brname = virDomainNetGetActualBridgeName(net);
             virBufferAsprintf(&buf, "bridge%cbr=%s", type_sep, brname);
@@ -3374,6 +3380,8 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
             virBufferAsprintf(&buf, ",sndbuf=%lu", net->tune.sndbuf);
     }
 
+    virObjectUnref(cfg);
+
     if (virBufferError(&buf)) {
         virBufferFreeAndReset(&buf);
         virReportOOMError();
@@ -4706,7 +4714,7 @@ error:
 }
 
 static int
-qemuBuildGraphicsCommandLine(virQEMUDriverPtr driver,
+qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg,
                              virCommandPtr cmd,
                              virDomainDefPtr def,
                              qemuCapsPtr caps,
@@ -4724,11 +4732,11 @@ qemuBuildGraphicsCommandLine(virQEMUDriverPtr driver,
         }
 
         if (graphics->data.vnc.socket ||
-            driver->vncAutoUnixSocket) {
+            cfg->vncAutoUnixSocket) {
 
             if (!graphics->data.vnc.socket &&
                 virAsprintf(&graphics->data.vnc.socket,
-                            "%s/%s.vnc", driver->libDir, def->name) == -1) {
+                            "%s/%s.vnc", cfg->libDir, def->name) == -1) {
                 goto no_memory;
             }
 
@@ -4774,7 +4782,7 @@ qemuBuildGraphicsCommandLine(virQEMUDriverPtr driver,
             }
 
             if (!listenAddr)
-                listenAddr = driver->vncListen;
+                listenAddr = cfg->vncListen;
 
             escapeAddr = strchr(listenAddr, ':') != NULL;
             if (escapeAddr)
@@ -4792,26 +4800,26 @@ qemuBuildGraphicsCommandLine(virQEMUDriverPtr driver,
 
         if (qemuCapsGet(caps, QEMU_CAPS_VNC_COLON)) {
             if (graphics->data.vnc.auth.passwd ||
-                driver->vncPassword)
+                cfg->vncPassword)
                 virBufferAddLit(&opt, ",password");
 
-            if (driver->vncTLS) {
+            if (cfg->vncTLS) {
                 virBufferAddLit(&opt, ",tls");
-                if (driver->vncTLSx509verify) {
+                if (cfg->vncTLSx509verify) {
                     virBufferAsprintf(&opt, ",x509verify=%s",
-                                      driver->vncTLSx509certdir);
+                                      cfg->vncTLSx509certdir);
                 } else {
                     virBufferAsprintf(&opt, ",x509=%s",
-                                      driver->vncTLSx509certdir);
+                                      cfg->vncTLSx509certdir);
                 }
             }
 
-            if (driver->vncSASL) {
+            if (cfg->vncSASL) {
                 virBufferAddLit(&opt, ",sasl");
 
-                if (driver->vncSASLdir)
+                if (cfg->vncSASLdir)
                     virCommandAddEnvPair(cmd, "SASL_CONF_DIR",
-                                         driver->vncSASLdir);
+                                         cfg->vncSASLdir);
 
                 /* TODO: Support ACLs later */
             }
@@ -4828,7 +4836,7 @@ qemuBuildGraphicsCommandLine(virQEMUDriverPtr driver,
          * prevent it opening the host OS audio devices, since that causes
          * security issues and might not work when using VNC.
          */
-        if (driver->vncAllowHostAudio) {
+        if (cfg->vncAllowHostAudio) {
             virCommandAddEnvPass(cmd, "QEMU_AUDIO_DRV");
         } else {
             virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=none");
@@ -4884,7 +4892,7 @@ qemuBuildGraphicsCommandLine(virQEMUDriverPtr driver,
             virBufferAsprintf(&opt, "port=%u", port);
 
         if (tlsPort > 0) {
-            if (!driver->spiceTLS) {
+            if (!cfg->spiceTLS) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                _("spice TLS port set in XML configuration,"
                                  " but TLS is disabled in qemu.conf"));
@@ -4927,7 +4935,7 @@ qemuBuildGraphicsCommandLine(virQEMUDriverPtr driver,
         }
 
         if (!listenAddr)
-            listenAddr = driver->spiceListen;
+            listenAddr = cfg->spiceListen;
         if (listenAddr)
             virBufferAsprintf(&opt, ",addr=%s", listenAddr);
 
@@ -4951,12 +4959,12 @@ qemuBuildGraphicsCommandLine(virQEMUDriverPtr driver,
          * making it visible on CLI, so there's no use of password=XXX
          * in this bit of the code */
         if (!graphics->data.spice.auth.passwd &&
-            !driver->spicePassword)
+            !cfg->spicePassword)
             virBufferAddLit(&opt, ",disable-ticketing");
 
-        if (driver->spiceTLS)
+        if (cfg->spiceTLS)
             virBufferAsprintf(&opt, ",x509-dir=%s",
-                              driver->spiceTLSx509certdir);
+                              cfg->spiceTLSx509certdir);
 
         switch (defaultMode) {
         case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
@@ -4974,7 +4982,7 @@ qemuBuildGraphicsCommandLine(virQEMUDriverPtr driver,
             int mode = graphics->data.spice.channels[i];
             switch (mode) {
             case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
-                if (!driver->spiceTLS) {
+                if (!cfg->spiceTLS) {
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                    _("spice secure channels set in XML configuration, but TLS is disabled in qemu.conf"));
                     goto error;
@@ -5087,6 +5095,7 @@ qemuBuildCommandLine(virConnectPtr conn,
         VIR_DOMAIN_CONTROLLER_TYPE_CCID,
     };
     virArch hostarch = virArchFromHost();
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d "
               "caps=%p migrateFrom=%s migrateFD=%d "
@@ -5159,7 +5168,7 @@ qemuBuildCommandLine(virConnectPtr conn,
 
     if (qemuCapsGet(caps, QEMU_CAPS_NAME)) {
         virCommandAddArg(cmd, "-name");
-        if (driver->setProcessName &&
+        if (cfg->setProcessName &&
             qemuCapsGet(caps, QEMU_CAPS_NAME_PROCESS)) {
             virCommandAddArgFormat(cmd, "%s,process=qemu:%s",
                                    def->name, def->name);
@@ -5208,12 +5217,12 @@ qemuBuildCommandLine(virConnectPtr conn,
     def->mem.max_balloon = VIR_DIV_UP(def->mem.max_balloon, 1024) * 1024;
     virCommandAddArgFormat(cmd, "%llu", def->mem.max_balloon / 1024);
     if (def->mem.hugepage_backed) {
-        if (!driver->hugetlbfs_mount) {
+        if (!cfg->hugetlbfsMount) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            "%s", _("hugetlbfs filesystem is not mounted"));
             goto error;
         }
-        if (!driver->hugepage_path) {
+        if (!cfg->hugepagePath) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            "%s", _("hugepages are disabled by administrator config"));
             goto error;
@@ -5225,7 +5234,7 @@ qemuBuildCommandLine(virConnectPtr conn,
             goto error;
         }
         virCommandAddArgList(cmd, "-mem-prealloc", "-mem-path",
-                             driver->hugepage_path, NULL);
+                             cfg->hugepagePath, NULL);
     }
 
     virCommandAddArg(cmd, "-smp");
@@ -6108,7 +6117,7 @@ qemuBuildCommandLine(virConnectPtr conn,
                  * supported.
                  */
                 if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
-                    driver->privileged ||
+                    cfg->privileged ||
                     (!qemuCapsGet(caps, QEMU_CAPS_NETDEV_BRIDGE))) {
                     int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net,
                                                         caps);
@@ -6554,7 +6563,7 @@ qemuBuildCommandLine(virConnectPtr conn,
     }
 
     for (i = 0 ; i < def->ngraphics ; ++i) {
-        if (qemuBuildGraphicsCommandLine(driver, cmd, def, caps,
+        if (qemuBuildGraphicsCommandLine(cfg, cmd, def, caps,
                                          def->graphics[i]) < 0)
             goto error;
     }
@@ -7041,21 +7050,23 @@ qemuBuildCommandLine(virConnectPtr conn,
     }
 
     if (qemuCapsGet(caps, QEMU_CAPS_SECCOMP_SANDBOX)) {
-        if (driver->seccompSandbox == 0)
+        if (cfg->seccompSandbox == 0)
             virCommandAddArgList(cmd, "-sandbox", "off", NULL);
-        else if (driver->seccompSandbox > 0)
+        else if (cfg->seccompSandbox > 0)
             virCommandAddArgList(cmd, "-sandbox", "on", NULL);
-    } else if (driver->seccompSandbox > 0) {
+    } else if (cfg->seccompSandbox > 0) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("QEMU does not support seccomp sandboxes"));
         goto error;
     }
 
+    virObjectUnref(cfg);
     return cmd;
 
  no_memory:
     virReportOOMError();
  error:
+    virObjectUnref(cfg);
     /* free up any resources in the network driver */
     for (i = 0; i <= last_good_net; i++)
         virDomainConfNWFilterTeardown(def->nets[i]);
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index ee48333..46c1892 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -51,10 +51,28 @@
 #include "cpu/cpu.h"
 #include "domain_nwfilter.h"
 #include "virfile.h"
+#include "virstring.h"
 #include "configmake.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
+static virClassPtr virQEMUDriverConfigClass;
+static void virQEMUDriverConfigDispose(void *obj);
+
+static int virQEMUConfigOnceInit(void)
+{
+    if (!(virQEMUDriverConfigClass = virClassNew(virClassForObject(),
+                                                 "virQEMUDriverConfig",
+                                                 sizeof(virQEMUDriverConfig),
+                                                 virQEMUDriverConfigDispose)))
+        return -1;
+
+    return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virQEMUConfig)
+
+
 struct _qemuDriverCloseDef {
     virConnectPtr conn;
     qemuDriverCloseCallback cb;
@@ -70,68 +88,221 @@ void qemuDriverUnlock(virQEMUDriverPtr driver)
 }
 
 
-int qemuLoadDriverConfig(virQEMUDriverPtr driver,
-                         const char *filename) {
-    virConfPtr conf = NULL;
-    virConfValuePtr p;
-    char *user = NULL;
-    char *group = NULL;
-    int ret = -1;
-    int i;
+virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
+{
+    virQEMUDriverConfigPtr cfg;
+
+    if (virQEMUConfigInitialize() < 0)
+        return NULL;
+
+    if (!(cfg = virObjectNew(virQEMUDriverConfigClass)))
+        return NULL;
+
+    cfg->privileged = privileged;
+    cfg->uri = privileged ? "qemu:///system" : "qemu:///session";
+
+    if (privileged) {
+        if (virGetUserID(QEMU_USER, &cfg->user) < 0)
+            goto error;
+    } else {
+        cfg->user = 0;
+    }
+    if (privileged) {
+        if (virGetGroupID(QEMU_GROUP, &cfg->group) < 0)
+            goto error;
+    } else {
+        cfg->group = 0;
+    }
+    cfg->dynamicOwnership = privileged ? true : false;
+
+    cfg->cgroupControllers =
+        (1 << VIR_CGROUP_CONTROLLER_CPU) |
+        (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
+        (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
+        (1 << VIR_CGROUP_CONTROLLER_BLKIO) |
+        (1 << VIR_CGROUP_CONTROLLER_CPUSET) |
+        (1 << VIR_CGROUP_CONTROLLER_CPUACCT);
+
+
+    if (privileged) {
+        if (virAsprintf(&cfg->logDir,
+                        "%s/log/libvirt/qemu", LOCALSTATEDIR) < 0)
+            goto no_memory;
+
+        if ((cfg->configBaseDir = strdup(SYSCONFDIR "/libvirt")) == NULL)
+            goto no_memory;
+
+        if (virAsprintf(&cfg->stateDir,
+                      "%s/run/libvirt/qemu", LOCALSTATEDIR) < 0)
+            goto no_memory;
+
+        if (virAsprintf(&cfg->libDir,
+                      "%s/lib/libvirt/qemu", LOCALSTATEDIR) < 0)
+            goto no_memory;
+
+        if (virAsprintf(&cfg->cacheDir,
+                      "%s/cache/libvirt/qemu", LOCALSTATEDIR) < 0)
+            goto no_memory;
+        if (virAsprintf(&cfg->saveDir,
+                      "%s/lib/libvirt/qemu/save", LOCALSTATEDIR) < 0)
+            goto no_memory;
+        if (virAsprintf(&cfg->snapshotDir,
+                        "%s/lib/libvirt/qemu/snapshot", LOCALSTATEDIR) < 0)
+            goto no_memory;
+        if (virAsprintf(&cfg->autoDumpPath,
+                        "%s/lib/libvirt/qemu/dump", LOCALSTATEDIR) < 0)
+            goto no_memory;
+    } else {
+        char *rundir;
+        char *cachedir;
+
+        cachedir = virGetUserCacheDirectory();
+        if (!cachedir)
+            goto error;
 
-    /* Setup critical defaults */
-    driver->securityDefaultConfined = true;
-    driver->securityRequireConfined = false;
-    driver->dynamicOwnership = 1;
-    driver->clearEmulatorCapabilities = 1;
+        if (virAsprintf(&cfg->logDir,
+                        "%s/qemu/log", cachedir) < 0) {
+            VIR_FREE(cachedir);
+            goto no_memory;
+        }
+        if (virAsprintf(&cfg->cacheDir, "%s/qemu/cache", cachedir) < 0) {
+            VIR_FREE(cachedir);
+            goto no_memory;
+        }
+        VIR_FREE(cachedir);
+
+        rundir = virGetUserRuntimeDirectory();
+        if (!rundir)
+            goto error;
+        if (virAsprintf(&cfg->stateDir, "%s/qemu/run", rundir) < 0) {
+            VIR_FREE(rundir);
+            goto no_memory;
+        }
+        VIR_FREE(rundir);
+
+        if (!(cfg->configBaseDir = virGetUserConfigDirectory()))
+            goto error;
+
+        if (virAsprintf(&cfg->libDir, "%s/qemu/lib", cfg->configBaseDir) < 0)
+            goto no_memory;
+        if (virAsprintf(&cfg->saveDir, "%s/qemu/save", cfg->configBaseDir) < 0)
+            goto no_memory;
+        if (virAsprintf(&cfg->snapshotDir, "%s/qemu/snapshot", cfg->configBaseDir) < 0)
+            goto no_memory;
+        if (virAsprintf(&cfg->autoDumpPath, "%s/qemu/dump", cfg->configBaseDir) < 0)
+            goto no_memory;
+    }
 
-    if (!(driver->vncListen = strdup("127.0.0.1")))
+    if (virAsprintf(&cfg->configDir, "%s/qemu", cfg->configBaseDir) < 0)
+        goto no_memory;
+    if (virAsprintf(&cfg->autostartDir, "%s/qemu/autostart", cfg->configBaseDir) < 0)
         goto no_memory;
 
-    driver->remotePortMin = QEMU_REMOTE_PORT_MIN;
-    driver->remotePortMax = QEMU_REMOTE_PORT_MAX;
 
-    if (!(driver->vncTLSx509certdir = strdup(SYSCONFDIR "/pki/libvirt-vnc")))
+    if (!(cfg->vncListen = strdup("127.0.0.1")))
+        goto no_memory;
+
+    if (!(cfg->vncTLSx509certdir
+          = strdup(SYSCONFDIR "/pki/libvirt-vnc")))
         goto no_memory;
 
-    if (!(driver->spiceListen = strdup("127.0.0.1")))
+    if (!(cfg->spiceListen = strdup("127.0.0.1")))
         goto no_memory;
 
-    if (!(driver->spiceTLSx509certdir
+    if (!(cfg->spiceTLSx509certdir
           = strdup(SYSCONFDIR "/pki/libvirt-spice")))
         goto no_memory;
 
+    cfg->remotePortMin = QEMU_REMOTE_PORT_MIN;
+    cfg->remotePortMax = QEMU_REMOTE_PORT_MAX;
+
 #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
     /* For privileged driver, try and find hugepage mount automatically.
      * Non-privileged driver requires admin to create a dir for the
      * user, chown it, and then let user configure it manually */
-    if (driver->privileged &&
-        !(driver->hugetlbfs_mount = virFileFindMountPoint("hugetlbfs"))) {
+    if (privileged &&
+        !(cfg->hugetlbfsMount = virFileFindMountPoint("hugetlbfs"))) {
         if (errno != ENOENT) {
             virReportSystemError(errno, "%s",
                                  _("unable to find hugetlbfs mountpoint"));
-            goto cleanup;
+            goto error;
         }
     }
 #endif
 
-    if (!(driver->lockManager = virLockManagerPluginNew("nop",
-                                                        "qemu",
-                                                        driver->configBaseDir,
-                                                        0)))
-        goto cleanup;
+    cfg->clearEmulatorCapabilities = true;
+
+    cfg->securityDefaultConfined = true;
+    cfg->securityRequireConfined = false;
+
+    cfg->keepAliveInterval = 5;
+    cfg->keepAliveCount = 5;
+    cfg->seccompSandbox = -1;
+
+    return cfg;
+
+no_memory:
+    virReportOOMError();
+error:
+    virObjectUnref(cfg);
+    return NULL;
+}
+
+
+static void virQEMUDriverConfigDispose(void *obj)
+{
+    virQEMUDriverConfigPtr cfg = obj;
+
+
+    virStringFreeList(cfg->cgroupDeviceACL);
+
+    VIR_FREE(cfg->configBaseDir);
+    VIR_FREE(cfg->configDir);
+    VIR_FREE(cfg->autostartDir);
+    VIR_FREE(cfg->logDir);
+    VIR_FREE(cfg->stateDir);
+
+    VIR_FREE(cfg->libDir);
+    VIR_FREE(cfg->cacheDir);
+    VIR_FREE(cfg->saveDir);
+    VIR_FREE(cfg->snapshotDir);
+
+    VIR_FREE(cfg->vncTLSx509certdir);
+    VIR_FREE(cfg->vncListen);
+    VIR_FREE(cfg->vncPassword);
+    VIR_FREE(cfg->vncSASLdir);
+
+    VIR_FREE(cfg->spiceTLSx509certdir);
+    VIR_FREE(cfg->spiceListen);
+    VIR_FREE(cfg->spicePassword);
+
+    VIR_FREE(cfg->hugetlbfsMount);
+    VIR_FREE(cfg->hugepagePath);
+
+    VIR_FREE(cfg->saveImageFormat);
+    VIR_FREE(cfg->dumpImageFormat);
+    VIR_FREE(cfg->autoDumpPath);
+
+    virStringFreeList(cfg->securityDriverNames);
+
+    VIR_FREE(cfg->lockManagerName);
+}
 
-    driver->keepAliveInterval = 5;
-    driver->keepAliveCount = 5;
-    driver->seccompSandbox = -1;
+
+int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
+                                const char *filename)
+{
+    virConfPtr conf = NULL;
+    virConfValuePtr p;
+    int ret = -1;
+    int i;
 
     /* Just check the file is readable before opening it, otherwise
      * libvirt emits an error.
      */
     if (access(filename, R_OK) == -1) {
         VIR_INFO("Could not read qemu config file %s", filename);
-        ret = 0;
-        goto cleanup;
+        return 0;
     }
 
     if (!(conf = virConfReadFile(filename, 0)))
@@ -151,6 +322,12 @@ int qemuLoadDriverConfig(virQEMUDriverPtr driver,
     if (p)                            \
         VAR = p->l;
 
+#define GET_VALUE_BOOL(NAME, VAR)     \
+    p = virConfGetValue(conf, NAME);  \
+    CHECK_TYPE(NAME, VIR_CONF_LONG);  \
+    if (p)                            \
+        VAR = p->l != 0;
+
 #define GET_VALUE_STR(NAME, VAR)           \
     p = virConfGetValue(conf, NAME);       \
     CHECK_TYPE(NAME, VIR_CONF_STRING);     \
@@ -160,15 +337,15 @@ int qemuLoadDriverConfig(virQEMUDriverPtr driver,
             goto no_memory;                \
     }
 
-    GET_VALUE_LONG("vnc_auto_unix_socket", driver->vncAutoUnixSocket);
-    GET_VALUE_LONG("vnc_tls", driver->vncTLS);
-    GET_VALUE_LONG("vnc_tls_x509_verify", driver->vncTLSx509verify);
-    GET_VALUE_STR("vnc_tls_x509_cert_dir", driver->vncTLSx509certdir);
-    GET_VALUE_STR("vnc_listen", driver->vncListen);
-    GET_VALUE_STR("vnc_password", driver->vncPassword);
-    GET_VALUE_LONG("vnc_sasl", driver->vncSASL);
-    GET_VALUE_STR("vnc_sasl_dir", driver->vncSASLdir);
-    GET_VALUE_LONG("vnc_allow_host_audio", driver->vncAllowHostAudio);
+    GET_VALUE_BOOL("vnc_auto_unix_socket", cfg->vncAutoUnixSocket);
+    GET_VALUE_BOOL("vnc_tls", cfg->vncTLS);
+    GET_VALUE_BOOL("vnc_tls_x509_verify", cfg->vncTLSx509verify);
+    GET_VALUE_STR("vnc_tls_x509_cert_dir", cfg->vncTLSx509certdir);
+    GET_VALUE_STR("vnc_listen", cfg->vncListen);
+    GET_VALUE_STR("vnc_password", cfg->vncPassword);
+    GET_VALUE_BOOL("vnc_sasl", cfg->vncSASL);
+    GET_VALUE_STR("vnc_sasl_dir", cfg->vncSASLdir);
+    GET_VALUE_BOOL("vnc_allow_host_audio", cfg->vncAllowHostAudio);
 
     p = virConfGetValue(conf, "security_driver");
     if (p && p->type == VIR_CONF_LIST) {
@@ -184,36 +361,36 @@ int qemuLoadDriverConfig(virQEMUDriverPtr driver,
             }
         }
 
-        if (VIR_ALLOC_N(driver->securityDriverNames, len + 1) < 0)
+        if (VIR_ALLOC_N(cfg->securityDriverNames, len + 1) < 0)
             goto no_memory;
 
         for (i = 0, pp = p->list; pp; i++, pp = pp->next) {
-            if (!(driver->securityDriverNames[i] = strdup(pp->str)))
+            if (!(cfg->securityDriverNames[i] = strdup(pp->str)))
                 goto no_memory;
         }
-        driver->securityDriverNames[len] = NULL;
+        cfg->securityDriverNames[len] = NULL;
     } else {
         CHECK_TYPE("security_driver", VIR_CONF_STRING);
         if (p && p->str) {
-            if (VIR_ALLOC_N(driver->securityDriverNames, 2) < 0 ||
-                !(driver->securityDriverNames[0] = strdup(p->str)))
+            if (VIR_ALLOC_N(cfg->securityDriverNames, 2) < 0 ||
+                !(cfg->securityDriverNames[0] = strdup(p->str)))
                 goto no_memory;
 
-            driver->securityDriverNames[1] = NULL;
+            cfg->securityDriverNames[1] = NULL;
         }
     }
 
-    GET_VALUE_LONG("security_default_confined", driver->securityDefaultConfined);
-    GET_VALUE_LONG("security_require_confined", driver->securityRequireConfined);
+    GET_VALUE_BOOL("security_default_confined", cfg->securityDefaultConfined);
+    GET_VALUE_BOOL("security_require_confined", cfg->securityRequireConfined);
 
-    GET_VALUE_LONG("spice_tls", driver->spiceTLS);
-    GET_VALUE_STR("spice_tls_x509_cert_dir", driver->spiceTLSx509certdir);
-    GET_VALUE_STR("spice_listen", driver->spiceListen);
-    GET_VALUE_STR("spice_password", driver->spicePassword);
+    GET_VALUE_BOOL("spice_tls", cfg->spiceTLS);
+    GET_VALUE_STR("spice_tls_x509_cert_dir", cfg->spiceTLSx509certdir);
+    GET_VALUE_STR("spice_listen", cfg->spiceListen);
+    GET_VALUE_STR("spice_password", cfg->spicePassword);
 
 
-    GET_VALUE_LONG("remote_display_port_min", driver->remotePortMin);
-    if (driver->remotePortMin < QEMU_REMOTE_PORT_MIN) {
+    GET_VALUE_LONG("remote_display_port_min", cfg->remotePortMin);
+    if (cfg->remotePortMin < QEMU_REMOTE_PORT_MIN) {
         /* if the port is too low, we can't get the display name
          * to tell to vnc (usually subtract 5900, e.g. localhost:1
          * for port 5901) */
@@ -224,9 +401,9 @@ int qemuLoadDriverConfig(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
-    GET_VALUE_LONG("remote_display_port_max", driver->remotePortMax);
-    if (driver->remotePortMax > QEMU_REMOTE_PORT_MAX ||
-        driver->remotePortMax < driver->remotePortMin) {
+    GET_VALUE_LONG("remote_display_port_max", cfg->remotePortMax);
+    if (cfg->remotePortMax > QEMU_REMOTE_PORT_MAX ||
+        cfg->remotePortMax < cfg->remotePortMin) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                         _("%s: remote_display_port_max: port must be between "
                           "the minimal port and %d"),
@@ -234,7 +411,7 @@ int qemuLoadDriverConfig(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
-    if (driver->remotePortMin > driver->remotePortMax) {
+    if (cfg->remotePortMin > cfg->remotePortMax) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                         _("%s: remote_display_port_min: min port must not be "
                           "greater than max port"), filename);
@@ -243,21 +420,17 @@ int qemuLoadDriverConfig(virQEMUDriverPtr driver,
 
     p = virConfGetValue(conf, "user");
     CHECK_TYPE("user", VIR_CONF_STRING);
-    if (!(user = strdup(p && p->str ? p->str : QEMU_USER)))
-        goto no_memory;
-
-    if (virGetUserID(user, &driver->user) < 0)
+    if (p && p->str &&
+        virGetUserID(p->str, &cfg->user) < 0)
         goto cleanup;
 
     p = virConfGetValue(conf, "group");
     CHECK_TYPE("group", VIR_CONF_STRING);
-    if (!(group = strdup(p && p->str ? p->str : QEMU_GROUP)))
-        goto no_memory;
-
-    if (virGetGroupID(group, &driver->group) < 0)
+    if (p && p->str &&
+        virGetGroupID(p->str, &cfg->group) < 0)
         goto cleanup;
 
-    GET_VALUE_LONG("dynamic_ownership", driver->dynamicOwnership);
+    GET_VALUE_BOOL("dynamic_ownership", cfg->dynamicOwnership);
 
     p = virConfGetValue(conf, "cgroup_controllers");
     CHECK_TYPE("cgroup_controllers", VIR_CONF_LIST);
@@ -277,19 +450,11 @@ int qemuLoadDriverConfig(virQEMUDriverPtr driver,
                                _("Unknown cgroup controller '%s'"), pp->str);
                 goto cleanup;
             }
-            driver->cgroupControllers |= (1 << ctl);
+            cfg->cgroupControllers |= (1 << ctl);
         }
-    } else {
-        driver->cgroupControllers =
-            (1 << VIR_CGROUP_CONTROLLER_CPU) |
-            (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
-            (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
-            (1 << VIR_CGROUP_CONTROLLER_BLKIO) |
-            (1 << VIR_CGROUP_CONTROLLER_CPUSET) |
-            (1 << VIR_CGROUP_CONTROLLER_CPUACCT);
     }
     for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
-        if (driver->cgroupControllers & (1 << i)) {
+        if (cfg->cgroupControllers & (1 << i)) {
             VIR_INFO("Configured cgroup controller '%s'",
                      virCgroupControllerTypeToString(i));
         }
@@ -302,7 +467,7 @@ int qemuLoadDriverConfig(virQEMUDriverPtr driver,
         virConfValuePtr pp;
         for (pp = p->list; pp; pp = pp->next)
             len++;
-        if (VIR_ALLOC_N(driver->cgroupDeviceACL, 1+len) < 0)
+        if (VIR_ALLOC_N(cfg->cgroupDeviceACL, 1+len) < 0)
             goto no_memory;
 
         for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
@@ -312,66 +477,41 @@ int qemuLoadDriverConfig(virQEMUDriverPtr driver,
                                  "list of strings"));
                 goto cleanup;
             }
-            if (!(driver->cgroupDeviceACL[i] = strdup(pp->str)))
+            if (!(cfg->cgroupDeviceACL[i] = strdup(pp->str)))
                 goto no_memory;
         }
-        driver->cgroupDeviceACL[i] = NULL;
+        cfg->cgroupDeviceACL[i] = NULL;
     }
 
-    GET_VALUE_STR("save_image_format", driver->saveImageFormat);
-    GET_VALUE_STR("dump_image_format", driver->dumpImageFormat);
-    GET_VALUE_STR("auto_dump_path", driver->autoDumpPath);
-    GET_VALUE_LONG("auto_dump_bypass_cache", driver->autoDumpBypassCache);
-    GET_VALUE_LONG("auto_start_bypass_cache", driver->autoStartBypassCache);
-
-    GET_VALUE_STR("hugetlbfs_mount", driver->hugetlbfs_mount);
-
-    p = virConfGetValue(conf, "mac_filter");
-    CHECK_TYPE("mac_filter", VIR_CONF_LONG);
-    if (p && p->l) {
-        driver->macFilter = p->l;
-        if (!(driver->ebtables = ebtablesContextNew("qemu"))) {
-            driver->macFilter = 0;
-            virReportSystemError(errno,
-                                 _("failed to enable mac filter in '%s'"),
-                                 __FILE__);
-            goto cleanup;
-        }
+    GET_VALUE_STR("save_image_format", cfg->saveImageFormat);
+    GET_VALUE_STR("dump_image_format", cfg->dumpImageFormat);
+    GET_VALUE_STR("auto_dump_path", cfg->autoDumpPath);
+    GET_VALUE_BOOL("auto_dump_bypass_cache", cfg->autoDumpBypassCache);
+    GET_VALUE_BOOL("auto_start_bypass_cache", cfg->autoStartBypassCache);
 
-        if ((errno = networkDisableAllFrames(driver))) {
-            virReportSystemError(errno,
-                         _("failed to add rule to drop all frames in '%s'"),
-                                 __FILE__);
-            goto cleanup;
-        }
-    }
+    GET_VALUE_STR("hugetlbfs_mount", cfg->hugetlbfsMount);
 
-    GET_VALUE_LONG("relaxed_acs_check", driver->relaxedACS);
-    GET_VALUE_LONG("clear_emulator_capabilities", driver->clearEmulatorCapabilities);
-    GET_VALUE_LONG("allow_disk_format_probing", driver->allowDiskFormatProbing);
-    GET_VALUE_LONG("set_process_name", driver->setProcessName);
-    GET_VALUE_LONG("max_processes", driver->maxProcesses);
-    GET_VALUE_LONG("max_files", driver->maxFiles);
-
-    p = virConfGetValue(conf, "lock_manager");
-    CHECK_TYPE("lock_manager", VIR_CONF_STRING);
-    if (p && p->str) {
-        virLockManagerPluginUnref(driver->lockManager);
-        if (!(driver->lockManager =
-              virLockManagerPluginNew(p->str, "qemu", driver->configBaseDir, 0)))
-            VIR_ERROR(_("Failed to load lock manager %s"), p->str);
-    }
+    GET_VALUE_BOOL("mac_filter", cfg->macFilter);
+
+    GET_VALUE_BOOL("relaxed_acs_check", cfg->relaxedACS);
+    GET_VALUE_BOOL("clear_emulator_capabilities", cfg->clearEmulatorCapabilities);
+    GET_VALUE_BOOL("allow_disk_format_probing", cfg->allowDiskFormatProbing);
+    GET_VALUE_BOOL("set_process_name", cfg->setProcessName);
+    GET_VALUE_LONG("max_processes", cfg->maxProcesses);
+    GET_VALUE_LONG("max_files", cfg->maxFiles);
 
-    GET_VALUE_LONG("max_queued", driver->max_queued);
-    GET_VALUE_LONG("keepalive_interval", driver->keepAliveInterval);
-    GET_VALUE_LONG("keepalive_count", driver->keepAliveCount);
-    GET_VALUE_LONG("seccomp_sandbox", driver->seccompSandbox);
+    GET_VALUE_STR("lock_manager", cfg->lockManagerName);
+
+    GET_VALUE_LONG("max_queued", cfg->maxQueuedJobs);
+
+    GET_VALUE_LONG("keepalive_interval", cfg->keepAliveInterval);
+    GET_VALUE_LONG("keepalive_count", cfg->keepAliveCount);
+
+    GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
 
     ret = 0;
 
 cleanup:
-    VIR_FREE(user);
-    VIR_FREE(group);
     virConfFree(conf);
     return ret;
 
@@ -379,9 +519,15 @@ no_memory:
     virReportOOMError();
     goto cleanup;
 }
+#undef GET_VALUE_BOOL
 #undef GET_VALUE_LONG
 #undef GET_VALUE_STRING
 
+virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver)
+{
+    return virObjectRef(driver->config);
+}
+
 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 6009118..b9fcebf 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -53,11 +53,26 @@ typedef qemuDriverCloseDef *qemuDriverCloseDefPtr;
 typedef struct _virQEMUDriver virQEMUDriver;
 typedef virQEMUDriver *virQEMUDriverPtr;
 
-/* Main driver state */
-struct _virQEMUDriver {
-    virMutex lock;
-
-    virThreadPoolPtr workerPool;
+typedef struct _virQEMUDriverConfig virQEMUDriverConfig;
+typedef virQEMUDriverConfig *virQEMUDriverConfigPtr;
+
+/* Main driver config. The data in these object
+ * instances is immutable, so can be accessed
+ * without locking. Threads must, however, hold
+ * a valid reference on the object to prevent it
+ * being released while they use it.
+ *
+ * eg
+ *  qemuDriverLock(driver);
+ *  virQEMUDriverConfigPtr cfg = virObjectRef(driver->config);
+ *  qemuDriverUnlock(driver);
+ *
+ *  ...do stuff with 'cfg'..
+ *
+ *  virObjectUnref(cfg);
+ */
+struct _virQEMUDriverConfig {
+    virObject parent;
 
     bool privileged;
     const char *uri;
@@ -66,19 +81,9 @@ struct _virQEMUDriver {
     gid_t group;
     int dynamicOwnership;
 
-    unsigned int qemuVersion;
-    int nextvmid;
-
-    virCgroupPtr cgroup;
     int cgroupControllers;
     char **cgroupDeviceACL;
 
-    size_t nactive;
-    virStateInhibitCallback inhibitCallback;
-    void *inhibitOpaque;
-
-    virDomainObjList domains;
-
     /* These five directories are ones libvirtd uses (so must be root:root
      * to avoid security risk from QEMU processes */
     char *configBaseDir;
@@ -92,60 +97,95 @@ struct _virQEMUDriver {
     char *cacheDir;
     char *saveDir;
     char *snapshotDir;
-    char *qemuImgBinary;
-    unsigned int vncAutoUnixSocket : 1;
-    unsigned int vncTLS : 1;
-    unsigned int vncTLSx509verify : 1;
-    unsigned int vncSASL : 1;
+
+    bool vncAutoUnixSocket;
+    bool vncTLS;
+    bool vncTLSx509verify;
+    bool vncSASL;
     char *vncTLSx509certdir;
     char *vncListen;
     char *vncPassword;
     char *vncSASLdir;
-    unsigned int spiceTLS : 1;
+
+    bool spiceTLS;
     char *spiceTLSx509certdir;
     char *spiceListen;
     char *spicePassword;
+
     int remotePortMin;
     int remotePortMax;
-    char *hugetlbfs_mount;
-    char *hugepage_path;
 
-    unsigned int macFilter : 1;
-    ebtablesContext *ebtables;
+    char *hugetlbfsMount;
+    char *hugepagePath;
+
+    bool macFilter;
 
-    unsigned int relaxedACS : 1;
-    unsigned int vncAllowHostAudio : 1;
-    unsigned int clearEmulatorCapabilities : 1;
-    unsigned int allowDiskFormatProbing : 1;
-    unsigned int setProcessName : 1;
+    bool relaxedACS;
+    bool vncAllowHostAudio;
+    bool clearEmulatorCapabilities;
+    bool allowDiskFormatProbing;
+    bool setProcessName;
 
     int maxProcesses;
     int maxFiles;
 
-    int max_queued;
-
-    virCapsPtr caps;
-    qemuCapsCachePtr capsCache;
-
-    virDomainEventStatePtr domainEventState;
+    int maxQueuedJobs;
 
     char **securityDriverNames;
     bool securityDefaultConfined;
     bool securityRequireConfined;
-    virSecurityManagerPtr securityManager;
 
     char *saveImageFormat;
     char *dumpImageFormat;
 
     char *autoDumpPath;
     bool autoDumpBypassCache;
-
     bool autoStartBypassCache;
 
+    char *lockManagerName;
+
+    int keepAliveInterval;
+    unsigned int keepAliveCount;
+
+    int seccompSandbox;
+};
+
+/* Main driver state */
+struct _virQEMUDriver {
+    virMutex lock;
+
+    virQEMUDriverConfigPtr config;
+
+    virThreadPoolPtr workerPool;
+
+    unsigned int qemuVersion;
+
+    int nextvmid;
+
+    virCgroupPtr cgroup;
+
+    size_t nactive;
+
+    virStateInhibitCallback inhibitCallback;
+    void *inhibitOpaque;
+
+    virDomainObjList domains;
+
+    char *qemuImgBinary;
+
+    ebtablesContext *ebtables;
+
+    virCapsPtr caps;
+
+    qemuCapsCachePtr capsCache;
+
+    virDomainEventStatePtr domainEventState;
+
+    virSecurityManagerPtr securityManager;
+
     pciDeviceList *activePciHostdevs;
     usbDeviceList *activeUsbHostdevs;
 
-    /* The devices which is are not in use by the host or any guest. */
     pciDeviceList *inactivePciHostdevs;
 
     virHashTablePtr sharedDisks;
@@ -156,16 +196,7 @@ struct _virQEMUDriver {
 
     virLockManagerPluginPtr lockManager;
 
-    /* Mapping of 'char *uuidstr' -> qemuDriverCloseDefPtr of domains
-     * which want a specific cleanup to be done when a connection is
-     * closed. Such cleanup may be to automatically destroy the
-     * domain or abort a particular job running on it.
-     */
     virHashTablePtr closeCallbacks;
-
-    int keepAliveInterval;
-    unsigned int keepAliveCount;
-    int seccompSandbox;
 };
 
 typedef struct _qemuDomainCmdlineDef qemuDomainCmdlineDef;
@@ -186,8 +217,13 @@ struct _qemuDomainCmdlineDef {
 
 void qemuDriverLock(virQEMUDriverPtr driver);
 void qemuDriverUnlock(virQEMUDriverPtr driver);
-int qemuLoadDriverConfig(virQEMUDriverPtr driver,
-                         const char *filename);
+
+virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged);
+
+int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
+                                const char *filename);
+
+virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver);
 
 struct qemuDomainDiskInfo {
     bool removable;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 1ae75e9..cc02f0e 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -663,14 +663,14 @@ void qemuDomainSetNamespaceHooks(virCapsPtr caps)
 static void
 qemuDomainObjSaveJob(virQEMUDriverPtr driver, virDomainObjPtr obj)
 {
-    if (!virDomainObjIsActive(obj)) {
-        /* don't write the state file yet, it will be written once the domain
-         * gets activated */
-        return;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
+    if (virDomainObjIsActive(obj)) {
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, obj) < 0)
+            VIR_WARN("Failed to save status on vm %s", obj->def->name);
     }
 
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, obj) < 0)
-        VIR_WARN("Failed to save status on vm %s", obj->def->name);
+    virObjectUnref(cfg);
 }
 
 void
@@ -768,11 +768,15 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver,
     unsigned long long now;
     unsigned long long then;
     bool nested = job == QEMU_JOB_ASYNC_NESTED;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     priv->jobs_queued++;
 
-    if (virTimeMillisNow(&now) < 0)
+    if (virTimeMillisNow(&now) < 0) {
+        virObjectUnref(cfg);
         return -1;
+    }
+
     then = now + QEMU_JOB_WAIT_TIME;
 
     virObjectRef(obj);
@@ -780,8 +784,8 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver,
         qemuDriverUnlock(driver);
 
 retry:
-    if (driver->max_queued &&
-        priv->jobs_queued > driver->max_queued) {
+    if (cfg->maxQueuedJobs &&
+        priv->jobs_queued > cfg->maxQueuedJobs) {
         goto error;
     }
 
@@ -826,6 +830,7 @@ retry:
     if (qemuDomainTrackJob(job))
         qemuDomainObjSaveJob(driver, obj);
 
+    virObjectUnref(cfg);
     return 0;
 
 error:
@@ -841,8 +846,8 @@ error:
     if (errno == ETIMEDOUT)
         virReportError(VIR_ERR_OPERATION_TIMEOUT,
                        "%s", _("cannot acquire state change lock"));
-    else if (driver->max_queued &&
-             priv->jobs_queued > driver->max_queued)
+    else if (cfg->maxQueuedJobs &&
+             priv->jobs_queued > cfg->maxQueuedJobs)
         virReportError(VIR_ERR_OPERATION_FAILED,
                        "%s", _("cannot acquire state change lock "
                                "due to max_queued limit"));
@@ -856,6 +861,7 @@ error:
         virObjectLock(obj);
     }
     virObjectUnref(obj);
+    virObjectUnref(cfg);
     return -1;
 }
 
@@ -1397,11 +1403,12 @@ void qemuDomainObjCheckTaint(virQEMUDriverPtr driver,
                              int logFD)
 {
     int i;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
-    if (driver->privileged &&
-        (!driver->clearEmulatorCapabilities ||
-         driver->user == 0 ||
-         driver->group == 0))
+    if (cfg->privileged &&
+        (!cfg->clearEmulatorCapabilities ||
+         cfg->user == 0 ||
+         cfg->group == 0))
         qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_HIGH_PRIVILEGES, logFD);
 
     if (obj->def->namespaceData) {
@@ -1418,6 +1425,8 @@ void qemuDomainObjCheckTaint(virQEMUDriverPtr driver,
 
     for (i = 0 ; i < obj->def->nnets ; i++)
         qemuDomainObjCheckNetTaint(driver, obj, obj->def->nets[i], logFD);
+
+    virObjectUnref(cfg);
 }
 
 
@@ -1426,12 +1435,16 @@ void qemuDomainObjCheckDiskTaint(virQEMUDriverPtr driver,
                                  virDomainDiskDefPtr disk,
                                  int logFD)
 {
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
     if ((!disk->format || disk->format == VIR_STORAGE_FILE_AUTO) &&
-        driver->allowDiskFormatProbing)
+        cfg->allowDiskFormatProbing)
         qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_DISK_PROBING, logFD);
 
     if (disk->rawio == 1)
         qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_HIGH_PRIVILEGES, logFD);
+
+    virObjectUnref(cfg);
 }
 
 
@@ -1451,7 +1464,7 @@ void qemuDomainObjCheckNetTaint(virQEMUDriverPtr driver,
 
 
 static int
-qemuDomainOpenLogHelper(virQEMUDriverPtr driver,
+qemuDomainOpenLogHelper(virQEMUDriverConfigPtr cfg,
                         virDomainObjPtr vm,
                         int oflags,
                         mode_t mode)
@@ -1460,7 +1473,7 @@ qemuDomainOpenLogHelper(virQEMUDriverPtr driver,
     int fd = -1;
     bool trunc = false;
 
-    if (virAsprintf(&logfile, "%s/%s.log", driver->logDir, vm->def->name) < 0) {
+    if (virAsprintf(&logfile, "%s/%s.log", cfg->logDir, vm->def->name) < 0) {
         virReportOOMError();
         return -1;
     }
@@ -1503,27 +1516,34 @@ int
 qemuDomainCreateLog(virQEMUDriverPtr driver, virDomainObjPtr vm,
                     bool append)
 {
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     int oflags;
+    int ret;
 
     oflags = O_CREAT | O_WRONLY;
     /* Only logrotate files in /var/log, so only append if running privileged */
-    if (driver->privileged || append)
+    if (cfg->privileged || append)
         oflags |= O_APPEND;
     else
         oflags |= O_TRUNC;
 
-    return qemuDomainOpenLogHelper(driver, vm, oflags, S_IRUSR | S_IWUSR);
+    ret = qemuDomainOpenLogHelper(cfg, vm, oflags, S_IRUSR | S_IWUSR);
+    virObjectUnref(cfg);
+    return ret;
 }
 
 
 int
 qemuDomainOpenLog(virQEMUDriverPtr driver, virDomainObjPtr vm, off_t pos)
 {
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     int fd;
     off_t off;
     int whence;
 
-    if ((fd = qemuDomainOpenLogHelper(driver, vm, O_RDONLY, 0)) < 0)
+    fd = qemuDomainOpenLogHelper(cfg, vm, O_RDONLY, 0);
+    virObjectUnref(cfg);
+    if (fd < 0)
         return -1;
 
     if (pos < 0) {
@@ -1748,6 +1768,7 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
     virDomainSnapshotObjPtr parentsnap = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (!metadata_only) {
         if (!virDomainObjIsActive(vm)) {
@@ -1764,7 +1785,7 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
         }
     }
 
-    if (virAsprintf(&snapFile, "%s/%s/%s.xml", driver->snapshotDir,
+    if (virAsprintf(&snapFile, "%s/%s/%s.xml", cfg->snapshotDir,
                     vm->def->name, snap->def->name) < 0) {
         virReportOOMError();
         goto cleanup;
@@ -1780,7 +1801,7 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
             } else {
                 parentsnap->def->current = true;
                 if (qemuDomainSnapshotWriteMetadata(vm, parentsnap,
-                                                    driver->snapshotDir) < 0) {
+                                                    cfg->snapshotDir) < 0) {
                     VIR_WARN("failed to set parent snapshot '%s' as current",
                              snap->def->parent);
                     parentsnap->def->current = false;
@@ -1799,7 +1820,7 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
 
 cleanup:
     VIR_FREE(snapFile);
-
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -1845,22 +1866,24 @@ qemuDomainRemoveInactive(virQEMUDriverPtr driver,
                          virDomainObjPtr vm)
 {
     char *snapDir;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     /* Remove any snapshot metadata prior to removing the domain */
     if (qemuDomainSnapshotDiscardAllMetadata(driver, vm) < 0) {
         VIR_WARN("unable to remove all snapshots for domain %s",
                  vm->def->name);
     }
-    else if (virAsprintf(&snapDir, "%s/%s", driver->snapshotDir,
+    else if (virAsprintf(&snapDir, "%s/%s", cfg->snapshotDir,
                          vm->def->name) < 0) {
         VIR_WARN("unable to remove snapshot directory %s/%s",
-                 driver->snapshotDir, vm->def->name);
+                 cfg->snapshotDir, vm->def->name);
     } else {
         if (rmdir(snapDir) < 0 && errno != ENOENT)
             VIR_WARN("unable to remove snapshot directory %s", snapDir);
         VIR_FREE(snapDir);
     }
     virDomainRemoveInactive(&driver->domains, vm);
+    virObjectUnref(cfg);
 }
 
 void
@@ -1869,14 +1892,17 @@ qemuDomainSetFakeReboot(virQEMUDriverPtr driver,
                         bool value)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (priv->fakeReboot == value)
         return;
 
     priv->fakeReboot = value;
 
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
         VIR_WARN("Failed to save status on vm %s", vm->def->name);
+
+    virObjectUnref(cfg);
 }
 
 int
@@ -1889,6 +1915,7 @@ qemuDomainCheckDiskPresence(virQEMUDriverPtr driver,
     virDomainDiskDefPtr disk;
     char uuid[VIR_UUID_STRING_BUFLEN];
     virDomainEventPtr event = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virUUIDFormat(vm->def->uuid, uuid);
 
@@ -1899,8 +1926,8 @@ qemuDomainCheckDiskPresence(virQEMUDriverPtr driver,
             continue;
 
         if (virFileAccessibleAs(disk->src, F_OK,
-                                driver->user,
-                                driver->group) >= 0) {
+                                cfg->user,
+                                cfg->group) >= 0) {
             /* disk accessible */
             continue;
         }
@@ -1946,6 +1973,7 @@ qemuDomainCheckDiskPresence(virQEMUDriverPtr driver,
     ret = 0;
 
 cleanup:
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -2026,23 +2054,27 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
                              virDomainDiskDefPtr disk,
                              bool force)
 {
-    bool probe = driver->allowDiskFormatProbing;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    int ret = 0;
 
     if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
-        return 0;
+        goto cleanup;
 
     if (disk->backingChain) {
         if (force) {
             virStorageFileFreeMetadata(disk->backingChain);
             disk->backingChain = NULL;
         } else {
-            return 0;
+            goto cleanup;
         }
     }
     disk->backingChain = virStorageFileGetMetadata(disk->src, disk->format,
-                                                   driver->user, driver->group,
-                                                   probe);
+                                                   cfg->user, cfg->group,
+                                                   cfg->allowDiskFormatProbing);
     if (!disk->backingChain)
-        return -1;
-    return 0;
+        ret = -1;
+
+cleanup:
+    virObjectUnref(cfg);
+    return ret;
 }
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 812bf95..f98a757 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -286,8 +286,9 @@ qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED,
     struct qemuAutostartData *data = opaque;
     virErrorPtr err;
     int flags = 0;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(data->driver);
 
-    if (data->driver->autoStartBypassCache)
+    if (cfg->autoStartBypassCache)
         flags |= VIR_DOMAIN_START_BYPASS_CACHE;
 
     virObjectLock(vm);
@@ -317,20 +318,20 @@ qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED,
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(cfg);
 }
 
 
 static void
 qemuAutostartDomains(virQEMUDriverPtr driver)
 {
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     /* XXX: Figure out a better way todo this. The domain
      * startup code needs a connection handle in order
      * to lookup the bridge associated with a virtual
      * network
      */
-    virConnectPtr conn = virConnectOpen(driver->privileged ?
-                                        "qemu:///system" :
-                                        "qemu:///session");
+    virConnectPtr conn = virConnectOpen(cfg->uri);
     /* Ignoring NULL conn which is mostly harmless here */
     struct qemuAutostartData data = { driver, conn };
 
@@ -340,6 +341,7 @@ qemuAutostartDomains(virQEMUDriverPtr driver)
 
     if (conn)
         virConnectClose(conn);
+    virObjectUnref(cfg);
 }
 
 static int
@@ -348,16 +350,17 @@ qemuSecurityInit(virQEMUDriverPtr driver)
     char **names;
     virSecurityManagerPtr mgr = NULL;
     virSecurityManagerPtr stack = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
-    if (driver->securityDriverNames &&
-        driver->securityDriverNames[0]) {
-        names = driver->securityDriverNames;
+    if (cfg->securityDriverNames &&
+        cfg->securityDriverNames[0]) {
+        names = cfg->securityDriverNames;
         while (names && *names) {
             if (!(mgr = virSecurityManagerNew(*names,
                                               QEMU_DRIVER_NAME,
-                                              driver->allowDiskFormatProbing,
-                                              driver->securityDefaultConfined,
-                                              driver->securityRequireConfined)))
+                                              cfg->allowDiskFormatProbing,
+                                              cfg->securityDefaultConfined,
+                                              cfg->securityRequireConfined)))
                 goto error;
             if (!stack) {
                 if (!(stack = virSecurityManagerNewStack(mgr)))
@@ -372,23 +375,23 @@ qemuSecurityInit(virQEMUDriverPtr driver)
     } else {
         if (!(mgr = virSecurityManagerNew(NULL,
                                           QEMU_DRIVER_NAME,
-                                          driver->allowDiskFormatProbing,
-                                          driver->securityDefaultConfined,
-                                          driver->securityRequireConfined)))
+                                          cfg->allowDiskFormatProbing,
+                                          cfg->securityDefaultConfined,
+                                          cfg->securityRequireConfined)))
             goto error;
         if (!(stack = virSecurityManagerNewStack(mgr)))
             goto error;
         mgr = NULL;
     }
 
-    if (driver->privileged) {
+    if (cfg->privileged) {
         if (!(mgr = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
-                                             driver->user,
-                                             driver->group,
-                                             driver->allowDiskFormatProbing,
-                                             driver->securityDefaultConfined,
-                                             driver->securityRequireConfined,
-                                             driver->dynamicOwnership)))
+                                             cfg->user,
+                                             cfg->group,
+                                             cfg->allowDiskFormatProbing,
+                                             cfg->securityDefaultConfined,
+                                             cfg->securityRequireConfined,
+                                             cfg->dynamicOwnership)))
             goto error;
         if (!stack) {
             if (!(stack = virSecurityManagerNewStack(mgr)))
@@ -401,12 +404,14 @@ qemuSecurityInit(virQEMUDriverPtr driver)
     }
 
     driver->securityManager = stack;
+    virObjectUnref(cfg);
     return 0;
 
 error:
     VIR_ERROR(_("Failed to initialize security drivers"));
     virSecurityManagerFree(stack);
     virSecurityManagerFree(mgr);
+    virObjectUnref(cfg);
     return -1;
 }
 
@@ -419,14 +424,16 @@ qemuCreateCapabilities(virQEMUDriverPtr driver)
     virSecurityManagerPtr *sec_managers = NULL;
     /* Security driver data */
     const char *doi, *model;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     /* Basic host arch / guest machine capabilities */
     if (!(caps = qemuCapsInit(driver->capsCache))) {
         virReportOOMError();
+        virObjectUnref(cfg);
         return NULL;
     }
 
-    if (driver->allowDiskFormatProbing) {
+    if (cfg->allowDiskFormatProbing) {
         caps->defaultDiskDriverName = NULL;
         caps->defaultDiskDriverType = VIR_STORAGE_FILE_AUTO;
     } else {
@@ -469,6 +476,7 @@ qemuCreateCapabilities(virQEMUDriverPtr driver)
     }
     VIR_FREE(sec_managers);
 
+    virObjectUnref(cfg);
     return caps;
 
 no_memory:
@@ -476,6 +484,7 @@ no_memory:
 err_exit:
     VIR_FREE(sec_managers);
     virCapabilitiesFree(caps);
+    virObjectUnref(cfg);
     return NULL;
 }
 
@@ -648,13 +657,13 @@ qemuStartup(bool privileged,
             virStateInhibitCallback callback,
             void *opaque)
 {
-    char *base;
     char *driverConf = NULL;
     int rc;
     virConnectPtr conn = NULL;
     char ebuf[1024];
     char *membase = NULL;
     char *mempath = NULL;
+    virQEMUDriverConfigPtr cfg;
 
     if (VIR_ALLOC(qemu_driver) < 0)
         return -1;
@@ -666,8 +675,6 @@ qemuStartup(bool privileged,
     }
     qemuDriverLock(qemu_driver);
 
-    qemu_driver->privileged = privileged;
-    qemu_driver->uri = privileged ? "qemu:///system" : "qemu:///session";
     qemu_driver->inhibitCallback = callback;
     qemu_driver->inhibitOpaque = opaque;
 
@@ -686,141 +693,85 @@ qemuStartup(bool privileged,
     if (privileged)
         qemu_driver->hostsysinfo = virSysinfoRead();
 
-    if (privileged) {
-        if (virAsprintf(&qemu_driver->logDir,
-                        "%s/log/libvirt/qemu", LOCALSTATEDIR) == -1)
-            goto out_of_memory;
-
-        if ((qemu_driver->configBaseDir = strdup(SYSCONFDIR "/libvirt")) == NULL)
-            goto out_of_memory;
-        base = qemu_driver->configBaseDir;
-
-        if (virAsprintf(&qemu_driver->stateDir,
-                      "%s/run/libvirt/qemu", LOCALSTATEDIR) == -1)
-            goto out_of_memory;
-
-        if (virAsprintf(&qemu_driver->libDir,
-                      "%s/lib/libvirt/qemu", LOCALSTATEDIR) == -1)
-            goto out_of_memory;
-
-        if (virAsprintf(&qemu_driver->cacheDir,
-                      "%s/cache/libvirt/qemu", LOCALSTATEDIR) == -1)
-            goto out_of_memory;
-        if (virAsprintf(&qemu_driver->saveDir,
-                      "%s/lib/libvirt/qemu/save", LOCALSTATEDIR) == -1)
-            goto out_of_memory;
-        if (virAsprintf(&qemu_driver->snapshotDir,
-                        "%s/lib/libvirt/qemu/snapshot", LOCALSTATEDIR) == -1)
-            goto out_of_memory;
-        if (virAsprintf(&qemu_driver->autoDumpPath,
-                        "%s/lib/libvirt/qemu/dump", LOCALSTATEDIR) == -1)
-            goto out_of_memory;
-    } else {
-        char *rundir;
-        char *cachedir;
-
-        cachedir = virGetUserCacheDirectory();
-        if (!cachedir)
-            goto error;
-
-        if (virAsprintf(&qemu_driver->logDir,
-                        "%s/qemu/log", cachedir) == -1) {
-            VIR_FREE(cachedir);
-            goto out_of_memory;
-        }
-        if (virAsprintf(&qemu_driver->cacheDir, "%s/qemu/cache", cachedir) == -1) {
-            VIR_FREE(cachedir);
-            goto out_of_memory;
-        }
-        VIR_FREE(cachedir);
+    if (!(qemu_driver->config = cfg = virQEMUDriverConfigNew(privileged)))
+        goto error;
 
-        rundir = virGetUserRuntimeDirectory();
-        if (!rundir)
-            goto error;
-        if (virAsprintf(&qemu_driver->stateDir, "%s/qemu/run", rundir) == -1) {
-            VIR_FREE(rundir);
-            goto out_of_memory;
-        }
-        VIR_FREE(rundir);
+    if (virAsprintf(&driverConf, "%s/qemu.conf", cfg->configBaseDir) < 0)
+        goto out_of_memory;
 
-        if (!(qemu_driver->configBaseDir = virGetUserConfigDirectory()))
-            goto error;
-        base = qemu_driver->configBaseDir;
-        if (virAsprintf(&qemu_driver->libDir, "%s/qemu/lib", base) == -1)
-            goto out_of_memory;
-        if (virAsprintf(&qemu_driver->saveDir, "%s/qemu/save", base) == -1)
-            goto out_of_memory;
-        if (virAsprintf(&qemu_driver->snapshotDir, "%s/qemu/snapshot", base) == -1)
-            goto out_of_memory;
-        if (virAsprintf(&qemu_driver->autoDumpPath, "%s/qemu/dump", base) == -1)
-            goto out_of_memory;
-    }
+    if (virQEMUDriverConfigLoadFile(cfg, driverConf) < 0)
+        goto error;
+    VIR_FREE(driverConf);
 
-    if (virFileMakePath(qemu_driver->stateDir) < 0) {
+    if (virFileMakePath(cfg->stateDir) < 0) {
         VIR_ERROR(_("Failed to create state dir '%s': %s"),
-                  qemu_driver->stateDir, virStrerror(errno, ebuf, sizeof(ebuf)));
+                  cfg->stateDir, virStrerror(errno, ebuf, sizeof(ebuf)));
         goto error;
     }
-    if (virFileMakePath(qemu_driver->libDir) < 0) {
+    if (virFileMakePath(cfg->libDir) < 0) {
         VIR_ERROR(_("Failed to create lib dir '%s': %s"),
-                  qemu_driver->libDir, virStrerror(errno, ebuf, sizeof(ebuf)));
+                  cfg->libDir, virStrerror(errno, ebuf, sizeof(ebuf)));
         goto error;
     }
-    if (virFileMakePath(qemu_driver->cacheDir) < 0) {
+    if (virFileMakePath(cfg->cacheDir) < 0) {
         VIR_ERROR(_("Failed to create cache dir '%s': %s"),
-                  qemu_driver->cacheDir, virStrerror(errno, ebuf, sizeof(ebuf)));
+                  cfg->cacheDir, virStrerror(errno, ebuf, sizeof(ebuf)));
         goto error;
     }
-    if (virFileMakePath(qemu_driver->saveDir) < 0) {
+    if (virFileMakePath(cfg->saveDir) < 0) {
         VIR_ERROR(_("Failed to create save dir '%s': %s"),
-                  qemu_driver->saveDir, virStrerror(errno, ebuf, sizeof(ebuf)));
+                  cfg->saveDir, virStrerror(errno, ebuf, sizeof(ebuf)));
         goto error;
     }
-    if (virFileMakePath(qemu_driver->snapshotDir) < 0) {
+    if (virFileMakePath(cfg->snapshotDir) < 0) {
         VIR_ERROR(_("Failed to create save dir '%s': %s"),
-                  qemu_driver->snapshotDir, virStrerror(errno, ebuf, sizeof(ebuf)));
+                  cfg->snapshotDir, virStrerror(errno, ebuf, sizeof(ebuf)));
         goto error;
     }
-    if (virFileMakePath(qemu_driver->autoDumpPath) < 0) {
+    if (virFileMakePath(cfg->autoDumpPath) < 0) {
         VIR_ERROR(_("Failed to create dump dir '%s': %s"),
-                  qemu_driver->autoDumpPath, virStrerror(errno, ebuf, sizeof(ebuf)));
+                  cfg->autoDumpPath, virStrerror(errno, ebuf, sizeof(ebuf)));
         goto error;
     }
 
-    /* Configuration paths are either ~/.libvirt/qemu/... (session) or
-     * /etc/libvirt/qemu/... (system).
-     */
-    if (virAsprintf(&driverConf, "%s/qemu.conf", base) < 0 ||
-        virAsprintf(&qemu_driver->configDir, "%s/qemu", base) < 0 ||
-        virAsprintf(&qemu_driver->autostartDir, "%s/qemu/autostart", base) < 0)
-        goto out_of_memory;
-
     rc = virCgroupForDriver("qemu", &qemu_driver->cgroup, privileged, 1);
     if (rc < 0) {
         VIR_INFO("Unable to create cgroup for driver: %s",
                  virStrerror(-rc, ebuf, sizeof(ebuf)));
     }
 
-    if (qemuLoadDriverConfig(qemu_driver, driverConf) < 0) {
+
+    if (!(qemu_driver->lockManager =
+          virLockManagerPluginNew(cfg->lockManagerName ?
+                                  cfg->lockManagerName : "nop",
+                                  "qemu",
+                                  cfg->configBaseDir,
+                                  0)))
         goto error;
-    }
-    VIR_FREE(driverConf);
+
+   if (cfg->macFilter) {
+        if (!(qemu_driver->ebtables = ebtablesContextNew("qemu"))) {
+            virReportSystemError(errno,
+                                 _("failed to enable mac filter in '%s'"),
+                                 __FILE__);
+            goto error;
+        }
+
+        if ((errno = networkDisableAllFrames(qemu_driver))) {
+            virReportSystemError(errno,
+                                 _("failed to add rule to drop all frames in '%s'"),
+                                 __FILE__);
+            goto error;
+        }
+   }
 
     /* Allocate bitmap for remote display port reservations. We cannot
      * do this before the config is loaded properly, since the port
      * numbers are configurable now */
     if ((qemu_driver->remotePorts =
-         virPortAllocatorNew(qemu_driver->remotePortMin,
-                             qemu_driver->remotePortMax)) == NULL)
-        goto error;
-
-    /* We should always at least have the 'nop' manager, so
-     * NULLs here are a fatal error
-     */
-    if (!qemu_driver->lockManager) {
-        VIR_ERROR(_("Missing lock manager implementation"));
+         virPortAllocatorNew(cfg->remotePortMin,
+                             cfg->remotePortMax)) == NULL)
         goto error;
-    }
 
     if (qemuSecurityInit(qemu_driver) < 0)
         goto error;
@@ -838,35 +789,35 @@ qemuStartup(bool privileged,
         goto error;
 
     if (privileged) {
-        if (chown(qemu_driver->libDir, qemu_driver->user, qemu_driver->group) < 0) {
+        if (chown(cfg->libDir, cfg->user, cfg->group) < 0) {
             virReportSystemError(errno,
                                  _("unable to set ownership of '%s' to user %d:%d"),
-                                 qemu_driver->libDir, qemu_driver->user, qemu_driver->group);
+                                 cfg->libDir, cfg->user, cfg->group);
             goto error;
         }
-        if (chown(qemu_driver->cacheDir, qemu_driver->user, qemu_driver->group) < 0) {
+        if (chown(cfg->cacheDir, cfg->user, cfg->group) < 0) {
             virReportSystemError(errno,
                                  _("unable to set ownership of '%s' to %d:%d"),
-                                 qemu_driver->cacheDir, qemu_driver->user, qemu_driver->group);
+                                 cfg->cacheDir, cfg->user, cfg->group);
             goto error;
         }
-        if (chown(qemu_driver->saveDir, qemu_driver->user, qemu_driver->group) < 0) {
+        if (chown(cfg->saveDir, cfg->user, cfg->group) < 0) {
             virReportSystemError(errno,
                                  _("unable to set ownership of '%s' to %d:%d"),
-                                 qemu_driver->saveDir, qemu_driver->user, qemu_driver->group);
+                                 cfg->saveDir, cfg->user, cfg->group);
             goto error;
         }
-        if (chown(qemu_driver->snapshotDir, qemu_driver->user, qemu_driver->group) < 0) {
+        if (chown(cfg->snapshotDir, cfg->user, cfg->group) < 0) {
             virReportSystemError(errno,
                                  _("unable to set ownership of '%s' to %d:%d"),
-                                 qemu_driver->snapshotDir, qemu_driver->user, qemu_driver->group);
+                                 cfg->snapshotDir, cfg->user, cfg->group);
             goto error;
         }
     }
 
-    qemu_driver->capsCache = qemuCapsCacheNew(qemu_driver->libDir,
-                                              qemu_driver->user,
-                                              qemu_driver->group);
+    qemu_driver->capsCache = qemuCapsCacheNew(cfg->libDir,
+                                              cfg->user,
+                                              cfg->group);
     if (!qemu_driver->capsCache)
         goto error;
 
@@ -880,10 +831,10 @@ qemuStartup(bool privileged,
      * NB the check for '/', since user may config "" to disable hugepages
      * even when mounted
      */
-    if (qemu_driver->hugetlbfs_mount &&
-        qemu_driver->hugetlbfs_mount[0] == '/') {
+    if (cfg->hugetlbfsMount &&
+        cfg->hugetlbfsMount[0] == '/') {
         if (virAsprintf(&membase, "%s/libvirt",
-                        qemu_driver->hugetlbfs_mount) < 0 ||
+                        cfg->hugetlbfsMount) < 0 ||
             virAsprintf(&mempath, "%s/qemu", membase) < 0)
             goto out_of_memory;
 
@@ -892,20 +843,20 @@ qemuStartup(bool privileged,
                                  _("unable to create hugepage path %s"), mempath);
             goto error;
         }
-        if (qemu_driver->privileged) {
+        if (cfg->privileged) {
             if (virFileUpdatePerm(membase, 0, S_IXGRP | S_IXOTH) < 0)
                 goto error;
-            if (chown(mempath, qemu_driver->user, qemu_driver->group) < 0) {
+            if (chown(mempath, cfg->user, cfg->group) < 0) {
                 virReportSystemError(errno,
                                      _("unable to set ownership on %s to %d:%d"),
-                                     mempath, qemu_driver->user,
-                                     qemu_driver->group);
+                                     mempath, cfg->user,
+                                     cfg->group);
                 goto error;
             }
         }
         VIR_FREE(membase);
 
-        qemu_driver->hugepage_path = mempath;
+        cfg->hugepagePath = mempath;
     }
 
     if (qemuDriverCloseCallbackInit(qemu_driver) < 0)
@@ -914,7 +865,7 @@ qemuStartup(bool privileged,
     /* Get all the running persistent or transient configs first */
     if (virDomainLoadAllConfigs(qemu_driver->caps,
                                 &qemu_driver->domains,
-                                qemu_driver->stateDir,
+                                cfg->stateDir,
                                 NULL,
                                 1, QEMU_EXPECTED_VIRT_TYPES,
                                 NULL, NULL) < 0)
@@ -929,24 +880,26 @@ qemuStartup(bool privileged,
 
     virHashForEach(qemu_driver->domains.objs, qemuDomainNetsRestart, NULL);
 
-    conn = virConnectOpen(qemu_driver->uri);
+    conn = virConnectOpen(cfg->uri);
 
     qemuProcessReconnectAll(conn, qemu_driver);
 
     /* Then inactive persistent configs */
     if (virDomainLoadAllConfigs(qemu_driver->caps,
                                 &qemu_driver->domains,
-                                qemu_driver->configDir,
-                                qemu_driver->autostartDir,
+                                cfg->configDir,
+                                cfg->autostartDir,
                                 0, QEMU_EXPECTED_VIRT_TYPES,
                                 NULL, NULL) < 0)
         goto error;
 
 
-    virHashForEach(qemu_driver->domains.objs, qemuDomainSnapshotLoad,
-                   qemu_driver->snapshotDir);
+    virHashForEach(qemu_driver->domains.objs,
+                   qemuDomainSnapshotLoad,
+                   cfg->snapshotDir);
 
-    virHashForEach(qemu_driver->domains.objs, qemuDomainManagedSaveLoad,
+    virHashForEach(qemu_driver->domains.objs,
+                   qemuDomainManagedSaveLoad,
                    qemu_driver);
 
     qemu_driver->workerPool = virThreadPoolNew(0, 1, 0, processWatchdogEvent, qemu_driver);
@@ -999,18 +952,21 @@ static void qemuNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque)
  */
 static int
 qemuReload(void) {
+    virQEMUDriverConfigPtr cfg;
+
     if (!qemu_driver)
         return 0;
 
     qemuDriverLock(qemu_driver);
+    cfg = virQEMUDriverGetConfig(qemu_driver);
     virDomainLoadAllConfigs(qemu_driver->caps,
                             &qemu_driver->domains,
-                            qemu_driver->configDir,
-                            qemu_driver->autostartDir,
+                            cfg->configDir,
+                            cfg->autostartDir,
                             0, QEMU_EXPECTED_VIRT_TYPES,
                             qemuNotifyLoadDomain, qemu_driver);
     qemuDriverUnlock(qemu_driver);
-
+    virObjectUnref(cfg);
     return 0;
 }
 
@@ -1024,22 +980,16 @@ qemuReload(void) {
 static int
 qemuStop(void) {
     int ret = -1;
-    const char *uri;
     virConnectPtr conn;
-    int numDomains;
+    int numDomains = 0;
     size_t i;
     int state;
     virDomainPtr *domains = NULL;
     unsigned int *flags = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(qemu_driver);
 
-    qemuDriverLock(qemu_driver);
-    uri = qemu_driver->privileged ?
-        "qemu:///system" :
-        "qemu:///session";
-    qemuDriverUnlock(qemu_driver);
-
-    if (!(conn = virConnectOpen(uri)))
-        return -1;
+    if (!(conn = virConnectOpen(cfg->uri)))
+        goto cleanup;
 
     if ((numDomains = virConnectListAllDomains(conn,
                                                &domains,
@@ -1078,6 +1028,9 @@ qemuStop(void) {
         virDomainFree(domains[i]);
     VIR_FREE(domains);
     VIR_FREE(flags);
+    if (conn)
+        virConnectClose(conn);
+    virObjectUnref(cfg);
 
     return ret;
 }
@@ -1089,8 +1042,6 @@ qemuStop(void) {
  */
 static int
 qemuShutdown(void) {
-    int i;
-
     if (!qemu_driver)
         return -1;
 
@@ -1110,43 +1061,12 @@ qemuShutdown(void) {
 
     qemuDriverCloseCallbackShutdown(qemu_driver);
 
-    VIR_FREE(qemu_driver->configBaseDir);
-    VIR_FREE(qemu_driver->configDir);
-    VIR_FREE(qemu_driver->autostartDir);
-    VIR_FREE(qemu_driver->logDir);
-    VIR_FREE(qemu_driver->stateDir);
-    VIR_FREE(qemu_driver->libDir);
-    VIR_FREE(qemu_driver->cacheDir);
-    VIR_FREE(qemu_driver->saveDir);
-    VIR_FREE(qemu_driver->snapshotDir);
     VIR_FREE(qemu_driver->qemuImgBinary);
-    VIR_FREE(qemu_driver->autoDumpPath);
-    VIR_FREE(qemu_driver->vncTLSx509certdir);
-    VIR_FREE(qemu_driver->vncListen);
-    VIR_FREE(qemu_driver->vncPassword);
-    VIR_FREE(qemu_driver->vncSASLdir);
-    VIR_FREE(qemu_driver->spiceTLSx509certdir);
-    VIR_FREE(qemu_driver->spiceListen);
-    VIR_FREE(qemu_driver->spicePassword);
-    VIR_FREE(qemu_driver->hugetlbfs_mount);
-    VIR_FREE(qemu_driver->hugepage_path);
-    VIR_FREE(qemu_driver->saveImageFormat);
-    VIR_FREE(qemu_driver->dumpImageFormat);
-
-    for (i = 0 ; (qemu_driver->securityDriverNames != NULL &&
-                  qemu_driver->securityDriverNames[i] != NULL) ; i++)
-        VIR_FREE(qemu_driver->securityDriverNames[i]);
-    VIR_FREE(qemu_driver->securityDriverNames);
+
     virSecurityManagerFree(qemu_driver->securityManager);
 
     ebtablesContextFree(qemu_driver->ebtables);
 
-    if (qemu_driver->cgroupDeviceACL) {
-        for (i = 0 ; qemu_driver->cgroupDeviceACL[i] != NULL ; i++)
-            VIR_FREE(qemu_driver->cgroupDeviceACL[i]);
-        VIR_FREE(qemu_driver->cgroupDeviceACL);
-    }
-
     /* Free domain callback list */
     virDomainEventStateFree(qemu_driver->domainEventState);
 
@@ -1167,61 +1087,71 @@ static virDrvOpenStatus qemuOpen(virConnectPtr conn,
                                  virConnectAuthPtr auth ATTRIBUTE_UNUSED,
                                  unsigned int flags)
 {
+    virQEMUDriverConfigPtr cfg = NULL;
+    virDrvOpenStatus ret = VIR_DRV_OPEN_ERROR;
     virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
 
     if (conn->uri == NULL) {
-        if (qemu_driver == NULL)
-            return VIR_DRV_OPEN_DECLINED;
+        if (qemu_driver == NULL) {
+            ret = VIR_DRV_OPEN_DECLINED;
+            goto cleanup;
+        }
+
+        cfg = virQEMUDriverGetConfig(qemu_driver);
 
-        if (!(conn->uri = virURIParse(qemu_driver->privileged ?
-                                      "qemu:///system" :
-                                      "qemu:///session")))
-            return VIR_DRV_OPEN_ERROR;
+        if (!(conn->uri = virURIParse(cfg->uri)))
+            goto cleanup;
     } else {
         /* If URI isn't 'qemu' its definitely not for us */
         if (conn->uri->scheme == NULL ||
-            STRNEQ(conn->uri->scheme, "qemu"))
-            return VIR_DRV_OPEN_DECLINED;
+            STRNEQ(conn->uri->scheme, "qemu")) {
+            ret = VIR_DRV_OPEN_DECLINED;
+            goto cleanup;
+        }
 
         /* Allow remote driver to deal with URIs with hostname server */
-        if (conn->uri->server != NULL)
-            return VIR_DRV_OPEN_DECLINED;
+        if (conn->uri->server != NULL) {
+            ret = VIR_DRV_OPEN_DECLINED;
+            goto cleanup;
+        }
 
         if (qemu_driver == NULL) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("qemu state driver is not active"));
-            return VIR_DRV_OPEN_ERROR;
+            goto cleanup;
         }
 
         if (conn->uri->path == NULL) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("no QEMU URI path given, try %s"),
-                           qemu_driver->privileged
-                           ? "qemu:///system"
-                           : "qemu:///session");
-                return VIR_DRV_OPEN_ERROR;
+                           cfg->uri);
+            goto cleanup;
         }
 
-        if (qemu_driver->privileged) {
+        cfg = virQEMUDriverGetConfig(qemu_driver);
+        if (cfg->privileged) {
             if (STRNEQ(conn->uri->path, "/system") &&
                 STRNEQ(conn->uri->path, "/session")) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("unexpected QEMU URI path '%s', try qemu:///system"),
                                conn->uri->path);
-                return VIR_DRV_OPEN_ERROR;
+                goto cleanup;
             }
         } else {
             if (STRNEQ(conn->uri->path, "/session")) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("unexpected QEMU URI path '%s', try qemu:///session"),
                                conn->uri->path);
-                return VIR_DRV_OPEN_ERROR;
+                goto cleanup;
             }
         }
     }
     conn->privateData = qemu_driver;
 
-    return VIR_DRV_OPEN_SUCCESS;
+    ret = VIR_DRV_OPEN_SUCCESS;
+cleanup:
+    virObjectUnref(cfg);
+    return ret;
 }
 
 static int qemuClose(virConnectPtr conn) {
@@ -1737,6 +1667,7 @@ static int qemuDomainSuspend(virDomainPtr dom) {
     virDomainPausedReason reason;
     int eventDetail;
     int state;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     qemuDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -1754,6 +1685,7 @@ static int qemuDomainSuspend(virDomainPtr dom) {
         goto cleanup;
     }
 
+    cfg = virQEMUDriverGetConfig(driver);
     priv = vm->privateData;
 
     if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_SUSPEND) < 0)
@@ -1792,7 +1724,7 @@ static int qemuDomainSuspend(virDomainPtr dom) {
                                              eventDetail);
         }
     }
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
         goto endjob;
     ret = 0;
 
@@ -1807,6 +1739,7 @@ cleanup:
     if (event)
         qemuDomainEventQueue(driver, event);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -1817,6 +1750,7 @@ static int qemuDomainResume(virDomainPtr dom) {
     int ret = -1;
     virDomainEventPtr event = NULL;
     int state;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     qemuDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -1829,6 +1763,8 @@ static int qemuDomainResume(virDomainPtr dom) {
         goto cleanup;
     }
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
         goto cleanup;
 
@@ -1856,7 +1792,7 @@ static int qemuDomainResume(virDomainPtr dom) {
                                          VIR_DOMAIN_EVENT_RESUMED,
                                          VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
     }
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
         goto endjob;
     ret = 0;
 
@@ -1870,6 +1806,7 @@ cleanup:
     if (event)
         qemuDomainEventQueue(driver, event);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -2232,6 +2169,7 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
     virDomainObjPtr vm;
     virDomainDefPtr persistentDef = NULL;
     int ret = -1, r;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -2240,6 +2178,8 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
         goto cleanup;
 
@@ -2263,7 +2203,7 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
             persistentDef->mem.max_balloon = newmem;
             if (persistentDef->mem.cur_balloon > newmem)
                 persistentDef->mem.cur_balloon = newmem;
-            ret = virDomainSaveConfig(driver->configDir, persistentDef);
+            ret = virDomainSaveConfig(cfg->configDir, persistentDef);
             goto endjob;
         }
 
@@ -2298,7 +2238,7 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
         if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
             sa_assert(persistentDef);
             persistentDef->mem.cur_balloon = newmem;
-            ret = virDomainSaveConfig(driver->configDir, persistentDef);
+            ret = virDomainSaveConfig(cfg->configDir, persistentDef);
             goto endjob;
         }
     }
@@ -2311,6 +2251,7 @@ endjob:
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -2692,6 +2633,7 @@ qemuOpenFile(virQEMUDriverPtr driver, const char *path, int oflags,
     int path_shared = virStorageFileIsSharedFS(path);
     uid_t uid = getuid();
     gid_t gid = getgid();
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     /* path might be a pre-existing block dev, in which case
      * we need to skip the create step, and also avoid unlink
@@ -2701,7 +2643,7 @@ qemuOpenFile(virQEMUDriverPtr driver, const char *path, int oflags,
 
         /* Don't force chown on network-shared FS
          * as it is likely to fail. */
-        if (path_shared <= 0 || driver->dynamicOwnership)
+        if (path_shared <= 0 || cfg->dynamicOwnership)
             vfoflags |= VIR_FILE_OPEN_FORCE_OWNER;
 
         if (stat(path, &sb) == 0) {
@@ -2709,7 +2651,7 @@ qemuOpenFile(virQEMUDriverPtr driver, const char *path, int oflags,
             /* If the path is regular file which exists
              * already and dynamic_ownership is off, we don't
              * want to change it's ownership, just open it as-is */
-            if (is_reg && !driver->dynamicOwnership) {
+            if (is_reg && !cfg->dynamicOwnership) {
                 uid = sb.st_uid;
                 gid = sb.st_gid;
             }
@@ -2729,11 +2671,11 @@ qemuOpenFile(virQEMUDriverPtr driver, const char *path, int oflags,
             /* If we failed as root, and the error was permission-denied
                (EACCES or EPERM), assume it's on a network-connected share
                where root access is restricted (eg, root-squashed NFS). If the
-               qemu user (driver->user) is non-root, just set a flag to
+               qemu user (cfg->user) is non-root, just set a flag to
                bypass security driver shenanigans, and retry the operation
                after doing setuid to qemu user */
             if ((fd != -EACCES && fd != -EPERM) ||
-                driver->user == getuid()) {
+                cfg->user == getuid()) {
                 virReportSystemError(-fd,
                                      _("Failed to create file '%s'"),
                                      path);
@@ -2764,11 +2706,11 @@ qemuOpenFile(virQEMUDriverPtr driver, const char *path, int oflags,
                    goto cleanup;
             }
 
-            /* Retry creating the file as driver->user */
+            /* Retry creating the file as cfg->user */
 
             if ((fd = virFileOpenAs(path, oflags,
                                     S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP,
-                                    driver->user, driver->group,
+                                    cfg->user, cfg->group,
                                     vfoflags | VIR_FILE_OPEN_FORK)) < 0) {
                 virReportSystemError(-fd,
                                    _("Error from child process creating '%s'"),
@@ -2788,7 +2730,7 @@ cleanup:
         *needUnlink = need_unlink;
     if (bypassSecurityDriver)
         *bypassSecurityDriver = bypass_security;
-
+    virObjectUnref(cfg);
     return fd;
 }
 
@@ -3062,6 +3004,7 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml,
     int compressed;
     int ret = -1;
     virDomainObjPtr vm = NULL;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
                   VIR_DOMAIN_SAVE_RUNNING |
@@ -3069,10 +3012,11 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml,
 
     qemuDriverLock(driver);
 
-    if (driver->saveImageFormat == NULL)
+    cfg = virQEMUDriverGetConfig(driver);
+    if (cfg->saveImageFormat == NULL)
         compressed = QEMU_SAVE_FORMAT_RAW;
     else {
-        compressed = qemuSaveCompressionTypeFromString(driver->saveImageFormat);
+        compressed = qemuSaveCompressionTypeFromString(cfg->saveImageFormat);
         if (compressed < 0) {
             virReportError(VIR_ERR_OPERATION_FAILED,
                            "%s", _("Invalid save image format specified "
@@ -3110,7 +3054,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
-
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -3124,12 +3068,15 @@ static char *
 qemuDomainManagedSavePath(virQEMUDriverPtr driver, virDomainObjPtr vm)
 {
     char *ret;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
-    if (virAsprintf(&ret, "%s/%s.save", driver->saveDir, vm->def->name) < 0) {
+    if (virAsprintf(&ret, "%s/%s.save", cfg->saveDir, vm->def->name) < 0) {
         virReportOOMError();
+        virObjectUnref(cfg);
         return NULL;
     }
 
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -3347,30 +3294,35 @@ cleanup:
 static virQEMUSaveFormat
 getCompressionType(virQEMUDriverPtr driver)
 {
-    int compress = QEMU_SAVE_FORMAT_RAW;
+    int ret = QEMU_SAVE_FORMAT_RAW;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     /*
      * We reuse "save" flag for "dump" here. Then, we can support the same
      * format in "save" and "dump".
      */
-    if (driver->dumpImageFormat) {
-        compress = qemuSaveCompressionTypeFromString(driver->dumpImageFormat);
+    if (cfg->dumpImageFormat) {
+        ret = qemuSaveCompressionTypeFromString(cfg->dumpImageFormat);
         /* Use "raw" as the format if the specified format is not valid,
          * or the compress program is not available.
          */
-        if (compress < 0) {
+        if (ret < 0) {
             VIR_WARN("%s", _("Invalid dump image format specified in "
                              "configuration file, using raw"));
-            return QEMU_SAVE_FORMAT_RAW;
+            ret = QEMU_SAVE_FORMAT_RAW;
+            goto cleanup;
         }
-        if (!qemuCompressProgramAvailable(compress)) {
+        if (!qemuCompressProgramAvailable(ret)) {
             VIR_WARN("%s", _("Compression program for dump image format "
                              "in configuration file isn't available, "
                              "using raw"));
-            return QEMU_SAVE_FORMAT_RAW;
+            ret = QEMU_SAVE_FORMAT_RAW;
+            goto cleanup;
         }
     }
-    return compress;
+cleanup:
+    virObjectUnref(cfg);
+    return ret;
 }
 
 static int qemuDomainCoreDump(virDomainPtr dom,
@@ -3496,6 +3448,7 @@ qemuDomainScreenshot(virDomainPtr dom,
     int tmp_fd = -1;
     char *ret = NULL;
     bool unlink_tmp = false;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(0, NULL);
 
@@ -3503,6 +3456,7 @@ qemuDomainScreenshot(virDomainPtr dom,
         goto cleanup;
 
     priv = vm->privateData;
+    cfg = virQEMUDriverGetConfig(driver);
 
     if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
         goto cleanup;
@@ -3522,7 +3476,7 @@ qemuDomainScreenshot(virDomainPtr dom,
         goto endjob;
     }
 
-    if (virAsprintf(&tmp, "%s/qemu.screendump.XXXXXX", driver->cacheDir) < 0) {
+    if (virAsprintf(&tmp, "%s/qemu.screendump.XXXXXX", cfg->cacheDir) < 0) {
         virReportOOMError();
         goto endjob;
     }
@@ -3567,6 +3521,7 @@ endjob:
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -3575,9 +3530,11 @@ static void processWatchdogEvent(void *data, void *opaque)
     int ret;
     struct qemuDomainWatchdogEvent *wdEvent = data;
     virQEMUDriverPtr driver = opaque;
+    virQEMUDriverConfigPtr cfg;
 
     qemuDriverLock(driver);
     virObjectLock(wdEvent->vm);
+    cfg = virQEMUDriverGetConfig(driver);
 
     switch (wdEvent->action) {
     case VIR_DOMAIN_WATCHDOG_ACTION_DUMP:
@@ -3586,7 +3543,7 @@ static void processWatchdogEvent(void *data, void *opaque)
             unsigned int flags = 0;
 
             if (virAsprintf(&dumpfile, "%s/%s-%u",
-                            driver->autoDumpPath,
+                            cfg->autoDumpPath,
                             wdEvent->vm->def->name,
                             (unsigned int)time(NULL)) < 0) {
                 virReportOOMError();
@@ -3606,7 +3563,7 @@ static void processWatchdogEvent(void *data, void *opaque)
                 goto endjob;
             }
 
-            flags |= driver->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0;
+            flags |= cfg->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0;
             ret = doCoreDump(driver, wdEvent->vm, dumpfile,
                              getCompressionType(driver), flags);
             if (ret < 0)
@@ -3639,6 +3596,7 @@ unlock:
     virObjectUnref(wdEvent->vm);
     qemuDriverUnlock(driver);
     VIR_FREE(wdEvent);
+    virObjectUnref(cfg);
 }
 
 static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
@@ -3854,6 +3812,7 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
     int max;
     int ret = -1;
     bool maximum;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -3865,6 +3824,8 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
         return -1;
     }
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
@@ -3923,7 +3884,7 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
             persistentDef->vcpus = nvcpus;
         }
 
-        if (virDomainSaveConfig(driver->configDir, persistentDef) < 0)
+        if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
             goto endjob;
     }
 
@@ -3936,6 +3897,7 @@ endjob:
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -3964,10 +3926,13 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
     int newVcpuPinNum = 0;
     virDomainVcpuPinDefPtr *newVcpuPin = NULL;
     virBitmapPtr pcpumap = NULL;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
@@ -4062,7 +4027,7 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
         if (newVcpuPin)
             virDomainVcpuPinDefArrayFree(newVcpuPin, newVcpuPinNum);
 
-        if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
             goto cleanup;
     }
 
@@ -4095,7 +4060,7 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
             }
         }
 
-        ret = virDomainSaveConfig(driver->configDir, persistentDef);
+        ret = virDomainSaveConfig(cfg->configDir, persistentDef);
         goto cleanup;
     }
 
@@ -4109,6 +4074,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     virBitmapFree(pcpumap);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -4219,10 +4185,13 @@ qemuDomainPinEmulator(virDomainPtr dom,
     int newVcpuPinNum = 0;
     virDomainVcpuPinDefPtr *newVcpuPin = NULL;
     virBitmapPtr pcpumap = NULL;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
@@ -4314,7 +4283,7 @@ qemuDomainPinEmulator(virDomainPtr dom,
             goto cleanup;
         }
 
-        if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
             goto cleanup;
     }
 
@@ -4336,7 +4305,7 @@ qemuDomainPinEmulator(virDomainPtr dom,
             }
         }
 
-        ret = virDomainSaveConfig(driver->configDir, persistentDef);
+        ret = virDomainSaveConfig(cfg->configDir, persistentDef);
         goto cleanup;
     }
 
@@ -4351,6 +4320,7 @@ cleanup:
 
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -4879,6 +4849,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
     virDomainEventPtr event;
     int intermediatefd = -1;
     virCommandPtr cmd = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (header->version == 2) {
         const char *prog = qemuSaveCompressionTypeToString(header->compressed);
@@ -4957,7 +4928,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
                                "%s", _("failed to resume domain"));
             goto out;
         }
-        if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Failed to save status on vm %s", vm->def->name);
             goto out;
         }
@@ -4978,7 +4949,7 @@ out:
     if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
                                                  vm->def, path) < 0)
         VIR_WARN("failed to restore save state label on %s", path);
-
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -5336,10 +5307,12 @@ static char *qemuDomainXMLToNative(virConnectPtr conn,
     virCommandPtr cmd = NULL;
     char *ret = NULL;
     int i;
+    virQEMUDriverConfigPtr cfg;
 
     virCheckFlags(0, NULL);
 
     qemuDriverLock(driver);
+    cfg = virQEMUDriverGetConfig(driver);
 
     if (STRNEQ(format, QEMU_CONFIG_FORMAT_ARGV)) {
         virReportError(VIR_ERR_INVALID_ARG,
@@ -5429,7 +5402,7 @@ static char *qemuDomainXMLToNative(virConnectPtr conn,
 
     monitor_json = qemuCapsGet(caps, QEMU_CAPS_MONITOR_JSON);
 
-    if (qemuProcessPrepareMonitorChr(driver, &monConfig, def->name) < 0)
+    if (qemuProcessPrepareMonitorChr(cfg, &monConfig, def->name) < 0)
         goto cleanup;
 
     if (qemuAssignDeviceAliases(def, caps) < 0)
@@ -5448,6 +5421,7 @@ cleanup:
     virObjectUnref(caps);
     virCommandFree(cmd);
     virDomainDefFree(def);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -5615,8 +5589,10 @@ static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
     virDomainEventPtr event = NULL;
     qemuCapsPtr caps = NULL;
     int dupVM;
+    virQEMUDriverConfigPtr cfg;
 
     qemuDriverLock(driver);
+    cfg = virQEMUDriverGetConfig(driver);
     if (!(def = virDomainDefParseString(driver->caps, xml,
                                         QEMU_EXPECTED_VIRT_TYPES,
                                         VIR_DOMAIN_XML_INACTIVE)))
@@ -5666,7 +5642,7 @@ static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
     }
     vm->persistent = 1;
 
-    if (virDomainSaveConfig(driver->configDir,
+    if (virDomainSaveConfig(cfg->configDir,
                             vm->newDef ? vm->newDef : vm->def) < 0) {
         if (def_backup) {
             /* There is backup so this VM was defined before.
@@ -5705,6 +5681,7 @@ cleanup:
         qemuDomainEventQueue(driver, event);
     virObjectUnref(caps);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return dom;
 }
 
@@ -5718,11 +5695,13 @@ qemuDomainUndefineFlags(virDomainPtr dom,
     char *name = NULL;
     int ret = -1;
     int nsnapshots;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE |
                   VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA, -1);
 
     qemuDriverLock(driver);
+    cfg = virQEMUDriverGetConfig(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
 
     if (!vm) {
@@ -5772,7 +5751,7 @@ qemuDomainUndefineFlags(virDomainPtr dom,
         }
     }
 
-    if (virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm) < 0)
+    if (virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm) < 0)
         goto cleanup;
 
     event = virDomainEventNewFromObj(vm,
@@ -5801,6 +5780,7 @@ cleanup:
     if (event)
         qemuDomainEventQueue(driver, event);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -6436,12 +6416,15 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
     unsigned int affect;
     qemuCapsPtr caps = NULL;
     qemuDomainObjPrivatePtr priv;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
                   (action == QEMU_DEVICE_UPDATE ?
                    VIR_DOMAIN_DEVICE_MODIFY_FORCE : 0), -1);
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     affect = flags & (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG);
 
     qemuDriverLock(driver);
@@ -6556,7 +6539,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, driver->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
             ret = -1;
             goto endjob;
         }
@@ -6564,7 +6547,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
 
     /* Finally, if no error until here, we can save config. */
     if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-        ret = virDomainSaveConfig(driver->configDir, vmdef);
+        ret = virDomainSaveConfig(cfg->configDir, vmdef);
         if (!ret) {
             virDomainObjAssignDef(vm, vmdef, false);
             vmdef = NULL;
@@ -6584,6 +6567,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -6642,10 +6626,11 @@ static int qemuDomainSetAutostart(virDomainPtr dom,
     virDomainObjPtr vm;
     char *configFile = NULL, *autostartLink = NULL;
     int ret = -1;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     qemuDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
-
+    cfg = virQEMUDriverGetConfig(driver);
     if (!vm) {
         char uuidstr[VIR_UUID_STRING_BUFLEN];
         virUUIDFormat(dom->uuid, uuidstr);
@@ -6663,16 +6648,16 @@ static int qemuDomainSetAutostart(virDomainPtr dom,
     autostart = (autostart != 0);
 
     if (vm->autostart != autostart) {
-        if ((configFile = virDomainConfigFile(driver->configDir, vm->def->name)) == NULL)
+        if ((configFile = virDomainConfigFile(cfg->configDir, vm->def->name)) == NULL)
             goto cleanup;
-        if ((autostartLink = virDomainConfigFile(driver->autostartDir, vm->def->name)) == NULL)
+        if ((autostartLink = virDomainConfigFile(cfg->autostartDir, vm->def->name)) == NULL)
             goto cleanup;
 
         if (autostart) {
-            if (virFileMakePath(driver->autostartDir) < 0) {
+            if (virFileMakePath(cfg->autostartDir) < 0) {
                 virReportSystemError(errno,
                                      _("cannot create autostart directory %s"),
-                                     driver->autostartDir);
+                                     cfg->autostartDir);
                 goto cleanup;
             }
 
@@ -6701,6 +6686,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -6911,6 +6897,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
     int ret = -1;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -6924,12 +6911,12 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
 
     qemuDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
-
     if (vm == NULL) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("No such domain %s"), dom->uuid);
         goto cleanup;
     }
+    cfg = virQEMUDriverGetConfig(driver);
 
     if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
                                         &persistentDef) < 0)
@@ -7040,7 +7027,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
             }
         }
 
-        if (virDomainSaveConfig(driver->configDir, persistentDef) < 0)
+        if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
             ret = -1;
     }
 
@@ -7049,6 +7036,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -7254,7 +7242,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
     int hard_limit_index = 0;
     int swap_hard_limit_index = 0;
     unsigned long long val = 0;
-
+    virQEMUDriverConfigPtr cfg = NULL;
     int ret = -1;
     int rc;
 
@@ -7281,6 +7269,8 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
         goto cleanup;
     }
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
@@ -7395,7 +7385,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
     }
 
     if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-        if (virDomainSaveConfig(driver->configDir, persistentDef) < 0)
+        if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
             ret = -1;
     }
 
@@ -7404,6 +7394,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -7579,6 +7570,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
     virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     int ret = -1;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -7599,6 +7591,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
                        _("No such domain %s"), dom->uuid);
         goto cleanup;
     }
+    cfg = virQEMUDriverGetConfig(driver);
 
     if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
                                         &persistentDef) < 0)
@@ -7704,7 +7697,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
         if (!persistentDef->numatune.memory.placement_mode)
             persistentDef->numatune.memory.placement_mode =
                 VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
-        if (virDomainSaveConfig(driver->configDir, persistentDef) < 0)
+        if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
             ret = -1;
     }
 
@@ -7713,6 +7706,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -7928,6 +7922,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
     long long value_l;
     int ret = -1;
     int rc;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -7955,6 +7950,8 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
         goto cleanup;
     }
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
                                         &vmdef) < 0)
         goto cleanup;
@@ -8056,12 +8053,12 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
         }
     }
 
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
         goto cleanup;
 
 
     if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-        rc = virDomainSaveConfig(driver->configDir, vmdef);
+        rc = virDomainSaveConfig(cfg->configDir, vmdef);
         if (rc < 0)
             goto cleanup;
 
@@ -8077,6 +8074,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 #undef SCHED_RANGE_CHECK
@@ -8740,6 +8738,7 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
     int ret = -1;
     virDomainNetDefPtr net = NULL, persistentNet = NULL;
     virNetDevBandwidthPtr bandwidth = NULL, newBandwidth = NULL;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -8768,6 +8767,8 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
         goto cleanup;
     }
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
@@ -8884,7 +8885,7 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
             }
         }
 
-        if (virDomainSaveConfig(driver->configDir, persistentDef) < 0)
+        if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
             goto cleanup;
     }
 
@@ -8896,6 +8897,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -9140,12 +9142,15 @@ qemuDomainMemoryPeek(virDomainPtr dom,
     char *tmp = NULL;
     int fd = -1, ret = -1;
     qemuDomainObjPrivatePtr priv;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_MEMORY_VIRTUAL | VIR_MEMORY_PHYSICAL, -1);
 
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (flags != VIR_MEMORY_VIRTUAL && flags != VIR_MEMORY_PHYSICAL) {
         virReportError(VIR_ERR_INVALID_ARG,
                        "%s", _("flags parameter must be VIR_MEMORY_VIRTUAL or VIR_MEMORY_PHYSICAL"));
@@ -9161,7 +9166,7 @@ qemuDomainMemoryPeek(virDomainPtr dom,
         goto endjob;
     }
 
-    if (virAsprintf(&tmp, "%s/qemu.mem.XXXXXX", driver->cacheDir) < 0) {
+    if (virAsprintf(&tmp, "%s/qemu.mem.XXXXXX", cfg->cacheDir) < 0) {
         virReportOOMError();
         goto endjob;
     }
@@ -9211,6 +9216,7 @@ cleanup:
     VIR_FREE(tmp);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -9229,12 +9235,15 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
     struct stat sb;
     int i;
     int format;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(0, -1);
 
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (!path || path[0] == '\0') {
         virReportError(VIR_ERR_INVALID_ARG,
                        "%s", _("NULL or empty path"));
@@ -9268,9 +9277,10 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
     if (disk->format) {
         format = disk->format;
     } else {
-        if (driver->allowDiskFormatProbing) {
-            if ((format = virStorageFileProbeFormat(disk->src, driver->user,
-                                                    driver->group)) < 0)
+        if (cfg->allowDiskFormatProbing) {
+            if ((format = virStorageFileProbeFormat(disk->src,
+                                                    cfg->user,
+                                                    cfg->group)) < 0)
                 goto cleanup;
         } else {
             virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -9356,6 +9366,7 @@ cleanup:
     VIR_FORCE_CLOSE(fd);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -9922,6 +9933,7 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
     virDomainObjPtr vm;
     int ret = -1;
     enum qemuMigrationJobPhase phase;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
 
@@ -9935,6 +9947,8 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
         goto cleanup;
     }
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT))
         goto cleanup;
 
@@ -9955,7 +9969,7 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
     } else if (!virDomainObjIsActive(vm) &&
                (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE))) {
         if (flags & VIR_MIGRATE_UNDEFINE_SOURCE)
-            virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
+            virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
         qemuDomainRemoveInactive(driver, vm);
         vm = NULL;
     }
@@ -9964,6 +9978,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -10398,6 +10413,7 @@ qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver,
     virStorageFileMetadataPtr origchain = disk->backingChain;
     bool origreadonly = disk->readonly;
     int ret = -1;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     disk->src = (char *) file; /* casting away const is safe here */
     disk->format = VIR_STORAGE_FILE_RAW;
@@ -10412,7 +10428,7 @@ qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver,
             VIR_WARN("Failed to teardown cgroup for disk path %s", disk->src);
         if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
             VIR_WARN("Unable to release lock on %s", disk->src);
-    } else if (virDomainLockDiskAttach(driver->lockManager, driver->uri,
+    } else if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
                                        vm, disk) < 0 ||
                (cgroup && qemuSetupDiskCgroup(vm, cgroup, disk) < 0) ||
                virSecurityManagerSetImageLabel(driver->securityManager,
@@ -10427,6 +10443,7 @@ cleanup:
     disk->format = origformat;
     disk->backingChain = origchain;
     disk->readonly = origreadonly;
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -10513,16 +10530,16 @@ qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver,
     virDomainDiskDefPtr defdisk;
     virCommandPtr cmd = NULL;
     const char *qemuImgPath;
-    virBitmapPtr created;
-
+    virBitmapPtr created = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     int ret = -1;
 
     if (!(qemuImgPath = qemuFindQemuImgBinary(driver)))
-        return -1;
+        goto cleanup;
 
     if (!(created = virBitmapNew(snap->def->ndisks))) {
         virReportOOMError();
-        return -1;
+        goto cleanup;
     }
 
     /* If reuse is true, then qemuDomainSnapshotPrepare already
@@ -10552,7 +10569,7 @@ qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver,
                                    defdisk->src,
                                    virStorageFileFormatTypeToString(defdisk->format));
         } else {
-            if (!driver->allowDiskFormatProbing) {
+            if (!cfg->allowDiskFormatProbing) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                _("unknown image format of '%s' and "
                                  "format probing is disabled"),
@@ -10600,7 +10617,7 @@ cleanup:
     virCommandFree(cmd);
 
     /* unlink images if creation has failed */
-    if (ret < 0) {
+    if (ret < 0 && created) {
         ssize_t bit = -1;
         while ((bit = virBitmapNextSetBit(created, bit)) >= 0) {
             snapdisk = &(snap->def->disks[bit]);
@@ -10610,6 +10627,7 @@ cleanup:
         }
     }
     virBitmapFree(created);
+    virObjectUnref(cfg);
 
     return ret;
 }
@@ -11001,6 +11019,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
     bool persist = false;
     bool reuse = (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT) != 0;
     virCgroupPtr cgroup = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
@@ -11095,10 +11114,11 @@ cleanup:
     virCgroupFree(&cgroup);
 
     if (ret == 0 || !qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION)) {
-        if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0 ||
-            (persist && virDomainSaveConfig(driver->configDir, vm->newDef) < 0))
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0 ||
+            (persist && virDomainSaveConfig(cfg->configDir, vm->newDef) < 0))
             ret = -1;
     }
+    virObjectUnref(cfg);
 
     return ret;
 }
@@ -11302,6 +11322,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
     virDomainSnapshotObjPtr other = NULL;
     int align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL;
     int align_match = true;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
                   VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT |
@@ -11336,6 +11357,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
         goto cleanup;
     }
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (qemuProcessAutoDestroyActive(driver, vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("domain is marked for auto destroy"));
@@ -11581,7 +11604,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
         if (update_current) {
             vm->current_snapshot->def->current = false;
             if (qemuDomainSnapshotWriteMetadata(vm, vm->current_snapshot,
-                                                driver->snapshotDir) < 0)
+                                                cfg->snapshotDir) < 0)
                 goto cleanup;
             vm->current_snapshot = NULL;
         }
@@ -11631,7 +11654,7 @@ cleanup:
     if (vm) {
         if (snapshot && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
             if (qemuDomainSnapshotWriteMetadata(vm, snap,
-                                                driver->snapshotDir) < 0) {
+                                                cfg->snapshotDir) < 0) {
                 /* if writing of metadata fails, error out rather than trying
                  * to silently carry on  without completing the snapshot */
                 virDomainSnapshotFree(snapshot);
@@ -11658,6 +11681,7 @@ cleanup:
     virDomainSnapshotDefFree(def);
     VIR_FREE(xml);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return snapshot;
 }
 
@@ -12007,6 +12031,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
     qemuDomainObjPrivatePtr priv;
     int rc;
     virDomainDefPtr config = NULL;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
                   VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED |
@@ -12034,6 +12059,9 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
                        _("no domain with matching uuid '%s'"), uuidstr);
         goto cleanup;
     }
+
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (virDomainHasDiskMirror(vm)) {
         virReportError(VIR_ERR_BLOCK_COPY_ACTIVE, "%s",
                        _("domain has active block copy job"));
@@ -12081,7 +12109,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
     if (vm->current_snapshot) {
         vm->current_snapshot->def->current = false;
         if (qemuDomainSnapshotWriteMetadata(vm, vm->current_snapshot,
-                                            driver->snapshotDir) < 0)
+                                            cfg->snapshotDir) < 0)
             goto cleanup;
         vm->current_snapshot = NULL;
         /* XXX Should we restore vm->current_snapshot after this point
@@ -12308,7 +12336,7 @@ endjob:
 cleanup:
     if (vm && ret == 0) {
         if (qemuDomainSnapshotWriteMetadata(vm, snap,
-                                            driver->snapshotDir) < 0)
+                                            cfg->snapshotDir) < 0)
             ret = -1;
         else
             vm->current_snapshot = snap;
@@ -12323,6 +12351,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
 
     return ret;
 }
@@ -12331,7 +12360,7 @@ cleanup:
 typedef struct _virQEMUSnapReparent virQEMUSnapReparent;
 typedef virQEMUSnapReparent *virQEMUSnapReparentPtr;
 struct _virQEMUSnapReparent {
-    virQEMUDriverPtr driver;
+    virQEMUDriverConfigPtr cfg;
     virDomainSnapshotObjPtr parent;
     virDomainObjPtr vm;
     int err;
@@ -12367,9 +12396,10 @@ qemuDomainSnapshotReparentChildren(void *payload,
         rep->last = snap;
 
     rep->err = qemuDomainSnapshotWriteMetadata(rep->vm, snap,
-                                               rep->driver->snapshotDir);
+                                               rep->cfg->snapshotDir);
 }
 
+
 static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
                                     unsigned int flags)
 {
@@ -12382,6 +12412,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
     virQEMUSnapReparent rep;
     bool metadata_only = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY);
     int external = 0;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
                   VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY |
@@ -12396,6 +12427,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
         goto cleanup;
     }
 
+    cfg = virQEMUDriverGetConfig(driver);
     if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
         goto cleanup;
 
@@ -12434,7 +12466,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
             if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
                 snap->def->current = true;
                 if (qemuDomainSnapshotWriteMetadata(vm, snap,
-                                                    driver->snapshotDir) < 0) {
+                                                    cfg->snapshotDir) < 0) {
                     virReportError(VIR_ERR_INTERNAL_ERROR,
                                    _("failed to set snapshot '%s' as current"),
                                    snap->def->name);
@@ -12445,7 +12477,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
             vm->current_snapshot = snap;
         }
     } else if (snap->nchildren) {
-        rep.driver = driver;
+        rep.cfg = cfg;
         rep.parent = snap->parent;
         rep.vm = vm;
         rep.err = 0;
@@ -12478,6 +12510,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -12827,6 +12860,7 @@ qemuDomainBlockPivot(virConnectPtr conn,
     char *oldsrc = NULL;
     int oldformat;
     virStorageFileMetadataPtr oldchain = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     /* Probe the status, if needed.  */
     if (!disk->mirroring) {
@@ -12903,7 +12937,7 @@ qemuDomainBlockPivot(virConnectPtr conn,
         goto cleanup;
     }
     if (disk->mirrorFormat && disk->mirrorFormat != VIR_STORAGE_FILE_RAW &&
-        (virDomainLockDiskAttach(driver->lockManager, driver->uri,
+        (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
                                  vm, disk) < 0 ||
          (cgroup && qemuSetupDiskCgroup(vm, cgroup, disk) < 0) ||
          virSecurityManagerSetImageLabel(driver->securityManager, vm->def,
@@ -12966,6 +13000,7 @@ cleanup:
                            _("resuming after drive-reopen failed"));
         }
     }
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -13182,6 +13217,7 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
     bool need_unlink = false;
     char *mirror = NULL;
     virCgroupPtr cgroup = NULL;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     /* Preliminaries: find the disk we are editing, sanity checks */
     virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
@@ -13190,7 +13226,7 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
     priv = vm->privateData;
-
+    cfg = virQEMUDriverGetConfig(driver);
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                        _("domain is not running"));
@@ -13294,8 +13330,8 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
          * also passed the RAW flag (and format is non-NULL), or it is
          * safe for us to probe the format from the file that we will
          * be using.  */
-        disk->mirrorFormat = virStorageFileProbeFormat(dest, driver->user,
-                                                       driver->group);
+        disk->mirrorFormat = virStorageFileProbeFormat(dest, cfg->user,
+                                                       cfg->group);
     }
     if (!format && disk->mirrorFormat > 0)
         format = virStorageFileFormatTypeToString(disk->mirrorFormat);
@@ -13345,6 +13381,7 @@ cleanup:
     VIR_FREE(device);
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -13615,6 +13652,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
     int idx = -1;
     bool set_bytes = false;
     bool set_iops = false;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -13645,6 +13683,8 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
         goto cleanup;
     }
     priv = vm->privateData;
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (!qemuCapsGet(priv->caps, QEMU_CAPS_DRIVE_IOTUNE)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("block I/O throttling not supported with this "
@@ -13747,7 +13787,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
             info.write_iops_sec = oldinfo->write_iops_sec;
         }
         persistentDef->disks[idx]->blkdeviotune = info;
-        ret = virDomainSaveConfig(driver->configDir, persistentDef);
+        ret = virDomainSaveConfig(cfg->configDir, persistentDef);
         if (ret < 0) {
             virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                            _("Write to config file failed"));
@@ -13764,6 +13804,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -13991,6 +14032,7 @@ qemuDomainSetMetadata(virDomainPtr dom,
     virDomainObjPtr vm;
     virDomainDefPtr persistentDef;
     int ret = -1;
+    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -13998,6 +14040,8 @@ qemuDomainSetMetadata(virDomainPtr dom,
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
+    cfg = virQEMUDriverGetConfig(driver);
+
     if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags,
                                         &persistentDef) < 0)
         goto cleanup;
@@ -14056,7 +14100,7 @@ qemuDomainSetMetadata(virDomainPtr dom,
             break;
         }
 
-        if (virDomainSaveConfig(driver->configDir, persistentDef) < 0)
+        if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
             goto cleanup;
     }
 
@@ -14065,6 +14109,7 @@ qemuDomainSetMetadata(virDomainPtr dom,
 cleanup:
     if (vm)
         virObjectUnlock(vm);
+    virObjectUnref(cfg);
     return ret;
 no_memory:
     virReportOOMError();
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index ba6dadd..1b8a9cd 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -410,9 +410,10 @@ int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,
     int last_processed_hostdev_vf = -1;
     int i;
     int ret = -1;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (!(pcidevs = qemuGetPciHostDeviceList(hostdevs, nhostdevs)))
-        return -1;
+        goto cleanup;
 
     /* We have to use 9 loops here. *All* devices must
      * be detached before we reset any of them, because
@@ -430,7 +431,7 @@ int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,
         pciDevice *dev = pciDeviceListGet(pcidevs, i);
         pciDevice *other;
 
-        if (!pciDeviceIsAssignable(dev, !driver->relaxedACS)) {
+        if (!pciDeviceIsAssignable(dev, !cfg->relaxedACS)) {
             virReportError(VIR_ERR_OPERATION_INVALID,
                            _("PCI device %s is not assignable"),
                            pciDeviceGetName(dev));
@@ -482,7 +483,7 @@ int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,
          if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
              hostdev->parent.data.net) {
              if (qemuDomainHostdevNetConfigReplace(hostdev, uuid,
-                                                   driver->stateDir) < 0) {
+                                                   cfg->stateDir) < 0) {
                  goto resetvfnetconfig;
              }
          }
@@ -568,7 +569,7 @@ resetvfnetconfig:
          virDomainHostdevDefPtr hostdev = hostdevs[i];
          if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
              hostdev->parent.data.net) {
-             qemuDomainHostdevNetConfigRestore(hostdev, driver->stateDir);
+             qemuDomainHostdevNetConfigRestore(hostdev, cfg->stateDir);
          }
     }
 
@@ -580,6 +581,7 @@ reattachdevs:
 
 cleanup:
     pciDeviceListFree(pcidevs);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -848,6 +850,7 @@ void qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver,
 {
     pciDeviceList *pcidevs;
     int i;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (!(pcidevs = qemuGetActivePciHostDeviceList(driver,
                                                    hostdevs,
@@ -856,7 +859,7 @@ void qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver,
         VIR_ERROR(_("Failed to allocate pciDeviceList: %s"),
                   err ? err->message : _("unknown error"));
         virResetError(err);
-        return;
+        goto cleanup;
     }
 
     /* Again 4 loops; mark all devices as inactive before reset
@@ -893,7 +896,7 @@ void qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver,
              continue;
          if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
              hostdev->parent.data.net) {
-             qemuDomainHostdevNetConfigRestore(hostdev, driver->stateDir);
+             qemuDomainHostdevNetConfigRestore(hostdev, cfg->stateDir);
          }
     }
 
@@ -914,6 +917,8 @@ void qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver,
     }
 
     pciDeviceListFree(pcidevs);
+cleanup:
+    virObjectUnref(cfg);
 }
 
 static void
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 18c4109..6c328d6 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -57,10 +57,11 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
 {
     virDomainDiskDefPtr origdisk = NULL;
     int i;
-    int ret;
+    int ret = -1;
     char *driveAlias = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int retries = CHANGE_MEDIA_RETRIES;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     for (i = 0 ; i < vm->def->ndisks ; i++) {
         if (vm->def->disks[i]->bus == disk->bus &&
@@ -75,13 +76,13 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
                        _("No device with bus '%s' and target '%s'"),
                        virDomainDiskBusTypeToString(disk->bus),
                        disk->dst);
-        return -1;
+        goto cleanup;
     }
 
     if (!origdisk->info.alias) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("missing disk device alias name for %s"), origdisk->dst);
-        return -1;
+        goto cleanup;
     }
 
     if (origdisk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY &&
@@ -89,18 +90,18 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Removable media not supported for %s device"),
                        virDomainDiskDeviceTypeToString(disk->device));
-        return -1;
+        goto cleanup;
     }
 
-    if (virDomainLockDiskAttach(driver->lockManager, driver->uri,
+    if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
                                 vm, disk) < 0)
-        return -1;
+        goto cleanup;
 
     if (virSecurityManagerSetImageLabel(driver->securityManager,
                                         vm->def, disk) < 0) {
         if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
             VIR_WARN("Unable to release lock on %s", disk->src);
-        return -1;
+        goto cleanup;
     }
 
     if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, priv->caps)))
@@ -162,15 +163,15 @@ exit_monitor:
     disk->src = NULL;
     origdisk->type = disk->type;
 
-    VIR_FREE(driveAlias);
 
     virDomainDiskDefFree(disk);
 
+cleanup:
+    VIR_FREE(driveAlias);
+    virObjectUnref(cfg);
     return ret;
 
 error:
-    VIR_FREE(driveAlias);
-
     if (virSecurityManagerRestoreImageLabel(driver->securityManager,
                                             vm->def, disk) < 0)
         VIR_WARN("Unable to restore security label on new media %s", disk->src);
@@ -178,7 +179,7 @@ error:
     if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
         VIR_WARN("Unable to release lock on %s", disk->src);
 
-    return -1;
+    goto cleanup;
 }
 
 int
@@ -229,30 +230,31 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn,
                                   virDomainObjPtr vm,
                                   virDomainDiskDefPtr disk)
 {
-    int i, ret;
+    int i, ret = -1;
     const char* type = virDomainDiskBusTypeToString(disk->bus);
     qemuDomainObjPrivatePtr priv = vm->privateData;
     char *devstr = NULL;
     char *drivestr = NULL;
     bool releaseaddr = false;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     for (i = 0 ; i < vm->def->ndisks ; i++) {
         if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
             virReportError(VIR_ERR_OPERATION_FAILED,
                            _("target %s already exists"), disk->dst);
-            return -1;
+            goto cleanup;
         }
     }
 
-    if (virDomainLockDiskAttach(driver->lockManager, driver->uri,
+    if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
                                 vm, disk) < 0)
-        return -1;
+        goto cleanup;
 
     if (virSecurityManagerSetImageLabel(driver->securityManager,
                                         vm->def, disk) < 0) {
         if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
             VIR_WARN("Unable to release lock on %s", disk->src);
-        return -1;
+        goto cleanup;
     }
 
     if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) {
@@ -312,15 +314,13 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn,
 
     virDomainDiskInsertPreAlloced(vm->def, disk);
 
+cleanup:
     VIR_FREE(devstr);
     VIR_FREE(drivestr);
-
-    return 0;
+    virObjectUnref(cfg);
+    return ret;
 
 error:
-    VIR_FREE(devstr);
-    VIR_FREE(drivestr);
-
     if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) &&
         (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
         releaseaddr &&
@@ -335,7 +335,7 @@ error:
     if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
         VIR_WARN("Unable to release lock on %s", disk->src);
 
-    return -1;
+    goto cleanup;
 }
 
 
@@ -468,24 +468,25 @@ int qemuDomainAttachSCSIDisk(virConnectPtr conn,
     char *drivestr = NULL;
     char *devstr = NULL;
     int ret = -1;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     for (i = 0 ; i < vm->def->ndisks ; i++) {
         if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
             virReportError(VIR_ERR_OPERATION_FAILED,
                            _("target %s already exists"), disk->dst);
-            return -1;
+            goto cleanup;
         }
     }
 
-    if (virDomainLockDiskAttach(driver->lockManager, driver->uri,
+    if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
                                 vm, disk) < 0)
-        return -1;
+        goto cleanup;
 
     if (virSecurityManagerSetImageLabel(driver->securityManager,
                                         vm->def, disk) < 0) {
         if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
             VIR_WARN("Unable to release lock on %s", disk->src);
-        return -1;
+        goto cleanup;
     }
 
     /* We should have an address already, so make sure */
@@ -563,15 +564,13 @@ int qemuDomainAttachSCSIDisk(virConnectPtr conn,
 
     virDomainDiskInsertPreAlloced(vm->def, disk);
 
+cleanup:
     VIR_FREE(devstr);
     VIR_FREE(drivestr);
-
-    return 0;
+    virObjectUnref(cfg);
+    return ret;
 
 error:
-    VIR_FREE(devstr);
-    VIR_FREE(drivestr);
-
     if (virSecurityManagerRestoreImageLabel(driver->securityManager,
                                             vm->def, disk) < 0)
         VIR_WARN("Unable to restore security label on %s", disk->src);
@@ -579,7 +578,7 @@ error:
     if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
         VIR_WARN("Unable to release lock on %s", disk->src);
 
-    return -1;
+    goto cleanup;
 }
 
 
@@ -589,27 +588,28 @@ int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn,
                                          virDomainDiskDefPtr disk)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    int i, ret;
+    int i, ret = -1;
     char *drivestr = NULL;
     char *devstr = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     for (i = 0 ; i < vm->def->ndisks ; i++) {
         if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
             virReportError(VIR_ERR_OPERATION_FAILED,
                            _("target %s already exists"), disk->dst);
-            return -1;
+            goto cleanup;
         }
     }
 
-    if (virDomainLockDiskAttach(driver->lockManager, driver->uri,
+    if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
                                 vm, disk) < 0)
-        return -1;
+        goto cleanup;
 
     if (virSecurityManagerSetImageLabel(driver->securityManager,
                                         vm->def, disk) < 0) {
         if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
             VIR_WARN("Unable to release lock on %s", disk->src);
-        return -1;
+        goto cleanup;
     }
 
     /* XXX not correct once we allow attaching a USB CDROM */
@@ -657,15 +657,13 @@ int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn,
 
     virDomainDiskInsertPreAlloced(vm->def, disk);
 
+cleanup:
     VIR_FREE(devstr);
     VIR_FREE(drivestr);
-
-    return 0;
+    virObjectUnref(cfg);
+    return ret;
 
 error:
-    VIR_FREE(devstr);
-    VIR_FREE(drivestr);
-
     if (virSecurityManagerRestoreImageLabel(driver->securityManager,
                                             vm->def, disk) < 0)
         VIR_WARN("Unable to restore security label on %s", disk->src);
@@ -673,7 +671,7 @@ error:
     if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
         VIR_WARN("Unable to release lock on %s", disk->src);
 
-    return -1;
+    goto cleanup;
 }
 
 
@@ -697,11 +695,12 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
     bool releaseaddr = false;
     bool iface_connected = false;
     int actualType;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     /* preallocate new slot for device */
     if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0) {
         virReportOOMError();
-        return -1;
+        goto cleanup;
     }
 
     /* If appropriate, grab a physical device from the configured
@@ -709,7 +708,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
      * to the one defined in the network definition.
      */
     if (networkAllocateActualDevice(net) < 0)
-        return -1;
+        goto cleanup;
 
     actualType = virDomainNetGetActualType(net);
 
@@ -738,7 +737,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
          * supported.
          */
         if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
-            driver->privileged ||
+            cfg->privileged ||
             (!qemuCapsGet(priv->caps, QEMU_CAPS_NETDEV_BRIDGE))) {
             if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net,
                                                  priv->caps)) < 0)
@@ -918,6 +917,7 @@ cleanup:
     VIR_FORCE_CLOSE(tapfd);
     VIR_FREE(vhostfd_name);
     VIR_FORCE_CLOSE(vhostfd);
+    virObjectUnref(cfg);
 
     return ret;
 
@@ -1820,11 +1820,12 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
     const char *oldListenAddr, *newListenAddr;
     const char *oldListenNetwork, *newListenNetwork;
     int ret = -1;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (!olddev) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("cannot find existing graphics device to modify"));
-        return -1;
+        goto cleanup;
     }
 
     oldListenAddr = virDomainGraphicsListenGetAddress(olddev, 0);
@@ -1839,22 +1840,22 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
              (olddev->data.vnc.port != dev->data.vnc.port))) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("cannot change port settings on vnc graphics"));
-            return -1;
+            goto cleanup;
         }
         if (STRNEQ_NULLABLE(oldListenAddr,newListenAddr)) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("cannot change listen address setting on vnc graphics"));
-            return -1;
+            goto cleanup;
         }
         if (STRNEQ_NULLABLE(oldListenNetwork,newListenNetwork)) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("cannot change listen network setting on vnc graphics"));
-            return -1;
+            goto cleanup;
         }
         if (STRNEQ_NULLABLE(olddev->data.vnc.keymap, dev->data.vnc.keymap)) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("cannot change keymap setting on vnc graphics"));
-            return -1;
+            goto cleanup;
         }
 
         /* If a password lifetime was, or is set, or action if connected has
@@ -1866,11 +1867,11 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
             STRNEQ_NULLABLE(olddev->data.vnc.auth.passwd,
                             dev->data.vnc.auth.passwd)) {
             VIR_DEBUG("Updating password on VNC server %p %p",
-                      dev->data.vnc.auth.passwd, driver->vncPassword);
+                      dev->data.vnc.auth.passwd, cfg->vncPassword);
             ret = qemuDomainChangeGraphicsPasswords(driver, vm,
                                                     VIR_DOMAIN_GRAPHICS_TYPE_VNC,
                                                     &dev->data.vnc.auth,
-                                                    driver->vncPassword);
+                                                    cfg->vncPassword);
             if (ret < 0)
                 return ret;
 
@@ -1894,23 +1895,23 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
              (olddev->data.spice.tlsPort != dev->data.spice.tlsPort))) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("cannot change port settings on spice graphics"));
-            return -1;
+            goto cleanup;
         }
         if (STRNEQ_NULLABLE(oldListenAddr, newListenAddr)) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("cannot change listen address setting on spice graphics"));
-            return -1;
+            goto cleanup;
         }
         if (STRNEQ_NULLABLE(oldListenNetwork, newListenNetwork)) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("cannot change listen network setting on spice graphics"));
-            return -1;
+            goto cleanup;
         }
         if (STRNEQ_NULLABLE(olddev->data.spice.keymap,
                             dev->data.spice.keymap)) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                             _("cannot change keymap setting on spice graphics"));
-            return -1;
+            goto cleanup;
         }
 
         /* We must reset the password if it has changed but also if:
@@ -1926,11 +1927,11 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
             STRNEQ_NULLABLE(olddev->data.spice.auth.passwd,
                             dev->data.spice.auth.passwd)) {
             VIR_DEBUG("Updating password on SPICE server %p %p",
-                      dev->data.spice.auth.passwd, driver->spicePassword);
+                      dev->data.spice.auth.passwd, cfg->spicePassword);
             ret = qemuDomainChangeGraphicsPasswords(driver, vm,
                                                     VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
                                                     &dev->data.spice.auth,
-                                                    driver->spicePassword);
+                                                    cfg->spicePassword);
 
             if (ret < 0)
                 return ret;
@@ -1955,6 +1956,8 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
         break;
     }
 
+cleanup:
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -2327,42 +2330,43 @@ qemuDomainDetachHostPciDevice(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainHostdevSubsysPtr subsys = &detach->source.subsys;
-    int ret;
+    int ret = -1, rv;
     pciDevice *pci;
     pciDevice *activePci;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (qemuIsMultiFunctionDevice(vm->def, detach->info)) {
         virReportError(VIR_ERR_OPERATION_FAILED,
                        _("cannot hot unplug multifunction PCI device: %.4x:%.2x:%.2x.%.1x"),
                        subsys->u.pci.domain, subsys->u.pci.bus,
                        subsys->u.pci.slot,   subsys->u.pci.function);
-        return -1;
+        goto cleanup;
     }
 
     if (!virDomainDeviceAddressIsValid(detach->info,
                                        VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
         virReportError(VIR_ERR_OPERATION_FAILED,
                        "%s", _("device cannot be detached without a PCI address"));
-        return -1;
+        goto cleanup;
     }
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) {
-        ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
+        rv = qemuMonitorDelDevice(priv->mon, detach->info->alias);
     } else {
-        ret = qemuMonitorRemovePCIDevice(priv->mon, &detach->info->addr.pci);
+        rv = qemuMonitorRemovePCIDevice(priv->mon, &detach->info->addr.pci);
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
-    virDomainAuditHostdev(vm, detach, "detach", ret == 0);
-    if (ret < 0)
-        return -1;
+    virDomainAuditHostdev(vm, detach, "detach", rv == 0);
+    if (rv < 0)
+        goto cleanup;
 
     /*
      * For SRIOV net host devices, unset mac and port profile before
      * reset and reattach device
      */
      if (detach->parent.data.net)
-         qemuDomainHostdevNetConfigRestore(detach, driver->stateDir);
+         qemuDomainHostdevNetConfigRestore(detach, cfg->stateDir);
 
     pci = pciGetDevice(subsys->u.pci.domain, subsys->u.pci.bus,
                        subsys->u.pci.slot,   subsys->u.pci.function);
@@ -2372,14 +2376,12 @@ qemuDomainDetachHostPciDevice(virQEMUDriverPtr driver,
             pciResetDevice(activePci, driver->activePciHostdevs,
                            driver->inactivePciHostdevs) == 0) {
             qemuReattachPciDevice(activePci, driver);
+            ret = 0;
         } else {
             /* reset of the device failed, treat it as if it was returned */
             pciFreeDevice(activePci);
-            ret = -1;
         }
         pciFreeDevice(pci);
-    } else {
-        ret = -1;
     }
 
     if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE) &&
@@ -2387,6 +2389,8 @@ qemuDomainDetachHostPciDevice(virQEMUDriverPtr driver,
                                         detach->info->addr.pci.slot) < 0)
         VIR_WARN("Unable to release PCI address on host device");
 
+cleanup:
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -2546,6 +2550,7 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
     char *hostnet_name = NULL;
     char mac[VIR_MAC_STRING_BUFLEN];
     virNetDevVPortProfilePtr vport = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     detachidx = virDomainNetFindIdx(vm->def, dev->data.net);
     if (detachidx == -2) {
@@ -2553,7 +2558,7 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
                        _("multiple devices matching mac address %s found"),
                        virMacAddrFormat(&dev->data.net->mac, mac));
         goto cleanup;
-        }
+    }
     else if (detachidx < 0) {
         virReportError(VIR_ERR_OPERATION_FAILED,
                        _("network device %s not found"),
@@ -2642,11 +2647,11 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
                          virDomainNetGetActualDirectDev(detach),
                          virDomainNetGetActualDirectMode(detach),
                          virDomainNetGetActualVirtPortProfile(detach),
-                         driver->stateDir));
+                         cfg->stateDir));
         VIR_FREE(detach->ifname);
     }
 
-    if ((driver->macFilter) && (detach->ifname != NULL)) {
+    if (cfg->macFilter && (detach->ifname != NULL)) {
         if ((errno = networkDisallowMacOnPort(driver,
                                               detach->ifname,
                                               &detach->mac))) {
@@ -2669,6 +2674,7 @@ cleanup:
         virDomainNetDefFree(detach);
     }
     VIR_FREE(hostnet_name);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -2683,10 +2689,13 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
     time_t now = time(NULL);
     char expire_time [64];
     const char *connected = NULL;
-    int ret;
+    int ret = -1;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
-    if (!auth->passwd && !driver->vncPassword)
-        return 0;
+    if (!auth->passwd && !cfg->vncPassword) {
+        ret = 0;
+        goto cleanup;
+    }
 
     if (auth->connected)
         connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected);
@@ -2708,7 +2717,7 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
         }
     }
     if (ret != 0)
-        goto cleanup;
+        goto end_job;
 
     if (auth->expires) {
         time_t lifetime = auth->validTo - now;
@@ -2733,9 +2742,10 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
         }
     }
 
-cleanup:
+end_job:
     qemuDomainObjExitMonitorWithDriver(driver, vm);
-
+cleanup:
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -2743,17 +2753,24 @@ int qemuDomainAttachLease(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
                           virDomainLeaseDefPtr lease)
 {
+    int ret = -1;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
     if (virDomainLeaseInsertPreAlloc(vm->def) < 0)
-        return -1;
+        goto cleanup;
 
-    if (virDomainLockLeaseAttach(driver->lockManager, driver->uri,
+    if (virDomainLockLeaseAttach(driver->lockManager, cfg->uri,
                                  vm, lease) < 0) {
         virDomainLeaseInsertPreAlloced(vm->def, NULL);
-        return -1;
+        goto cleanup;
     }
 
     virDomainLeaseInsertPreAlloced(vm->def, lease);
-    return 0;
+    ret = 0;
+
+cleanup:
+    virObjectUnref(cfg);
+    return ret;
 }
 
 int qemuDomainDetachLease(virQEMUDriverPtr driver,
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index d03e361..f4aa9a2 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -265,6 +265,7 @@ qemuMigrationCookieGraphicsAlloc(virQEMUDriverPtr driver,
 {
     qemuMigrationCookieGraphicsPtr mig = NULL;
     const char *listenAddr;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (VIR_ALLOC(mig) < 0)
         goto no_memory;
@@ -274,32 +275,33 @@ qemuMigrationCookieGraphicsAlloc(virQEMUDriverPtr driver,
         mig->port = def->data.vnc.port;
         listenAddr = virDomainGraphicsListenGetAddress(def, 0);
         if (!listenAddr)
-            listenAddr = driver->vncListen;
+            listenAddr = cfg->vncListen;
 
 #ifdef WITH_GNUTLS
-        if (driver->vncTLS &&
-            !(mig->tlsSubject = qemuDomainExtractTLSSubject(driver->vncTLSx509certdir)))
+        if (cfg->vncTLS &&
+            !(mig->tlsSubject = qemuDomainExtractTLSSubject(cfg->vncTLSx509certdir)))
             goto error;
 #endif
     } else {
         mig->port = def->data.spice.port;
-        if (driver->spiceTLS)
+        if (cfg->spiceTLS)
             mig->tlsPort = def->data.spice.tlsPort;
         else
             mig->tlsPort = -1;
         listenAddr = virDomainGraphicsListenGetAddress(def, 0);
         if (!listenAddr)
-            listenAddr = driver->spiceListen;
+            listenAddr = cfg->spiceListen;
 
 #ifdef WITH_GNUTLS
-        if (driver->spiceTLS &&
-            !(mig->tlsSubject = qemuDomainExtractTLSSubject(driver->spiceTLSx509certdir)))
+        if (cfg->spiceTLS &&
+            !(mig->tlsSubject = qemuDomainExtractTLSSubject(cfg->spiceTLSx509certdir)))
             goto error;
 #endif
     }
     if (!(mig->listen = strdup(listenAddr)))
         goto no_memory;
 
+    virObjectUnref(cfg);
     return mig;
 
 no_memory:
@@ -308,6 +310,7 @@ no_memory:
 error:
 #endif
     qemuMigrationCookieGraphicsFree(mig);
+    virObjectUnref(cfg);
     return NULL;
 }
 
@@ -2474,6 +2477,7 @@ static int doTunnelMigrate(virQEMUDriverPtr driver,
     virNetSocketPtr sock = NULL;
     int ret = -1;
     qemuMigrationSpec spec;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("driver=%p, vm=%p, st=%p, cookiein=%s, cookieinlen=%d, "
               "cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu",
@@ -2485,6 +2489,7 @@ static int doTunnelMigrate(virQEMUDriverPtr driver,
         !qemuCapsGet(priv->caps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) {
         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                        _("Source qemu is too old to support tunnelled migration"));
+        virObjectUnref(cfg);
         return -1;
     }
 
@@ -2516,13 +2521,13 @@ static int doTunnelMigrate(virQEMUDriverPtr driver,
 
         if (virAsprintf(&spec.dest.unix_socket.file,
                         "%s/qemu.tunnelmigrate.src.%s",
-                        driver->libDir, vm->def->name) < 0) {
+                        cfg->libDir, vm->def->name) < 0) {
             virReportOOMError();
             goto cleanup;
         }
 
         if (virNetSocketNewListenUNIX(spec.dest.unix_socket.file, 0700,
-                                      driver->user, driver->group,
+                                      cfg->user, cfg->group,
                                       &sock) < 0 ||
             virNetSocketListen(sock, 1) < 0)
             goto cleanup;
@@ -2542,6 +2547,7 @@ cleanup:
         VIR_FREE(spec.dest.unix_socket.file);
     }
 
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -2902,6 +2908,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
     bool p2p;
     virErrorPtr orig_err = NULL;
     bool offline = false;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("driver=%p, sconn=%p, vm=%p, xmlin=%s, dconnuri=%s, "
               "uri=%s, flags=%lx, dname=%s, resource=%lu",
@@ -2918,11 +2925,12 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
     if (dconn == NULL) {
         virReportError(VIR_ERR_OPERATION_FAILED,
                        _("Failed to connect to remote libvirt URI %s"), dconnuri);
+        virObjectUnref(cfg);
         return -1;
     }
 
-    if (virConnectSetKeepAlive(dconn, driver->keepAliveInterval,
-                               driver->keepAliveCount) < 0)
+    if (virConnectSetKeepAlive(dconn, cfg->keepAliveInterval,
+                               cfg->keepAliveCount) < 0)
         goto cleanup;
 
     qemuDomainObjEnterRemoteWithDriver(driver, vm);
@@ -2982,7 +2990,7 @@ cleanup:
         virSetError(orig_err);
         virFreeError(orig_err);
     }
-
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -3012,6 +3020,7 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver,
     int ret = -1;
     int resume = 0;
     virErrorPtr orig_err = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
         goto cleanup;
@@ -3085,7 +3094,7 @@ endjob:
                (!vm->persistent ||
                 (ret == 0 && (flags & VIR_MIGRATE_UNDEFINE_SOURCE)))) {
         if (flags & VIR_MIGRATE_UNDEFINE_SOURCE)
-            virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
+            virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
         qemuDomainRemoveInactive(driver, vm);
         vm = NULL;
     }
@@ -3100,6 +3109,7 @@ cleanup:
         virObjectUnlock(vm);
     if (event)
         qemuDomainEventQueue(driver, event);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -3313,6 +3323,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
     virErrorPtr orig_err = NULL;
     int cookie_flags = 0;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
               "cookieout=%p, cookieoutlen=%p, flags=%lx, retcode=%d",
@@ -3370,7 +3381,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
                 vm->newDef = vmdef = mig->persistent;
             else
                 vmdef = virDomainObjGetPersistentDef(driver->caps, vm);
-            if (!vmdef || virDomainSaveConfig(driver->configDir, vmdef) < 0) {
+            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
                  * shuts down, management tools are in for a surprise.  On the
@@ -3464,7 +3475,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
         }
 
         if (virDomainObjIsActive(vm) &&
-            virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+            virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Failed to save status on vm %s", vm->def->name);
             goto endjob;
         }
@@ -3503,6 +3514,7 @@ cleanup:
         virSetError(orig_err);
         virFreeError(orig_err);
     }
+    virObjectUnref(cfg);
     return dom;
 }
 
@@ -3518,6 +3530,8 @@ int qemuMigrationConfirm(virQEMUDriverPtr driver,
     qemuMigrationCookiePtr mig;
     virDomainEventPtr event = NULL;
     int rv = -1;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
     VIR_DEBUG("driver=%p, conn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
               "flags=%x, retcode=%d",
               driver, conn, vm, NULLSTR(cookiein), cookieinlen,
@@ -3531,7 +3545,7 @@ int qemuMigrationConfirm(virQEMUDriverPtr driver,
                              : QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED);
 
     if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, 0)))
-        return -1;
+        goto cleanup;
 
     if (flags & VIR_MIGRATE_OFFLINE)
         goto done;
@@ -3565,7 +3579,7 @@ int qemuMigrationConfirm(virQEMUDriverPtr driver,
         event = virDomainEventNewFromObj(vm,
                                          VIR_DOMAIN_EVENT_RESUMED,
                                          VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
-        if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Failed to save status on vm %s", vm->def->name);
             goto cleanup;
         }
@@ -3578,6 +3592,7 @@ done:
 cleanup:
     if (event)
         qemuDomainEventQueue(driver, event);
+    virObjectUnref(cfg);
     return rv;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a2ce007..d1d3d95 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -90,10 +90,12 @@ qemuProcessRemoveDomainStatus(virQEMUDriverPtr driver,
     char ebuf[1024];
     char *file = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    int ret = -1;
 
-    if (virAsprintf(&file, "%s/%s.xml", driver->stateDir, vm->def->name) < 0) {
+    if (virAsprintf(&file, "%s/%s.xml", cfg->stateDir, vm->def->name) < 0) {
         virReportOOMError();
-        return -1;
+        goto cleanup;
     }
 
     if (unlink(file) < 0 && errno != ENOENT && errno != ENOTDIR)
@@ -107,7 +109,10 @@ qemuProcessRemoveDomainStatus(virQEMUDriverPtr driver,
         VIR_WARN("Failed to remove PID file for %s: %s",
                  vm->def->name, virStrerror(errno, ebuf, sizeof(ebuf)));
 
-    return 0;
+    ret = 0;
+cleanup:
+    virObjectUnref(cfg);
+    return ret;
 }
 
 
@@ -654,6 +659,7 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virQEMUDriverPtr driver = qemu_driver;
     qemuDomainObjPrivatePtr priv;
     virDomainEventPtr event = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("vm=%p", vm);
 
@@ -680,7 +686,7 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                      VIR_DOMAIN_EVENT_SHUTDOWN,
                                      VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED);
 
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
         VIR_WARN("Unable to save status on vm %s after state change",
                  vm->def->name);
     }
@@ -698,6 +704,7 @@ unlock:
         qemuDomainEventQueue(driver, event);
         qemuDriverUnlock(driver);
     }
+    virObjectUnref(cfg);
 
     return 0;
 }
@@ -709,6 +716,7 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 {
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr event = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
     if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
@@ -732,7 +740,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, driver->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after state change",
                      vm->def->name);
         }
@@ -746,6 +754,7 @@ unlock:
         qemuDomainEventQueue(driver, event);
         qemuDriverUnlock(driver);
     }
+    virObjectUnref(cfg);
 
     return 0;
 }
@@ -757,6 +766,7 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 {
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr event = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
     if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
@@ -777,7 +787,7 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                          VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
 
         VIR_DEBUG("Using lock state '%s' on resume event", NULLSTR(priv->lockState));
-        if (virDomainLockProcessResume(driver->lockManager, driver->uri,
+        if (virDomainLockProcessResume(driver->lockManager, cfg->uri,
                                        vm, priv->lockState) < 0) {
             /* Don't free priv->lockState on error, because we need
              * to make sure we have state still present if the user
@@ -787,7 +797,7 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         }
         VIR_FREE(priv->lockState);
 
-        if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after state change",
                      vm->def->name);
         }
@@ -801,7 +811,7 @@ unlock:
         qemuDomainEventQueue(driver, event);
         qemuDriverUnlock(driver);
     }
-
+    virObjectUnref(cfg);
     return 0;
 }
 
@@ -813,6 +823,7 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 {
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr event;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
     event = virDomainEventRTCChangeNewFromObj(vm, offset);
@@ -820,7 +831,7 @@ 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, driver->stateDir, vm) < 0)
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
         VIR_WARN("unable to save domain status with RTC change");
 
     virObjectUnlock(vm);
@@ -831,6 +842,7 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         qemuDriverUnlock(driver);
     }
 
+    virObjectUnref(cfg);
     return 0;
 }
 
@@ -843,6 +855,7 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr watchdogEvent = NULL;
     virDomainEventPtr lifecycleEvent = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
     watchdogEvent = virDomainEventWatchdogNewFromObj(vm, action);
@@ -862,7 +875,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, driver->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after watchdog event",
                      vm->def->name);
         }
@@ -899,6 +912,7 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         qemuDriverUnlock(driver);
     }
 
+    virObjectUnref(cfg);
     return 0;
 }
 
@@ -917,6 +931,7 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     const char *srcPath;
     const char *devAlias;
     virDomainDiskDefPtr disk;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
     disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);
@@ -947,7 +962,7 @@ 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, driver->stateDir, vm) < 0)
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
             VIR_WARN("Unable to save status on vm %s after IO error", vm->def->name);
     }
     virObjectUnlock(vm);
@@ -963,6 +978,7 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         qemuDriverUnlock(driver);
     }
 
+    virObjectUnref(cfg);
     return 0;
 }
 
@@ -1117,6 +1133,7 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr event = NULL;
     virDomainDiskDefPtr disk;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
     disk = qemuProcessFindDomainDiskByAlias(vm, devAlias);
@@ -1131,7 +1148,7 @@ 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, driver->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after tray moved event",
                      vm->def->name);
         }
@@ -1144,7 +1161,7 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         qemuDomainEventQueue(driver, event);
         qemuDriverUnlock(driver);
     }
-
+    virObjectUnref(cfg);
     return 0;
 }
 
@@ -1155,6 +1172,7 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr event = NULL;
     virDomainEventPtr lifecycleEvent = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
     event = virDomainEventPMWakeupNewFromObj(vm);
@@ -1172,7 +1190,7 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                                   VIR_DOMAIN_EVENT_STARTED,
                                                   VIR_DOMAIN_EVENT_STARTED_WAKEUP);
 
-        if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after wakeup event",
                      vm->def->name);
         }
@@ -1189,6 +1207,7 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         qemuDriverUnlock(driver);
     }
 
+    virObjectUnref(cfg);
     return 0;
 }
 
@@ -1199,6 +1218,7 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr event = NULL;
     virDomainEventPtr lifecycleEvent = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
     event = virDomainEventPMSuspendNewFromObj(vm);
@@ -1215,7 +1235,7 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                      VIR_DOMAIN_EVENT_PMSUSPENDED,
                                      VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY);
 
-        if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after suspend event",
                      vm->def->name);
         }
@@ -1234,7 +1254,7 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
             qemuDomainEventQueue(driver, lifecycleEvent);
         qemuDriverUnlock(driver);
     }
-
+    virObjectUnref(cfg);
     return 0;
 }
 
@@ -1245,6 +1265,7 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 {
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr event;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
     event = virDomainEventBalloonChangeNewFromObj(vm, actual);
@@ -1253,7 +1274,7 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
               vm->def->mem.cur_balloon, actual);
     vm->def->mem.cur_balloon = actual;
 
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
         VIR_WARN("unable to save domain status with balloon change");
 
     virObjectUnlock(vm);
@@ -1264,6 +1285,7 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         qemuDriverUnlock(driver);
     }
 
+    virObjectUnref(cfg);
     return 0;
 }
 
@@ -1274,6 +1296,7 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virQEMUDriverPtr driver = qemu_driver;
     virDomainEventPtr event = NULL;
     virDomainEventPtr lifecycleEvent = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
     event = virDomainEventPMSuspendDiskNewFromObj(vm);
@@ -1290,7 +1313,7 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                      VIR_DOMAIN_EVENT_PMSUSPENDED,
                                      VIR_DOMAIN_EVENT_PMSUSPENDED_DISK);
 
-        if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+        if (virDomainSaveStatus(driver->caps,cfg->stateDir, vm) < 0) {
             VIR_WARN("Unable to save status on vm %s after suspend event",
                      vm->def->name);
         }
@@ -1310,6 +1333,8 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         qemuDriverUnlock(driver);
     }
 
+    virObjectUnref(cfg);
+
     return 0;
 }
 
@@ -2179,6 +2204,7 @@ qemuProcessInitPasswords(virConnectPtr conn,
 {
     int ret = 0;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     int i;
 
     for (i = 0 ; i < vm->def->ngraphics; ++i) {
@@ -2187,12 +2213,12 @@ qemuProcessInitPasswords(virConnectPtr conn,
             ret = qemuDomainChangeGraphicsPasswords(driver, vm,
                                                     VIR_DOMAIN_GRAPHICS_TYPE_VNC,
                                                     &graphics->data.vnc.auth,
-                                                    driver->vncPassword);
+                                                    cfg->vncPassword);
         } else if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
             ret = qemuDomainChangeGraphicsPasswords(driver, vm,
                                                     VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
                                                     &graphics->data.spice.auth,
-                                                    driver->spicePassword);
+                                                    cfg->spicePassword);
         }
     }
 
@@ -2225,6 +2251,7 @@ qemuProcessInitPasswords(virConnectPtr conn,
     }
 
 cleanup:
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -2643,28 +2670,28 @@ qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
 
 
 static int
-qemuProcessLimits(virQEMUDriverPtr driver)
+qemuProcessLimits(virQEMUDriverConfigPtr cfg)
 {
     struct rlimit rlim;
 
-    if (driver->maxProcesses > 0) {
-        rlim.rlim_cur = rlim.rlim_max = driver->maxProcesses;
+    if (cfg->maxProcesses > 0) {
+        rlim.rlim_cur = rlim.rlim_max = cfg->maxProcesses;
         if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
             virReportSystemError(errno,
                                  _("cannot limit number of processes to %d"),
-                                 driver->maxProcesses);
+                                 cfg->maxProcesses);
             return -1;
         }
     }
 
-    if (driver->maxFiles > 0) {
+    if (cfg->maxFiles > 0) {
         /* Max number of opened files is one greater than
          * actual limit. See man setrlimit */
-        rlim.rlim_cur = rlim.rlim_max = driver->maxFiles + 1;
+        rlim.rlim_cur = rlim.rlim_max = cfg->maxFiles + 1;
         if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
             virReportSystemError(errno,
                                  _("cannot set max opened files to %d"),
-                                 driver->maxFiles);
+                                 cfg->maxFiles);
             return -1;
         }
     }
@@ -2685,6 +2712,7 @@ static int qemuProcessHook(void *data)
     struct qemuProcessHookData *h = data;
     int ret = -1;
     int fd;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(h->driver);
 
     /* Some later calls want pid present */
     h->vm->pid = getpid();
@@ -2700,7 +2728,7 @@ static int qemuProcessHook(void *data)
     if (virSecurityManagerSetSocketLabel(h->driver->securityManager, h->vm->def) < 0)
         goto cleanup;
     if (virDomainLockProcessStart(h->driver->lockManager,
-                                  h->driver->uri,
+                                  cfg->uri,
                                   h->vm,
                                   /* QEMU is always paused initially */
                                   true,
@@ -2709,7 +2737,7 @@ static int qemuProcessHook(void *data)
     if (virSecurityManagerClearSocketLabel(h->driver->securityManager, h->vm->def) < 0)
         goto cleanup;
 
-    if (qemuProcessLimits(h->driver) < 0)
+    if (qemuProcessLimits(cfg) < 0)
         goto cleanup;
 
     /* This must take place before exec(), so that all QEMU
@@ -2735,12 +2763,13 @@ static int qemuProcessHook(void *data)
     ret = 0;
 
 cleanup:
+    virObjectUnref(cfg);
     VIR_DEBUG("Hook complete ret=%d", ret);
     return ret;
 }
 
 int
-qemuProcessPrepareMonitorChr(virQEMUDriverPtr driver,
+qemuProcessPrepareMonitorChr(virQEMUDriverConfigPtr cfg,
                              virDomainChrSourceDefPtr monConfig,
                              const char *vm)
 {
@@ -2748,7 +2777,7 @@ qemuProcessPrepareMonitorChr(virQEMUDriverPtr driver,
     monConfig->data.nix.listen = true;
 
     if (virAsprintf(&monConfig->data.nix.path, "%s/%s.monitor",
-                    driver->libDir, vm) < 0) {
+                    cfg->libDir, vm) < 0) {
         virReportOOMError();
         return -1;
     }
@@ -2767,17 +2796,18 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
                      virConnectPtr conn, virDomainRunningReason reason,
                      enum qemuDomainAsyncJob asyncJob)
 {
-    int ret;
+    int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("Using lock state '%s'", NULLSTR(priv->lockState));
-    if (virDomainLockProcessResume(driver->lockManager, driver->uri,
+    if (virDomainLockProcessResume(driver->lockManager, cfg->uri,
                                    vm, priv->lockState) < 0) {
         /* Don't free priv->lockState on error, because we need
          * to make sure we have state still present if the user
          * tries to resume again
          */
-        return -1;
+        goto cleanup;
     }
     VIR_FREE(priv->lockState);
 
@@ -2795,6 +2825,8 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
         VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
     }
 
+cleanup:
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -3152,6 +3184,7 @@ qemuProcessReconnect(void *opaque)
     struct qemuDomainJobObj oldjob;
     int state;
     int reason;
+    virQEMUDriverConfigPtr cfg;
 
     memcpy(&oldjob, &data->oldjob, sizeof(oldjob));
 
@@ -3160,7 +3193,7 @@ qemuProcessReconnect(void *opaque)
     qemuDriverLock(driver);
     virObjectLock(obj);
 
-
+    cfg = virQEMUDriverGetConfig(driver);
     VIR_DEBUG("Reconnect monitor to %p '%s'", obj, obj->def->name);
 
     priv = obj->privateData;
@@ -3242,7 +3275,7 @@ qemuProcessReconnect(void *opaque)
         goto error;
 
     /* update domain state XML with possibly updated state in virDomainObj */
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, obj) < 0)
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, obj) < 0)
         goto error;
 
     /* Run an hook to allow admins to do some magic */
@@ -3276,6 +3309,7 @@ endjob:
     qemuDriverUnlock(driver);
 
     virConnectClose(conn);
+    virObjectUnref(cfg);
 
     return;
 
@@ -3316,6 +3350,7 @@ error:
     qemuDriverUnlock(driver);
 
     virConnectClose(conn);
+    virObjectUnref(cfg);
 }
 
 static void
@@ -3515,6 +3550,7 @@ int qemuProcessStart(virConnectPtr conn,
     char *nodeset = NULL;
     virBitmapPtr nodemask = NULL;
     unsigned int stop_flags;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     /* Okay, these are just internal flags,
      * but doesn't hurt to check */
@@ -3537,6 +3573,7 @@ int qemuProcessStart(virConnectPtr conn,
     if (virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("VM is already active"));
+        virObjectUnref(cfg);
         return -1;
     }
 
@@ -3594,9 +3631,9 @@ int qemuProcessStart(virConnectPtr conn,
     }
     virDomainAuditSecurityLabel(vm, true);
 
-    if (driver->hugepage_path && vm->def->mem.hugepage_backed) {
+    if (cfg->hugepagePath && vm->def->mem.hugepage_backed) {
         if (virSecurityManagerSetHugepages(driver->securityManager,
-                    vm->def, driver->hugepage_path) < 0) {
+                                           vm->def, cfg->hugepagePath) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                     "%s", _("Unable to set huge path in security driver"));
             goto cleanup;
@@ -3632,7 +3669,7 @@ int qemuProcessStart(virConnectPtr conn,
 
                 graphics->data.spice.port = port;
             }
-            if (driver->spiceTLS &&
+            if (cfg->spiceTLS &&
                 (graphics->data.spice.autoport ||
                  graphics->data.spice.tlsPort == -1)) {
                 unsigned short tlsPort;
@@ -3659,9 +3696,9 @@ int qemuProcessStart(virConnectPtr conn,
                 }
                 graphics->listens[0].type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS;
                 if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC)
-                    graphics->listens[0].address = strdup(driver->vncListen);
+                    graphics->listens[0].address = strdup(cfg->vncListen);
                 else
-                    graphics->listens[0].address = strdup(driver->spiceListen);
+                    graphics->listens[0].address = strdup(cfg->spiceListen);
                 if (!graphics->listens[0].address) {
                     VIR_SHRINK_N(graphics->listens, graphics->nListens, 1);
                     virReportOOMError();
@@ -3671,10 +3708,10 @@ int qemuProcessStart(virConnectPtr conn,
         }
     }
 
-    if (virFileMakePath(driver->logDir) < 0) {
+    if (virFileMakePath(cfg->logDir) < 0) {
         virReportSystemError(errno,
                              _("cannot create log directory %s"),
-                             driver->logDir);
+                             cfg->logDir);
         goto cleanup;
     }
 
@@ -3736,7 +3773,7 @@ int qemuProcessStart(virConnectPtr conn,
     }
 
     VIR_DEBUG("Preparing monitor state");
-    if (qemuProcessPrepareMonitorChr(driver, priv->monConfig, vm->def->name) < 0)
+    if (qemuProcessPrepareMonitorChr(cfg, priv->monConfig, vm->def->name) < 0)
         goto cleanup;
 
     if (qemuCapsGet(priv->caps, QEMU_CAPS_MONITOR_JSON))
@@ -3749,7 +3786,7 @@ int qemuProcessStart(virConnectPtr conn,
     priv->gotShutdown = false;
 
     VIR_FREE(priv->pidfile);
-    if (!(priv->pidfile = virPidFileBuildPath(driver->stateDir, vm->def->name))) {
+    if (!(priv->pidfile = virPidFileBuildPath(cfg->stateDir, vm->def->name))) {
         virReportSystemError(errno,
                              "%s", _("Failed to build pidfile path."));
         goto cleanup;
@@ -3821,8 +3858,8 @@ int qemuProcessStart(virConnectPtr conn,
                  virStrerror(errno, ebuf, sizeof(ebuf)));
 
     VIR_DEBUG("Clear emulator capabilities: %d",
-              driver->clearEmulatorCapabilities);
-    if (driver->clearEmulatorCapabilities)
+              cfg->clearEmulatorCapabilities);
+    if (cfg->clearEmulatorCapabilities)
         virCommandClearCaps(cmd);
 
     /* in case a certain disk is desirous of CAP_SYS_RAWIO, add this */
@@ -3887,7 +3924,7 @@ int qemuProcessStart(virConnectPtr conn,
     }
 
     VIR_DEBUG("Writing early domain status to disk");
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0) {
         goto cleanup;
     }
 
@@ -4038,7 +4075,7 @@ int qemuProcessStart(virConnectPtr conn,
         goto cleanup;
 
     VIR_DEBUG("Writing domain status to disk");
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
         goto cleanup;
 
     /* finally we can call the 'started' hook script if any */
@@ -4060,6 +4097,7 @@ int qemuProcessStart(virConnectPtr conn,
 
     virCommandFree(cmd);
     VIR_FORCE_CLOSE(logfile);
+    virObjectUnref(cfg);
 
     return 0;
 
@@ -4072,6 +4110,7 @@ cleanup:
     virCommandFree(cmd);
     VIR_FORCE_CLOSE(logfile);
     qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags);
+    virObjectUnref(cfg);
 
     return -1;
 }
@@ -4133,12 +4172,14 @@ void qemuProcessStop(virQEMUDriverPtr driver,
     int logfile = -1;
     char *timestamp;
     char ebuf[1024];
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("Shutting down VM '%s' pid=%d flags=%x",
               vm->def->name, vm->pid, flags);
 
     if (!virDomainObjIsActive(vm)) {
         VIR_DEBUG("VM '%s' not active", vm->def->name);
+        virObjectUnref(cfg);
         return;
     }
 
@@ -4183,7 +4224,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
 
     virDomainConfVMNWFilterTeardown(vm);
 
-    if (driver->macFilter) {
+    if (cfg->macFilter) {
         def = vm->def;
         for (i = 0 ; i < def->nnets ; i++) {
             virDomainNetDefPtr net = def->nets[i];
@@ -4277,7 +4318,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
                              virDomainNetGetActualDirectDev(net),
                              virDomainNetGetActualDirectMode(net),
                              virDomainNetGetActualVirtPortProfile(net),
-                             driver->stateDir));
+                             cfg->stateDir));
             VIR_FREE(net->ifname);
         }
         /* release the physical device (or any other resources used by
@@ -4354,6 +4395,7 @@ retry:
         virSetError(orig_err);
         virFreeError(orig_err);
     }
+    virObjectUnref(cfg);
 }
 
 
@@ -4376,12 +4418,14 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
     virSecurityLabelDefPtr seclabeldef = NULL;
     virSecurityManagerPtr* sec_managers = NULL;
     const char *model;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("Beginning VM attach process");
 
     if (virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("VM is already active"));
+        virObjectUnref(cfg);
         return -1;
     }
 
@@ -4399,10 +4443,10 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
         driver->inhibitCallback(true, driver->inhibitOpaque);
     driver->nactive++;
 
-    if (virFileMakePath(driver->logDir) < 0) {
+    if (virFileMakePath(cfg->logDir) < 0) {
         virReportSystemError(errno,
                              _("cannot create log directory %s"),
-                             driver->logDir);
+                             cfg->logDir);
         goto cleanup;
     }
 
@@ -4535,7 +4579,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
         virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
 
     VIR_DEBUG("Writing domain status to disk");
-    if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
+    if (virDomainSaveStatus(driver->caps, cfg->stateDir, vm) < 0)
         goto cleanup;
 
     /* Run an hook to allow admins to do some magic */
@@ -4558,6 +4602,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
     VIR_FORCE_CLOSE(logfile);
     VIR_FREE(seclabel);
     VIR_FREE(sec_managers);
+    virObjectUnref(cfg);
 
     return 0;
 
@@ -4571,6 +4616,7 @@ cleanup:
     VIR_FREE(seclabel);
     VIR_FREE(sec_managers);
     virDomainChrSourceDefFree(monConfig);
+    virObjectUnref(cfg);
     return -1;
 }
 
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 313fa39..2dc8041 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -25,7 +25,7 @@
 # include "qemu_conf.h"
 # include "qemu_domain.h"
 
-int qemuProcessPrepareMonitorChr(virQEMUDriverPtr driver,
+int qemuProcessPrepareMonitorChr(virQEMUDriverConfigPtr cfg,
                                  virDomainChrSourceDefPtr monConfig,
                                  const char *vm);
 
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index e465f3d..8062a02 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -116,10 +116,9 @@ mymain(void)
 {
     int ret = 0;
 
+    driver.config = virQEMUDriverConfigNew(false);
     if ((driver.caps = testQemuCapsInit()) == NULL)
         return EXIT_FAILURE;
-    if ((driver.stateDir = strdup("/nowhere")) == NULL)
-        return EXIT_FAILURE;
 
 # define DO_TEST_FULL(name, extraFlags, migrateFrom)                     \
     do {                                                                \
@@ -193,17 +192,8 @@ mymain(void)
     DO_TEST("graphics-vnc");
     DO_TEST("graphics-vnc-socket");
 
-    driver.vncSASL = 1;
-    driver.vncSASLdir = strdup("/root/.sasl2");
     DO_TEST("graphics-vnc-sasl");
-    driver.vncTLS = 1;
-    driver.vncTLSx509verify = 1;
-    driver.vncTLSx509certdir = strdup("/etc/pki/tls/qemu");
     DO_TEST("graphics-vnc-tls");
-    driver.vncSASL = driver.vncTLSx509verify = driver.vncTLS = 0;
-    VIR_FREE(driver.vncSASLdir);
-    VIR_FREE(driver.vncTLSx509certdir);
-    driver.vncSASLdir = driver.vncTLSx509certdir = NULL;
 
     DO_TEST("graphics-sdl");
     DO_TEST("graphics-sdl-fullscreen");
@@ -252,7 +242,7 @@ mymain(void)
 
     DO_TEST_FULL("qemu-ns-no-env", 1, NULL);
 
-    VIR_FREE(driver.stateDir);
+    virObjectUnref(driver.config);
     virCapabilitiesFree(driver.caps);
 
     return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.args
index a3f09e3..dd99025 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.args
@@ -2,4 +2,4 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
 SASL_CONF_DIR=/root/.sasl2 QEMU_AUDIO_DRV=none /usr/bin/qemu -S -M pc -m 214 \
 -smp 1 -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb -hda \
 /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -vnc \
-127.0.0.1:3,tls,x509verify=/etc/pki/tls/qemu,sasl
+127.0.0.1:3,tls,x509verify=/etc/pki/libvirt-vnc,sasl
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 88e1c36..4e90b26 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -278,18 +278,23 @@ mymain(void)
     if (!abs_top_srcdir)
         abs_top_srcdir = "..";
 
+    driver.config = virQEMUDriverConfigNew(false);
+    VIR_FREE(driver.config->spiceListen);
+    VIR_FREE(driver.config->vncListen);
+
     if ((driver.caps = testQemuCapsInit()) == NULL)
         return EXIT_FAILURE;
-    if ((driver.stateDir = strdup("/nowhere")) == NULL)
-        return EXIT_FAILURE;
-    if ((driver.hugetlbfs_mount = strdup("/dev/hugepages")) == NULL)
+    VIR_FREE(driver.config->stateDir);
+    if ((driver.config->stateDir = strdup("/nowhere")) == NULL)
         return EXIT_FAILURE;
-    if ((driver.hugepage_path = strdup("/dev/hugepages/libvirt/qemu")) == NULL)
+    VIR_FREE(driver.config->hugetlbfsMount);
+    if ((driver.config->hugetlbfsMount = strdup("/dev/hugepages")) == NULL)
         return EXIT_FAILURE;
-    driver.spiceTLS = 1;
-    if (!(driver.spiceTLSx509certdir = strdup("/etc/pki/libvirt-spice")))
+    VIR_FREE(driver.config->hugepagePath);
+    if ((driver.config->hugepagePath = strdup("/dev/hugepages/libvirt/qemu")) == NULL)
         return EXIT_FAILURE;
-    if (!(driver.spicePassword = strdup("123456")))
+    driver.config->spiceTLS = 1;
+    if (!(driver.config->spicePassword = strdup("123456")))
         return EXIT_FAILURE;
     if (virAsprintf(&map, "%s/src/cpu/cpu_map.xml", abs_top_srcdir) < 0 ||
         cpuMapOverride(map) < 0) {
@@ -546,17 +551,15 @@ mymain(void)
     DO_TEST("graphics-vnc", QEMU_CAPS_VNC);
     DO_TEST("graphics-vnc-socket", QEMU_CAPS_VNC);
 
-    driver.vncSASL = 1;
-    driver.vncSASLdir = strdup("/root/.sasl2");
+    driver.config->vncSASL = 1;
+    VIR_FREE(driver.config->vncSASLdir);
+    driver.config->vncSASLdir = strdup("/root/.sasl2");
     DO_TEST("graphics-vnc-sasl", QEMU_CAPS_VNC, QEMU_CAPS_VGA);
-    driver.vncTLS = 1;
-    driver.vncTLSx509verify = 1;
-    driver.vncTLSx509certdir = strdup("/etc/pki/tls/qemu");
+    driver.config->vncTLS = 1;
+    driver.config->vncTLSx509verify = 1;
     DO_TEST("graphics-vnc-tls", QEMU_CAPS_VNC);
-    driver.vncSASL = driver.vncTLSx509verify = driver.vncTLS = 0;
-    VIR_FREE(driver.vncSASLdir);
-    VIR_FREE(driver.vncTLSx509certdir);
-    driver.vncSASLdir = driver.vncTLSx509certdir = NULL;
+    driver.config->vncSASL = driver.config->vncTLSx509verify = driver.config->vncTLS = 0;
+    driver.config->vncSASLdir = driver.config->vncTLSx509certdir = NULL;
 
     DO_TEST("graphics-sdl", NONE);
     DO_TEST("graphics-sdl-fullscreen", NONE);
@@ -868,7 +871,7 @@ mymain(void)
             QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
             QEMU_CAPS_DEVICE_QXL, QEMU_CAPS_DEVICE_QXL_VGA);
 
-    VIR_FREE(driver.stateDir);
+    virObjectUnref(driver.config);
     virCapabilitiesFree(driver.caps);
     VIR_FREE(map);
 
diff --git a/tests/qemuxmlnstest.c b/tests/qemuxmlnstest.c
index 93f1f1b..38b5e88 100644
--- a/tests/qemuxmlnstest.c
+++ b/tests/qemuxmlnstest.c
@@ -201,19 +201,9 @@ mymain(void)
     if (!abs_top_srcdir)
         abs_top_srcdir = "..";
 
+    driver.config = virQEMUDriverConfigNew(false);
     if ((driver.caps = testQemuCapsInit()) == NULL)
         return EXIT_FAILURE;
-    if ((driver.stateDir = strdup("/nowhere")) == NULL)
-        return EXIT_FAILURE;
-    if ((driver.hugetlbfs_mount = strdup("/dev/hugepages")) == NULL)
-        return EXIT_FAILURE;
-    if ((driver.hugepage_path = strdup("/dev/hugepages/libvirt/qemu")) == NULL)
-        return EXIT_FAILURE;
-    driver.spiceTLS = 1;
-    if (!(driver.spiceTLSx509certdir = strdup("/etc/pki/libvirt-spice")))
-        return EXIT_FAILURE;
-    if (!(driver.spicePassword = strdup("123456")))
-        return EXIT_FAILURE;
     if (virAsprintf(&map, "%s/src/cpu/cpu_map.xml", abs_top_srcdir) < 0 ||
         cpuMapOverride(map) < 0) {
         VIR_FREE(map);
@@ -260,7 +250,7 @@ mymain(void)
     DO_TEST("qemu-ns-commandline-ns0", false, NONE);
     DO_TEST("qemu-ns-commandline-ns1", false, NONE);
 
-    VIR_FREE(driver.stateDir);
+    virObjectUnref(driver.config);
     virCapabilitiesFree(driver.caps);
     VIR_FREE(map);
 
-- 
1.8.1

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]