[libvirt] [PATCH 2/3] Ensure all cgroup partitions have a suffix of ".partition"

Daniel P. Berrange berrange at redhat.com
Fri Apr 26 10:45:47 UTC 2013


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

If the partition named passed in the XML does not already have
a suffix, ensure it gets a '.partition' added to each component.
The exceptions are /machine, /user and /system which do not need
to have a suffix, since they are fixed partitions at the top
level.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/util/vircgroup.c  |  57 +++++++++++++++++++++--
 tests/vircgrouptest.c | 123 ++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 143 insertions(+), 37 deletions(-)

diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 0084aea..297408d 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -49,6 +49,7 @@
 #include "virfile.h"
 #include "virhash.h"
 #include "virhashcode.h"
+#include "virstring.h"
 
 #define CGROUP_MAX_VAL 512
 
@@ -1091,6 +1092,47 @@ cleanup:
 
 
 #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
+static char *virCgroupSetPartitionSuffix(const char *path)
+{
+    char **tokens = virStringSplit(path, "/", 0);
+    size_t i;
+    char *ret = NULL;
+
+    if (!tokens)
+        return NULL;
+
+    for (i = 0 ; tokens[i] != NULL ; i++) {
+        /* Whitelist the 3 top level fixed dirs
+         * NB i == 0 is "", since we have leading '/'
+         */
+        if (i == 1 &&
+            (STREQ(tokens[i], "machine") ||
+             STREQ(tokens[i], "system") ||
+             STREQ(tokens[i], "user"))) {
+            continue;
+        }
+        /* If there is no suffix set already, then
+         * add ".partition"
+         */
+        if (STRNEQ(tokens[i], "") &&
+            !strchr(tokens[i], '.')) {
+            if (VIR_REALLOC_N(tokens[i],
+                              strlen(tokens[i]) + strlen(".partition") + 1) < 0) {
+                virReportOOMError();
+                goto cleanup;
+            }
+            strcat(tokens[i], ".partition");
+        }
+    }
+
+    if (!(ret = virStringJoin((const char **)tokens, "/")))
+        goto cleanup;
+
+cleanup:
+    virStringFreeList(tokens);
+    return ret;
+}
+
 /**
  * virCgroupNewPartition:
  * @path: path for the partition
@@ -1110,19 +1152,28 @@ int virCgroupNewPartition(const char *path,
     int rc;
     char *parentPath = NULL;
     virCgroupPtr parent = NULL;
+    char *newpath;
     VIR_DEBUG("path=%s create=%d controllers=%x",
               path, create, controllers);
 
     if (path[0] != '/')
         return -EINVAL;
 
-    rc = virCgroupNew(path, NULL, controllers, group);
+    /* XXX convert all cgroups APIs to use error report
+     * APIs instead of returning errno */
+    if (!(newpath = virCgroupSetPartitionSuffix(path))) {
+        virResetLastError();
+        rc = -ENOMEM;
+        goto cleanup;
+    }
+
+    rc = virCgroupNew(newpath, NULL, controllers, group);
     if (rc != 0)
         goto cleanup;
 
