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

[libvirt] [PATCH v2 4/5] qemu: replace old cgroup



---
 src/conf/domain_conf.h    |   5 +
 src/qemu/qemu_cgroup.c    | 162 +++++++++------------
 src/qemu/qemu_cgroup.h    |   3 +-
 src/qemu/qemu_driver.c    | 351 ++++++++++++++++------------------------------
 src/qemu/qemu_hotplug.c   |  21 ++-
 src/qemu/qemu_migration.c |  20 +--
 src/qemu/qemu_process.c   |   7 +-
 7 files changed, 207 insertions(+), 362 deletions(-)

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9a9e0b1..1cf27e1 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -48,6 +48,7 @@
 # include "device_conf.h"
 # include "virbitmap.h"
 # include "virstoragefile.h"
+# include "vircgroup.h"
 
 /* forward declarations of all device types, required by
  * virDomainDeviceDef
@@ -1889,6 +1890,10 @@ struct _virDomainObj {
     void (*privateDataFreeFunc)(void *);
 
     int taint;
+
+    virCgroupPtr cgroup;
+    virCgroupPtr *vcpuCgroups;
+    virCgroupPtr cgroupEmulator;
 };
 
 typedef struct _virDomainObjList virDomainObjList;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 6527146..1dfbe35 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -203,7 +203,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
     if (driver->cgroup == NULL)
         return 0; /* Not supported, so claim success */
 
-    rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 1);
+    rc = virCgroupNew(vm->def->name, driver->cgroup, &vm->cgroup);
     if (rc != 0) {
         virReportSystemError(-rc,
                              _("Unable to create cgroup for %s"),
@@ -211,6 +211,17 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
+    rc = virCgroupMakePath(vm->cgroup);
+    if (rc != 0) {
+        virReportSystemError(-rc,
+                             _("Unable to create cgroup path for %s"),
+                             vm->def->name);
+        virCgroupFree(&vm->cgroup);
+        goto cleanup;
+    }
+
+    cgroup = vm->cgroup;
+
     if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
         qemuCgroupData data = { vm, cgroup };
         rc = virCgroupDenyAllDevices(cgroup);
@@ -434,14 +445,9 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
         }
     }
 done:
-    virCgroupFree(&cgroup);
     return 0;
 
 cleanup:
-    if (cgroup) {
-        virCgroupRemove(cgroup);
-        virCgroupFree(&cgroup);
-    }
     return -1;
 }
 
