[libvirt] [PATCH 07/18] Store a virCgroupPtr instance in qemuDomainObjPrivatePtr

Daniel P. Berrange berrange at redhat.com
Thu Apr 4 13:40:26 UTC 2013


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

Instead of calling virCgroupForDomain every time we need
the virCgrouPtr instance, just do it once at Vm startup
and cache a reference to the object in qemuDomainObjPrivatePtr
until shutdown of the VM. Removing the virCgroupPtr from
the QEMU driver state also means we don't have stale mount
info, if someone mounts the cgroups filesystem after libvirtd
has been started

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/qemu/qemu_cgroup.c    | 283 +++++++++++++++------------------
 src/qemu/qemu_cgroup.h    |  22 +--
 src/qemu/qemu_conf.h      |   4 -
 src/qemu/qemu_domain.c    |   1 +
 src/qemu/qemu_domain.h    |   3 +
 src/qemu/qemu_driver.c    | 397 +++++++++++++++-------------------------------
 src/qemu/qemu_hotplug.c   |  53 +------
 src/qemu/qemu_migration.c |  25 +--
 src/qemu/qemu_process.c   |  13 +-
 9 files changed, 291 insertions(+), 510 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 5aa9416..019aa2e 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -45,26 +45,21 @@ static const char *const defaultDeviceACL[] = {
 #define DEVICE_PTY_MAJOR 136
 #define DEVICE_SND_MAJOR 116
 
-bool qemuCgroupControllerActive(virQEMUDriverPtr driver,
-                                int controller)
-{
-    return virCgroupHasController(driver->cgroup, controller);
-}
-
 static int
 qemuSetupDiskPathAllow(virDomainDiskDefPtr disk,
                        const char *path,
                        size_t depth ATTRIBUTE_UNUSED,
                        void *opaque)
 {
-    qemuCgroupData *data = opaque;
+    virDomainObjPtr vm = opaque;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
     int rc;
 
     VIR_DEBUG("Process path %s for disk", path);
-    rc = virCgroupAllowDevicePath(data->cgroup, path,
+    rc = virCgroupAllowDevicePath(priv->cgroup, path,
                                   (disk->readonly ? VIR_CGROUP_DEVICE_READ
                                    : VIR_CGROUP_DEVICE_RW));
-    virDomainAuditCgroupPath(data->vm, data->cgroup, "allow", path,
+    virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path,
                              disk->readonly ? "r" : "rw", rc);
     if (rc < 0) {
         if (rc == -EACCES) { /* Get this for root squash NFS */
@@ -81,14 +76,18 @@ qemuSetupDiskPathAllow(virDomainDiskDefPtr disk,
 
 
 int qemuSetupDiskCgroup(virDomainObjPtr vm,
-                        virCgroupPtr cgroup,
                         virDomainDiskDefPtr disk)
 {
-    qemuCgroupData data = { vm, cgroup };
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+
+    if (!virCgroupHasController(priv->cgroup,
+                                VIR_CGROUP_CONTROLLER_DEVICES))
+        return 0;
+
     return virDomainDiskDefForeachPath(disk,
                                        true,
                                        qemuSetupDiskPathAllow,
-                                       &data);
+                                       vm);
 }
 
 
@@ -98,13 +97,14 @@ qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
                          size_t depth ATTRIBUTE_UNUSED,
                          void *opaque)
 {
-    qemuCgroupData *data = opaque;
+    virDomainObjPtr vm = opaque;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
     int rc;
 
     VIR_DEBUG("Process path %s for disk", path);
-    rc = virCgroupDenyDevicePath(data->cgroup, path,
+    rc = virCgroupDenyDevicePath(priv->cgroup, path,
                                  VIR_CGROUP_DEVICE_RWM);
-    virDomainAuditCgroupPath(data->vm, data->cgroup, "deny", path, "rwm", rc);
+    virDomainAuditCgroupPath(vm, priv->cgroup, "deny", path, "rwm", rc);
     if (rc < 0) {
         if (rc == -EACCES) { /* Get this for root squash NFS */
             VIR_DEBUG("Ignoring EACCES for %s", path);
@@ -120,14 +120,18 @@ qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
 
 
 int qemuTeardownDiskCgroup(virDomainObjPtr vm,
-                           virCgroupPtr cgroup,
                            virDomainDiskDefPtr disk)
 {
-    qemuCgroupData data = { vm, cgroup };
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+
+    if (!virCgroupHasController(priv->cgroup,
+                                VIR_CGROUP_CONTROLLER_DEVICES))
+        return 0;
+
     return virDomainDiskDefForeachPath(disk,
                                        true,
                                        qemuTeardownDiskPathDeny,
-                                       &data);
+                                       vm);
 }
 
 
@@ -136,7 +140,8 @@ qemuSetupChardevCgroup(virDomainDefPtr def,
                        virDomainChrDefPtr dev,
                        void *opaque)
 {
-    qemuCgroupData *data = opaque;
+    virDomainObjPtr vm = opaque;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
     int rc;
 
     if (dev->source.type != VIR_DOMAIN_CHR_TYPE_DEV)
@@ -144,9 +149,9 @@ qemuSetupChardevCgroup(virDomainDefPtr def,
 
 
     VIR_DEBUG("Process path '%s' for disk", dev->source.data.file.path);
-    rc = virCgroupAllowDevicePath(data->cgroup, dev->source.data.file.path,
+    rc = virCgroupAllowDevicePath(priv->cgroup, dev->source.data.file.path,
                                   VIR_CGROUP_DEVICE_RW);
-    virDomainAuditCgroupPath(data->vm, data->cgroup, "allow",
+    virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
                              dev->source.data.file.path, "rw", rc);
     if (rc < 0) {
         virReportSystemError(-rc,
@@ -163,13 +168,14 @@ int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev ATTRIBUTE_UNUSED,
                                  const char *path,
                                  void *opaque)
 {
-    qemuCgroupData *data = opaque;
+    virDomainObjPtr vm = opaque;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
     int rc;
 
     VIR_DEBUG("Process path '%s' for USB device", path);
-    rc = virCgroupAllowDevicePath(data->cgroup, path,
+    rc = virCgroupAllowDevicePath(priv->cgroup, path,
                                   VIR_CGROUP_DEVICE_RW);
-    virDomainAuditCgroupPath(data->vm, data->cgroup, "allow", path, "rw", rc);
+    virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path, "rw", rc);
     if (rc < 0) {
         virReportSystemError(-rc,
                              _("Unable to allow device %s"),
@@ -180,34 +186,73 @@ int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev ATTRIBUTE_UNUSED,
     return 0;
 }
 
+
+int qemuInitCgroup(virQEMUDriverPtr driver,
+                   virDomainObjPtr vm)
+{
+    int rc;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virCgroupPtr driverGroup = NULL;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
+    virCgroupFree(&priv->cgroup);
+
+    rc = virCgroupForDriver("qemu", &driverGroup,
+                            cfg->privileged, true,
+                            cfg->cgroupControllers);
+    if (rc != 0) {
+        if (rc == -ENXIO ||
+            rc == -EPERM ||
+            rc == -EACCES) { /* No cgroups mounts == success */
+            VIR_DEBUG("No cgroups present/configured/accessible, ignoring error");
+            goto done;
+        }
+
+        virReportSystemError(-rc,
+                             _("Unable to create cgroup for %s"),
+                             vm->def->name);
+        goto cleanup;
+    }
+
+    rc = virCgroupForDomain(driverGroup, vm->def->name, &priv->cgroup, 1);
+    if (rc != 0) {
+        virReportSystemError(-rc,
+                             _("Unable to create cgroup for %s"),
+                             vm->def->name);
+        goto cleanup;
+    }
+
+done:
+    rc = 0;
+cleanup:
+    virCgroupFree(&driverGroup);
+    virObjectUnref(cfg);
+    return rc;
+}
+
+
 int qemuSetupCgroup(virQEMUDriverPtr driver,
                     virDomainObjPtr vm,
                     virBitmapPtr nodemask)
 {
-    virCgroupPtr cgroup = NULL;
-    int rc;
+    int rc = -1;
     unsigned int i;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    qemuDomainObjPrivatePtr priv = vm->privateData;
     const char *const *deviceACL =
         cfg->cgroupDeviceACL ?
         (const char *const *)cfg->cgroupDeviceACL :
         defaultDeviceACL;
 
-    if (driver->cgroup == NULL)
-        goto done; /* Not supported, so claim success */
+    if (qemuInitCgroup(driver, vm) < 0)
+        return -1;
 
-    rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 1);
-    if (rc != 0) {
-        virReportSystemError(-rc,
-                             _("Unable to create cgroup for %s"),
-                             vm->def->name);
-        goto cleanup;
-    }
+    if (!priv->cgroup)
+        goto done;
 
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
-        qemuCgroupData data = { vm, cgroup };
-        rc = virCgroupDenyAllDevices(cgroup);
-        virDomainAuditCgroup(vm, cgroup, "deny", "all", rc == 0);
+    if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) {
+        rc = virCgroupDenyAllDevices(priv->cgroup);
+        virDomainAuditCgroup(vm, priv->cgroup, "deny", "all", rc == 0);
         if (rc != 0) {
             if (rc == -EPERM) {
                 VIR_WARN("Group devices ACL is not accessible, disabling whitelisting");
@@ -220,13 +265,13 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
         }
 
         for (i = 0; i < vm->def->ndisks ; i++) {
-            if (qemuSetupDiskCgroup(vm, cgroup, vm->def->disks[i]) < 0)
+            if (qemuSetupDiskCgroup(vm,vm->def->disks[i]) < 0)
                 goto cleanup;
         }
 
-        rc = virCgroupAllowDeviceMajor(cgroup, 'c', DEVICE_PTY_MAJOR,
+        rc = virCgroupAllowDeviceMajor(priv->cgroup, 'c', DEVICE_PTY_MAJOR,
                                        VIR_CGROUP_DEVICE_RW);
-        virDomainAuditCgroupMajor(vm, cgroup, "allow", DEVICE_PTY_MAJOR,
+        virDomainAuditCgroupMajor(vm, priv->cgroup, "allow", DEVICE_PTY_MAJOR,
                                   "pty", "rw", rc == 0);
         if (rc != 0) {
             virReportSystemError(-rc, "%s",
@@ -239,9 +284,9 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
              ((vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
                cfg->vncAllowHostAudio) ||
               (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL)))) {
-            rc = virCgroupAllowDeviceMajor(cgroup, 'c', DEVICE_SND_MAJOR,
+            rc = virCgroupAllowDeviceMajor(priv->cgroup, 'c', DEVICE_SND_MAJOR,
                                            VIR_CGROUP_DEVICE_RW);
-            virDomainAuditCgroupMajor(vm, cgroup, "allow", DEVICE_SND_MAJOR,
+            virDomainAuditCgroupMajor(vm, priv->cgroup, "allow", DEVICE_SND_MAJOR,
                                       "sound", "rw", rc == 0);
             if (rc != 0) {
                 virReportSystemError(-rc, "%s",
@@ -257,9 +302,9 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
                 continue;
             }
 
-            rc = virCgroupAllowDevicePath(cgroup, deviceACL[i],
+            rc = virCgroupAllowDevicePath(priv->cgroup, deviceACL[i],
                                           VIR_CGROUP_DEVICE_RW);
-            virDomainAuditCgroupPath(vm, cgroup, "allow", deviceACL[i], "rw", rc);
+            virDomainAuditCgroupPath(vm, priv->cgroup, "allow", deviceACL[i], "rw", rc);
             if (rc < 0 &&
                 rc != -ENOENT) {
                 virReportSystemError(-rc,
@@ -272,7 +317,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
         if (virDomainChrDefForeach(vm->def,
                                    true,
                                    qemuSetupChardevCgroup,
-                                   &data) < 0)
+                                   vm) < 0)
             goto cleanup;
 
         for (i = 0; i < vm->def->nhostdevs; i++) {
@@ -292,7 +337,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
                 goto cleanup;
 
             if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup,
-                                        &data) < 0) {
+                                        vm) < 0) {
                 virUSBDeviceFree(usb);
                 goto cleanup;
             }
@@ -301,8 +346,8 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
     }
 
     if (vm->def->blkio.weight != 0) {
-        if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) {
-            rc = virCgroupSetBlkioWeight(cgroup, vm->def->blkio.weight);
+        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_BLKIO)) {
+            rc = virCgroupSetBlkioWeight(priv->cgroup, vm->def->blkio.weight);
             if (rc != 0) {
                 virReportSystemError(-rc,
                                      _("Unable to set io weight for domain %s"),
@@ -317,12 +362,12 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
     }
 
     if (vm->def->blkio.ndevices) {
-        if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) {
+        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_BLKIO)) {
             for (i = 0; i < vm->def->blkio.ndevices; i++) {
                 virBlkioDeviceWeightPtr dw = &vm->def->blkio.devices[i];
                 if (!dw->weight)
                     continue;
-                rc = virCgroupSetBlkioDeviceWeight(cgroup, dw->path,
+                rc = virCgroupSetBlkioDeviceWeight(priv->cgroup, dw->path,
                                                    dw->weight);
                 if (rc != 0) {
                     virReportSystemError(-rc,
@@ -339,7 +384,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
         }
     }
 
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
+    if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_MEMORY)) {
         unsigned long long hard_limit = vm->def->mem.hard_limit;
 
         if (!hard_limit) {
@@ -357,7 +402,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
             hard_limit += vm->def->ndisks * 32768;
         }
 
-        rc = virCgroupSetMemoryHardLimit(cgroup, hard_limit);
+        rc = virCgroupSetMemoryHardLimit(priv->cgroup, hard_limit);
         if (rc != 0) {
             virReportSystemError(-rc,
                                  _("Unable to set memory hard limit for domain %s"),
@@ -365,7 +410,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
             goto cleanup;
         }
         if (vm->def->mem.soft_limit != 0) {
-            rc = virCgroupSetMemorySoftLimit(cgroup, vm->def->mem.soft_limit);
+            rc = virCgroupSetMemorySoftLimit(priv->cgroup, vm->def->mem.soft_limit);
             if (rc != 0) {
                 virReportSystemError(-rc,
                                      _("Unable to set memory soft limit for domain %s"),
@@ -375,7 +420,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
         }
 
         if (vm->def->mem.swap_hard_limit != 0) {
-            rc = virCgroupSetMemSwapHardLimit(cgroup, vm->def->mem.swap_hard_limit);
+            rc = virCgroupSetMemSwapHardLimit(priv->cgroup, vm->def->mem.swap_hard_limit);
             if (rc != 0) {
                 virReportSystemError(-rc,
                                      _("Unable to set swap hard limit for domain %s"),
@@ -393,8 +438,8 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
     }
 
     if (vm->def->cputune.shares != 0) {
-        if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
-            rc = virCgroupSetCpuShares(cgroup, vm->def->cputune.shares);
+        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
+            rc = virCgroupSetCpuShares(priv->cgroup, vm->def->cputune.shares);
             if (rc != 0) {
                 virReportSystemError(-rc,
                                      _("Unable to set io cpu shares for domain %s"),
@@ -411,7 +456,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
          (vm->def->numatune.memory.placement_mode ==
           VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) &&
         vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
-        qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
+        virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
         char *mask = NULL;
         if (vm->def->numatune.memory.placement_mode ==
             VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)
@@ -424,7 +469,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
             goto cleanup;
         }
 
-        rc = virCgroupSetCpusetMems(cgroup, mask);
+        rc = virCgroupSetCpusetMems(priv->cgroup, mask);
         VIR_FREE(mask);
         if (rc != 0) {
             virReportSystemError(-rc,
@@ -433,18 +478,12 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
             goto cleanup;
         }
     }
-done:
-    virObjectUnref(cfg);
-    virCgroupFree(&cgroup);
-    return 0;
 
+done:
+    rc = 0;
 cleanup:
     virObjectUnref(cfg);
-    if (cgroup) {
-        virCgroupRemove(cgroup);
-        virCgroupFree(&cgroup);
-    }
-    return -1;
+    return rc == 0 ? 0 : -1;
 }
 
 int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup, unsigned long long period,
@@ -538,9 +577,8 @@ cleanup:
     return rc;
 }
 
-int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
+int qemuSetupCgroupForVcpu(virDomainObjPtr vm)
 {
-    virCgroupPtr cgroup = NULL;
     virCgroupPtr cgroup_vcpu = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainDefPtr def = vm->def;
@@ -550,8 +588,7 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
     long long quota = vm->def->cputune.quota;
 
     if ((period || quota) &&
-        (!driver->cgroup ||
-         !qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU))) {
+        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("cgroup cpu is required for scheduler tuning"));
         return -1;
@@ -561,28 +598,19 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
      * with virProcessInfoSetAffinity, thus the lack of cgroups is not fatal
      * here.
      */
-    if (driver->cgroup == NULL)
+    if (priv->cgroup == NULL)
         return 0;
 
-    rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0);
-    if (rc != 0) {
-        virReportSystemError(-rc,
-                             _("Unable to find cgroup for %s"),
-                             vm->def->name);
-        goto cleanup;
-    }
-
     if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
         /* If we don't know VCPU<->PID mapping or all vcpu runs in the same
          * thread, we cannot control each vcpu.
          */
         VIR_WARN("Unable to get vcpus' pids.");
-        virCgroupFree(&cgroup);
         return 0;
     }
 
     for (i = 0; i < priv->nvcpupids; i++) {
-        rc = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 1);
+        rc = virCgroupForVcpu(priv->cgroup, i, &cgroup_vcpu, 1);
         if (rc < 0) {
             virReportSystemError(-rc,
                                  _("Unable to create vcpu cgroup for %s(vcpu:"
@@ -606,7 +634,7 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
         }
 
         /* Set vcpupin in cgroup if vcpupin xml is provided */
-        if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
+        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
             /* find the right CPU to pin, otherwise
              * qemuSetupCgroupVcpuPin will fail. */
             for (j = 0; j < def->cputune.nvcpupin; j++) {
@@ -626,7 +654,6 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
         virCgroupFree(&cgroup_vcpu);
     }
 
-    virCgroupFree(&cgroup);
     return 0;
 
 cleanup:
@@ -635,11 +662,6 @@ cleanup:
         virCgroupFree(&cgroup_vcpu);
     }
 
-    if (cgroup) {
-        virCgroupRemove(cgroup);
-        virCgroupFree(&cgroup);
-    }
-
     return -1;
 }
 
@@ -649,33 +671,24 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
 {
     virBitmapPtr cpumask = NULL;
     virBitmapPtr cpumap = NULL;
-    virCgroupPtr cgroup = NULL;
     virCgroupPtr cgroup_emulator = NULL;
     virDomainDefPtr def = vm->def;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
     unsigned long long period = vm->def->cputune.emulator_period;
     long long quota = vm->def->cputune.emulator_quota;
     int rc;
 
     if ((period || quota) &&
-        (!driver->cgroup ||
-         !qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU))) {
+        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("cgroup cpu is required for scheduler tuning"));
         return -1;
     }
 
-    if (driver->cgroup == NULL)
+    if (priv->cgroup == NULL)
         return 0; /* Not supported, so claim success */
 
-    rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0);
-    if (rc != 0) {
-        virReportSystemError(-rc,
-                             _("Unable to find cgroup for %s"),
-                             vm->def->name);
-        goto cleanup;
-    }
-
-    rc = virCgroupForEmulator(cgroup, &cgroup_emulator, 1);
+    rc = virCgroupForEmulator(priv->cgroup, &cgroup_emulator, 1);
     if (rc < 0) {
         virReportSystemError(-rc,
                              _("Unable to create emulator cgroup for %s"),
@@ -683,7 +696,7 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
-    rc = virCgroupMoveTask(cgroup, cgroup_emulator);
+    rc = virCgroupMoveTask(priv->cgroup, cgroup_emulator);
     if (rc < 0) {
         virReportSystemError(-rc,
                              _("Unable to move tasks from domain cgroup to "
@@ -703,7 +716,7 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
     }
 
     if (cpumask) {
-        if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
+        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
             rc = qemuSetupCgroupEmulatorPin(cgroup_emulator, cpumask);
             if (rc < 0)
                 goto cleanup;
@@ -712,7 +725,7 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
     }
 
     if (period || quota) {
-        if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
+        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
             if ((rc = qemuSetupCgroupVcpuBW(cgroup_emulator, period,
                                             quota)) < 0)
                 goto cleanup;
@@ -720,7 +733,6 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
     }
 
     virCgroupFree(&cgroup_emulator);
-    virCgroupFree(&cgroup);
     virBitmapFree(cpumap);
     return 0;
 
@@ -732,67 +744,34 @@ cleanup:
         virCgroupFree(&cgroup_emulator);
     }
 
-    if (cgroup) {
-        virCgroupRemove(cgroup);
-        virCgroupFree(&cgroup);
-    }
-
     return rc;
 }
 
-int qemuRemoveCgroup(virQEMUDriverPtr driver,
-                     virDomainObjPtr vm,
-                     int quiet)
+int qemuRemoveCgroup(virDomainObjPtr vm)
 {
-    virCgroupPtr cgroup;
-    int rc;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
 
-    if (driver->cgroup == NULL)
+    if (priv->cgroup == NULL)
         return 0; /* Not supported, so claim success */
 
-    rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0);
-    if (rc != 0) {
-        if (!quiet)
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Unable to find cgroup for %s"),
-                           vm->def->name);
-        return rc;
-    }
-
-    rc = virCgroupRemove(cgroup);
-    virCgroupFree(&cgroup);
-    return rc;
+    return virCgroupRemove(priv->cgroup);
 }
 
-int qemuAddToCgroup(virQEMUDriverPtr driver,
-                    virDomainDefPtr def)
+int qemuAddToCgroup(virDomainObjPtr vm)
 {
-    virCgroupPtr cgroup = NULL;
-    int ret = -1;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
     int rc;
 
-    if (driver->cgroup == NULL)
+    if (priv->cgroup == NULL)
         return 0; /* Not supported, so claim success */
 
-    rc = virCgroupForDomain(driver->cgroup, def->name, &cgroup, 0);
-    if (rc != 0) {
-        virReportSystemError(-rc,
-                             _("unable to find cgroup for domain %s"),
-                             def->name);
-        goto cleanup;
-    }
-
-    rc = virCgroupAddTask(cgroup, getpid());
+    rc = virCgroupAddTask(priv->cgroup, getpid());
     if (rc != 0) {
         virReportSystemError(-rc,
                              _("unable to add domain %s task %d to cgroup"),
-                             def->name, getpid());
-        goto cleanup;
+                             vm->def->name, getpid());
+        return -1;
     }
 
-    ret = 0;
-
-cleanup:
-    virCgroupFree(&cgroup);
-    return ret;
+    return 0;
 }
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
index a677d07..6cbfebc 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -25,26 +25,19 @@
 # define __QEMU_CGROUP_H__
 
 # include "virusb.h"
+# include "vircgroup.h"
 # include "domain_conf.h"
 # include "qemu_conf.h"
 
-struct _qemuCgroupData {
-    virDomainObjPtr vm;
-    virCgroupPtr cgroup;
-};
-typedef struct _qemuCgroupData qemuCgroupData;
-
-bool qemuCgroupControllerActive(virQEMUDriverPtr driver,
-                                int controller);
 int qemuSetupDiskCgroup(virDomainObjPtr vm,
-                        virCgroupPtr cgroup,
                         virDomainDiskDefPtr disk);
 int qemuTeardownDiskCgroup(virDomainObjPtr vm,
-                           virCgroupPtr cgroup,
                            virDomainDiskDefPtr disk);
 int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev,
                                  const char *path,
                                  void *opaque);
+int qemuInitCgroup(virQEMUDriverPtr driver,
+                   virDomainObjPtr vm);
 int qemuSetupCgroup(virQEMUDriverPtr driver,
                     virDomainObjPtr vm,
                     virBitmapPtr nodemask);
@@ -56,14 +49,11 @@ int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup,
                            int nvcpupin,
                            int vcpuid);
 int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, virBitmapPtr cpumask);
-int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm);
+int qemuSetupCgroupForVcpu(virDomainObjPtr vm);
 int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
                                virBitmapPtr nodemask);
-int qemuRemoveCgroup(virQEMUDriverPtr driver,
-                     virDomainObjPtr vm,
-                     int quiet);
-int qemuAddToCgroup(virQEMUDriverPtr driver,
-                    virDomainDefPtr def);
+int qemuRemoveCgroup(virDomainObjPtr vm);
+int qemuAddToCgroup(virDomainObjPtr vm);
 
 #endif /* __QEMU_CGROUP_H__ */
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index c5ddaad..21ddd38 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -34,7 +34,6 @@
 # include "domain_event.h"
 # include "virthread.h"
 # include "security/security_manager.h"
-# include "vircgroup.h"
 # include "virpci.h"
 # include "virusb.h"
 # include "cpu_conf.h"
@@ -164,9 +163,6 @@ struct _virQEMUDriver {
     /* Atomic increment only */
     int nextvmid;
 
-    /* Immutable pointer. Immutable object */
-    virCgroupPtr cgroup;
-
     /* Atomic inc/dec only */
     unsigned int nactive;
 
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c79b05d..6e2966f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -235,6 +235,7 @@ qemuDomainObjPrivateFree(void *data)
 
     virObjectUnref(priv->qemuCaps);
 
+    virCgroupFree(&priv->cgroup);
     qemuDomainPCIAddressSetFree(priv->pciaddrs);
     qemuDomainCCWAddressSetFree(priv->ccwaddrs);
     virDomainChrSourceDefFree(priv->monConfig);
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 26d5859..e68f2e0 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -25,6 +25,7 @@
 # define __QEMU_DOMAIN_H__
 
 # include "virthread.h"
+# include "vircgroup.h"
 # include "domain_conf.h"
 # include "snapshot_conf.h"
 # include "qemu_monitor.h"
@@ -165,6 +166,8 @@ struct _qemuDomainObjPrivate {
     qemuDomainCleanupCallback *cleanupCallbacks;
     size_t ncleanupCallbacks;
     size_t ncleanupCallbacks_max;
+
+    virCgroupPtr cgroup;
 };
 
 struct qemuDomainWatchdogEvent
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2809a77..ab6b74d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -551,7 +551,6 @@ qemuStartup(bool privileged,
             void *opaque)
 {
     char *driverConf = NULL;
-    int rc;
     virConnectPtr conn = NULL;
     char ebuf[1024];
     char *membase = NULL;
@@ -628,13 +627,6 @@ qemuStartup(bool privileged,
         goto error;
     }
 
-    rc = virCgroupForDriver("qemu", &qemu_driver->cgroup, privileged, 1,
-                            cfg->cgroupControllers);
-    if (rc < 0) {
-        VIR_INFO("Unable to create cgroup for driver: %s",
-                 virStrerror(-rc, ebuf, sizeof(ebuf)));
-    }
-
     qemu_driver->qemuImgBinary = virFindFileInPath("kvm-img");
     if (!qemu_driver->qemuImgBinary)
         qemu_driver->qemuImgBinary = virFindFileInPath("qemu-img");
@@ -977,8 +969,6 @@ qemuShutdown(void) {
     /* Free domain callback list */
     virDomainEventStateFree(qemu_driver->domainEventState);
 
-    virCgroupFree(&qemu_driver->cgroup);
-
     virLockManagerPluginUnref(qemu_driver->lockManager);
 
     virMutexDestroy(&qemu_driver->lock);
@@ -3542,9 +3532,7 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
     int vcpus = oldvcpus;
     pid_t *cpupids = NULL;
     int ncpupids;
-    virCgroupPtr cgroup = NULL;
     virCgroupPtr cgroup_vcpu = NULL;
-    bool cgroup_available = false;
 
     qemuDomainObjEnterMonitor(driver, vm);
 
@@ -3607,15 +3595,12 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
-    cgroup_available = (virCgroupForDomain(driver->cgroup, vm->def->name,
-                                           &cgroup, 0) == 0);
-
     if (nvcpus > oldvcpus) {
         for (i = oldvcpus; i < nvcpus; i++) {
-            if (cgroup_available) {
+            if (priv->cgroup) {
                 int rv = -1;
                 /* Create cgroup for the onlined vcpu */
-                rv = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 1);
+                rv = virCgroupForVcpu(priv->cgroup, i, &cgroup_vcpu, 1);
                 if (rv < 0) {
                     virReportSystemError(-rv,
                                          _("Unable to create vcpu cgroup for %s(vcpu:"
@@ -3658,7 +3643,7 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
                 vcpupin->vcpuid = i;
                 vm->def->cputune.vcpupin[vm->def->cputune.nvcpupin++] = vcpupin;
 
-                if (cgroup_available) {
+                if (cgroup_vcpu) {
                     if (qemuSetupCgroupVcpuPin(cgroup_vcpu,
                                                vm->def->cputune.vcpupin,
                                                vm->def->cputune.nvcpupin, i) < 0) {
@@ -3686,10 +3671,10 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
         for (i = oldvcpus - 1; i >= nvcpus; i--) {
             virDomainVcpuPinDefPtr vcpupin = NULL;
 
-            if (cgroup_available) {
+            if (priv->cgroup) {
                 int rv = -1;
 
-                rv = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 0);
+                rv = virCgroupForVcpu(priv->cgroup, i, &cgroup_vcpu, 0);
                 if (rv < 0) {
                     virReportSystemError(-rv,
                                          _("Unable to access vcpu cgroup for %s(vcpu:"
@@ -3720,8 +3705,6 @@ cleanup:
     vm->def->vcpus = vcpus;
     VIR_FREE(cpupids);
     virDomainAuditVcpu(vm, oldvcpus, nvcpus, "update", rc == 1);
-    if (cgroup)
-        virCgroupFree(&cgroup);
     if (cgroup_vcpu)
         virCgroupFree(&cgroup_vcpu);
     return ret;
@@ -3854,7 +3837,6 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     virDomainDefPtr persistentDef = NULL;
-    virCgroupPtr cgroup_dom = NULL;
     virCgroupPtr cgroup_vcpu = NULL;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
@@ -3930,9 +3912,8 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
         }
 
         /* Configure the corresponding cpuset cgroup before set affinity. */
-        if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
-            if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup_dom, 0) == 0 &&
-                virCgroupForVcpu(cgroup_dom, vcpu, &cgroup_vcpu, 0) == 0 &&
+        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
+            if (virCgroupForVcpu(priv->cgroup, vcpu, &cgroup_vcpu, 0) == 0 &&
                 qemuSetupCgroupVcpuPin(cgroup_vcpu, newVcpuPin, newVcpuPinNum, vcpu) < 0) {
                 virReportError(VIR_ERR_OPERATION_INVALID,
                                _("failed to set cpuset.cpus in cgroup"
@@ -4009,8 +3990,6 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
 cleanup:
     if (cgroup_vcpu)
         virCgroupFree(&cgroup_vcpu);
-    if (cgroup_dom)
-        virCgroupFree(&cgroup_dom);
     if (vm)
         virObjectUnlock(vm);
     virBitmapFree(pcpumap);
@@ -4121,7 +4100,6 @@ qemuDomainPinEmulator(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    virCgroupPtr cgroup_dom = NULL;
     virCgroupPtr cgroup_emulator = NULL;
     pid_t pid;
     virDomainDefPtr persistentDef = NULL;
@@ -4185,22 +4163,19 @@ qemuDomainPinEmulator(virDomainPtr dom,
                 goto cleanup;
             }
 
-            if (qemuCgroupControllerActive(driver,
-                                           VIR_CGROUP_CONTROLLER_CPUSET)) {
+            if (virCgroupHasController(priv->cgroup,
+                                       VIR_CGROUP_CONTROLLER_CPUSET)) {
                 /*
                  * Configure the corresponding cpuset cgroup.
                  * If no cgroup for domain or hypervisor exists, do nothing.
                  */
-                if (virCgroupForDomain(driver->cgroup, vm->def->name,
-                                       &cgroup_dom, 0) == 0) {
-                    if (virCgroupForEmulator(cgroup_dom, &cgroup_emulator, 0) == 0) {
-                        if (qemuSetupCgroupEmulatorPin(cgroup_emulator,
-                                                       newVcpuPin[0]->cpumask) < 0) {
-                            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-                                           _("failed to set cpuset.cpus in cgroup"
-                                             " for emulator threads"));
-                            goto cleanup;
-                        }
+                if (virCgroupForEmulator(priv->cgroup, &cgroup_emulator, 0) == 0) {
+                    if (qemuSetupCgroupEmulatorPin(cgroup_emulator,
+                                                   newVcpuPin[0]->cpumask) < 0) {
+                        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                                       _("failed to set cpuset.cpus in cgroup"
+                                         " for emulator threads"));
+                        goto cleanup;
                     }
                 }
             } else {
@@ -4264,8 +4239,6 @@ qemuDomainPinEmulator(virDomainPtr dom,
 cleanup:
     if (cgroup_emulator)
         virCgroupFree(&cgroup_emulator);
-    if (cgroup_dom)
-        virCgroupFree(&cgroup_dom);
     virBitmapFree(pcpumap);
     virObjectUnref(caps);
     if (vm)
@@ -5758,16 +5731,8 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
     if (qemuDomainDetermineDiskChain(driver, disk, false) < 0)
         goto end;
 
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0)) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Unable to find cgroup for %s"),
-                           vm->def->name);
-            goto end;
-        }
-        if (qemuSetupDiskCgroup(vm, cgroup, disk) < 0)
-            goto end;
-    }
+    if (qemuSetupDiskCgroup(vm, disk) < 0)
+        goto end;
 
     switch (disk->device)  {
     case VIR_DOMAIN_DISK_DEVICE_CDROM:
@@ -5833,7 +5798,7 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
     }
 
     if (ret != 0 && cgroup) {
-        if (qemuTeardownDiskCgroup(vm, cgroup, disk) < 0)
+        if (qemuTeardownDiskCgroup(vm, disk) < 0)
             VIR_WARN("Failed to teardown cgroup for disk path %s",
                      NULLSTR(disk->src));
     }
@@ -5841,8 +5806,6 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
 end:
     if (ret != 0)
         ignore_value(qemuRemoveSharedDisk(driver, disk, vm->def->name));
-    if (cgroup)
-        virCgroupFree(&cgroup);
     virObjectUnref(caps);
     virDomainDeviceDefFree(dev_copy);
     return ret;
@@ -6025,7 +5988,6 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm,
     virDomainDiskDefPtr disk = dev->data.disk;
     virDomainDiskDefPtr orig_disk = NULL;
     virDomainDiskDefPtr tmp = NULL;
-    virCgroupPtr cgroup = NULL;
     virDomainDeviceDefPtr dev_copy = NULL;
     virCapsPtr caps = NULL;
     int ret = -1;
@@ -6033,17 +5995,8 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm,
     if (qemuDomainDetermineDiskChain(driver, disk, false) < 0)
         goto end;
 
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
-        if (virCgroupForDomain(driver->cgroup,
-                               vm->def->name, &cgroup, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Unable to find cgroup for %s"),
-                           vm->def->name);
-            goto end;
-        }
-        if (qemuSetupDiskCgroup(vm, cgroup, disk) < 0)
-            goto end;
-    }
+    if (qemuSetupDiskCgroup(vm, disk) < 0)
+        goto end;
 
     switch (disk->device) {
     case VIR_DOMAIN_DISK_DEVICE_CDROM:
@@ -6094,14 +6047,12 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm,
         break;
     }
 
-    if (ret != 0 && cgroup) {
-        if (qemuTeardownDiskCgroup(vm, cgroup, disk) < 0)
-             VIR_WARN("Failed to teardown cgroup for disk path %s",
-                      NULLSTR(disk->src));
-    }
+    if (ret != 0 &&
+        qemuTeardownDiskCgroup(vm, disk) < 0)
+        VIR_WARN("Failed to teardown cgroup for disk path %s",
+                 NULLSTR(disk->src));
+
 end:
-    if (cgroup)
-        virCgroupFree(&cgroup);
     virObjectUnref(caps);
     virDomainDeviceDefFree(dev_copy);
     return ret;
@@ -6735,15 +6686,25 @@ static char *qemuGetSchedulerType(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     char *ret = NULL;
     int rc;
+    virDomainObjPtr vm = NULL;
+    qemuDomainObjPrivatePtr priv;
+
+    vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
+    if (vm == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("No such domain %s"), dom->uuid);
+        goto cleanup;
+    }
+    priv = vm->privateData;
 
-    if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
+    if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("cgroup CPU controller is not mounted"));
         goto cleanup;
     }
 
     if (nparams) {
-        rc = qemuGetCpuBWStatus(driver->cgroup);
+        rc = qemuGetCpuBWStatus(priv->cgroup);
         if (rc < 0)
             goto cleanup;
         else if (rc == 0)
@@ -6757,6 +6718,8 @@ static char *qemuGetSchedulerType(virDomainPtr dom,
         virReportOOMError();
 
 cleanup:
+    if (vm)
+        virObjectUnlock(vm);
     return ret;
 }
 
@@ -6896,12 +6859,12 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
     int ret = -1;
     virQEMUDriverConfigPtr cfg = NULL;
     virCapsPtr caps = NULL;
+    qemuDomainObjPrivatePtr priv;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -6919,6 +6882,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
                        _("No such domain %s"), dom->uuid);
         goto cleanup;
     }
+    priv = vm->privateData;
     cfg = virQEMUDriverGetConfig(driver);
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
         goto cleanup;
@@ -6928,18 +6892,11 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
         goto cleanup;
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) {
+        if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_BLKIO)) {
             virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                            _("blkio cgroup isn't mounted"));
             goto cleanup;
         }
-
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("cannot find cgroup for domain %s"),
-                           vm->def->name);
-            goto cleanup;
-        }
     }
 
     ret = 0;
@@ -6956,7 +6913,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
                     continue;
                 }
 
-                rc = virCgroupSetBlkioWeight(group, params[i].value.ui);
+                rc = virCgroupSetBlkioWeight(priv->cgroup, params[i].value.ui);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set blkio weight tunable"));
@@ -6974,7 +6931,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
                     continue;
                 }
                 for (j = 0; j < ndevices; j++) {
-                    rc = virCgroupSetBlkioDeviceWeight(group,
+                    rc = virCgroupSetBlkioDeviceWeight(priv->cgroup,
                                                        devices[j].path,
                                                        devices[j].weight);
                     if (rc < 0) {
@@ -7037,7 +6994,6 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
     }
 
 cleanup:
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(caps);
@@ -7053,13 +7009,13 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i, j;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
     unsigned int val;
     int ret = -1;
     int rc;
     virCapsPtr caps = NULL;
+    qemuDomainObjPrivatePtr priv;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -7077,6 +7033,7 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
                        _("No such domain %s"), dom->uuid);
         goto cleanup;
     }
+    priv = vm->privateData;
 
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
         goto cleanup;
@@ -7093,17 +7050,11 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
         goto cleanup;
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) {
+        if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_BLKIO)) {
             virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                            _("blkio cgroup isn't mounted"));
             goto cleanup;
         }
-
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("cannot find cgroup for domain %s"), vm->def->name);
-            goto cleanup;
-        }
     }
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
@@ -7113,7 +7064,7 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
 
             switch (i) {
             case 0: /* fill blkio weight here */
-                rc = virCgroupGetBlkioWeight(group, &val);
+                rc = virCgroupGetBlkioWeight(priv->cgroup, &val);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to get blkio weight"));
@@ -7226,8 +7177,6 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
     ret = 0;
 
 cleanup:
-    if (group)
-        virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(caps);
@@ -7242,7 +7191,6 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainDefPtr persistentDef = NULL;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     unsigned long long swap_hard_limit;
     unsigned long long memory_hard_limit;
@@ -7254,6 +7202,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
     int ret = -1;
     int rc;
     virCapsPtr caps = NULL;
+    qemuDomainObjPrivatePtr priv;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -7272,6 +7221,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
     if (!(vm = qemuDomObjFromDomain(dom)))
         return -1;
 
+    priv = vm->privateData;
     cfg = virQEMUDriverGetConfig(driver);
 
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
@@ -7282,17 +7232,11 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
         goto cleanup;
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
+        if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_MEMORY)) {
             virReportError(VIR_ERR_OPERATION_INVALID,
                            "%s", _("cgroup memory controller is not mounted"));
             goto cleanup;
         }
-
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("cannot find cgroup for domain %s"), vm->def->name);
-            goto cleanup;
-        }
     }
 
 #define VIR_GET_LIMIT_PARAMETER(PARAM, VALUE)                                \
@@ -7320,7 +7264,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
 
     if (set_swap_hard_limit) {
         if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-            if ((rc = virCgroupSetMemSwapHardLimit(group, swap_hard_limit)) < 0) {
+            if ((rc = virCgroupSetMemSwapHardLimit(priv->cgroup, swap_hard_limit)) < 0) {
                 virReportSystemError(-rc, "%s",
                                      _("unable to set memory swap_hard_limit tunable"));
                 goto cleanup;
@@ -7334,7 +7278,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
 
     if (set_memory_hard_limit) {
         if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-            if ((rc = virCgroupSetMemoryHardLimit(group, memory_hard_limit)) < 0) {
+            if ((rc = virCgroupSetMemoryHardLimit(priv->cgroup, memory_hard_limit)) < 0) {
                 virReportSystemError(-rc, "%s",
                                      _("unable to set memory hard_limit tunable"));
                 goto cleanup;
@@ -7348,7 +7292,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
 
     if (set_memory_soft_limit) {
         if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-            if ((rc = virCgroupSetMemorySoftLimit(group, memory_soft_limit)) < 0) {
+            if ((rc = virCgroupSetMemorySoftLimit(priv->cgroup, memory_soft_limit)) < 0) {
                 virReportSystemError(-rc, "%s",
                                      _("unable to set memory soft_limit tunable"));
                 goto cleanup;
@@ -7367,7 +7311,6 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
     ret = 0;
 
 cleanup:
-    virCgroupFree(&group);
     virObjectUnlock(vm);
     virObjectUnref(caps);
     virObjectUnref(cfg);
@@ -7382,12 +7325,12 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
     int ret = -1;
     int rc;
     virCapsPtr caps = NULL;
+    qemuDomainObjPrivatePtr priv;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -7404,6 +7347,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
         goto cleanup;
     }
 
+    priv = vm->privateData;
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
         goto cleanup;
 
@@ -7412,17 +7356,11 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
         goto cleanup;
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
+        if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_MEMORY)) {
             virReportError(VIR_ERR_OPERATION_INVALID,
                            "%s", _("cgroup memory controller is not mounted"));
             goto cleanup;
         }
-
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("cannot find cgroup for domain %s"), vm->def->name);
-            goto cleanup;
-        }
     }
 
     if ((*nparams) == 0) {
@@ -7473,12 +7411,9 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
         virTypedParameterPtr param = &params[i];
         unsigned long long val = 0;
 
-        /* Coverity does not realize that if we get here, group is set.  */
-        sa_assert(group);
-
         switch (i) {
         case 0: /* fill memory hard limit here */
-            rc = virCgroupGetMemoryHardLimit(group, &val);
+            rc = virCgroupGetMemoryHardLimit(priv->cgroup, &val);
             if (rc != 0) {
                 virReportSystemError(-rc, "%s",
                                      _("unable to get memory hard limit"));
@@ -7491,7 +7426,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
             break;
 
         case 1: /* fill memory soft limit here */
-            rc = virCgroupGetMemorySoftLimit(group, &val);
+            rc = virCgroupGetMemorySoftLimit(priv->cgroup, &val);
             if (rc != 0) {
                 virReportSystemError(-rc, "%s",
                                      _("unable to get memory soft limit"));
@@ -7504,7 +7439,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
             break;
 
         case 2: /* fill swap hard limit here */
-            rc = virCgroupGetMemSwapHardLimit(group, &val);
+            rc = virCgroupGetMemSwapHardLimit(priv->cgroup, &val);
             if (rc != 0) {
                 virReportSystemError(-rc, "%s",
                                      _("unable to get swap hard limit"));
@@ -7528,8 +7463,6 @@ out:
     ret = 0;
 
 cleanup:
-    if (group)
-        virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(caps);
@@ -7545,11 +7478,11 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
     virDomainDefPtr persistentDef = NULL;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     int ret = -1;
     virQEMUDriverConfigPtr cfg = NULL;
     virCapsPtr caps = NULL;
+    qemuDomainObjPrivatePtr priv;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -7568,6 +7501,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
                        _("No such domain %s"), dom->uuid);
         goto cleanup;
     }
+    priv = vm->privateData;
     cfg = virQEMUDriverGetConfig(driver);
 
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
@@ -7578,18 +7512,11 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
         goto cleanup;
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
+        if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
             virReportError(VIR_ERR_OPERATION_INVALID,
                            "%s", _("cgroup cpuset controller is not mounted"));
             goto cleanup;
         }
-
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("cannot find cgroup for domain %s"),
-                           vm->def->name);
-            goto cleanup;
-        }
     }
 
     ret = 0;
@@ -7642,7 +7569,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
                     continue;
                 }
 
-                if ((rc = virCgroupSetCpusetMems(group, nodeset_str) != 0)) {
+                if ((rc = virCgroupSetCpusetMems(priv->cgroup, nodeset_str) != 0)) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set numa tunable"));
                     virBitmapFree(nodeset);
@@ -7682,7 +7609,6 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
     }
 
 cleanup:
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(caps);
@@ -7698,13 +7624,13 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
     char *nodeset = NULL;
     int ret = -1;
     int rc;
     virCapsPtr caps = NULL;
+    qemuDomainObjPrivatePtr priv;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -7722,6 +7648,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
                        _("No such domain %s"), dom->uuid);
         goto cleanup;
     }
+    priv = vm->privateData;
 
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
         goto cleanup;
@@ -7737,18 +7664,11 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
     }
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
+        if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_MEMORY)) {
             virReportError(VIR_ERR_OPERATION_INVALID,
                            "%s", _("cgroup memory controller is not mounted"));
             goto cleanup;
         }
-
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("cannot find cgroup for domain %s"),
-                           vm->def->name);
-            goto cleanup;
-        }
     }
 
     for (i = 0; i < QEMU_NB_NUMA_PARAM && i < *nparams; i++) {
@@ -7771,7 +7691,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
                 if (!nodeset)
                     nodeset = strdup("");
             } else {
-                rc = virCgroupGetCpusetMems(group, &nodeset);
+                rc = virCgroupGetCpusetMems(priv->cgroup, &nodeset);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to get numa nodeset"));
@@ -7798,7 +7718,6 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
 
 cleanup:
     VIR_FREE(nodeset);
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(caps);
@@ -7906,6 +7825,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
     int rc;
     virQEMUDriverConfigPtr cfg = NULL;
     virCapsPtr caps = NULL;
+    qemuDomainObjPrivatePtr priv;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -7931,6 +7851,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
         goto cleanup;
     }
 
+    priv = vm->privateData;
     cfg = virQEMUDriverGetConfig(driver);
 
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
@@ -7948,17 +7869,11 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
     }
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
+        if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
             virReportError(VIR_ERR_OPERATION_INVALID,
                            "%s", _("cgroup CPU controller is not mounted"));
             goto cleanup;
         }
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("cannot find cgroup for domain %s"),
-                           vm->def->name);
-            goto cleanup;
-        }
     }
 
     for (i = 0; i < nparams; i++) {
@@ -7968,7 +7883,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
 
         if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_CPU_SHARES)) {
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-                if ((rc = virCgroupSetCpuShares(group, value_ul))) {
+                if ((rc = virCgroupSetCpuShares(priv->cgroup, value_ul))) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set cpu shares tunable"));
                     goto cleanup;
@@ -8054,7 +7969,6 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
 
 cleanup:
     virDomainDefFree(vmdef);
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(caps);
@@ -8098,7 +8012,7 @@ qemuGetVcpuBWLive(virCgroupPtr cgroup, unsigned long long *period,
 }
 
 static int
-qemuGetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
+qemuGetVcpusBWLive(virDomainObjPtr vm,
                    unsigned long long *period, long long *quota)
 {
     virCgroupPtr cgroup_vcpu = NULL;
@@ -8109,7 +8023,7 @@ qemuGetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
     priv = vm->privateData;
     if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
         /* We do not create sub dir for each vcpu */
-        rc = qemuGetVcpuBWLive(cgroup, period, quota);
+        rc = qemuGetVcpuBWLive(priv->cgroup, period, quota);
         if (rc < 0)
             goto cleanup;
 
@@ -8119,7 +8033,7 @@ qemuGetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
     }
 
     /* get period and quota for vcpu0 */
-    rc = virCgroupForVcpu(cgroup, 0, &cgroup_vcpu, 0);
+    rc = virCgroupForVcpu(priv->cgroup, 0, &cgroup_vcpu, 0);
     if (!cgroup_vcpu) {
         virReportSystemError(-rc,
                              _("Unable to find vcpu cgroup for %s(vcpu: 0)"),
@@ -8183,7 +8097,6 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
                                 unsigned int flags)
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     unsigned long long shares;
     unsigned long long period;
@@ -8196,6 +8109,7 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
     int saved_nparams = 0;
     virDomainDefPtr persistentDef;
     virCapsPtr caps = NULL;
+    qemuDomainObjPrivatePtr priv;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -8204,13 +8118,6 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
     /* We don't return strings, and thus trivially support this flag.  */
     flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
 
-    if (*nparams > 1) {
-        rc = qemuGetCpuBWStatus(driver->cgroup);
-        if (rc < 0)
-            goto cleanup;
-        cpu_bw_status = !!rc;
-    }
-
     vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
 
     if (vm == NULL) {
@@ -8219,6 +8126,15 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
         goto cleanup;
     }
 
+    priv = vm->privateData;
+
+    if (*nparams > 1) {
+        rc = qemuGetCpuBWStatus(priv->cgroup);
+        if (rc < 0)
+            goto cleanup;
+        cpu_bw_status = !!rc;
+    }
+
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
         goto cleanup;
 
@@ -8237,19 +8153,13 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
         goto out;
     }
 
-    if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
+    if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("cgroup CPU controller is not mounted"));
         goto cleanup;
     }
 
