diff container.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/container.c	Wed Dec 29 23:28:14 2010 +0100
@@ -0,0 +1,113 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lxcstats.h"
+#include "_lxcstats.h"
+
+static int
+_lxcst_unselect_current_and_parent(const struct dirent* d)
+{
+    return (strcmp(d->d_name, ".") && strcmp(d->d_name, ".."));
+}
+
+struct lxcst *
+_lxcst_container_new(struct _lxcst_controller *ct, const char *name)
+{
+    char            buf[256];
+    struct lxcst    *c;
+
+    assert(ct);
+    assert(name);
+
+    printf("new container %s\n", name);
+
+    c = calloc(1, sizeof(*c));
+    if (!c)
+        return (NULL);
+
+    _lxcst_join_path(buf, sizeof(buf), ct->cgroup_dir, name);
+
+    c->name = strdup(name);
+    c->cgroup_dir = strdup(buf);
+    if (!c->name || !c->cgroup_dir)
+        goto free_container;
+
+    return (c);
+
+free_container:
+    free(c->name);
+    free(c);
+    return (NULL);
+}
+
+void
+_lxcst_container_delete(struct lxcst *c)
+{
+    if (c) {
+        free(c->name);
+        free(c->cgroup_dir);
+        free(c->cpuacct.percpu);
+        free(c);
+    }
+}
+
+int
+_lxcst_container_read_infos(struct lxcst *c)
+{
+    int i;
+
+    assert(c);
+
+    for (i = 0; _lxcst_probes[i].fn; ++i)
+        if (_lxcst_probes[i].fn((c)))
+            warn("%s probe failed for container %s", _lxcst_probes[i].name, c->name);
+
+    return (0);
+}
+
+int
+lxcst_span_containers(lxcst_handle *hdl, int (*cb)(void *, const struct lxcst *), void *ctx)
+{
+    int             n;
+    struct dirent   **c_vec;
+    struct lxcst    *c;
+
+    assert(hdl);
+    assert(hdl->cgroup_dir);
+    assert(cb);
+
+    n = scandir(hdl->cgroup_dir, &c_vec, &_lxcst_unselect_current_and_parent, NULL);
+    if (n > 0) {
+        while (n--) {
+            if (_lxcst_isdir(hdl, c_vec[n])) {
+                c = _lxcst_container_new(hdl, c_vec[n]->d_name);
+                if (c && _lxcst_container_read_infos(c) == 0
+                    && cb(ctx, c)) {
+                    errno = EINTR;
+                    goto abort_by_cb;
+                }
+            }
+            free(c_vec[n]);
+        }
+        free(c_vec);
+    } else if (n < 0) {
+        return (-1);
+    }
+
+    return (0);
+
+abort_by_cb:
+    free(c_vec[n + 1]);
+    while (n--)
+        free(c_vec[n]);
+    free(c_vec);
+    return (-1);
+}