changeset 9:6f2e13f5fcfd

Add the memory probe
author Louis Opter <louis@dotcloud.com>
date Sun, 02 Jan 2011 01:50:27 +0100
parents fe254ba0818d
children 3a1977ecccc7
files CMakeLists.txt lxcstats.h probes/cpuacct.c probes/memory.c probes/probes.c probes/probes.h probes/tests/CMakeLists.txt probes/tests/memory.c
diffstat 8 files changed, 95 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sun Jan 02 01:14:56 2011 +0100
+++ b/CMakeLists.txt	Sun Jan 02 01:50:27 2011 +0100
@@ -32,6 +32,7 @@
 
 SET(PROBES_SRC
     probes/cpuacct.c
+    probes/memory.c
     probes/probes.c
    )
 
--- a/lxcstats.h	Sun Jan 02 01:14:56 2011 +0100
+++ b/lxcstats.h	Sun Jan 02 01:50:27 2011 +0100
@@ -19,6 +19,12 @@
         uint32_t    system;     /*< CPU time spent in kernelland                        */
         uint32_t    *percpu;    /*< CPU time per CPU (zero-terminated array or NULL)    */
     }               cpuacct;    /*< CPU accounting in USER_HZ                           */
+    struct {
+        uint64_t    used;       /*< RAM used by applications                            */
+        uint64_t    mapped;     /*< RAM used for mapped file (includes tmpfs/shmem)     */
+        uint64_t    cached;     /*< RAM cached by the kernel                            */
+        uint64_t    swapped;    /*< SWAP used                                           */
+    }               memory;     /*< Memory accounting in bytes                          */
 };
 
 /**
--- a/probes/cpuacct.c	Sun Jan 02 01:14:56 2011 +0100
+++ b/probes/cpuacct.c	Sun Jan 02 01:50:27 2011 +0100
@@ -85,7 +85,7 @@
 
             free(values);
             return (0);
-        } 
+        }
 
 err:
         free(c->cpuacct.percpu);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/probes/memory.c	Sun Jan 02 01:50:27 2011 +0100
@@ -0,0 +1,48 @@
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lxcstats.h"
+#include "_lxcstats.h"
+
+static int
+read_stat(struct lxcst *c)
+{
+    char    path[PATH_MAX];
+    char    *values;
+    char    *fields[12];
+    int     ret;
+
+    _lxcst_join_path(path, sizeof(path), c->cgroup_dir, "memory.stat");
+    ret = _lxcst_read_file(path, &values);
+    if (ret > 0) {
+        values[ret - 1] = '\0'; /* Replace the last \n by a \0 */
+        if (_lxcst_strsplit(values, fields, ARRAY_SIZE(fields)) == ARRAY_SIZE(fields)) {
+            errno = 0;
+            c->memory.cached = strtoull(fields[1], NULL, 10);
+            c->memory.used = strtoull(fields[3], NULL, 10);
+            c->memory.mapped = strtoull(fields[5], NULL, 10);
+            c->memory.swapped = strtoull(fields[11], NULL, 10);
+            if (!errno) {
+                free(values);
+                return (0);
+            }
+        }
+        free(values);
+    }
+
+    memset(&c->memory, 0, sizeof(c->memory));
+    return (-1);
+}
+
+int
+_lxcst_probe_memory(struct lxcst *c)
+{
+    assert(c);
+
+    return (read_stat(c));
+}
--- a/probes/probes.c	Sun Jan 02 01:14:56 2011 +0100
+++ b/probes/probes.c	Sun Jan 02 01:50:27 2011 +0100
@@ -5,5 +5,6 @@
 
 const struct _lxcst_probe _lxcst_probes[] = {
     { &_lxcst_probe_cpuacct, "cpuacct" },
+    { &_lxcst_probe_memory, "memory" },
     { NULL, NULL }
 };
--- a/probes/probes.h	Sun Jan 02 01:14:56 2011 +0100
+++ b/probes/probes.h	Sun Jan 02 01:50:27 2011 +0100
@@ -11,5 +11,6 @@
 extern const struct _lxcst_probe _lxcst_probes[];
 
 int _lxcst_probe_cpuacct(struct lxcst *c);
+int _lxcst_probe_memory(struct lxcst *c);
 
 #endif
--- a/probes/tests/CMakeLists.txt	Sun Jan 02 01:14:56 2011 +0100
+++ b/probes/tests/CMakeLists.txt	Sun Jan 02 01:50:27 2011 +0100
@@ -6,6 +6,7 @@
 
 SET(TESTS
     cpuacct
+    memory
    )
 
 FOREACH(I ${TESTS})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/probes/tests/memory.c	Sun Jan 02 01:50:27 2011 +0100
@@ -0,0 +1,36 @@
+#include <sys/types.h>
+
+#include <err.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "lxcstats.h"
+#include "_lxcstats.h"
+#include "probes/probes.h"
+
+int
+main(void)
+{
+    lxcst_handle    *hdl;
+    struct lxcst    *c;
+
+    hdl = lxcst_open();
+    if (!hdl)
+        err(EXIT_FAILURE, "lxcst_open failed");
+
+    c = _lxcst_container_new(hdl, ".");
+    if (!c)
+        err(EXIT_FAILURE, "cant create container");
+
+    if (_lxcst_probe_memory(c))
+        err(EXIT_FAILURE, "probe cpuacct failed");
+
+    printf("used %ju\nmapped %ju\ncached %ju\nswapped %ju\n",
+           c->memory.used, c->memory.mapped, c->memory.cached, c->memory.swapped);
+
+    _lxcst_container_delete(c);
+
+    lxcst_close(hdl);
+
+    return (EXIT_SUCCESS);
+}