-    if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("cannot find cgroup for domain %s"), vm->def->name);
-        goto cleanup;
-    }
-
-    rc = virCgroupGetCpuShares(group, &shares);
+    rc = virCgroupGetCpuShares(priv->cgroup, &shares);
     if (rc != 0) {
         virReportSystemError(-rc, "%s",
                              _("unable to get cpu shares tunable"));
@@ -8257,13 +8167,13 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
     }
 
     if (*nparams > 1 && cpu_bw_status) {
-        rc = qemuGetVcpusBWLive(vm, group, &period, &quota);
+        rc = qemuGetVcpusBWLive(vm, &period, &quota);
         if (rc != 0)
             goto cleanup;
     }
 
     if (*nparams > 3 && cpu_bw_status) {
-        rc = qemuGetEmulatorBandwidthLive(vm, group, &emulator_period,
+        rc = qemuGetEmulatorBandwidthLive(vm, priv->cgroup, &emulator_period,
                                           &emulator_quota);
         if (rc != 0)
             goto cleanup;
@@ -8316,7 +8226,6 @@ out:
     ret = 0;
 
 cleanup:
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(caps);
@@ -8712,7 +8621,6 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
     int ret = -1;
@@ -8876,7 +8784,6 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
 cleanup:
     virNetDevBandwidthFree(bandwidth);
     virNetDevBandwidthFree(newBandwidth);
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(caps);
@@ -8893,7 +8800,6 @@ qemuDomainGetInterfaceParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr def = NULL;
     virDomainDefPtr persistentDef = NULL;
@@ -9000,8 +8906,6 @@ qemuDomainGetInterfaceParameters(virDomainPtr dom,
     ret = 0;
 
 cleanup:
-    if (group)
-        virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(caps);
@@ -10607,7 +10511,6 @@ typedef enum {
 static int
 qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver,
                                   virDomainObjPtr vm,
-                                  virCgroupPtr cgroup,
                                   virDomainDiskDefPtr disk,
                                   const char *file,
                                   qemuDomainDiskChainMode mode)
@@ -10631,13 +10534,13 @@ qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver,
         if (virSecurityManagerRestoreImageLabel(driver->securityManager,
                                                 vm->def, disk) < 0)
             VIR_WARN("Unable to restore security label on %s", disk->src);
-        if (cgroup && qemuTeardownDiskCgroup(vm, cgroup, disk) < 0)
+        if (qemuTeardownDiskCgroup(vm, disk) < 0)
             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, cfg->uri,
                                        vm, disk) < 0 ||
-               (cgroup && qemuSetupDiskCgroup(vm, cgroup, disk) < 0) ||
+               qemuSetupDiskCgroup(vm, disk) < 0 ||
                virSecurityManagerSetImageLabel(driver->securityManager,
                                                vm->def, disk) < 0) {
         goto cleanup;
@@ -11073,7 +10976,6 @@ cleanup:
 static int
 qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
                                          virDomainObjPtr vm,
-                                         virCgroupPtr cgroup,
                                          virDomainSnapshotDiskDefPtr snap,
                                          virDomainDiskDefPtr disk,
                                          virDomainDiskDefPtr persistDisk,
@@ -11123,9 +11025,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     virStorageFileFreeMetadata(disk->backingChain);
     disk->backingChain = NULL;
 
-    if (qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, source,
+    if (qemuDomainPrepareDiskChainElement(driver, vm, disk, source,
                                           VIR_DISK_CHAIN_READ_WRITE) < 0) {
-        qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, source,
+        qemuDomainPrepareDiskChainElement(driver, vm, disk, source,
                                           VIR_DISK_CHAIN_NO_ACCESS);
         goto cleanup;
     }
@@ -11167,7 +11069,6 @@ cleanup:
 static void
 qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
                                        virDomainObjPtr vm,
-                                       virCgroupPtr cgroup,
                                        virDomainDiskDefPtr origdisk,
                                        virDomainDiskDefPtr disk,
                                        virDomainDiskDefPtr persistDisk,
@@ -11184,7 +11085,7 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
-    qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, origdisk->src,
+    qemuDomainPrepareDiskChainElement(driver, vm, disk, origdisk->src,
                                       VIR_DISK_CHAIN_NO_ACCESS);
     if (need_unlink && stat(disk->src, &st) == 0 &&
         S_ISREG(st.st_mode) && unlink(disk->src) < 0)
@@ -11221,7 +11122,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
     int i;
     bool persist = false;
     bool reuse = (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT) != 0;
-    virCgroupPtr cgroup = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (!virDomainObjIsActive(vm)) {
@@ -11230,15 +11130,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) &&
-        virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Unable to find cgroup for %s"),
-                       vm->def->name);
-        goto cleanup;
-    }
-    /* 'cgroup' is still NULL if cgroups are disabled.  */
-
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_TRANSACTION)) {
         if (!(actions = virJSONValueNewArray())) {
             virReportOOMError();
@@ -11274,7 +11165,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
             }
         }
 
