diff probes/cpuacct.c @ 0:6ce4443e7545

Add the draft of an API to collect statistics on LXC
author Louis Opter <kalessin@kalessin.fr>
date Wed, 29 Dec 2010 23:28:14 +0100
parents
children 2cb8a6cbe468
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/probes/cpuacct.c	Wed Dec 29 23:28:14 2010 +0100
@@ -0,0 +1,90 @@
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "lxcstats.h"
+#include "_lxcstats.h"
+
+static int
+read_stat(struct lxcst *c)
+{
+    char    path[PATH_MAX];
+    char    *values;
+    int     ret;
+
+    _lxcst_join_path(path, sizeof(path), c->cgroup_dir, "cpuacct.stat");
+    ret = _lxcst_read_file(path, &values);
+    if (ret > 0) {
+        values[ret - 1] = '\0'; /* Replace the last \n by a \0 */
+        ret = sscanf(values, "user %u\nsystem %u", &c->cpuacct.user, &c->cpuacct.system);
+        free(values);
+        if (ret == 2)
+            return (0);
+    }
+
+    c->cpuacct.user = 0;
+    c->cpuacct.system = 0;
+    return (1);
+}
+
+static int
+read_usage_percpu(struct lxcst *c)
+{
+    char    path[PATH_MAX];
+    char    *values;
+    int     ret;
+    char    *p;
+    int     ncpus;
+    int     i;
+
+    _lxcst_join_path(path, sizeof(path), c->cgroup_dir, "cpuacct.usage_percpu");
+    ret = _lxcst_read_file(path, &values);
+    if (ret > 0) {
+        values[ret - 1] = '\0';
+
+        p = values;
+        for (ncpus = 0; ; ncpus++) {
+            p = strchr(p + 1, ' ');
+            if (!p)
+                break ;
+        }
+
+        if (ncpus)
+            c->cpuacct.percpu = calloc(ncpus + 1, sizeof(*c->cpuacct.percpu));
+
+        if (c->cpuacct.percpu) {
+            errno = 0;
+            p = values;
+            for (i = 0; i != ncpus && *p; ++i) {
+                c->cpuacct.percpu[i] = strtoll(p, &p, 10);
+                if (errno)
+                    goto err;
+                p += strcspn(p, "0123456789");
+            }
+
+            free(values);
+            return (0);
+        } 
+
+err:
+        free(c->cpuacct.percpu);
+        c->cpuacct.percpu = NULL;
+        free(values);
+    }
+
+    return (1);
+}
+
+int
+_lxcst_probe_cpuacct(struct lxcst *c)
+{
+    assert(c);
+
+    return (read_stat(c)
+            || read_usage_percpu(c));
+}