提交 9ddfe7ee 编写于 作者: D Daniel P. Berrange

Ensure all cgroup partitions have a suffix of ".partition"

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: NDaniel P. Berrange <berrange@redhat.com>
上级 824e86e7
......@@ -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;
}
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册