-        ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm, cgroup,
+        ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm,
                                                        &snap->def->disks[i],
                                                        vm->def->disks[i],
                                                        persistDisk, actions,
@@ -11303,7 +11194,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
                         persistDisk = vm->newDef->disks[indx];
                 }
 
-                qemuDomainSnapshotUndoSingleDiskActive(driver, vm, cgroup,
+                qemuDomainSnapshotUndoSingleDiskActive(driver, vm,
                                                        snap->def->dom->disks[i],
                                                        vm->def->disks[i],
                                                        persistDisk,
@@ -11314,7 +11205,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
     qemuDomainObjExitMonitor(driver, vm);
 
 cleanup:
-    virCgroupFree(&cgroup);
 
     if (ret == 0 || !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_TRANSACTION)) {
         if (virDomainSaveStatus(driver->xmlconf, cfg->stateDir, vm) < 0 ||
@@ -13065,7 +12955,6 @@ qemuDomainBlockPivot(virConnectPtr conn,
     virDomainBlockJobInfo info;
     const char *format = virStorageFileFormatTypeToString(disk->mirrorFormat);
     bool resume = false;
-    virCgroupPtr cgroup = NULL;
     char *oldsrc = NULL;
     int oldformat;
     virStorageFileMetadataPtr oldchain = NULL;
@@ -13125,14 +13014,6 @@ qemuDomainBlockPivot(virConnectPtr conn,
      * label the entire chain.  This action is safe even if the
      * backing chain has already been labeled; but only necessary when
      * we know for sure that there is a backing chain.  */
-    if (disk->mirrorFormat && disk->mirrorFormat != VIR_STORAGE_FILE_RAW &&
-        qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) &&
-        virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Unable to find cgroup for %s"),
-                       vm->def->name);
-        goto cleanup;
-    }
     oldsrc = disk->src;
     oldformat = disk->format;
     oldchain = disk->backingChain;
@@ -13148,7 +13029,7 @@ qemuDomainBlockPivot(virConnectPtr conn,
     if (disk->mirrorFormat && disk->mirrorFormat != VIR_STORAGE_FILE_RAW &&
         (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
                                  vm, disk) < 0 ||
-         (cgroup && qemuSetupDiskCgroup(vm, cgroup, disk) < 0) ||
+         qemuSetupDiskCgroup(vm, disk) < 0 ||
          virSecurityManagerSetImageLabel(driver->securityManager, vm->def,
                                          disk) < 0)) {
         disk->src = oldsrc;
@@ -13192,8 +13073,6 @@ qemuDomainBlockPivot(virConnectPtr conn,
     disk->mirroring = false;
 
 cleanup:
-    if (cgroup)
-        virCgroupFree(&cgroup);
     if (resume && virDomainObjIsActive(vm) &&
         qemuProcessStartCPUs(driver, vm, conn,
                              VIR_DOMAIN_RUNNING_UNPAUSED,
@@ -13421,7 +13300,6 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
     struct stat st;
     bool need_unlink = false;
     char *mirror = NULL;
-    virCgroupPtr cgroup = NULL;
     virQEMUDriverConfigPtr cfg = NULL;
 
     /* Preliminaries: find the disk we are editing, sanity checks */
@@ -13437,13 +13315,6 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
                        _("domain is not running"));
         goto cleanup;
     }
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) &&
-        virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Unable to find cgroup for %s"),
-                       vm->def->name);
-        goto cleanup;
-    }
 
     device = qemuDiskPathToAlias(vm, path, &idx);
     if (!device) {
@@ -13545,9 +13416,9 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
         goto endjob;
     }
 
-    if (qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, dest,
+    if (qemuDomainPrepareDiskChainElement(driver, vm, disk, dest,
                                           VIR_DISK_CHAIN_READ_WRITE) < 0) {
-        qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, dest,
+        qemuDomainPrepareDiskChainElement(driver, vm, disk, dest,
                                           VIR_DISK_CHAIN_NO_ACCESS);
         goto endjob;
     }
@@ -13559,7 +13430,7 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
     virDomainAuditDisk(vm, NULL, dest, "mirror", ret >= 0);
     qemuDomainObjExitMonitor(driver, vm);
     if (ret < 0) {
-        qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, dest,
+        qemuDomainPrepareDiskChainElement(driver, vm, disk, dest,
                                           VIR_DISK_CHAIN_NO_ACCESS);
         goto endjob;
     }
@@ -13581,8 +13452,6 @@ endjob:
     }
 
 cleanup:
-    if (cgroup)
-        virCgroupFree(&cgroup);
     VIR_FREE(device);
     if (vm)
         virObjectUnlock(vm);
@@ -13638,7 +13507,6 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base,
     virStorageFileMetadataPtr top_meta = NULL;
     const char *top_parent = NULL;
     const char *base_canon = NULL;
-    virCgroupPtr cgroup = NULL;
     bool clean_access = false;
 
     virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW, -1);
@@ -13722,18 +13590,11 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base,
      * revoke access to files removed from the chain, when the commit
      * operation succeeds, but doing that requires tracking the
      * operation in XML across libvirtd restarts.  */
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) &&
-        virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Unable to find cgroup for %s"),
-                       vm->def->name);
-        goto endjob;
-    }
     clean_access = true;
