validate and verify microseconds passed by plugins
Costa Tsaousis (ktsaou) committed
Nov 7, 2016 at 23:06 UTC
5cc93f911208376ab5c770286b1b1139047b7e7d
2 files changed
+38
-21
src/rrd.c
+36
-19
@@ -974,35 +974,52 @@ collected_number rrddim_set(RRDSET *st, const char *id, collected_number value)
974
return rrddim_set_by_pointer(st, rd, value);
975
}
976
977
-void rrdset_next_usec(RRDSET *st, unsigned long long microseconds)
977
+void rrdset_next_usec_unfiltered(RRDSET *st, unsigned long long microseconds)
978
{
979
- if(!microseconds) rrdset_next(st);
980
- else {
981
- debug(D_RRD_CALLS, "rrdset_next_usec() for chart %s with microseconds %llu", st->name, microseconds);
982
-
983
- if(unlikely(st->debug)) debug(D_RRD_STATS, "%s: NEXT: %llu microseconds", st->name, microseconds);
984
- st->usec_since_last_update = microseconds;
979
+ if(unlikely(!st->last_collected_time.tv_sec || !microseconds)) {
980
+ // the first entry
981
+ microseconds = st->update_every * 1000000ULL;
982
}
983
+ st->usec_since_last_update = microseconds;
984
}
985
988
-void rrdset_next(RRDSET *st)
986
+void rrdset_next_usec(RRDSET *st, unsigned long long microseconds)
987
{
990
- unsigned long long microseconds = 0;
988
+ struct timeval now;
989
+ gettimeofday(&now, NULL);
990
992
- if(likely(st->last_collected_time.tv_sec)) {
993
- struct timeval now;
994
- gettimeofday(&now, NULL);
991
+ if(unlikely(!st->last_collected_time.tv_sec)) {
992
+ // the first entry
993
+ microseconds = st->update_every * 1000000ULL;
994
+ }
995
+ else if(unlikely(!microseconds)) {
996
+ // no dt given by the plugin
997
microseconds = usec_dt(&now, &st->last_collected_time);
998
}
997
- // prevent infinite loop
998
- else microseconds = st->update_every * 1000000ULL;
999
+ else {
1000
+ // microseconds has the time since the last collection
1001
+ unsigned long long now_usec = timeval_usec(&now);
1002
+ unsigned long long last_usec = timeval_usec(&st->last_collected_time);
1003
+ unsigned long long since_last_usec = usec_dt(&now, &st->last_collected_time);
1004
1000
- rrdset_next_usec(st, microseconds);
1001
-}
1005
+ // verify the microseconds given is good
1006
+ if(unlikely(last_usec + microseconds > now_usec)) {
1007
+ debug(D_RRD_CALLS, "rrdset_next_usec() for chart %s with dt %llu is %llu usec to the future", st->name, microseconds, last_usec + microseconds - now_usec);
1008
1003
-void rrdset_next_plugins(RRDSET *st)
1004
-{
1005
- rrdset_next(st);
1009
+ if(unlikely(last_usec + microseconds > now_usec + 10000))
1010
+ error("Invalid dt %llu usec given - it leads %llu usec to the future, for chart '%s' (%s).", microseconds, last_usec + microseconds - now_usec, st->name, st->id);
1011
+
1012
+ microseconds = since_last_usec;
1013
+ }
1014
+ else if(unlikely(microseconds < since_last_usec * 0.2 || microseconds > since_last_usec * 1.2)) {
1015
+ error("Invalid dt %llu usec given - expected %llu usec +/- 20%%, for chart '%s' (%s).", microseconds, since_last_usec, st->name, st->id);
1016
+ microseconds = since_last_usec;
1017
+ }
1018
+ }
1019
+ debug(D_RRD_CALLS, "rrdset_next_usec() for chart %s with microseconds %llu", st->name, microseconds);
1020
+
1021
+ if(unlikely(st->debug)) debug(D_RRD_STATS, "%s: NEXT: %llu microseconds", st->name, microseconds);
1022
+ st->usec_since_last_update = microseconds;
1023
}
1024
1025
unsigned long long rrdset_done(RRDSET *st)
src/rrd.h
+2
-2
@@ -355,9 +355,9 @@ extern RRDSET *rrdset_find(const char *id);
355
extern RRDSET *rrdset_find_bytype(const char *type, const char *id);
356
extern RRDSET *rrdset_find_byname(const char *name);
357
358
+extern void rrdset_next_usec_unfiltered(RRDSET *st, unsigned long long microseconds);
359
extern void rrdset_next_usec(RRDSET *st, unsigned long long microseconds);
359
-extern void rrdset_next(RRDSET *st);
360
-extern void rrdset_next_plugins(RRDSET *st);
360
+#define rrdset_next(st) rrdset_next_usec(st, 0ULL)
361
362
extern unsigned long long rrdset_done(RRDSET *st);
363