diff --git a/src/damon.c b/src/damon.c index 49fac0f..62f53b6 100644 --- a/src/damon.c +++ b/src/damon.c @@ -18,15 +18,14 @@ #include -#include #include -#include #include #include #include #include #include #include +#include "rrd.h" #include "damon.h" #include "../config.h" @@ -40,9 +39,6 @@ #ifndef PROGNAME # define PROGNAME "DaMon" #endif -#ifndef RRDTOOL -# define RRDTOOL "rrdtool" -#endif /* DaMon */ @@ -78,7 +74,8 @@ static void _damon_destroy(DaMon * damon); static int _damon_perror(char const * message, int error); -static int _rrd_update(DaMon * damon, char const * filename, int args_cnt, ...); +static int _damon_update(DaMon * damon, char const * filename, + int args_cnt, ...); /* functions */ @@ -201,7 +198,7 @@ static int _refresh_uptime(AppClient * ac, Host * host, char * rrd) if(appclient_call(ac, (void **)&ret, "uptime") != 0) return error_print(PROGNAME); sprintf(rrd, "%s%c%s", host->hostname, DAMON_SEP, "uptime.rrd"); - _rrd_update(host->damon, rrd, 1, ret); + _damon_update(host->damon, rrd, 1, ret); return 0; } @@ -216,7 +213,7 @@ static int _refresh_load(AppClient * ac, Host * host, char * rrd) if(res != 0) return 0; sprintf(rrd, "%s%c%s", host->hostname, DAMON_SEP, "load.rrd"); - _rrd_update(host->damon, rrd, 3, load[0], load[1], load[2]); + _damon_update(host->damon, rrd, 3, load[0], load[1], load[2]); return 0; } @@ -227,7 +224,7 @@ static int _refresh_procs(AppClient * ac, Host * host, char * rrd) if(appclient_call(ac, (void **)&res, "procs") != 0) return 1; sprintf(rrd, "%s%c%s", host->hostname, DAMON_SEP, "procs.rrd"); - _rrd_update(host->damon, rrd, 1, res); + _damon_update(host->damon, rrd, 1, res); return 0; } @@ -240,7 +237,7 @@ static int _refresh_ram(AppClient * ac, Host * host, char * rrd) &ram[3]) != 0) return 1; sprintf(rrd, "%s%c%s", host->hostname, DAMON_SEP, "ram.rrd"); - _rrd_update(host->damon, rrd, 4, ram[0], ram[1], ram[2], ram[3]); + _damon_update(host->damon, rrd, 4, ram[0], ram[1], ram[2], ram[3]); return 0; } @@ -252,7 +249,7 @@ static int _refresh_swap(AppClient * ac, Host * host, char * rrd) if(appclient_call(ac, (void **)&res, "swap", &swap[0], &swap[1]) != 0) return 1; sprintf(rrd, "%s%c%s", host->hostname, DAMON_SEP, "swap.rrd"); - _rrd_update(host->damon, rrd, 2, swap[0], swap[1]); + _damon_update(host->damon, rrd, 2, swap[0], swap[1]); return 0; } @@ -263,7 +260,7 @@ static int _refresh_users(AppClient * ac, Host * host, char * rrd) if(appclient_call(ac, (void **)&res, "users") != 0) return 1; sprintf(rrd, "%s%c%s", host->hostname, DAMON_SEP, "users.rrd"); - _rrd_update(host->damon, rrd, 1, res); + _damon_update(host->damon, rrd, 1, res); return 0; } @@ -291,7 +288,7 @@ static int _ifaces_if(AppClient * ac, Host * host, char * rrd, iface) != 0) return 1; sprintf(rrd, "%s%c%s%s", host->hostname, DAMON_SEP, iface, ".rrd"); - _rrd_update(host->damon, rrd, 2, res[0], res[1]); + _damon_update(host->damon, rrd, 2, res[0], res[1]); return 0; } @@ -317,7 +314,7 @@ static int _vols_vol(AppClient * ac, Host * host, char * rrd, char * vol) != 0) return 1; sprintf(rrd, "%s%s%s", host->hostname, vol, ".rrd"); /* FIXME */ - _rrd_update(host->damon, rrd, 2, res[0], res[1]); + _damon_update(host->damon, rrd, 2, res[0], res[1]); return 0; } @@ -514,58 +511,20 @@ static int _damon_perror(char const * message, int ret) } -/* rrd_update */ -static int _update_exec(char * argv[]); - -static int _rrd_update(DaMon * damon, char const * filename, int args_cnt, ...) +/* damon_update */ +static int _damon_update(DaMon * damon, char const * filename, + int args_cnt, ...) { - char * argv[] = { RRDTOOL, "update", NULL, NULL, NULL }; - struct timeval tv; - int pos; - int i; - va_list args; int ret; + char * path; + va_list args; - if(gettimeofday(&tv, NULL) != 0) - return _damon_perror("gettimeofday", 1); - argv[2] = string_new_append(damon->prefix, "/", filename, NULL); - if((argv[3] = malloc((args_cnt + 1) * 12)) == NULL) - return _damon_perror(NULL, 1); - pos = sprintf(argv[3], "%ld", tv.tv_sec); + if((path = string_new_append(damon->prefix, "/", filename, NULL)) + == NULL) + return -1; va_start(args, args_cnt); - for(i = 0; i < args_cnt; i++) - pos += sprintf(&argv[3][pos], ":%u", va_arg(args, unsigned)); + ret = rrd_updatev(RRDTYPE_UNKNOWN, path, args_cnt, args); va_end(args); - ret = _update_exec(argv); - free(argv[3]); - string_delete(argv[2]); + string_delete(path); return ret; } - -static int _update_exec(char * argv[]) -{ - pid_t pid; - int status; - int ret; - - if((pid = fork()) == -1) - return _damon_perror("fork", 1); - if(pid == 0) - { - execvp(argv[0], argv); - _damon_perror(argv[0], 1); - exit(2); - } -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s() ", __func__); - while(*argv != NULL) - fprintf(stderr, "%s ", *argv++); - fprintf(stderr, "\n"); -#endif - while((ret = waitpid(pid, &status, 0)) != -1) - if(WIFEXITED(status)) - break; - if(ret == -1) - return _damon_perror("waitpid", -1); - return WEXITSTATUS(status); -} diff --git a/src/project.conf b/src/project.conf index 24b77a7..3742158 100644 --- a/src/project.conf +++ b/src/project.conf @@ -3,7 +3,7 @@ cflags_force=-W `pkg-config --cflags libApp` cflags=-Wall -g -O2 -pedantic ldflags_force=`pkg-config --libs libApp` ldflags= -dist=Makefile,appbroker.sh,damon.h +dist=Makefile,appbroker.sh,damon.h,rrd.h [../data/Probe.h] type=script @@ -18,14 +18,17 @@ install=$(BINDIR) [DaMon] type=binary -sources=damon.c,damon-main.c +sources=damon.c,damon-main.c,rrd.c install=$(BINDIR) [damon.c] -depends=../config.h +depends=damon.h,rrd.h,../config.h [damon-main.c] depends=damon.h [probe.c] depends=../data/Probe.h,../config.h + +[rrd.c] +depends=rrd.h diff --git a/src/rrd.c b/src/rrd.c new file mode 100644 index 0000000..c72a1aa --- /dev/null +++ b/src/rrd.c @@ -0,0 +1,128 @@ +/* $Id$ */ +/* Copyright (c) 2016 Pierre Pronchery */ +/* This file is part of DeforaOS Network Probe */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include +#include +#include +#include +#include +#include +#include +#include "rrd.h" + +/* constants */ +#ifndef RRDTOOL +# define RRDTOOL "rrdtool" +#endif + + +/* RRD */ +/* private */ +/* prototypes */ +static int _rrd_exec(char * argv[]); +static int _rrd_perror(char const * message, int ret); + + +/* public */ +/* functions */ +/* rrd_update */ +int rrd_update(RRDType type, char const * filename, int args_cnt, ...) +{ + int ret; + va_list args; + + va_start(args, args_cnt); + ret = rrd_updatev(type, filename, args_cnt, args); + va_end(args); + return ret; +} + + +/* rrd_updatev */ +int rrd_updatev(RRDType type, char const * filename, int args_cnt, va_list args) +{ + char * argv[] = { RRDTOOL, "update", NULL, NULL, NULL }; + struct timeval tv; + size_t s; + int pos; + int i; + int ret; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(%u, \"%s\")\n", __func__, type, filename); +#endif + /* prepare the parameters */ + if(gettimeofday(&tv, NULL) != 0) + return _rrd_perror("gettimeofday", -errno); + if((argv[2] = string_new(filename)) == NULL) + return 1; + s = (args_cnt + 1) * 12; + if((argv[3] = malloc(s)) == NULL) + { + string_delete(argv[2]); + return _rrd_perror(NULL, -errno); + } + pos = snprintf(argv[3], s, "%ld", tv.tv_sec); + for(i = 0; i < args_cnt; i++) + pos += snprintf(&argv[3][pos], s - pos, ":%u", + va_arg(args, unsigned int)); + /* update the database */ + ret = _rrd_exec(argv); + free(argv[3]); + string_delete(argv[2]); + return ret; +} + + +/* private */ +/* functions */ +/* rrd_exec */ +static int _rrd_exec(char * argv[]) +{ + pid_t pid; + int status; + int ret; + + if((pid = fork()) == -1) + return _rrd_perror("fork", -errno); + if(pid == 0) + { + execvp(argv[0], argv); + _rrd_perror(argv[0], 1); + exit(2); + } +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() ", __func__); + while(*argv != NULL) + fprintf(stderr, "%s ", *argv++); + fprintf(stderr, "\n"); +#endif + while((ret = waitpid(pid, &status, 0)) != -1) + if(WIFEXITED(status)) + break; + if(ret == -1) + return _rrd_perror("waitpid", -errno); + return WEXITSTATUS(status); +} + + +/* rrd_perror */ +static int _rrd_perror(char const * message, int ret) +{ + return error_set_code(ret, "%s%s%s", (message != NULL) ? message : "", + (message != NULL) ? ": " : "", strerror(errno)); +} diff --git a/src/rrd.h b/src/rrd.h new file mode 100644 index 0000000..9f3b21a --- /dev/null +++ b/src/rrd.h @@ -0,0 +1,37 @@ +/* $Id$ */ +/* Copyright (c) 2016 Pierre Pronchery */ +/* This file is part of DeforaOS Network Probe */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#ifndef DAMON_RRD_H +# define DAMON_RRD_H + +# include + + +/* RRD */ +/* types */ +typedef enum _RRDType +{ + RRDTYPE_UNKNOWN = 0 +} RRDType; + + +/* functions */ +int rrd_update(RRDType type, char const * filename, int args_cnt, ...); +int rrd_updatev(RRDType type, char const * filename, + int args_cnt, va_list args); + +#endif /* !DAMON_RRD_H */