@@ -538,7 +544,6 @@ cleanup:
 
 int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
 {
-    virCgroupPtr cgroup = NULL;
     virCgroupPtr cgroup_vcpu = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainDefPtr def = vm->def;
@@ -546,6 +551,7 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
     unsigned int i, j;
     unsigned long long period = vm->def->cputune.period;
     long long quota = vm->def->cputune.quota;
+    char *vcpuName = NULL;
 
     if ((period || quota) &&
         (!driver->cgroup ||
@@ -559,35 +565,39 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
      * with virProcessInfoSetAffinity, thus the lack of cgroups is not fatal
      * here.
      */
-    if (driver->cgroup == NULL)
+    if (vm->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;
     }
 
+    if (VIR_ALLOC_N(vm->vcpuCgroups, priv->nvcpupids) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
     for (i = 0; i < priv->nvcpupids; i++) {
-        rc = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 1);
-        if (rc < 0) {
+        if (virAsprintf(&vcpuName, "vcpu%d", i) < 0)
+            goto cleanup;
+
+        if ((rc = virCgroupNew(vcpuName, vm->cgroup, &vm->vcpuCgroups[i])) < 0) {
             virReportSystemError(-rc,
                                  _("Unable to create vcpu cgroup for %s(vcpu:"
                                    " %d)"),
                                  vm->def->name, i);
+
             goto cleanup;
         }
+        VIR_FREE(vcpuName);
+    }
+
+    for (i = 0; i < priv->nvcpupids; i++) {
+        cgroup_vcpu = vm->vcpuCgroups[i];
 
         /* move the thread for vcpu to sub dir */
         rc = virCgroupAddTask(cgroup_vcpu, priv->vcpupids[i]);
@@ -620,24 +630,17 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
                 break;
             }
         }
-
-        virCgroupFree(&cgroup_vcpu);
     }
 
-    virCgroupFree(&cgroup);
     return 0;
 
 cleanup:
-    if (cgroup_vcpu) {
-        virCgroupRemove(cgroup_vcpu);
-        virCgroupFree(&cgroup_vcpu);
-    }
-
-    if (cgroup) {
-        virCgroupRemove(cgroup);
-        virCgroupFree(&cgroup);
+    if (vm->vcpuCgroups) {
+        for (i = 0; i < priv->nvcpupids; i++) {
+            if (vm->vcpuCgroups[i])
+                virCgroupFree(&vm->vcpuCgroups[i]);
+        }
     }
-
     return -1;
 }
 
@@ -647,8 +650,6 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
 {
     virBitmapPtr cpumask = NULL;
     virBitmapPtr cpumap = NULL;
-    virCgroupPtr cgroup = NULL;
-    virCgroupPtr cgroup_emulator = NULL;
     virDomainDefPtr def = vm->def;
     unsigned long long period = vm->def->cputune.emulator_period;
     long long quota = vm->def->cputune.emulator_quota;
@@ -662,20 +663,12 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
         return -1;
     }
 
-    if (driver->cgroup == NULL)
-        return 0; /* Not supported, so claim success */
+    if (vm->cgroup == NULL)
+        return 0;
 
-    rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0);
+    rc = virCgroupNew("emulator", vm->cgroup, &vm->cgroupEmulator);
     if (rc != 0) {
         virReportSystemError(-rc,
-                             _("Unable to find cgroup for %s"),
-                             vm->def->name);
-        goto cleanup;
-    }
-
-    rc = virCgroupForEmulator(cgroup, &cgroup_emulator, 1);
-    if (rc < 0) {
-        virReportSystemError(-rc,
                              _("Unable to create emulator cgroup for %s"),
                              vm->def->name);
         goto cleanup;
@@ -684,7 +677,7 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
     for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
         if (!qemuCgroupControllerActive(driver, i))
             continue;
-        rc = virCgroupMoveTask(cgroup, cgroup_emulator, i);
+        rc = virCgroupMoveTask(vm->cgroup, vm->cgroupEmulator, i);
         if (rc < 0) {
             virReportSystemError(-rc,
                                  _("Unable to move tasks from domain cgroup to "
@@ -706,7 +699,7 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
 
     if (cpumask) {
         if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
-            rc = qemuSetupCgroupEmulatorPin(cgroup_emulator, cpumask);
+            rc = qemuSetupCgroupEmulatorPin(vm->cgroupEmulator, cpumask);
             if (rc < 0)
                 goto cleanup;
         }
@@ -715,86 +708,61 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
 
     if (period || quota) {
         if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
-            if ((rc = qemuSetupCgroupVcpuBW(cgroup_emulator, period,
+            if ((rc = qemuSetupCgroupVcpuBW(vm->cgroupEmulator, period,
                                             quota)) < 0)
                 goto cleanup;
         }
     }
 
-    virCgroupFree(&cgroup_emulator);
-    virCgroupFree(&cgroup);
     virBitmapFree(cpumap);
     return 0;
 
 cleanup:
     virBitmapFree(cpumap);
 
-    if (cgroup_emulator) {
-        virCgroupRemove(cgroup_emulator);
-        virCgroupFree(&cgroup_emulator);
-    }
-
-    if (cgroup) {
-        virCgroupRemove(cgroup);
-        virCgroupFree(&cgroup);
-    }
+    if (vm->cgroupEmulator)
+        virCgroupFree(&vm->cgroupEmulator);
 
     return rc;
 }
 
-int qemuRemoveCgroup(virQEMUDriverPtr driver,
+int qemuRemoveCgroup(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
                      virDomainObjPtr vm,
-                     int quiet)
+                     int quiet ATTRIBUTE_UNUSED)
 {
-    virCgroupPtr cgroup;
-    int rc;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int i;
 
-    if (driver->cgroup == NULL)
-        return 0; /* Not supported, so claim success */
+    if (vm->cgroup)
+        virCgroupFree(&vm->cgroup);
 
-    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;
+    if (vm->cgroupEmulator)
+        virCgroupFree(&vm->cgroupEmulator);
+
+    if (vm->vcpuCgroups) {
+        for (i = 0; i < priv->nvcpupids; i++) {
+            if (vm->vcpuCgroups[i])
+                virCgroupFree(&vm->vcpuCgroups[i]);
+        }
     }
 
-    rc = virCgroupRemove(cgroup);
-    virCgroupFree(&cgroup);
-    return rc;
+    return 0;
 }
 
-int qemuAddToCgroup(virQEMUDriverPtr driver,
-                    virDomainDefPtr def)
+int qemuAddToCgroup(virDomainObjPtr vm)
 {
-    virCgroupPtr cgroup = NULL;
     int ret = -1;
-    int rc;
 
-    if (driver->cgroup == NULL)
+    if (vm->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());
-    if (rc != 0) {
-        virReportSystemError(-rc,
+    ret = virCgroupAddTask(vm->cgroup, getpid());
+    if (ret != 0) {
+        virReportSystemError(-ret,
                              _("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 75ef514..c4439c1 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -63,7 +63,6 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
 int qemuRemoveCgroup(virQEMUDriverPtr driver,
                      virDomainObjPtr vm,
                      int quiet);
-int qemuAddToCgroup(virQEMUDriverPtr driver,
-                    virDomainDefPtr def);
+int qemuAddToCgroup(virDomainObjPtr vm);
 
 #endif /* __QEMU_CGROUP_H__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 812bf95..932b96d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -655,6 +655,7 @@ qemuStartup(bool privileged,
     char ebuf[1024];
     char *membase = NULL;
     char *mempath = NULL;
+    virCgroupPtr appCgroup = NULL;
 
     if (VIR_ALLOC(qemu_driver) < 0)
         return -1;
@@ -795,12 +796,20 @@ qemuStartup(bool privileged,
         virAsprintf(&qemu_driver->autostartDir, "%s/qemu/autostart", base) < 0)
         goto out_of_memory;
 
-    rc = virCgroupForDriver("qemu", &qemu_driver->cgroup, privileged, 1);
+    rc = virCgroupGetAppRoot(&appCgroup, privileged);
+    if (rc < 0) {
+        VIR_INFO("Unable to create cgroup for libvirt: %s",
+                 virStrerror(-rc, ebuf, sizeof(ebuf)));
+        goto error;
+    }
+    rc = virCgroupNew("qemu", appCgroup, &qemu_driver->cgroup);
     if (rc < 0) {
         VIR_INFO("Unable to create cgroup for driver: %s",
                  virStrerror(-rc, ebuf, sizeof(ebuf)));
     }
 
+    virCgroupFree(&appCgroup);
+
     if (qemuLoadDriverConfig(qemu_driver, driverConf) < 0) {
         goto error;
     }
@@ -3652,9 +3661,8 @@ 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;
+    char *vcpuName = NULL;
 
     qemuDomainObjEnterMonitor(driver, vm);
 
@@ -3717,15 +3725,14 @@ 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 (vm->cgroup) {
                 int rv = -1;
                 /* Create cgroup for the onlined vcpu */
-                rv = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 1);
+                if (virAsprintf(&vcpuName, "cpu%d", i) < 0)
+                    goto cleanup;
+                rv = virCgroupNew(vcpuName, vm->cgroup,&cgroup_vcpu);
                 if (rv < 0) {
                     virReportSystemError(-rv,
                                          _("Unable to create vcpu cgroup for %s(vcpu:"
@@ -3734,13 +3741,15 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
                     goto cleanup;
                 }
 
+                VIR_FREE(vcpuName);
+
                 /* Add vcpu thread to the cgroup */
                 rv = virCgroupAddTask(cgroup_vcpu, cpupids[i]);
                 if (rv < 0) {
                     virReportSystemError(-rv,
                                          _("unable to add vcpu %d task %d to cgroup"),
                                          i, cpupids[i]);
-                    virCgroupRemove(cgroup_vcpu);
+                    virCgroupFree(&cgroup_vcpu);
                     goto cleanup;
                 }
             }
@@ -3768,7 +3777,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) {
@@ -3789,28 +3798,13 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
                     }
                 }
             }
-
-            virCgroupFree(&cgroup_vcpu);
         }
     } else {
         for (i = oldvcpus - 1; i >= nvcpus; i--) {
             virDomainVcpuPinDefPtr vcpupin = NULL;
 
-            if (cgroup_available) {
-                int rv = -1;
-
-                rv = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 0);
-                if (rv < 0) {
-                    virReportSystemError(-rv,
-                                         _("Unable to access vcpu cgroup for %s(vcpu:"
-                                           " %d)"),
-                                         vm->def->name, i);
-                    goto cleanup;
-                }
-
-                /* Remove cgroup for the offlined vcpu */
-                virCgroupRemove(cgroup_vcpu);
-                virCgroupFree(&cgroup_vcpu);
+            if (vm->cgroup) {
+                /* XXX: remove cgroup for vcpu */
             }
 
             /* Free vcpupin setting */
@@ -3830,10 +3824,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;
 
 unsupported:
@@ -4026,7 +4016,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 &&
+#if 0 /* XXX */
+            if (vm->cgroup &&
                 virCgroupForVcpu(cgroup_dom, vcpu, &cgroup_vcpu, 0) == 0 &&
                 qemuSetupCgroupVcpuPin(cgroup_vcpu, newVcpuPin, newVcpuPinNum, vcpu) < 0) {
                 virReportError(VIR_ERR_OPERATION_INVALID,
@@ -4034,6 +4025,7 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
                                  " for vcpu %d"), vcpu);
                 goto cleanup;
             }
+#endif
         } else {
             if (virProcessSetAffinity(priv->vcpupids[vcpu], pcpumap) < 0) {
                 virReportError(VIR_ERR_SYSTEM_ERROR,
@@ -4209,8 +4201,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;
     int ret = -1;
@@ -4272,16 +4262,13 @@ qemuDomainPinEmulator(virDomainPtr dom,
                  * 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 (vm->cgroupEmulator) {
+                    if (qemuSetupCgroupEmulatorPin(vm->cgroupEmulator,
+                                                   newVcpuPin[0]->cpumask) < 0) {
+                        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                                       _("failed to set cpuset.cpus in cgroup"
+                                         " for emulator threads"));
+                        goto cleanup;
                     }
                 }
             } else {
@@ -4343,10 +4330,6 @@ qemuDomainPinEmulator(virDomainPtr dom,
     ret = 0;
 
 cleanup:
-    if (cgroup_emulator)
-        virCgroupFree(&cgroup_emulator);
-    if (cgroup_dom)
-        virCgroupFree(&cgroup_dom);
     virBitmapFree(pcpumap);
 
     if (vm)
@@ -5817,7 +5800,6 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
                                virDomainDeviceDefPtr dev)
 {
     virDomainDiskDefPtr disk = dev->data.disk;
-    virCgroupPtr cgroup = NULL;
     int ret = -1;
 
     if (disk->driverName != NULL && !STREQ(disk->driverName, "qemu")) {
@@ -5836,13 +5818,7 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
         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)
+        if (vm->cgroup && qemuSetupDiskCgroup(vm, vm->cgroup, disk) < 0)
             goto end;
     }
     switch (disk->device)  {
@@ -5877,8 +5853,8 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
         break;
     }
 
-    if (ret != 0 && cgroup) {
-        if (qemuTeardownDiskCgroup(vm, cgroup, disk) < 0)
+    if (ret != 0 && vm->cgroup) {
+        if (qemuTeardownDiskCgroup(vm, vm->cgroup, disk) < 0)
             VIR_WARN("Failed to teardown cgroup for disk path %s",
                      NULLSTR(disk->src));
     }
@@ -5895,8 +5871,6 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
     }
 
 end:
-    if (cgroup)
-        virCgroupFree(&cgroup);
     return ret;
 }
 
@@ -6080,21 +6054,13 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm,
                               bool force)
 {
     virDomainDiskDefPtr disk = dev->data.disk;
-    virCgroupPtr cgroup = NULL;
     int ret = -1;
 
     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)
+        if (vm->cgroup && qemuSetupDiskCgroup(vm, vm->cgroup, disk) < 0)
             goto end;
     }
 
@@ -6112,14 +6078,12 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm,
         break;
     }
 
-    if (ret != 0 && cgroup) {
-        if (qemuTeardownDiskCgroup(vm, cgroup, disk) < 0)
+    if (ret != 0 && vm->cgroup) {
+        if (qemuTeardownDiskCgroup(vm, vm->cgroup, disk) < 0)
              VIR_WARN("Failed to teardown cgroup for disk path %s",
                       NULLSTR(disk->src));
     }
 end:
-    if (cgroup)
-        virCgroupFree(&cgroup);
     return ret;
 }
 
@@ -6907,7 +6871,6 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
     int ret = -1;
@@ -6942,7 +6905,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
             goto cleanup;
         }
 
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+        if (!vm->cgroup) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("cannot find cgroup for domain %s"),
                            vm->def->name);
@@ -6964,7 +6927,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
                     continue;
                 }
 
-                rc = virCgroupSetBlkioWeight(group, params[i].value.ui);
+                rc = virCgroupSetBlkioWeight(vm->cgroup, params[i].value.ui);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set blkio weight tunable"));
@@ -6982,7 +6945,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
                     continue;
                 }
                 for (j = 0; j < ndevices; j++) {
-                    rc = virCgroupSetBlkioDeviceWeight(group,
+                    rc = virCgroupSetBlkioDeviceWeight(vm->cgroup,
                                                        devices[j].path,
                                                        devices[j].weight);
                     if (rc < 0) {
@@ -7045,7 +7008,6 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
     }
 
 cleanup:
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
@@ -7060,7 +7022,6 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i, j;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
     unsigned int val;
@@ -7103,7 +7064,7 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
             goto cleanup;
         }
 
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+        if (!vm->cgroup) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("cannot find cgroup for domain %s"), vm->def->name);
             goto cleanup;
@@ -7117,7 +7078,7 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
 
             switch (i) {
             case 0: /* fill blkio weight here */
-                rc = virCgroupGetBlkioWeight(group, &val);
+                rc = virCgroupGetBlkioWeight(vm->cgroup, &val);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to get blkio weight"));
@@ -7230,8 +7191,6 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
     ret = 0;
 
 cleanup:
-    if (group)
-        virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
@@ -7247,7 +7206,6 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
     virDomainDefPtr persistentDef = NULL;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virTypedParameterPtr hard_limit = NULL;
     virTypedParameterPtr swap_hard_limit = NULL;
@@ -7292,7 +7250,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
             goto cleanup;
         }
 
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+        if (!vm->cgroup) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("cannot find cgroup for domain %s"), vm->def->name);
             goto cleanup;
@@ -7320,7 +7278,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
         /* Get current swap hard limit */
-        rc = virCgroupGetMemSwapHardLimit(group, &val);
+        rc = virCgroupGetMemSwapHardLimit(vm->cgroup, &val);
         if (rc != 0) {
             virReportSystemError(-rc, "%s",
                                  _("unable to get swap hard limit"));
@@ -7355,7 +7313,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
 
         if (STREQ(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) {
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-                rc = virCgroupSetMemoryHardLimit(group, param->value.ul);
+                rc = virCgroupSetMemoryHardLimit(vm->cgroup, param->value.ul);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set memory hard_limit tunable"));
@@ -7368,7 +7326,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
             }
         } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) {
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-                rc = virCgroupSetMemorySoftLimit(group, param->value.ul);
+                rc = virCgroupSetMemorySoftLimit(vm->cgroup, param->value.ul);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set memory soft_limit tunable"));
@@ -7381,7 +7339,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
             }
         } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)) {
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-                rc = virCgroupSetMemSwapHardLimit(group, param->value.ul);
+                rc = virCgroupSetMemSwapHardLimit(vm->cgroup, param->value.ul);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set swap_hard_limit tunable"));
@@ -7400,7 +7358,6 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
     }
 
 cleanup:
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
@@ -7415,7 +7372,6 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
     int ret = -1;