-    if (qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, base_canon,
+    if (qemuDomainPrepareDiskChainElement(driver, vm, disk, base_canon,
                                           VIR_DISK_CHAIN_READ_WRITE) < 0 ||
         (top_parent && top_parent != disk->src &&
-         qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk,
+         qemuDomainPrepareDiskChainElement(driver, vm, disk,
                                            top_parent,
                                            VIR_DISK_CHAIN_READ_WRITE) < 0))
         goto endjob;
@@ -13747,15 +13608,13 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base,
 endjob:
     if (ret < 0 && clean_access) {
         /* Revert access to read-only, if possible.  */
-        qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, base_canon,
+        qemuDomainPrepareDiskChainElement(driver, vm, disk, base_canon,
                                           VIR_DISK_CHAIN_READ_ONLY);
         if (top_parent && top_parent != disk->src)
-            qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk,
+            qemuDomainPrepareDiskChainElement(driver, vm, disk,
                                               top_parent,
                                               VIR_DISK_CHAIN_READ_ONLY);
     }
-    if (cgroup)
-        virCgroupFree(&cgroup);
     if (qemuDomainObjEndJob(driver, vm) == 0) {
         vm = NULL;
         goto cleanup;
@@ -14399,17 +14258,18 @@ cleanup:
 
 /* qemuDomainGetCPUStats() with start_cpu == -1 */
 static int
-qemuDomainGetTotalcpuStats(virCgroupPtr group,
+qemuDomainGetTotalcpuStats(virDomainObjPtr vm,
                            virTypedParameterPtr params,
                            int nparams)
 {
     unsigned long long cpu_time;
     int ret;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
 
     if (nparams == 0) /* return supported number of params */
         return QEMU_NB_TOTAL_CPU_STAT_PARAM;
     /* entry 0 is cputime */
-    ret = virCgroupGetCpuacctUsage(group, &cpu_time);
+    ret = virCgroupGetCpuacctUsage(priv->cgroup, &cpu_time);
     if (ret < 0) {
         virReportSystemError(-ret, "%s", _("unable to get cpu account"));
         return -1;
@@ -14423,7 +14283,7 @@ qemuDomainGetTotalcpuStats(virCgroupPtr group,
         unsigned long long user;
         unsigned long long sys;
 
-        ret = virCgroupGetCpuacctStat(group, &user, &sys);
+        ret = virCgroupGetCpuacctStat(priv->cgroup, &user, &sys);
         if (ret < 0) {
             virReportSystemError(-ret, "%s", _("unable to get cpu account"));
             return -1;
@@ -14461,22 +14321,22 @@ qemuDomainGetTotalcpuStats(virCgroupPtr group,
  *   s3 = t03 + t13
  */
 static int
-getSumVcpuPercpuStats(virCgroupPtr group,
-                      unsigned int nvcpu,
+getSumVcpuPercpuStats(virDomainObjPtr vm,
                       unsigned long long *sum_cpu_time,
                       unsigned int num)
 {
     int ret = -1;
     int i;
     char *buf = NULL;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
     virCgroupPtr group_vcpu = NULL;
 
-    for (i = 0; i < nvcpu; i++) {
+    for (i = 0; i < priv->nvcpupids; i++) {
         char *pos;
         unsigned long long tmp;
         int j;
 
-        if (virCgroupForVcpu(group, i, &group_vcpu, 0) < 0) {
+        if (virCgroupForVcpu(priv->cgroup, i, &group_vcpu, 0) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("error accessing cgroup cpuacct for vcpu"));
             goto cleanup;
@@ -14508,7 +14368,6 @@ cleanup:
 
 static int
 qemuDomainGetPercpuStats(virDomainObjPtr vm,
-                         virCgroupPtr group,
                          virTypedParameterPtr params,
                          unsigned int nparams,
                          int start_cpu,
@@ -14548,7 +14407,7 @@ qemuDomainGetPercpuStats(virDomainObjPtr vm,
     }
 
     /* we get percpu cputime accounting info. */
-    if (virCgroupGetCpuacctPercpuUsage(group, &buf))
+    if (virCgroupGetCpuacctPercpuUsage(priv->cgroup, &buf))
         goto cleanup;
     pos = buf;
     memset(params, 0, nparams * ncpus);
@@ -14588,7 +14447,7 @@ qemuDomainGetPercpuStats(virDomainObjPtr vm,
         virReportOOMError();
         goto cleanup;
     }
-    if (getSumVcpuPercpuStats(group, priv->nvcpupids, sum_cpu_time, n) < 0)
+    if (getSumVcpuPercpuStats(vm, sum_cpu_time, n) < 0)
         goto cleanup;
 
     sum_cpu_pos = sum_cpu_time;
@@ -14614,17 +14473,17 @@ cleanup:
 
 static int
 qemuDomainGetCPUStats(virDomainPtr domain,
-                virTypedParameterPtr params,
-                unsigned int nparams,
-                int start_cpu,
-                unsigned int ncpus,
-                unsigned int flags)
+                      virTypedParameterPtr params,
+                      unsigned int nparams,
+                      int start_cpu,
+                      unsigned int ncpus,
+                      unsigned int flags)
 {
     virQEMUDriverPtr driver = domain->conn->privateData;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     int ret = -1;
     bool isActive;
+    qemuDomainObjPrivatePtr priv;
 
     virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
 
@@ -14634,6 +14493,7 @@ qemuDomainGetCPUStats(virDomainPtr domain,
                        _("No such domain %s"), domain->uuid);
         goto cleanup;
     }
+    priv = vm->privateData;
 
     isActive = virDomainObjIsActive(vm);
     if (!isActive) {
@@ -14642,25 +14502,18 @@ qemuDomainGetCPUStats(virDomainPtr domain,
         goto cleanup;
     }
 
-    if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUACCT)) {
+    if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUACCT)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("cgroup CPUACCT controller is not mounted"));
         goto cleanup;
     }
 
-    if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("cannot find cgroup for domain %s"), vm->def->name);
-        goto cleanup;
-    }
-
     if (start_cpu == -1)
-        ret = qemuDomainGetTotalcpuStats(group, params, nparams);
+        ret = qemuDomainGetTotalcpuStats(vm, params, nparams);
     else
-        ret = qemuDomainGetPercpuStats(vm, group, params, nparams,
+        ret = qemuDomainGetPercpuStats(vm, params, nparams,
                                        start_cpu, ncpus);
 cleanup:
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     return ret;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index b978b97..a6c75cb 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1136,27 +1136,16 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
         goto error;
     }
 
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
-        virCgroupPtr cgroup = NULL;
+    if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) {
         virUSBDevicePtr usb;
-        qemuCgroupData data;
-
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Unable to find cgroup for %s"),
-                           vm->def->name);
-            goto error;
-        }
 
         if ((usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus,
                                 hostdev->source.subsys.u.usb.device,
                                 NULL)) == NULL)
             goto error;
 
-        data.vm = vm;
-        data.cgroup = cgroup;
         if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup,
-                                    &data) < 0) {
+                                    vm) < 0) {
             virUSBDeviceFree(usb);
             goto error;
         }
@@ -2032,7 +2021,6 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
     int i, ret = -1;
     virDomainDiskDefPtr detach = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    virCgroupPtr cgroup = NULL;
     char *drivestr = NULL;
 
     i = qemuFindDisk(vm->def, dev->data.disk->dst);
@@ -2052,15 +2040,6 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Unable to find cgroup for %s"),
-                           vm->def->name);
-            goto cleanup;
-        }
-    }
-
     if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
         virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
         if (!virDomainDeviceAddressIsValid(&detach->info,
@@ -2130,11 +2109,9 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
                                             vm->def, dev->data.disk) < 0)
         VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
 
