]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Auto-detect existing cgroup placement
authorDaniel P. Berrange <berrange@redhat.com>
Mon, 22 Jul 2013 12:59:28 +0000 (13:59 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 23 Jul 2013 21:46:31 +0000 (22:46 +0100)
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@redhat.com>
src/lxc/lxc_cgroup.c
src/lxc/lxc_cgroup.h
src/lxc/lxc_process.c
src/qemu/qemu_cgroup.c
src/qemu/qemu_cgroup.h
src/qemu/qemu_process.c

index 025720dff75bb42f9fc67212181a4f7671edf8f9..d9e9e0d4c68fac4be9ee6040b53c7d8169104159 100644 (file)
@@ -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 expect 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)
index f040de229d2dc1d86865397ed4c5fffe25a2ba2d..25a427c546b0c460159fa9a4357e7de09f8dd7f7 100644 (file)
@@ -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,
index 5b83ccbc902b3ac81e4b1665b3b6f9b2f7b6deb0..36429455ceacbfe91f5f3cd62fc69d4c58562409 100644 (file)
@@ -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;
 
index 02d2770af04d24dc541d509bf2ce4c95bc8d6243..61894900b7425262a52738b44b24dd831a9f745a 100644 (file)
@@ -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 expect 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)
index 5faa5f9528bda30981924d06dcd5f04196a6f777..14404d162518a889173066c8e6f16fdb77f7995d 100644 (file)
@@ -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);
index a46d944cb9f87eda17b696e3a75bd348a980efbb..c5f281a866924db9569ddc2625047276db5d5d4d 100644 (file)
@@ -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