@@ -7449,7 +7405,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
             goto cleanup;
         }
 
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+        if (!vm->cgroup) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("cannot find cgroup for domain %s"), vm->def->name);
             goto cleanup;
@@ -7509,7 +7465,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
 
         switch (i) {
         case 0: /* fill memory hard limit here */
-            rc = virCgroupGetMemoryHardLimit(group, &val);
+            rc = virCgroupGetMemoryHardLimit(vm->cgroup, &val);
             if (rc != 0) {
                 virReportSystemError(-rc, "%s",
                                      _("unable to get memory hard limit"));
@@ -7522,7 +7478,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
             break;
 
         case 1: /* fill memory soft limit here */
-            rc = virCgroupGetMemorySoftLimit(group, &val);
+            rc = virCgroupGetMemorySoftLimit(vm->cgroup, &val);
             if (rc != 0) {
                 virReportSystemError(-rc, "%s",
                                      _("unable to get memory soft limit"));
@@ -7535,7 +7491,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom,
             break;
 
         case 2: /* fill swap hard limit here */
-            rc = virCgroupGetMemSwapHardLimit(group, &val);
+            rc = virCgroupGetMemSwapHardLimit(vm->cgroup, &val);
             if (rc != 0) {
                 virReportSystemError(-rc, "%s",
                                      _("unable to get swap hard limit"));
@@ -7559,8 +7515,6 @@ out:
     ret = 0;
 
 cleanup:
-    if (group)
-        virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
@@ -7576,7 +7530,6 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
     virDomainDefPtr persistentDef = NULL;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     int ret = -1;
 
@@ -7611,7 +7564,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
             goto cleanup;
         }
 
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+        if (!vm->cgroup) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("cannot find cgroup for domain %s"),
                            vm->def->name);
@@ -7669,7 +7622,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
                     continue;
                 }
 
-                if ((rc = virCgroupSetCpusetMems(group, nodeset_str) != 0)) {
+                if ((rc = virCgroupSetCpusetMems(vm->cgroup, nodeset_str) != 0)) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set numa tunable"));
                     virBitmapFree(nodeset);
@@ -7709,7 +7662,6 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
     }
 
 cleanup:
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
@@ -7724,7 +7676,6 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr persistentDef = NULL;
     char *nodeset = NULL;
@@ -7767,7 +7718,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
             goto cleanup;
         }
 
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+        if (!vm->cgroup) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("cannot find cgroup for domain %s"),
                            vm->def->name);
