---
src/libvirt_private.syms | 9 +-
src/util/vircgroup.c | 812 +++++++----------------------------------------
src/util/vircgroup.h | 25 +-
3 files changed, 112 insertions(+), 734 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f5138af..78e387d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -73,8 +73,6 @@ virCapabilitiesSetMacPrefix;
# cgroup.h
-virCgroup2Free;
-virCgroup2New;
virCgroupAddTask;
virCgroupAddTaskController;
virCgroupAllowDevice;
@@ -86,10 +84,6 @@ virCgroupDenyAllDevices;
virCgroupDenyDevice;
virCgroupDenyDeviceMajor;
virCgroupDenyDevicePath;
-virCgroupForDomain;
-virCgroupForDriver;
-virCgroupForEmulator;
-virCgroupForVcpu;
virCgroupFree;
virCgroupGetAppRoot;
virCgroupGetBlkioWeight;
@@ -110,10 +104,11 @@ virCgroupGetMemSwapUsage;
virCgroupKill;
virCgroupKillPainfully;
virCgroupKillRecursive;
+virCgroupMakePath;
virCgroupMounted;
virCgroupMoveTask;
+virCgroupNew;
virCgroupPathOfController;
-virCgroupRemove;
virCgroupSetBlkioDeviceWeight;
virCgroupSetBlkioWeight;
virCgroupSetCpuCfsPeriod;
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index dbc9688..90ff97c 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -80,7 +80,7 @@ struct _virCgroupItem {
struct virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST];
};
-struct virCgroup2 {
+struct virCgroup {
virCgroupItemPtr items[VIR_CGROUP_CONTROLLER_LAST];
};
@@ -145,12 +145,6 @@ static int virCgroupControllersInit(struct virCgroupController
(*controllers)[VI
return rc;
}
-struct virCgroup {
- char *path;
-
- struct virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST];
-};
-
typedef enum {
VIR_CGROUP_NONE = 0, /* create subdir under each cgroup if possible. */
VIR_CGROUP_MEM_HIERACHY = 1 << 0, /* call virCgroupSetMemoryUseHierarchy
@@ -447,9 +441,21 @@ static int virCgroupItemKeyPath(virCgroupItemPtr cgroupItem,
return ret;
}
-int virCgroup2New(const char *name, virCgroup2Ptr parent, virCgroup2Ptr *cgroup)
+int virCgroupMakePath(virCgroupPtr cgroup)
{
- virCgroup2Ptr newCgroup = NULL;
+ int i;
+
+ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
+ if (virCgroupItemPath(cgroup->items[i], true, NULL) != 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+int virCgroupNew(const char *name, virCgroupPtr parent, virCgroupPtr *cgroup)
+{
+ virCgroupPtr newCgroup = NULL;
virCgroupItemPtr *parentCgroupItems;
int ret = -1;
int i = 0;
@@ -502,40 +508,24 @@ error:
return ret;
}
-void virCgroup2Free(virCgroup2Ptr *cgroup)
-{
- int i;
-
- if (!cgroup || !*cgroup)
- return;
-
- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
- virCgroupItemFree(&(*cgroup)->items[i]);
- }
-
- VIR_FREE(*cgroup);
- *cgroup = NULL;
-}
-
/**
* virCgroupFree:
*
* @group: The group structure to free
*/
-void virCgroupFree(virCgroupPtr *group)
+void virCgroupFree(virCgroupPtr *cgroup)
{
int i;
- if (*group == NULL)
+ if (!cgroup || !*cgroup)
return;
- for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
- VIR_FREE((*group)->controllers[i].mountPoint);
- VIR_FREE((*group)->controllers[i].placement);
+ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
+ virCgroupItemFree(&(*cgroup)->items[i]);
}
- VIR_FREE((*group)->path);
- VIR_FREE(*group);
+ VIR_FREE(*cgroup);
+ *cgroup = NULL;
}
/**
@@ -546,9 +536,13 @@ void virCgroupFree(virCgroupPtr *group)
*
* Returns true if a cgroup is subsystem is mounted.
*/
-bool virCgroupMounted(virCgroupPtr cgroup, int controller)
+bool virCgroupMounted(virCgroupPtr cgroup ATTRIBUTE_UNUSED,
+ int controller)
{
- return cgroup->controllers[controller].mountPoint != NULL;
+ if (rootCgroupItems[controller] &&
+ rootCgroupItems[controller]->controllers[controller].mountPoint)
+ return true;
+ return false;
}
#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
@@ -675,58 +669,8 @@ no_memory:
}
-
-static int virCgroupDetect(virCgroupPtr group)
-{
- int any = 0;
- int rc;
- int i;
-
- rc = virCgroupDetectMounts(&group->controllers);
- if (rc < 0) {
- VIR_ERROR(_("Failed to detect mounts for %s"), group->path);
- return rc;
- }
-
- /* Check that at least 1 controller is available */
- for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
- if (group->controllers[i].mountPoint != NULL)
- any = 1;
- }
- if (!any)
- return -ENXIO;
-
-
- rc = virCgroupDetectPlacement(&group->controllers);
-
- if (rc == 0) {
- /* Check that for every mounted controller, we found our placement */
- for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
- if (!group->controllers[i].mountPoint)
- continue;
-
- if (!group->controllers[i].placement) {
- VIR_ERROR(_("Could not find placement for controller %s at
%s"),
- virCgroupControllerTypeToString(i),
- group->controllers[i].placement);
- rc = -ENOENT;
- break;
- }
-
- VIR_DEBUG("Detected mount/mapping %i:%s at %s in %s", i,
- virCgroupControllerTypeToString(i),
- group->controllers[i].mountPoint,
- group->controllers[i].placement);
- }
- } else {
- VIR_ERROR(_("Failed to detect mapping for %s"), group->path);
- }
-
- return rc;
-}
#endif
-
int virCgroupPathOfController(virCgroupPtr group,
int controller,
const char *key,
@@ -735,8 +679,7 @@ int virCgroupPathOfController(virCgroupPtr group,
if (controller == -1) {
int i;
for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
- if (group->controllers[i].mountPoint &&
- group->controllers[i].placement) {
+ if (virCgroupMounted(group, i)) {
controller = i;
break;
}
@@ -745,64 +688,22 @@ int virCgroupPathOfController(virCgroupPtr group,
if (controller == -1)
return -ENOSYS;
- if (group->controllers[controller].mountPoint == NULL)
- return -ENOENT;
-
- if (group->controllers[controller].placement == NULL)
- return -ENOENT;
-
- if (virAsprintf(path, "%s%s%s/%s",
- group->controllers[controller].mountPoint,
- group->controllers[controller].placement,
- STREQ(group->path, "/") ? "" :
group->path,
+ if (virAsprintf(path, "%s%s%s",
+ group->items[controller]->path,
+ key ? "/" : "",
key ? key : "") == -1)
return -ENOMEM;
return 0;
}
-static int virCgroup2SetValueStr(virCgroup2Ptr group,
- int controller,
- const char *key,
- const char *value)
-{
- return virCgroupItemSetValueStr(group->items[controller],
- key, value);
-}
-
-static int virCgroup2GetValueStr(virCgroup2Ptr group,
- int controller,
- const char *key,
- char **value)
-{
- return virCgroupItemGetValueStr(group->items[controller],
- key, value);
-}
-
static int virCgroupSetValueStr(virCgroupPtr group,
int controller,
const char *key,
const char *value)
{
- int rc = 0;
- char *keypath = NULL;
-
- rc = virCgroupPathOfController(group, controller, key, &keypath);
- if (rc != 0)
- return rc;
-
- VIR_DEBUG("Set value '%s' to '%s'", keypath, value);
- rc = virFileWriteStr(keypath, value, 0);
- if (rc < 0) {
- rc = -errno;
- VIR_DEBUG("Failed to write value '%s': %m", value);
- } else {
- rc = 0;
- }
-
- VIR_FREE(keypath);
-
- return rc;
+ return virCgroupItemSetValueStr(group->items[controller],
+ key, value);
}
static int virCgroupGetValueStr(virCgroupPtr group,
@@ -810,34 +711,8 @@ static int virCgroupGetValueStr(virCgroupPtr group,
const char *key,
char **value)
{
- int rc;
- char *keypath = NULL;
-
- *value = NULL;
-
- rc = virCgroupPathOfController(group, controller, key, &keypath);
- if (rc != 0) {
- VIR_DEBUG("No path of %s, %s", group->path, key);
- return rc;
- }
-
- VIR_DEBUG("Get value %s", keypath);
-
- rc = virFileReadAll(keypath, 1024*1024, value);
- if (rc < 0) {
- rc = -errno;
- VIR_DEBUG("Failed to read %s: %m\n", keypath);
- } else {
- /* Terminated with '\n' has sometimes harmful effects to the caller */
- if ((*value)[rc - 1] == '\n')
- (*value)[rc - 1] = '\0';
-
- rc = 0;
- }
-
- VIR_FREE(keypath);
-
- return rc;
+ return virCgroupItemGetValueStr(group->items[controller],
+ key, value);
}
static int virCgroupSetValueU64(virCgroupPtr group,
@@ -858,8 +733,6 @@ static int virCgroupSetValueU64(virCgroupPtr group,
return rc;
}
-
-
static int virCgroupSetValueI64(virCgroupPtr group,
int controller,
const char *key,
@@ -919,45 +792,6 @@ out:
}
#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
-static int virCgroupCpuSetInherit(virCgroupPtr parent, virCgroupPtr group)
-{
- int i;
- int rc = 0;
- const char *inherit_values[] = {
- "cpuset.cpus",
- "cpuset.mems",
- };
-
- VIR_DEBUG("Setting up inheritance %s -> %s", parent->path,
group->path);
- for (i = 0; i < ARRAY_CARDINALITY(inherit_values) ; i++) {
- char *value;
-
- rc = virCgroupGetValueStr(parent,
- VIR_CGROUP_CONTROLLER_CPUSET,
- inherit_values[i],
- &value);
- if (rc != 0) {
- VIR_ERROR(_("Failed to get %s %d"), inherit_values[i], rc);
- break;
- }
-
- VIR_DEBUG("Inherit %s = %s", inherit_values[i], value);
-
- rc = virCgroupSetValueStr(group,
- VIR_CGROUP_CONTROLLER_CPUSET,
- inherit_values[i],
- value);
- VIR_FREE(value);
-
- if (rc != 0) {
- VIR_ERROR(_("Failed to set %s %d"), inherit_values[i], rc);
- break;
- }
- }
-
- return rc;
-}
-
static int virCgroupItemCpusetInherit(virCgroupItemPtr cgroupItem)
{
int i;
@@ -993,36 +827,6 @@ static int virCgroupItemCpusetInherit(virCgroupItemPtr cgroupItem)
return rc;
}
-static int virCgroupSetMemoryUseHierarchy(virCgroupPtr group)
-{
- int rc = 0;
- unsigned long long value;
- const char *filename = "memory.use_hierarchy";
-
- rc = virCgroupGetValueU64(group,
- VIR_CGROUP_CONTROLLER_MEMORY,
- filename, &value);
- if (rc != 0) {
- VIR_ERROR(_("Failed to read %s/%s (%d)"), group->path, filename,
rc);
- return rc;
- }
-
- /* Setting twice causes error, so if already enabled, skip setting */
- if (value == 1)
- return 0;
-
- VIR_DEBUG("Setting up %s/%s", group->path, filename);
- rc = virCgroupSetValueU64(group,
- VIR_CGROUP_CONTROLLER_MEMORY,
- filename, 1);
-
- if (rc != 0) {
- VIR_ERROR(_("Failed to set %s/%s (%d)"), group->path, filename,
rc);
- }
-
- return rc;
-}
-
static int virCgroupItemSetMemoryUseHierarchy(virCgroupItemPtr item)
{
int rc = 0;
@@ -1055,163 +859,6 @@ out:
return rc;
}
-static int virCgroupMakeGroup(virCgroupPtr parent,
- virCgroupPtr group,
- bool create,
- unsigned int flags)
-{
- int i;
- int rc = 0;
-
- VIR_DEBUG("Make group %s", group->path);
- for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
- char *path = NULL;
-
- /* Skip over controllers that aren't mounted */
- if (!group->controllers[i].mountPoint)
- continue;
-
- /* We need to control cpu bandwidth for each vcpu now */
- if ((flags & VIR_CGROUP_VCPU) &&
- (i != VIR_CGROUP_CONTROLLER_CPU &&
- i != VIR_CGROUP_CONTROLLER_CPUACCT &&
- i != VIR_CGROUP_CONTROLLER_CPUSET)) {
- /* treat it as unmounted and we can use virCgroupAddTask */
- VIR_FREE(group->controllers[i].mountPoint);
- continue;
- }
-
- rc = virCgroupPathOfController(group, i, "", &path);
- if (rc < 0)
- return rc;
- /* As of Feb 2011, clang can't see that the above function
- * call did not modify group. */
- sa_assert(group->controllers[i].mountPoint);
-
- VIR_DEBUG("Make controller %s", path);
- if (access(path, F_OK) != 0) {
- if (!create ||
- mkdir(path, 0755) < 0) {
- /* With a kernel that doesn't support multi-level directory
- * for blkio controller, libvirt will fail and disable all
- * other controllers even though they are available. So
- * treat blkio as unmounted if mkdir fails. */
- if (i == VIR_CGROUP_CONTROLLER_BLKIO) {
- rc = 0;
- VIR_FREE(group->controllers[i].mountPoint);
- VIR_FREE(path);
- continue;
- } else {
- rc = -errno;
- VIR_FREE(path);
- break;
- }
- }
- if (group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint != NULL
&&
- (i == VIR_CGROUP_CONTROLLER_CPUSET ||
- STREQ(group->controllers[i].mountPoint,
group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint))) {
- rc = virCgroupCpuSetInherit(parent, group);
- if (rc != 0) {
- VIR_FREE(path);
- break;
- }
- }
- /*
- * Note that virCgroupSetMemoryUseHierarchy should always be
- * called prior to creating subcgroups and attaching tasks.
- */
- if ((flags & VIR_CGROUP_MEM_HIERACHY) &&
- (group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint != NULL)
&&
- (i == VIR_CGROUP_CONTROLLER_MEMORY ||
- STREQ(group->controllers[i].mountPoint,
group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint))) {
- rc = virCgroupSetMemoryUseHierarchy(group);
- if (rc != 0) {
- VIR_FREE(path);
- break;
- }
- }
- }
-
- VIR_FREE(path);
- }
-
- return rc;
-}
-
-
-static int virCgroupNew(const char *path,
- virCgroupPtr *group)
-{
- int rc = 0;
- char *typpath = NULL;
-
- VIR_DEBUG("New group %s", path);
- *group = NULL;
-
- if (VIR_ALLOC((*group)) != 0) {
- rc = -ENOMEM;
- goto err;
- }
-
- if (!((*group)->path = strdup(path))) {
- rc = -ENOMEM;
- goto err;
- }
-
- rc = virCgroupDetect(*group);
- if (rc < 0)
- goto err;
-
- return rc;
-err:
- virCgroupFree(group);
- *group = NULL;
-
- VIR_FREE(typpath);
-
- return rc;
-}
-
-static int virCgroupAppRoot(bool privileged,
- virCgroupPtr *group,
- bool create)
-{
- virCgroupPtr rootgrp = NULL;
- int rc;
-
- rc = virCgroupNew("/", &rootgrp);
- if (rc != 0)
- return rc;
-
- if (privileged) {
- rc = virCgroupNew("/libvirt", group);
- } else {
- char *rootname;
- char *username;
- username = virGetUserName(getuid());
- if (!username) {
- rc = -ENOMEM;
- goto cleanup;
- }
- rc = virAsprintf(&rootname, "/libvirt-%s", username);
- VIR_FREE(username);
- if (rc < 0) {
- rc = -ENOMEM;
- goto cleanup;
- }
-
- rc = virCgroupNew(rootname, group);
- VIR_FREE(rootname);
- }
- if (rc != 0)
- goto cleanup;
-
- rc = virCgroupMakeGroup(rootgrp, *group, create, VIR_CGROUP_NONE);
-
-cleanup:
- virCgroupFree(&rootgrp);
- return rc;
-}
#endif
#if defined _DIRENT_HAVE_D_TYPE
@@ -1272,43 +919,6 @@ static int virCgroupRemoveRecursively(char *grppath
ATTRIBUTE_UNUSED)
#endif
/**
- * virCgroupRemove:
- *
- * @group: The group to be removed
- *
- * It first removes all child groups recursively
- * in depth first order and then removes @group
- * because the presence of the child groups
- * prevents removing @group.
- *
- * Returns: 0 on success
- */
-int virCgroupRemove(virCgroupPtr group)
-{
- int rc = 0;
- int i;
- char *grppath = NULL;
-
- for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
- /* Skip over controllers not mounted */
- if (!group->controllers[i].mountPoint)
- continue;
-
- if (virCgroupPathOfController(group,
- i,
- NULL,
- &grppath) != 0)
- continue;
-
- VIR_DEBUG("Removing cgroup %s and all child cgroups", grppath);
- rc = virCgroupRemoveRecursively(grppath);
- VIR_FREE(grppath);
- }
-
- return rc;
-}
-
-/**
* virCgroupAddTask:
*
* @group: The cgroup to add a task to
@@ -1323,7 +933,7 @@ int virCgroupAddTask(virCgroupPtr group, pid_t pid)
for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
/* Skip over controllers not mounted */
- if (!group->controllers[i].mountPoint)
+ if (!virCgroupMounted(group, i))
continue;
rc = virCgroupSetValueU64(group, i, "tasks", (unsigned long long)pid);
@@ -1348,7 +958,7 @@ int virCgroupAddTaskController(virCgroupPtr group, pid_t pid, int
controller)
if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST)
return -EINVAL;
- if (!group->controllers[controller].mountPoint)
+ if (!virCgroupMounted(group, controller))
return -EINVAL;
return virCgroupSetValueU64(group, controller, "tasks",
@@ -1411,12 +1021,6 @@ int virCgroupMoveTask(virCgroupPtr src_group, virCgroupPtr
dest_group,
controller > VIR_CGROUP_CONTROLLER_BLKIO)
return -EINVAL;
- if (!src_group->controllers[controller].mountPoint ||
- !dest_group->controllers[controller].mountPoint) {
- VIR_WARN("no vm cgroup in controller %d", controller);
- return 0;
- }
-
rc = virCgroupGetValueStr(src_group, controller, "tasks", &content);
if (rc != 0)
return rc;
@@ -1437,226 +1041,39 @@ cleanup:
err = virCgroupAddTaskStrController(src_group, content, controller);
if (err != 0)
VIR_ERROR(_("Cannot recover cgroup %s from %s"),
- src_group->controllers[controller].mountPoint,
- dest_group->controllers[controller].mountPoint);
+ src_group->items[controller]->path,
+ dest_group->items[controller]->path);
VIR_FREE(content);
return rc;
}
-/**
- * virCgroupForDriver:
- *
- * @name: name of this driver (e.g., xen, qemu, lxc)
- * @group: Pointer to returned virCgroupPtr
- *
- * Returns 0 on success
- */
-#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
-int virCgroupForDriver(const char *name,
- virCgroupPtr *group,
- bool privileged,
- bool create)
-{
- int rc;
- char *path = NULL;
- virCgroupPtr rootgrp = NULL;
-
- rc = virCgroupAppRoot(privileged, &rootgrp, create);
- if (rc != 0)
- goto out;
-
- if (virAsprintf(&path, "%s/%s", rootgrp->path, name) < 0) {
- rc = -ENOMEM;
- goto out;
- }
-
- rc = virCgroupNew(path, group);
- VIR_FREE(path);
-
- if (rc == 0) {
- rc = virCgroupMakeGroup(rootgrp, *group, create, VIR_CGROUP_NONE);
- if (rc != 0)
- virCgroupFree(group);
- }
-
-out:
- virCgroupFree(&rootgrp);
-
- return rc;
-}
-#else
-int virCgroupForDriver(const char *name ATTRIBUTE_UNUSED,
- virCgroupPtr *group ATTRIBUTE_UNUSED,
- bool privileged ATTRIBUTE_UNUSED,
- bool create ATTRIBUTE_UNUSED)
-{
- /* Claim no support */
- return -ENXIO;
-}
-#endif
-
-/**
-* virCgroupGetAppRoot:
-*
-* @group: Pointer to returned virCgroupPtr
-*
-* Returns 0 on success
-*/
-#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
-int virCgroupGetAppRoot(virCgroupPtr *group)
-{
- return virCgroupNew("/", group);
-}
-#else
-int virCgroupGetAppRoot(virCgroupPtr *group ATTRIBUTE_UNUSED)
-{
- return -ENXIO;
-}
-#endif
-
-/**
- * virCgroupForDomain:
- *
- * @driver: group for driver owning the domain
- * @name: name of the domain
- * @group: Pointer to returned virCgroupPtr
- *
- * Returns 0 on success
- */
-#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
-int virCgroupForDomain(virCgroupPtr driver,
- const char *name,
- virCgroupPtr *group,
- bool create)
-{
- int rc;
- char *path;
-
- if (driver == NULL)
- return -EINVAL;
-
- if (virAsprintf(&path, "%s/%s", driver->path, name) < 0)
- return -ENOMEM;
-
- rc = virCgroupNew(path, group);
- VIR_FREE(path);
-
- if (rc == 0) {
- /*
- * Create a cgroup with memory.use_hierarchy enabled to
- * surely account memory usage of lxc with ns subsystem
- * enabled. (To be exact, memory and ns subsystems are
- * enabled at the same time.)
- *
- * The reason why doing it here, not a upper group, say
- * a group for driver, is to avoid overhead to track
- * cumulative usage that we don't need.
- */
- rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_MEM_HIERACHY);
- if (rc != 0)
- virCgroupFree(group);
- }
-
- return rc;
-}
-#else
-int virCgroupForDomain(virCgroupPtr driver ATTRIBUTE_UNUSED,
- const char *name ATTRIBUTE_UNUSED,
- virCgroupPtr *group ATTRIBUTE_UNUSED,
- bool create ATTRIBUTE_UNUSED)
-{
- return -ENXIO;
-}
-#endif
-
-/**
- * virCgroupForVcpu:
- *
- * @driver: group for the domain
- * @vcpuid: id of the vcpu
- * @group: Pointer to returned virCgroupPtr
- *
- * Returns 0 on success
- */
-#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
-int virCgroupForVcpu(virCgroupPtr driver,
- int vcpuid,
- virCgroupPtr *group,
- bool create)
+int virCgroupGetAppRoot(virCgroupPtr *cgroup, bool privileged)
{
+ char *name = NULL;
+ char *user = NULL;
int rc;
- char *path;
- if (driver == NULL)
- return -EINVAL;
-
- if (virAsprintf(&path, "%s/vcpu%d", driver->path, vcpuid) < 0)
- return -ENOMEM;
-
- rc = virCgroupNew(path, group);
- VIR_FREE(path);
+ if (privileged)
+ name = strdup("libvirt");
+ else {
+ user = virGetUserName(getuid());
+ if (!user) {
+ return -ENOMEM;
+ }
- if (rc == 0) {
- rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_VCPU);
- if (rc != 0)
- virCgroupFree(group);
+ if (virAsprintf(&name, "libvirt-%s", user) < 0) {
+ VIR_FREE(user);
+ return -ENOMEM;
+ }
}
- return rc;
-}
-#else
-int virCgroupForVcpu(virCgroupPtr driver ATTRIBUTE_UNUSED,
- int vcpuid ATTRIBUTE_UNUSED,
- virCgroupPtr *group ATTRIBUTE_UNUSED,
- bool create ATTRIBUTE_UNUSED)
-{
- return -ENXIO;
-}
-#endif
-
-/**
- * virCgroupForEmulator:
- *
- * @driver: group for the domain
- * @group: Pointer to returned virCgroupPtr
- *
- * Returns: 0 on success or -errno on failure
- */
-#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
-int virCgroupForEmulator(virCgroupPtr driver,
- virCgroupPtr *group,
- bool create)
-{
- int rc;
- char *path;
-
- if (driver == NULL)
- return -EINVAL;
-
- if (virAsprintf(&path, "%s/emulator", driver->path) < 0)
- return -ENOMEM;
-
- rc = virCgroupNew(path, group);
- VIR_FREE(path);
-
- if (rc == 0) {
- rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_VCPU);
- if (rc != 0)
- virCgroupFree(group);
- }
+ rc = virCgroupNew(name, NULL, cgroup);
+ VIR_FREE(name);
return rc;
}
-#else
-int virCgroupForEmulator(virCgroupPtr driver ATTRIBUTE_UNUSED,
- virCgroupPtr *group ATTRIBUTE_UNUSED,
- bool create ATTRIBUTE_UNUSED)
-{
- return -ENXIO;
-}
-#endif
/**
* virCgroupSetBlkioWeight:
*
@@ -2390,21 +1807,20 @@ int virCgroupGetFreezerState(virCgroupPtr group, char **state)
#if defined HAVE_KILL && defined HAVE_MNTENT_H && defined
HAVE_GETMNTENT_R
-static int virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids)
+static int virCgroupItemKillInternal(virCgroupItemPtr item,
+ int signum,
+ virHashTablePtr pids)
{
- int rc;
+ int rc = -1;
int killedAny = 0;
char *keypath = NULL;
bool done = false;
FILE *fp = NULL;
- VIR_DEBUG("group=%p path=%s signum=%d pids=%p",
- group, group->path, signum, pids);
+ VIR_DEBUG("cgroupItem=%p signum=%d pids=%p",
+ item, signum, pids);
- rc = virCgroupPathOfController(group, -1, "tasks", &keypath);
- if (rc != 0) {
- VIR_DEBUG("No path of %s, tasks", group->path);
+ if (virAsprintf(&keypath, "%s/tasks", item->path) < 0)
return rc;
- }
/* PIDs may be forking as we kill them, so loop
* until there are no new PIDs found
@@ -2456,7 +1872,6 @@ cleanup:
return rc;
}
-
static uint32_t virCgroupPidCode(const void *name, uint32_t seed)
{
unsigned long pid_value = (unsigned long)(intptr_t)name;
@@ -2471,15 +1886,8 @@ static void *virCgroupPidCopy(const void *name)
return (void*)name;
}
-/*
- * Returns
- * < 0 : errno that occurred
- * 0 : no PIDs killed
- * 1 : at least one PID killed
- */
-int virCgroupKill(virCgroupPtr group, int signum)
+static int virCgroupItemKill(virCgroupItemPtr item, int signum)
{
- VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum);
int rc;
/* The 'tasks' file in cgroups can contain duplicated
* pids, so we use a hash to track which we've already
@@ -2492,82 +1900,65 @@ int virCgroupKill(virCgroupPtr group, int signum)
virCgroupPidCopy,
NULL);
- rc = virCgroupKillInternal(group, signum, pids);
+ rc = virCgroupItemKillInternal(item, signum, pids);
virHashFree(pids);
return rc;
}
-
-static int virCgroupKillRecursiveInternal(virCgroupPtr group, int signum, virHashTablePtr
pids, bool dormdir)
+/*
+ * Returns
+ * < 0 : errno that occurred
+ * 0 : no PIDs killed
+ * 1 : at least one PID killed
+ */
+int virCgroupKill(virCgroupPtr group, int signum)
{
int rc;
- int killedAny = 0;
- char *keypath = NULL;
- DIR *dp;
- virCgroupPtr subgroup = NULL;
- struct dirent *ent;
- VIR_DEBUG("group=%p path=%s signum=%d pids=%p", group, group->path,
signum, pids);
-
- rc = virCgroupPathOfController(group, -1, "", &keypath);
- if (rc != 0) {
- VIR_DEBUG("No path of %s, tasks", group->path);
- return rc;
- }
+ int i;
- if ((rc = virCgroupKillInternal(group, signum, pids)) != 0)
- return rc;
+ VIR_DEBUG("group=%p signum=%d", group, signum);
- VIR_DEBUG("Iterate over children of %s", keypath);
- if (!(dp = opendir(keypath))) {
- rc = -errno;
- return rc;
+ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
+ rc = virCgroupItemKill(group->items[i], signum);
+ if (rc < 0)
+ break;
}
- while ((ent = readdir(dp))) {
- char *subpath;
+ return rc;
+}
- if (STREQ(ent->d_name, "."))
- continue;
- if (STREQ(ent->d_name, ".."))
- continue;
- if (ent->d_type != DT_DIR)
- continue;
+static int virCgroupItemKillRecursiveInternal(virCgroupItemPtr item,
+ int signum,
+ virHashTablePtr pids)
+{
+ int rc;
+ int killedAny = 0;
+ virCgroupItemPtr child = NULL;
- VIR_DEBUG("Process subdir %s", ent->d_name);
- if (virAsprintf(&subpath, "%s/%s", group->path, ent->d_name)
< 0) {
- rc = -ENOMEM;
- goto cleanup;
- }
+ if ((rc = virCgroupItemKillInternal(item, signum, pids)) < 0)
+ return rc;
- if ((rc = virCgroupNew(subpath, &subgroup)) != 0)
- goto cleanup;
+ VIR_DEBUG("Iterate over children of %s", item->path);
- if ((rc = virCgroupKillRecursiveInternal(subgroup, signum, pids, true)) < 0)
- goto cleanup;
+ child = item->children;
+ while (child) {
+ rc = virCgroupItemKillRecursiveInternal(child, signum, pids);
if (rc == 1)
killedAny = 1;
- if (dormdir)
- virCgroupRemove(subgroup);
-
- virCgroupFree(&subgroup);
+ child = child->next;
}
rc = killedAny;
-cleanup:
- virCgroupFree(&subgroup);
- closedir(dp);
-
return rc;
}
-int virCgroupKillRecursive(virCgroupPtr group, int signum)
+static int virCgroupItemKillRecursive(virCgroupItemPtr item, int signum)
{
int rc;
- VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum);
virHashTablePtr pids = virHashCreateFull(100,
NULL,
virCgroupPidCode,
@@ -2575,19 +1966,30 @@ int virCgroupKillRecursive(virCgroupPtr group, int signum)
virCgroupPidCopy,
NULL);
- rc = virCgroupKillRecursiveInternal(group, signum, pids, false);
+ rc = virCgroupItemKillRecursiveInternal(item, signum, pids);
virHashFree(pids);
return rc;
}
+int virCgroupKillRecursive(virCgroupPtr group, int signum)
+{
+ int rc;
+ int i;
+
+ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
+ rc = virCgroupItemKillRecursive(group->items[i], signum);
+ }
+
+ return rc;
+}
int virCgroupKillPainfully(virCgroupPtr group)
{
int i;
int rc;
- VIR_DEBUG("cgroup=%p path=%s", group, group->path);
+ VIR_DEBUG("cgroup=%p", group);
for (i = 0 ; i < 15 ; i++) {
int signum;
if (i == 0)
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index f93c185..0ccca23 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -30,10 +30,6 @@
struct virCgroup;
typedef struct virCgroup *virCgroupPtr;
-struct virCgroup2;
-typedef struct virCgroup2 virCgroup2;
-typedef virCgroup2 *virCgroup2Ptr;
-
enum {
VIR_CGROUP_CONTROLLER_CPU,
VIR_CGROUP_CONTROLLER_CPUACCT,
@@ -53,21 +49,7 @@ int virCgroupForDriver(const char *name,
bool privileged,
bool create);
-int virCgroupGetAppRoot(virCgroupPtr *group);
-
-int virCgroupForDomain(virCgroupPtr driver,
- const char *name,
- virCgroupPtr *group,
- bool create);
-
-int virCgroupForVcpu(virCgroupPtr driver,
- int vcpuid,
- virCgroupPtr *group,
- bool create);
-
-int virCgroupForEmulator(virCgroupPtr driver,
- virCgroupPtr *group,
- bool create);
+int virCgroupGetAppRoot(virCgroupPtr *group, bool privileged);
int virCgroupPathOfController(virCgroupPtr group,
int controller,
@@ -163,6 +145,7 @@ int virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus);
int virCgroupRemove(virCgroupPtr group);
+int virCgroupNew(const char *name, virCgroupPtr parent, virCgroupPtr *cgroup);
void virCgroupFree(virCgroupPtr *group);
bool virCgroupMounted(virCgroupPtr cgroup, int controller);
@@ -170,8 +153,6 @@ int virCgroupKill(virCgroupPtr group, int signum);
int virCgroupKillRecursive(virCgroupPtr group, int signum);
int virCgroupKillPainfully(virCgroupPtr group);
-
-int virCgroup2New(const char *name, virCgroup2Ptr parent, virCgroup2Ptr *cgroup);
-void virCgroup2Free(virCgroup2Ptr *cgroup);
+int virCgroupMakePath(virCgroupPtr cgroup);
#endif /* __VIR_CGROUP_H__ */
--
1.8.0.1.240.ge8a1f5a