Mercurial > archived > louis > perso > liblxcstats
view probes/cpuacct.c @ 6:e2b88f50e136
cpuacct: replace strtoll by strtoul and replace sscanf by strsplit + strtoul
author | Louis Opter <louis@dotcloud.com> |
---|---|
date | Sat, 01 Jan 2011 16:18:17 +0100 |
parents | 2cb8a6cbe468 |
children | 6f2e13f5fcfd |
line wrap: on
line source
#include <sys/types.h> #include <assert.h> #include <errno.h> #include <limits.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "lxcstats.h" #include "_lxcstats.h" static inline uint32_t nsecs_to_user_hz(uint64_t counter) { /* * XXX I don't know if it will work for custom values of HZ in the kernel. */ return (counter / (NSEC_PER_SEC / sysconf(_SC_CLK_TCK))); } static int read_stat(struct lxcst *c) { char path[PATH_MAX]; char *values; char *fields[4]; 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 */ if (_lxcst_strsplit(values, fields, ARRAY_SIZE(fields)) == ARRAY_SIZE(fields)) { errno = 0; c->cpuacct.user = strtoul(fields[1], NULL, 10); c->cpuacct.system = strtoul(fields[3], NULL, 10); if (!errno) { free(values); return (0); } } free(values); } 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] = nsecs_to_user_hz(strtoul(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)); }