@@ -7795,7 +7746,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
                 if (!nodeset)
                     nodeset = strdup("");
             } else {
-                rc = virCgroupGetCpusetMems(group, &nodeset);
+                rc = virCgroupGetCpusetMems(vm->cgroup, &nodeset);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to get numa nodeset"));
@@ -7822,7 +7773,6 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
 
 cleanup:
     VIR_FREE(nodeset);
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
@@ -7830,13 +7780,11 @@ cleanup:
 }
 
 static int
-qemuSetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
+qemuSetVcpusBWLive(virDomainObjPtr vm,
                    unsigned long long period, long long quota)
 {
     int i;
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    virCgroupPtr cgroup_vcpu = NULL;
-    int rc;
 
     if (period == 0 && quota == 0)
         return 0;
@@ -7847,36 +7795,23 @@ qemuSetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
      */
     if (priv->nvcpupids != 0 && priv->vcpupids[0] != vm->pid) {
         for (i = 0; i < priv->nvcpupids; i++) {
-            rc = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 0);
-            if (rc < 0) {
-                virReportSystemError(-rc,
-                                     _("Unable to find vcpu cgroup for %s(vcpu:"
-                                       " %d)"),
-                                     vm->def->name, i);
+            if (vm->vcpuCgroups[i] &&
+                qemuSetupCgroupVcpuBW(vm->vcpuCgroups[i], period, quota) < 0)
                 goto cleanup;
-            }
-
-            if (qemuSetupCgroupVcpuBW(cgroup_vcpu, period, quota) < 0)
-                goto cleanup;
-
-            virCgroupFree(&cgroup_vcpu);
         }
     }
 
     return 0;
 
 cleanup:
