From: "Daniel P. Berrange" <berrange(a)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(a)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