[libvirt] [PATCH 05/13] Auto-detect existing cgroup placement

Daniel P. Berrange berrange at redhat.com
Tue Jul 23 15:21:10 UTC 2013


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

Use the new virCgroupNewDetect function to determine cgroup
placement of existing running VMs. This will allow the legacy
cgroups creation APIs to be removed entirely

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/lxc/lxc_cgroup.c    |  59 ++++++++++----------------
 src/lxc/lxc_cgroup.h    |   2 +-
 src/lxc/lxc_process.c   |  14 ++++++-
 src/qemu/qemu_cgroup.c  | 107 ++++++++++++++++++++++++++++--------------------
 src/qemu/qemu_cgroup.h  |   5 +--
 src/qemu/qemu_process.c |   2 +-
 6 files changed, 100 insertions(+), 89 deletions(-)

diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 025720d..c230c25 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -429,12 +429,12 @@ cleanup:
 }
 
 
-virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, bool startup)
+virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def)
 {
     virCgroupPtr parent = NULL;
     virCgroupPtr cgroup = NULL;
 
-    if (!def->resource && startup) {
+    if (!def->resource) {
         virDomainResourceDefPtr res;
 
         if (VIR_ALLOC(res) < 0)
@@ -448,41 +448,26 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, bool startup)
         def->resource = res;
     }
 
-    if (def->resource &&
-        def->resource->partition) {
-        if (def->resource->partition[0] != '/') {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("Resource partition '%s' must start with '/'"),
-                           def->resource->partition);
-            goto cleanup;
-        }
-        /* We only auto-create the default partition. In other
-         * cases we expec the sysadmin/app to have done so */
-        if (virCgroupNewPartition(def->resource->partition,
-                                  STREQ(def->resource->partition, "/machine"),
-                                  -1,
-                                  &parent) < 0)
-            goto cleanup;
-
-        if (virCgroupNewDomainPartition(parent,
-                                        "lxc",
-                                        def->name,
-                                        true,
-                                        &cgroup) < 0)
-            goto cleanup;
-    } else {
-        if (virCgroupNewDriver("lxc",
-                               true,
-                               -1,
-                               &parent) < 0)
-            goto cleanup;
-
-        if (virCgroupNewDomainDriver(parent,
-                                     def->name,
-                                     true,
-                                     &cgroup) < 0)
-            goto cleanup;
+    if (def->resource->partition[0] != '/') {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Resource partition '%s' must start with '/'"),
+                       def->resource->partition);
+        goto cleanup;
     }
+    /* We only auto-create the default partition. In other
+     * cases we expec the sysadmin/app to have done so */
+    if (virCgroupNewPartition(def->resource->partition,
+                              STREQ(def->resource->partition, "/machine"),
+                              -1,
+                              &parent) < 0)
+        goto cleanup;
+
+    if (virCgroupNewDomainPartition(parent,
+                                    "lxc",
+                                    def->name,
+                                    true,
+                                    &cgroup) < 0)
+        goto cleanup;
 
 cleanup:
     virCgroupFree(&parent);
@@ -495,7 +480,7 @@ virCgroupPtr virLXCCgroupJoin(virDomainDefPtr def)
     virCgroupPtr cgroup = NULL;
     int ret = -1;
 
-    if (!(cgroup = virLXCCgroupCreate(def, true)))
+    if (!(cgroup = virLXCCgroupCreate(def)))
         return NULL;
 
     if (virCgroupAddTask(cgroup, getpid()) < 0)
diff --git a/src/lxc/lxc_cgroup.h b/src/lxc/lxc_cgroup.h
index f040de2..25a427c 100644
--- a/src/lxc/lxc_cgroup.h
+++ b/src/lxc/lxc_cgroup.h
@@ -27,7 +27,7 @@
 # include "lxc_fuse.h"
 # include "virusb.h"
 
-virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, bool startup);
+virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def);
 virCgroupPtr virLXCCgroupJoin(virDomainDefPtr def);
 int virLXCCgroupSetup(virDomainDefPtr def,
                       virCgroupPtr cgroup,
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 5b83ccb..3642945 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -974,7 +974,7 @@ int virLXCProcessStart(virConnectPtr conn,
 
     virCgroupFree(&priv->cgroup);
 
-    if (!(priv->cgroup = virLXCCgroupCreate(vm->def, true)))
+    if (!(priv->cgroup = virLXCCgroupCreate(vm->def)))
         return -1;
 
     if (!virCgroupHasController(priv->cgroup,
@@ -1385,9 +1385,19 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm,
         if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
             goto error;
 
-        if (!(priv->cgroup = virLXCCgroupCreate(vm->def, false)))
+        if (virCgroupNewDetect(vm->pid, &priv->cgroup) < 0)
             goto error;
 
+        if (!virCgroupIsValidMachineGroup(priv->cgroup,
+                                          vm->def->name,
+                                          "lxc")) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Cgroup name is not valid for machine %s"),
+                           vm->def->name);
+            virCgroupFree(&priv->cgroup);
+            goto error;
+        }
+
         if (virLXCUpdateActiveUsbHostdevs(driver, vm->def) < 0)
             goto error;
 
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 02d2770..8559d26 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -627,10 +627,9 @@ qemuSetupCpuCgroup(virDomainObjPtr vm)
 }
 
 
-int
+static int
 qemuInitCgroup(virQEMUDriverPtr driver,
-               virDomainObjPtr vm,
-               bool startup)
+               virDomainObjPtr vm)
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -645,7 +644,7 @@ qemuInitCgroup(virQEMUDriverPtr driver,
 
     virCgroupFree(&priv->cgroup);
 
-    if (!vm->def->resource && startup) {
+    if (!vm->def->resource) {
         virDomainResourceDefPtr res;
 
         if (VIR_ALLOC(res) < 0)
@@ -659,59 +658,77 @@ qemuInitCgroup(virQEMUDriverPtr driver,
         vm->def->resource = res;
     }
 
-    if (vm->def->resource &&
-        vm->def->resource->partition) {
-        if (vm->def->resource->partition[0] != '/') {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("Resource partition '%s' must start with '/'"),
-                           vm->def->resource->partition);
-            goto cleanup;
-        }
-        /* We only auto-create the default partition. In other
-         * cases we expec the sysadmin/app to have done so */
-        if (virCgroupNewPartition(vm->def->resource->partition,
-                                  STREQ(vm->def->resource->partition, "/machine"),
-                                  cfg->cgroupControllers,
-                                  &parent) < 0) {
-            if (virCgroupNewIgnoreError())
-                goto done;
+    if (vm->def->resource->partition[0] != '/') {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Resource partition '%s' must start with '/'"),
+                       vm->def->resource->partition);
+        goto cleanup;
+    }
+    /* We only auto-create the default partition. In other
+     * cases we expec the sysadmin/app to have done so */
+    if (virCgroupNewPartition(vm->def->resource->partition,
+                              STREQ(vm->def->resource->partition, "/machine"),
+                              cfg->cgroupControllers,
+                              &parent) < 0) {
+        if (virCgroupNewIgnoreError())
+            goto done;
 
-            goto cleanup;
-        }
+        goto cleanup;
+    }
 
-        if (virCgroupNewDomainPartition(parent,
-                                        "qemu",
-                                        vm->def->name,
-                                        true,
-                                        &priv->cgroup) < 0)
-            goto cleanup;
-    } else {
-        if (virCgroupNewDriver("qemu",
-                               true,
-                               cfg->cgroupControllers,
-                               &parent) < 0) {
-            if (virCgroupNewIgnoreError())
-                goto done;
+    if (virCgroupNewDomainPartition(parent,
+                                    "qemu",
+                                    vm->def->name,
+                                    true,
+                                    &priv->cgroup) < 0)
+        goto cleanup;
 
-            goto cleanup;
-        }
+done:
+    ret = 0;
+cleanup:
+    virCgroupFree(&parent);
+    virObjectUnref(cfg);
+    return ret;
+}
 
-        if (virCgroupNewDomainDriver(parent,
-                                     vm->def->name,
-                                     true,
-                                     &priv->cgroup) < 0)
-            goto cleanup;
+
+int
+qemuConnectCgroup(virQEMUDriverPtr driver,
+                  virDomainObjPtr vm)
+{
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int ret = -1;
+
+    if (!cfg->privileged)
+        goto done;
+
+    if (!virCgroupAvailable())
+        goto done;
+
+    virCgroupFree(&priv->cgroup);
+
+    if (virCgroupNewDetect(vm->pid, &priv->cgroup) < 0) {
+        if (virCgroupNewIgnoreError())
+            goto done;
+        goto cleanup;
+    }
+
+    if (!virCgroupIsValidMachineGroup(priv->cgroup,
+                                      vm->def->name,
+                                      "qemu")) {
+        VIR_DEBUG("Cgroup name is not valid for machine");
+        virCgroupFree(&priv->cgroup);
+        goto done;
     }
 
 done:
     ret = 0;
 cleanup:
-    virCgroupFree(&parent);
     virObjectUnref(cfg);
     return ret;
 }
 
-
 int
 qemuSetupCgroup(virQEMUDriverPtr driver,
                 virDomainObjPtr vm,
@@ -721,7 +738,7 @@ qemuSetupCgroup(virQEMUDriverPtr driver,
     virCapsPtr caps = NULL;
     int ret = -1;
 
-    if (qemuInitCgroup(driver, vm, true) < 0)
+    if (qemuInitCgroup(driver, vm) < 0)
         return -1;
 
     if (!priv->cgroup)
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
index 5faa5f9..14404d1 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -39,9 +39,8 @@ int qemuSetupHostdevCGroup(virDomainObjPtr vm,
 int qemuTeardownHostdevCgroup(virDomainObjPtr vm,
                               virDomainHostdevDefPtr dev)
    ATTRIBUTE_RETURN_CHECK;
-int qemuInitCgroup(virQEMUDriverPtr driver,
-                   virDomainObjPtr vm,
-                   bool startup);
+int qemuConnectCgroup(virQEMUDriverPtr driver,
+                      virDomainObjPtr vm);
 int qemuSetupCgroup(virQEMUDriverPtr driver,
                     virDomainObjPtr vm,
                     virBitmapPtr nodemask);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a46d944..c5f281a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3070,7 +3070,7 @@ qemuProcessReconnect(void *opaque)
     if (qemuUpdateActiveScsiHostdevs(driver, obj->def) < 0)
         goto error;
 
-    if (qemuInitCgroup(driver, obj, false) < 0)
+    if (qemuConnectCgroup(driver, obj) < 0)
         goto error;
 
     /* XXX: Need to change as long as lock is introduced for
-- 
1.8.1.4




More information about the libvir-list mailing list