-    virCgroupFree(&cgroup_vcpu);
     return -1;
 }
 
 static int
-qemuSetEmulatorBandwidthLive(virDomainObjPtr vm, virCgroupPtr cgroup,
+qemuSetEmulatorBandwidthLive(virDomainObjPtr vm,
                              unsigned long long period, long long quota)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    virCgroupPtr cgroup_emulator = NULL;
-    int rc;
 
     if (period == 0 && quota == 0)
         return 0;
@@ -7885,23 +7820,17 @@ qemuSetEmulatorBandwidthLive(virDomainObjPtr vm, virCgroupPtr cgroup,
         return 0;
     }
 
-    rc = virCgroupForEmulator(cgroup, &cgroup_emulator, 0);
-    if (rc < 0) {
-        virReportSystemError(-rc,
-                             _("Unable to find emulator cgroup for %s"),
-                             vm->def->name);
-        goto cleanup;
+    if (!vm->cgroupEmulator) {
+        virReportError(VIR_ERR_NO_SUPPORT,
+                       _("Unable to find emulator cgroup for %s"),
+                       vm->def->name);
+        return -1;
     }
 
-    if (qemuSetupCgroupVcpuBW(cgroup_emulator, period, quota) < 0)
-        goto cleanup;
+    if (qemuSetupCgroupVcpuBW(vm->cgroupEmulator, period, quota) < 0)
+        return -1;
 
-    virCgroupFree(&cgroup_emulator);
     return 0;
-
-cleanup:
-    virCgroupFree(&cgroup_emulator);
-    return -1;
 }
 
 #define SCHED_RANGE_CHECK(VAR, NAME, MIN, MAX)                              \
@@ -7921,7 +7850,6 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     int i;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     virDomainDefPtr vmdef = NULL;
     unsigned long long value_ul;
@@ -7972,7 +7900,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
                            "%s", _("cgroup CPU controller is not mounted"));
             goto cleanup;
         }
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+        if (!vm->cgroup) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("cannot find cgroup for domain %s"),
                            vm->def->name);
@@ -7987,7 +7915,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(vm->cgroup, value_ul))) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set cpu shares tunable"));
                     goto cleanup;