-    if (cgroup != NULL) {
-        if (qemuTeardownDiskCgroup(vm, cgroup, dev->data.disk) < 0)
-            VIR_WARN("Failed to teardown cgroup for disk path %s",
-                     NULLSTR(dev->data.disk->src));
-    }
+    if (qemuTeardownDiskCgroup(vm, dev->data.disk) < 0)
+        VIR_WARN("Failed to teardown cgroup for disk path %s",
+                 NULLSTR(dev->data.disk->src));
 
     if (virDomainLockDiskDetach(driver->lockManager, vm, dev->data.disk) < 0)
         VIR_WARN("Unable to release lock on %s", dev->data.disk->src);
@@ -2142,7 +2119,6 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
     ret = 0;
 
 cleanup:
-    virCgroupFree(&cgroup);
     VIR_FREE(drivestr);
     return ret;
 }
@@ -2154,7 +2130,6 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
     int i, ret = -1;
     virDomainDiskDefPtr detach = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    virCgroupPtr cgroup = NULL;
     char *drivestr = NULL;
 
     i = qemuFindDisk(vm->def, dev->data.disk->dst);
@@ -2181,15 +2156,6 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Unable to find cgroup for %s"),
-                           vm->def->name);
-            goto cleanup;
-        }
-    }
-
     /* build the actual drive id string as the disk->info.alias doesn't
      * contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
     if (virAsprintf(&drivestr, "%s%s",
@@ -2222,11 +2188,9 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
                                             vm->def, dev->data.disk) < 0)
         VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
 
-    if (cgroup != NULL) {
-        if (qemuTeardownDiskCgroup(vm, cgroup, dev->data.disk) < 0)
-            VIR_WARN("Failed to teardown cgroup for disk path %s",
-                     NULLSTR(dev->data.disk->src));
-    }
+    if (qemuTeardownDiskCgroup(vm, dev->data.disk) < 0)
+        VIR_WARN("Failed to teardown cgroup for disk path %s",
+                 NULLSTR(dev->data.disk->src));
 
     if (virDomainLockDiskDetach(driver->lockManager, vm, dev->data.disk) < 0)
         VIR_WARN("Unable to release lock on disk %s", dev->data.disk->src);
@@ -2235,7 +2199,6 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
 
 cleanup:
     VIR_FREE(drivestr);
-    virCgroupFree(&cgroup);
     return ret;
 }
 
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 3f74add..1b8719e 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -4177,7 +4177,6 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
                     enum qemuDomainAsyncJob asyncJob)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    virCgroupPtr cgroup = NULL;
     int ret = -1;
     int rc;
     bool restoreLabel = false;
@@ -4211,21 +4210,13 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
          * given cgroup ACL permission.  We might also stumble on
          * a race present in some qemu versions where it does a wait()
          * that botches pclose.  */
