view 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 source

#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);
}