@@ -8003,7 +7931,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
                               QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD);
 
             if (flags & VIR_DOMAIN_AFFECT_LIVE && value_ul) {
-                if ((rc = qemuSetVcpusBWLive(vm, group, value_ul, 0)))
+                if ((rc = qemuSetVcpusBWLive(vm, value_ul, 0)))
                     goto cleanup;
 
                 vm->def->cputune.period = value_ul;
@@ -8017,7 +7945,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
                               QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA);
 
             if (flags & VIR_DOMAIN_AFFECT_LIVE && value_l) {
-                if ((rc = qemuSetVcpusBWLive(vm, group, 0, value_l)))
+                if ((rc = qemuSetVcpusBWLive(vm, 0, value_l)))
                     goto cleanup;
 
                 vm->def->cputune.quota = value_l;
@@ -8031,7 +7959,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
                               QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD);
 
             if (flags & VIR_DOMAIN_AFFECT_LIVE && value_ul) {
-                if ((rc = qemuSetEmulatorBandwidthLive(vm, group, value_ul, 0)))
+                if ((rc = qemuSetEmulatorBandwidthLive(vm, value_ul, 0)))
                     goto cleanup;
 
                 vm->def->cputune.emulator_period = value_ul;
@@ -8045,7 +7973,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
                               QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA);
 
             if (flags & VIR_DOMAIN_AFFECT_LIVE && value_l) {
-                if ((rc = qemuSetEmulatorBandwidthLive(vm, group, 0, value_l)))
+                if ((rc = qemuSetEmulatorBandwidthLive(vm, 0, value_l)))
                     goto cleanup;
 
                 vm->def->cputune.emulator_quota = value_l;
@@ -8073,7 +8001,6 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom,
 
 cleanup:
     virDomainDefFree(vmdef);
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
@@ -8119,52 +8046,39 @@ static int
 qemuGetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
                    unsigned long long *period, long long *quota)
 {
-    virCgroupPtr cgroup_vcpu = NULL;
     qemuDomainObjPrivatePtr priv = NULL;
-    int rc;
-    int ret = -1;
 
     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);
-        if (rc < 0)
-            goto cleanup;
+        if (qemuGetVcpuBWLive(cgroup, period, quota) < 0)
+            return -1;
 
         if (*quota > 0)
             *quota /= vm->def->vcpus;
-        goto out;
+
+        return 0;
     }
 
     /* get period and quota for vcpu0 */
-    rc = virCgroupForVcpu(cgroup, 0, &cgroup_vcpu, 0);
-    if (!cgroup_vcpu) {
-        virReportSystemError(-rc,
-                             _("Unable to find vcpu cgroup for %s(vcpu: 0)"),
-                             vm->def->name);
-        goto cleanup;
+    if (!vm->vcpuCgroups[0]) {
+        virReportError(VIR_ERR_NO_SUPPORT,
+                       _("Unable to find vcpu cgroup for %s(vcpu: 0)"),
+                       vm->def->name);
+        return -1;
     }
 
-    rc = qemuGetVcpuBWLive(cgroup_vcpu, period, quota);
-    if (rc < 0)
-        goto cleanup;
-
-out:
-    ret = 0;
+    if (qemuGetVcpuBWLive(vm->vcpuCgroups[0], period, quota) < 0)
+        return -1;
 
-cleanup:
-    virCgroupFree(&cgroup_vcpu);
-    return ret;
+    return 0;
 }
 
 static int
-qemuGetEmulatorBandwidthLive(virDomainObjPtr vm, virCgroupPtr cgroup,
+qemuGetEmulatorBandwidthLive(virDomainObjPtr vm,
                              unsigned long long *period, long long *quota)
 {
-    virCgroupPtr cgroup_emulator = NULL;
     qemuDomainObjPrivatePtr priv = NULL;
-    int rc;
-    int ret = -1;
 
     priv = vm->privateData;
     if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
@@ -8175,23 +8089,17 @@ qemuGetEmulatorBandwidthLive(virDomainObjPtr vm, virCgroupPtr cgroup,
     }
 
     /* get period and quota for emulator */
-    rc = virCgroupForEmulator(cgroup, &cgroup_emulator, 0);
-    if (!cgroup_emulator) {
-        virReportSystemError(-rc,
-                             _("Unable to find emulator cgroup for %s"),
-                             vm->def->name);
-        goto cleanup;
+    if (!vm->cgroupEmulator) {
+        virReportError(VIR_ERR_NO_SUPPORT,
+                       _("Unable to find emulator cgroup for %s"),
+                       vm->def->name);
+        return -1;
     }
 
-    rc = qemuGetVcpuBWLive(cgroup_emulator, period, quota);
-    if (rc < 0)
-        goto cleanup;
-
-    ret = 0;
+    if (qemuGetVcpuBWLive(vm->cgroupEmulator, period, quota) < 0)
+        return -1;
 
-cleanup:
-    virCgroupFree(&cgroup_emulator);
-    return ret;
+    return 0;
 }
 
 static int
@@ -8201,7 +8109,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;
@@ -8259,13 +8166,13 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
         goto cleanup;
     }
 
-    if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+    if (!vm->cgroup) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("cannot find cgroup for domain %s"), vm->def->name);
         goto cleanup;
     }
 
-    rc = virCgroupGetCpuShares(group, &shares);
+    rc = virCgroupGetCpuShares(vm->cgroup, &shares);
     if (rc != 0) {
         virReportSystemError(-rc, "%s",
                              _("unable to get cpu shares tunable"));
@@ -8273,13 +8180,13 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom,
     }
 
     if (*nparams > 1 && cpu_bw_status) {
-        rc = qemuGetVcpusBWLive(vm, group, &period, &quota);
+        rc = qemuGetVcpusBWLive(vm, vm->cgroup, &period, &quota);
         if (rc != 0)
             goto cleanup;
     }
 
     if (*nparams > 3 && cpu_bw_status) {
-        rc = qemuGetEmulatorBandwidthLive(vm, group, &emulator_period,
+        rc = qemuGetEmulatorBandwidthLive(vm, &emulator_period,
                                           &emulator_quota);
         if (rc != 0)
             goto cleanup;
@@ -8332,7 +8239,6 @@ out:
     ret = 0;
 
 cleanup:
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
@@ -11000,7 +10906,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
     int i;
     bool persist = false;
     bool reuse = (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT) != 0;
-    virCgroupPtr cgroup = NULL;
 
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
@@ -11009,7 +10914,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
     }
 
     if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) &&
