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

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