[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH 1/2] cpustats: collect VM user and sys times



On 2012年03月10日 01:37, Eric Blake wrote:
As documented in linux.git/Documentation/cgroups/cpuacct.txt,
cpuacct.stat returns user and system time in ticks (the same
unit used in times(2)).  It would be a bit nicer if it were like
getrusage(2) and reported timeval contents, or like cpuacct.usage
and in nanoseconds, but we can't be picky.

* src/util/cgroup.h (virCgroupGetCpuacctStat): New function.
* src/util/cgroup.c (virCgroupGetCpuacctStat): Implement it.
(virCgroupGetValueStr): Allow for multi-line files.
* src/libvirt_private.syms (cgroup.h): Export it.
---
  src/libvirt_private.syms |    1 +
  src/util/cgroup.c        |   51 ++++++++++++++++++++++++++++++++++++++++++++-
  src/util/cgroup.h        |    4 ++-
  3 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d7ec221..1f55f5d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -78,6 +78,7 @@ virCgroupGetCpuCfsPeriod;
  virCgroupGetCpuCfsQuota;
  virCgroupGetCpuShares;
  virCgroupGetCpuacctPercpuUsage;
+virCgroupGetCpuacctStat;
  virCgroupGetCpuacctUsage;
  virCgroupGetCpusetMems;
  virCgroupGetFreezerState;
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index c150fbb..ad49bc2 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -355,8 +355,8 @@ static int virCgroupGetValueStr(virCgroupPtr group,
          VIR_DEBUG("Failed to read %s: %m\n", keypath);
      } else {
          /* Terminated with '\n' has sometimes harmful effects to the caller */
-        char *p = strchr(*value, '\n');
-        if (p) *p = '\0';
+        if ((*value)[rc - 1] == '\n')
+            (*value)[rc - 1] = '\0';

          rc = 0;
      }
@@ -1561,6 +1561,53 @@ int virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage)
                                  "cpuacct.usage_percpu", usage);
  }

+#ifdef _SC_CLK_TCK
+int virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user,
+                            unsigned long long *sys)
+{
+    char *str;
+    char *p;
+    int ret;
+    static double scale = -1.0;
+
+    if ((ret = virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT,
+                                    "cpuacct.stat",&str))<  0)
+        return ret;
+    if (!(p = STRSKIP(str, "user ")) ||
+        virStrToLong_ull(p,&p, 10, user)<  0 ||
+        !(p = STRSKIP(p, "\nsystem ")) ||
+        virStrToLong_ull(p, NULL, 10, sys)<  0) {
+        ret = -EINVAL;
+        goto cleanup;
+    }
+    /* times reported are in system ticks (generally 100 Hz), but that
+     * rate can theoretically vary between machines.  Scale things
+     * into approximate nanoseconds.  */
+    if (scale<  0) {
+        long ticks_per_sec = sysconf(_SC_CLK_TCK);
+        if (ticks_per_sec == -1) {
+            ret = -errno;
+            goto cleanup;
+        }
+        scale = 1000000000.0 / ticks_per_sec;
+    }
+    *user *= scale;
+    *sys *= scale;
+
+    ret = 0;
+cleanup:
+    VIR_FREE(str);
+    return ret;
+}
+#else
+int virCgroupGetCpuacctStat(virCgroupPtr group ATTRIBUTE_UNUSED,
+                            unsigned long long *user ATTRIBUTE_UNUSED,
+                            unsigned long long *sys ATTRIBUTE_UNUSED)
+{
+    return -ENOSYS;
+}
+#endif
+
  int virCgroupSetFreezerState(virCgroupPtr group, const char *state)
  {
      return virCgroupSetValueStr(group,
diff --git a/src/util/cgroup.h b/src/util/cgroup.h
index b4e0f37..8486c42 100644
--- a/src/util/cgroup.h
+++ b/src/util/cgroup.h
@@ -1,7 +1,7 @@
  /*
   * cgroup.h: Interface to tools for managing cgroups
   *
- * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2011-2012 Red Hat, Inc.
   * Copyright IBM Corp. 2008
   *
   * See COPYING.LIB for the License of this software
@@ -116,6 +116,8 @@ int virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota);

  int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage);
  int virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage);
+int virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user,
+                            unsigned long long *sys);

  int virCgroupSetFreezerState(virCgroupPtr group, const char *state);
  int virCgroupGetFreezerState(virCgroupPtr group, char **state);


ACK


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]