-        virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0)) {
+        !vm->cgroup) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Unable to find cgroup for %s"),
                        vm->def->name);
@@ -11052,7 +10957,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
             }
         }
 
-        ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm, cgroup,
+        ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm, vm->cgroup,
                                                        &snap->def->disks[i],
                                                        vm->def->disks[i],
                                                        persistDisk, actions,
@@ -11081,7 +10986,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
                         persistDisk = vm->newDef->disks[indx];
                 }
 
-                qemuDomainSnapshotUndoSingleDiskActive(driver, vm, cgroup,
+                qemuDomainSnapshotUndoSingleDiskActive(driver, vm, vm->cgroup,
                                                        snap->def->dom->disks[i],
                                                        vm->def->disks[i],
                                                        persistDisk,
@@ -11092,8 +10997,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
 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))
@@ -12884,7 +12787,7 @@ qemuDomainBlockPivot(virConnectPtr conn,
      * 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) {
+        !vm->cgroup) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Unable to find cgroup for %s"),
                        vm->def->name);
@@ -12905,7 +12808,7 @@ qemuDomainBlockPivot(virConnectPtr conn,
     if (disk->mirrorFormat && disk->mirrorFormat != VIR_STORAGE_FILE_RAW &&
         (virDomainLockDiskAttach(driver->lockManager, driver->uri,
                                  vm, disk) < 0 ||
-         (cgroup && qemuSetupDiskCgroup(vm, cgroup, disk) < 0) ||
+         (cgroup && qemuSetupDiskCgroup(vm, vm->cgroup, disk) < 0) ||
          virSecurityManagerSetImageLabel(driver->securityManager, vm->def,
                                          disk) < 0)) {
         disk->src = oldsrc;
@@ -12949,8 +12852,6 @@ qemuDomainBlockPivot(virConnectPtr conn,
     disk->mirroring = false;
 
 cleanup:
-    if (cgroup)
-        virCgroupFree(&cgroup);
     if (resume && virDomainObjIsActive(vm) &&
         qemuProcessStartCPUs(driver, vm, conn,
                              VIR_DOMAIN_RUNNING_UNPAUSED,
@@ -13181,7 +13082,6 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
     struct stat st;
     bool need_unlink = false;
     char *mirror = NULL;
-    virCgroupPtr cgroup = NULL;
 
     /* Preliminaries: find the disk we are editing, sanity checks */
     virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
@@ -13197,7 +13097,7 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
         goto cleanup;
     }
     if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) &&
-        virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) < 0) {
+        !vm->cgroup) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Unable to find cgroup for %s"),
                        vm->def->name);
@@ -13304,9 +13204,9 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
         goto endjob;
     }
 
-    if (qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, dest,
+    if (qemuDomainPrepareDiskChainElement(driver, vm, vm->cgroup, disk, dest,
                                           VIR_DISK_CHAIN_READ_WRITE) < 0) {
-        qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, dest,
+        qemuDomainPrepareDiskChainElement(driver, vm, vm->cgroup, disk, dest,
                                           VIR_DISK_CHAIN_NO_ACCESS);
         goto endjob;
     }
@@ -13318,7 +13218,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, vm->cgroup, disk, dest,
                                           VIR_DISK_CHAIN_NO_ACCESS);
         goto endjob;
     }
@@ -13340,8 +13240,6 @@ endjob:
     }
 
 cleanup:
-    if (cgroup)
-        virCgroupFree(&cgroup);
     VIR_FREE(device);
     if (vm)
         virObjectUnlock(vm);
@@ -13396,7 +13294,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);
@@ -13481,17 +13378,17 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base,
      * 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) {
+        !vm->cgroup) {
         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, vm->cgroup, disk, base_canon,
                                           VIR_DISK_CHAIN_READ_WRITE) < 0 ||
         (top_parent && top_parent != disk->src &&
-         qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk,
+         qemuDomainPrepareDiskChainElement(driver, vm, vm->cgroup, disk,
                                            top_parent,
                                            VIR_DISK_CHAIN_READ_WRITE) < 0))
         goto endjob;
@@ -13505,15 +13402,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, vm->cgroup, disk, base_canon,
                                           VIR_DISK_CHAIN_READ_ONLY);
         if (top_parent && top_parent != disk->src)
-            qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk,
+            qemuDomainPrepareDiskChainElement(driver, vm, vm->cgroup, disk,
                                               top_parent,
                                               VIR_DISK_CHAIN_READ_ONLY);
     }
-    if (cgroup)
-        virCgroupFree(&cgroup);
     if (qemuDomainObjEndJob(driver, vm) == 0) {
         vm = NULL;
         goto cleanup;
@@ -14197,28 +14092,27 @@ 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;
-    virCgroupPtr group_vcpu = NULL;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
 
-    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 (!vm->vcpuCgroups[i]) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("error accessing cgroup cpuacct for vcpu"));
             goto cleanup;
         }
 
-        if (virCgroupGetCpuacctPercpuUsage(group_vcpu, &buf) < 0)
+        if (virCgroupGetCpuacctPercpuUsage(vm->vcpuCgroups[i], &buf) < 0)
             goto cleanup;
 
         pos = buf;
@@ -14231,13 +14125,11 @@ getSumVcpuPercpuStats(virCgroupPtr group,
             sum_cpu_time[j] += tmp;
         }
 
-        virCgroupFree(&group_vcpu);
         VIR_FREE(buf);
     }
 
     ret = 0;
 cleanup:
-    virCgroupFree(&group_vcpu);
     VIR_FREE(buf);
     return ret;
 }