-    if (STRNEQ(path, "/")) {
+    if (STRNEQ(newpath, "/")) {
         char *tmp;
-        if (!(parentPath = strdup(path))) {
+        if (!(parentPath = strdup(newpath))) {
             rc = -ENOMEM;
             goto cleanup;
         }
diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
index 9c2590f..b51106a 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -246,22 +246,22 @@ static int testCgroupNewForPartition(const void *args ATTRIBUTE_UNUSED)
     int ret = -1;
     int rv;
     const char *placementSmall[VIR_CGROUP_CONTROLLER_LAST] = {
-        [VIR_CGROUP_CONTROLLER_CPU] = "/virtualmachines",
-        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/virtualmachines",
+        [VIR_CGROUP_CONTROLLER_CPU] = "/virtualmachines.partition",
+        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/virtualmachines.partition",
         [VIR_CGROUP_CONTROLLER_CPUSET] = NULL,
-        [VIR_CGROUP_CONTROLLER_MEMORY] = "/virtualmachines",
+        [VIR_CGROUP_CONTROLLER_MEMORY] = "/virtualmachines.partition",
         [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
         [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
         [VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
     };
     const char *placementFull[VIR_CGROUP_CONTROLLER_LAST] = {
-        [VIR_CGROUP_CONTROLLER_CPU] = "/virtualmachines",
-        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/virtualmachines",
-        [VIR_CGROUP_CONTROLLER_CPUSET] = "/virtualmachines",
-        [VIR_CGROUP_CONTROLLER_MEMORY] = "/virtualmachines",
+        [VIR_CGROUP_CONTROLLER_CPU] = "/virtualmachines.partition",
+        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/virtualmachines.partition",
+        [VIR_CGROUP_CONTROLLER_CPUSET] = "/virtualmachines.partition",
+        [VIR_CGROUP_CONTROLLER_MEMORY] = "/virtualmachines.partition",
         [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
-        [VIR_CGROUP_CONTROLLER_FREEZER] = "/virtualmachines",
-        [VIR_CGROUP_CONTROLLER_BLKIO] = "/virtualmachines",
+        [VIR_CGROUP_CONTROLLER_FREEZER] = "/virtualmachines.partition",
+        [VIR_CGROUP_CONTROLLER_BLKIO] = "/virtualmachines.partition",
     };
 
     if ((rv = virCgroupNewPartition("/virtualmachines", false, -1, &cgroup)) != -ENOENT) {
@@ -294,14 +294,14 @@ static int testCgroupNewForPartition(const void *args ATTRIBUTE_UNUSED)
         fprintf(stderr, "Cannot create /virtualmachines cgroup: %d\n", -rv);
         goto cleanup;
     }
-    ret = validateCgroup(cgroup, "/virtualmachines", mountsSmall, links, placementSmall);
+    ret = validateCgroup(cgroup, "/virtualmachines.partition", mountsSmall, links, placementSmall);
     virCgroupFree(&cgroup);
 
     if ((rv = virCgroupNewPartition("/virtualmachines", true, -1, &cgroup)) != 0) {
         fprintf(stderr, "Cannot create /virtualmachines cgroup: %d\n", -rv);
         goto cleanup;
     }
-    ret = validateCgroup(cgroup, "/virtualmachines", mountsFull, links, placementFull);
+    ret = validateCgroup(cgroup, "/virtualmachines.partition", mountsFull, links, placementFull);
 
 cleanup:
     virCgroupFree(&cgroup);
@@ -315,38 +315,90 @@ static int testCgroupNewForPartitionNested(const void *args ATTRIBUTE_UNUSED)
     int ret = -1;
     int rv;
     const char *placementFull[VIR_CGROUP_CONTROLLER_LAST] = {
-        [VIR_CGROUP_CONTROLLER_CPU] = "/users/berrange",
-        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/users/berrange",
-        [VIR_CGROUP_CONTROLLER_CPUSET] = "/users/berrange",
-        [VIR_CGROUP_CONTROLLER_MEMORY] = "/users/berrange",
+        [VIR_CGROUP_CONTROLLER_CPU] = "/deployment.partition/production.partition",
+        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/deployment.partition/production.partition",
+        [VIR_CGROUP_CONTROLLER_CPUSET] = "/deployment.partition/production.partition",
+        [VIR_CGROUP_CONTROLLER_MEMORY] = "/deployment.partition/production.partition",
         [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
-        [VIR_CGROUP_CONTROLLER_FREEZER] = "/users/berrange",
-        [VIR_CGROUP_CONTROLLER_BLKIO] = "/users/berrange",
+        [VIR_CGROUP_CONTROLLER_FREEZER] = "/deployment.partition/production.partition",
+        [VIR_CGROUP_CONTROLLER_BLKIO] = "/deployment.partition/production.partition",
     };
 
-    if ((rv = virCgroupNewPartition("/users/berrange", false, -1, &cgroup)) != -ENOENT) {
-        fprintf(stderr, "Unexpected found /users/berrange cgroup: %d\n", -rv);
+    if ((rv = virCgroupNewPartition("/deployment/production", false, -1, &cgroup)) != -ENOENT) {
+        fprintf(stderr, "Unexpected found /deployment/production cgroup: %d\n", -rv);
         goto cleanup;
     }
 
-    /* Should not work, since we require /users to be pre-created */
-    if ((rv = virCgroupNewPartition("/users/berrange", true, -1, &cgroup)) != -ENOENT) {
-        fprintf(stderr, "Unexpected created /users/berrange cgroup: %d\n", -rv);
+    /* Should not work, since we require /deployment to be pre-created */
+    if ((rv = virCgroupNewPartition("/deployment/production", true, -1, &cgroup)) != -ENOENT) {
+        fprintf(stderr, "Unexpected created /deployment/production cgroup: %d\n", -rv);
         goto cleanup;
     }
 
-    if ((rv = virCgroupNewPartition("/users", true, -1, &cgroup)) != 0) {
-        fprintf(stderr, "Failed to create /users cgroup: %d\n", -rv);
+    if ((rv = virCgroupNewPartition("/deployment", true, -1, &cgroup)) != 0) {
+        fprintf(stderr, "Failed to create /deployment cgroup: %d\n", -rv);
         goto cleanup;
     }
 
     /* Should now work */
-    if ((rv = virCgroupNewPartition("/users/berrange", true, -1, &cgroup)) != 0) {
-        fprintf(stderr, "Failed to create /users/berrange cgroup: %d\n", -rv);
+    if ((rv = virCgroupNewPartition("/deployment/production", true, -1, &cgroup)) != 0) {
+        fprintf(stderr, "Failed to create /deployment/production cgroup: %d\n", -rv);
         goto cleanup;
     }
 
-    ret = validateCgroup(cgroup, "/users/berrange", mountsFull, links, placementFull);
+    ret = validateCgroup(cgroup, "/deployment.partition/production.partition",
+                         mountsFull, links, placementFull);
+
+cleanup:
+    virCgroupFree(&cgroup);
+    return ret;
+}
+
+
+static int testCgroupNewForPartitionNestedDeep(const void *args ATTRIBUTE_UNUSED)
+{
+    virCgroupPtr cgroup = NULL;
+    int ret = -1;
+    int rv;
+    const char *placementFull[VIR_CGROUP_CONTROLLER_LAST] = {
+        [VIR_CGROUP_CONTROLLER_CPU] = "/user/berrange.user/production.partition",
+        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/user/berrange.user/production.partition",
+        [VIR_CGROUP_CONTROLLER_CPUSET] = "/user/berrange.user/production.partition",
+        [VIR_CGROUP_CONTROLLER_MEMORY] = "/user/berrange.user/production.partition",
+        [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
+        [VIR_CGROUP_CONTROLLER_FREEZER] = "/user/berrange.user/production.partition",
+        [VIR_CGROUP_CONTROLLER_BLKIO] = "/user/berrange.user/production.partition",
+    };
+
+    if ((rv = virCgroupNewPartition("/user/berrange.user/production", false, -1, &cgroup)) != -ENOENT) {
+        fprintf(stderr, "Unexpected found /user/berrange.user/production cgroup: %d\n", -rv);
+        goto cleanup;
+    }
+
+    /* Should not work, since we require /user/berrange.user to be pre-created */
+    if ((rv = virCgroupNewPartition("/user/berrange.user/production", true, -1, &cgroup)) != -ENOENT) {
+        fprintf(stderr, "Unexpected created /user/berrange.user/production cgroup: %d\n", -rv);
+        goto cleanup;
+    }
+
+    if ((rv = virCgroupNewPartition("/user", true, -1, &cgroup)) != 0) {
+        fprintf(stderr, "Failed to create /user/berrange.user cgroup: %d\n", -rv);
+        goto cleanup;
+    }
+
+    if ((rv = virCgroupNewPartition("/user/berrange.user", true, -1, &cgroup)) != 0) {
+        fprintf(stderr, "Failed to create /user/berrange.user cgroup: %d\n", -rv);
+        goto cleanup;
+    }
+
+    /* Should now work */
+    if ((rv = virCgroupNewPartition("/user/berrange.user/production", true, -1, &cgroup)) != 0) {
+        fprintf(stderr, "Failed to create /user/berrange.user/production cgroup: %d\n", -rv);
+        goto cleanup;
+    }
+
+    ret = validateCgroup(cgroup, "/user/berrange.user/production.partition",
+                         mountsFull, links, placementFull);
 
 cleanup:
     virCgroupFree(&cgroup);
@@ -362,13 +414,13 @@ static int testCgroupNewForPartitionDomain(const void *args ATTRIBUTE_UNUSED)
     int ret = -1;
     int rv;
     const char *placement[VIR_CGROUP_CONTROLLER_LAST] = {
-        [VIR_CGROUP_CONTROLLER_CPU] = "/production/foo.libvirt-lxc",
-        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/production/foo.libvirt-lxc",
-        [VIR_CGROUP_CONTROLLER_CPUSET] = "/production/foo.libvirt-lxc",
-        [VIR_CGROUP_CONTROLLER_MEMORY] = "/production/foo.libvirt-lxc",
+        [VIR_CGROUP_CONTROLLER_CPU] = "/production.partition/foo.libvirt-lxc",
+        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/production.partition/foo.libvirt-lxc",
+        [VIR_CGROUP_CONTROLLER_CPUSET] = "/production.partition/foo.libvirt-lxc",
+        [VIR_CGROUP_CONTROLLER_MEMORY] = "/production.partition/foo.libvirt-lxc",
         [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
-        [VIR_CGROUP_CONTROLLER_FREEZER] = "/production/foo.libvirt-lxc",
-        [VIR_CGROUP_CONTROLLER_BLKIO] = "/production/foo.libvirt-lxc",
+        [VIR_CGROUP_CONTROLLER_FREEZER] = "/production.partition/foo.libvirt-lxc",
+        [VIR_CGROUP_CONTROLLER_BLKIO] = "/production.partition/foo.libvirt-lxc",
     };
 
     if ((rv = virCgroupNewPartition("/production", true, -1, &partitioncgroup)) != 0) {
@@ -381,7 +433,7 @@ static int testCgroupNewForPartitionDomain(const void *args ATTRIBUTE_UNUSED)
         goto cleanup;
     }
 
-    ret = validateCgroup(domaincgroup, "/production/foo.libvirt-lxc", mountsFull, links, placement);
+    ret = validateCgroup(domaincgroup, "/production.partition/foo.libvirt-lxc", mountsFull, links, placement);
 
 cleanup:
     virCgroupFree(&partitioncgroup);
@@ -424,6 +476,9 @@ mymain(void)
     if (virtTestRun("New cgroup for partition nested", 1, testCgroupNewForPartitionNested, NULL) < 0)
         ret = -1;
 
+    if (virtTestRun("New cgroup for partition nested deeply", 1, testCgroupNewForPartitionNestedDeep, NULL) < 0)
+        ret = -1;
+
     if (virtTestRun("New cgroup for domain partition", 1, testCgroupNewForPartitionDomain, NULL) < 0)
         ret = -1;
 
-- 
1.8.1.4




More information about the libvir-list mailing list