[libvirt] [PATCH RESEND RFC v4 1/6] Introduce the function virCgroupForVcpu

Wen Congyang wency at cn.fujitsu.com
Thu Jul 21 02:08:03 UTC 2011


Introduce the function virCgroupForVcpu() to create sub directory for each vcpu.
---
 src/libvirt_private.syms |    1 +
 src/util/cgroup.c        |   72 ++++++++++++++++++++++++++++++++++++++++++---
 src/util/cgroup.h        |    5 +++
 3 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3e3b1dd..30804eb 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -67,6 +67,7 @@ virCgroupDenyAllDevices;
 virCgroupDenyDevicePath;
 virCgroupForDomain;
 virCgroupForDriver;
+virCgroupForVcpu;
 virCgroupFree;
 virCgroupGetBlkioWeight;
 virCgroupGetCpuShares;
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index 740cedf..8994aca 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -52,6 +52,16 @@ struct virCgroup {
     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
+                                       * before creating subcgroups and
+                                       * attaching tasks
+                                       */
+    VIR_CGROUP_VCPU = 1 << 1, /* create subdir only under the cgroup cpu,
+                               * cpuacct and cpuset if possible. */
+} virCgroupFlags;
+
 /**
  * virCgroupFree:
  *
@@ -503,7 +513,7 @@ static int virCgroupSetMemoryUseHierarchy(virCgroupPtr group)
 }
 
 static int virCgroupMakeGroup(virCgroupPtr parent, virCgroupPtr group,
-                              int create, bool memory_hierarchy)
+                              int create, unsigned int flags)
 {
     int i;
     int rc = 0;
@@ -516,6 +526,13 @@ static int virCgroupMakeGroup(virCgroupPtr parent, virCgroupPtr group,
         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) {
+            /* 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;
@@ -555,7 +572,7 @@ static int virCgroupMakeGroup(virCgroupPtr parent, virCgroupPtr group,
              * Note that virCgroupSetMemoryUseHierarchy should always be
              * called prior to creating subcgroups and attaching tasks.
              */
-            if (memory_hierarchy &&
+            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))) {
@@ -641,7 +658,7 @@ static int virCgroupAppRoot(int privileged,
     if (rc != 0)
         goto cleanup;
 
-    rc = virCgroupMakeGroup(rootgrp, *group, create, false);
+    rc = virCgroupMakeGroup(rootgrp, *group, create, VIR_CGROUP_NONE);
 
 cleanup:
     virCgroupFree(&rootgrp);
@@ -801,7 +818,7 @@ int virCgroupForDriver(const char *name,
     VIR_FREE(path);
 
     if (rc == 0) {
-        rc = virCgroupMakeGroup(rootgrp, *group, create, false);
+        rc = virCgroupMakeGroup(rootgrp, *group, create, VIR_CGROUP_NONE);
         if (rc != 0)
             virCgroupFree(group);
     }
@@ -861,7 +878,7 @@ int virCgroupForDomain(virCgroupPtr driver,
          * a group for driver, is to avoid overhead to track
          * cumulative usage that we don't need.
          */
-        rc = virCgroupMakeGroup(driver, *group, create, true);
+        rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_MEM_HIERACHY);
         if (rc != 0)
             virCgroupFree(group);
     }
@@ -879,6 +896,51 @@ int virCgroupForDomain(virCgroupPtr driver ATTRIBUTE_UNUSED,
 #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,
+                     int create)
+{
+    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 (rc == 0) {
+        rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_VCPU);
+        if (rc != 0)
+            virCgroupFree(group);
+    }
+
+    return rc;
+}
+#else
+int virCgroupForVcpu(virCgroupPtr driver ATTRIBUTE_UNUSED,
+                     int vcpuid ATTRIBUTE_UNUSED,
+                     virCgroupPtr *group ATTRIBUTE_UNUSED,
+                     int create ATTRIBUTE_UNUSED)
+{
+    return -ENXIO;
+}
+#endif
+
+/**
  * virCgroupSetBlkioWeight:
  *
  * @group: The cgroup to change io weight for
diff --git a/src/util/cgroup.h b/src/util/cgroup.h
index 8ae756d..1d04418 100644
--- a/src/util/cgroup.h
+++ b/src/util/cgroup.h
@@ -40,6 +40,11 @@ int virCgroupForDomain(virCgroupPtr driver,
                        virCgroupPtr *group,
                        int create);
 
+int virCgroupForVcpu(virCgroupPtr driver,
+                     int vcpuid,
+                     virCgroupPtr *group,
+                     int create);
+
 int virCgroupPathOfController(virCgroupPtr group,
                               int controller,
                               const char *key,
-- 
1.7.1




More information about the libvir-list mailing list