[libvirt] [PATCH v2 3/5] cgroup: replace old cgroup

Hu Tao hutao at cn.fujitsu.com
Mon Feb 4 07:40:59 UTC 2013


---
 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




More information about the libvir-list mailing list