-        if (qemuCgroupControllerActive(driver,
-                                       VIR_CGROUP_CONTROLLER_DEVICES)) {
-            if (virCgroupForDomain(driver->cgroup, vm->def->name,
-                                   &cgroup, 0) != 0) {
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("Unable to find cgroup for %s"),
-                               vm->def->name);
-                goto cleanup;
-            }
-            rc = virCgroupAllowDevicePath(cgroup, path,
+        if (virCgroupHasController(priv->cgroup,
+                                   VIR_CGROUP_CONTROLLER_DEVICES)) {
+            rc = virCgroupAllowDevicePath(priv->cgroup, path,
                                           VIR_CGROUP_DEVICE_RW);
-            virDomainAuditCgroupPath(vm, cgroup, "allow", path, "rw", rc);
+            virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path, "rw", rc);
             if (rc == 1) {
                 /* path was not a device, no further need for cgroup */
-                virCgroupFree(&cgroup);
             } else if (rc < 0) {
                 virReportSystemError(-rc,
                                      _("Unable to allow device %s for %s"),
@@ -4326,14 +4317,14 @@ cleanup:
                                                  vm->def, path) < 0)
         VIR_WARN("failed to restore save state label on %s", path);
 
-    if (cgroup != NULL) {
-        rc = virCgroupDenyDevicePath(cgroup, path,
+    if (virCgroupHasController(priv->cgroup,
+                               VIR_CGROUP_CONTROLLER_DEVICES)) {
+        rc = virCgroupDenyDevicePath(priv->cgroup, path,
                                      VIR_CGROUP_DEVICE_RWM);
-        virDomainAuditCgroupPath(vm, cgroup, "deny", path, "rwm", rc);
+        virDomainAuditCgroupPath(vm, priv->cgroup, "deny", path, "rwm", rc);
         if (rc < 0)
             VIR_WARN("Unable to deny device %s for %s %d",
                      path, vm->def->name, rc);
-        virCgroupFree(&cgroup);
     }
     return ret;
 }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8c4bfb7..a86e62c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1395,6 +1395,7 @@ qemuProcessReadLogOutput(virDomainObjPtr vm,
         /* Filter out debug messages from intermediate libvirt process */
         while ((eol = strchr(filter_next, '\n'))) {
             *eol = '\0';
+            VIR_ERROR("<<<<<<<<<<<<%s>>>>>>>>>>", filter_next);
             if (virLogProbablyLogMessage(filter_next)) {
                 memmove(filter_next, eol + 1, got - (eol - buf));
                 got -= eol + 1 - filter_next;
@@ -2529,7 +2530,7 @@ static int qemuProcessHook(void *data)
      * memory allocation is on the correct NUMA node
      */
     VIR_DEBUG("Moving process to cgroup");
-    if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
+    if (qemuAddToCgroup(h->vm) < 0)
         goto cleanup;
 
     /* This must be done after cgroup placement to avoid resetting CPU
@@ -3004,6 +3005,9 @@ qemuProcessReconnect(void *opaque)
     if (qemuUpdateActiveUsbHostdevs(driver, obj->def) < 0)
         goto error;
 
+    if (qemuInitCgroup(driver, obj) < 0)
+        goto error;
+
     /* XXX: Need to change as long as lock is introduced for
      * qemu_driver->sharedDisks.
      */
@@ -3379,7 +3383,7 @@ int qemuProcessStart(virConnectPtr conn,
     /* Ensure no historical cgroup for this VM is lying around bogus
      * settings */
     VIR_DEBUG("Ensuring no historical cgroup is lying around");
-    qemuRemoveCgroup(driver, vm, 1);
+    qemuRemoveCgroup(vm);
 
     for (i = 0 ; i < vm->def->ngraphics; ++i) {
         virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
@@ -3740,7 +3744,7 @@ int qemuProcessStart(virConnectPtr conn,
         goto cleanup;
 
     VIR_DEBUG("Setting cgroup for each VCPU (if required)");
-    if (qemuSetupCgroupForVcpu(driver, vm) < 0)
+    if (qemuSetupCgroupForVcpu(vm) < 0)
         goto cleanup;
 
     VIR_DEBUG("Setting cgroup for emulator (if required)");
@@ -4075,7 +4079,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
     }
 
 retry:
-    if ((ret = qemuRemoveCgroup(driver, vm, 0)) < 0) {
+    if ((ret = qemuRemoveCgroup(vm)) < 0) {
         if (ret == -EBUSY && (retries++ < 5)) {
             usleep(200*1000);
             goto retry;
@@ -4083,6 +4087,7 @@ retry:
         VIR_WARN("Failed to remove cgroup for %s",
                  vm->def->name);
     }
+    virCgroupFree(&priv->cgroup);
 
     qemuProcessRemoveDomainStatus(driver, vm);
 
-- 
1.8.1.4




More information about the libvir-list mailing list