@@ -14257,7 +14149,6 @@ qemuDomainGetPercpuStats(virDomainObjPtr vm,
     unsigned long long *sum_cpu_time = NULL;
     unsigned long long *sum_cpu_pos;
     unsigned int n = 0;
-    qemuDomainObjPrivatePtr priv = vm->privateData;
     virTypedParameterPtr ent;
     int param_idx;
     unsigned long long cpu_time;
@@ -14324,7 +14215,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;
@@ -14357,7 +14248,6 @@ qemuDomainGetCPUStats(virDomainPtr domain,
                 unsigned int flags)
 {
     virQEMUDriverPtr driver = domain->conn->privateData;
-    virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
     int ret = -1;
     bool isActive;
@@ -14386,19 +14276,18 @@ qemuDomainGetCPUStats(virDomainPtr domain,
         goto cleanup;
     }
 
-    if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+    if (!vm->cgroup) {
         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->cgroup, params, nparams);
     else
-        ret = qemuDomainGetPercpuStats(vm, group, params, nparams,
+        ret = qemuDomainGetPercpuStats(vm, vm->cgroup, params, nparams,
                                        start_cpu, ncpus);
 cleanup:
-    virCgroupFree(&group);
     if (vm)
         virObjectUnlock(vm);
     qemuDriverUnlock(driver);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 18c4109..21c3a0e 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1117,11 +1117,10 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
     }
 
     if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
-        virCgroupPtr cgroup = NULL;
         usbDevice *usb;
         qemuCgroupData data;
 
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
+        if (!vm->cgroup) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Unable to find cgroup for %s"),
                            vm->def->name);
@@ -1134,7 +1133,7 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
             goto error;
 
         data.vm = vm;
-        data.cgroup = cgroup;
+        data.cgroup = vm->cgroup;
         if (usbDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, &data) < 0)
             goto error;
     }
@@ -2005,7 +2004,6 @@ int qemuDomainDetachPciDiskDevice(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);
@@ -2026,7 +2024,7 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver,
     }
 
     if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
+        if (!vm->cgroup) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Unable to find cgroup for %s"),
                            vm->def->name);
@@ -2087,8 +2085,8 @@ int qemuDomainDetachPciDiskDevice(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)
+    if (vm->cgroup != NULL) {
+        if (qemuTeardownDiskCgroup(vm, vm->cgroup, dev->data.disk) < 0)
             VIR_WARN("Failed to teardown cgroup for disk path %s",
                      NULLSTR(dev->data.disk->src));
     }
@@ -2099,7 +2097,6 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver,
     ret = 0;
 
 cleanup:
-    virCgroupFree(&cgroup);
     VIR_FREE(drivestr);
     return ret;
 }
@@ -2111,7 +2108,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);
@@ -2139,7 +2135,7 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
     }
 
     if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
-        if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
+        if (!vm->cgroup) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Unable to find cgroup for %s"),
                            vm->def->name);
@@ -2179,8 +2175,8 @@ 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)
+    if (vm->cgroup != NULL) {
+        if (qemuTeardownDiskCgroup(vm, vm->cgroup, dev->data.disk) < 0)
             VIR_WARN("Failed to teardown cgroup for disk path %s",
                      NULLSTR(dev->data.disk->src));
     }
@@ -2192,7 +2188,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 d03e361..d7992a3 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3591,7 +3591,6 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
                     enum qemuDomainAsyncJob asyncJob)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    virCgroupPtr cgroup = NULL;
     int ret = -1;
     int rc;
     bool restoreLabel = false;
@@ -3626,20 +3625,16 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
          * that botches pclose.  */
         if (qemuCgroupControllerActive(driver,
                                        VIR_CGROUP_CONTROLLER_DEVICES)) {
-            if (virCgroupForDomain(driver->cgroup, vm->def->name,
-                                   &cgroup, 0) != 0) {
+            if (!vm->cgroup) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("Unable to find cgroup for %s"),
                                vm->def->name);
                 goto cleanup;
             }
-            rc = virCgroupAllowDevicePath(cgroup, path,
+            rc = virCgroupAllowDevicePath(vm->cgroup, path,
                                           VIR_CGROUP_DEVICE_RW);
-            virDomainAuditCgroupPath(vm, cgroup, "allow", path, "rw", rc);
-            if (rc == 1) {
-                /* path was not a device, no further need for cgroup */
-                virCgroupFree(&cgroup);
-            } else if (rc < 0) {
+            virDomainAuditCgroupPath(vm, vm->cgroup, "allow", path, "rw", rc);
+            if (rc < 0) {
                 virReportSystemError(-rc,
                                      _("Unable to allow device %s for %s"),
                                      path, vm->def->name);
@@ -3733,14 +3728,13 @@ cleanup:
                                                  vm->def, path) < 0)
         VIR_WARN("failed to restore save state label on %s", path);
 
-    if (cgroup != NULL) {
-        rc = virCgroupDenyDevicePath(cgroup, path,
+    if (vm->cgroup != NULL) {
+        rc = virCgroupDenyDevicePath(vm->cgroup, path,
                                      VIR_CGROUP_DEVICE_RWM);
-        virDomainAuditCgroupPath(vm, cgroup, "deny", path, "rwm", rc);
+        virDomainAuditCgroupPath(vm, vm->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 a2ce007..efd9777 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2716,7 +2716,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
@@ -3603,11 +3603,6 @@ 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);
-
     for (i = 0 ; i < vm->def->ngraphics; ++i) {
         virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
         if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
-- 
1.8.0.1.240.ge8a1f5a


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