X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Frrd_update.c;h=5c42f92784c4ea0e00efb6429f6b1135e6ab54d9;hb=0a82736faf62f1667434aee71e51d876d20c6ced;hp=9da2cace41a418328e040128ac199c57f75fb7a5;hpb=482e470e5a6ab434ac17a92e35d275658b6b6e2f;p=rrdtool.git diff --git a/src/rrd_update.c b/src/rrd_update.c index 9da2cac..5c42f92 100644 --- a/src/rrd_update.c +++ b/src/rrd_update.c @@ -1,88 +1,9 @@ /***************************************************************************** - * RRDtool 1.1.x Copyright Tobias Oetiker, 1997 - 2004 + * RRDtool 1.2.11 Copyright by Tobi Oetiker, 1997-2005 ***************************************************************************** * rrd_update.c RRD Update Function ***************************************************************************** * $Id$ - * $Log$ - * Revision 1.17 2004/05/26 22:11:12 oetiker - * reduce compiler warnings. Many small fixes. -- Mike Slifcak - * - * Revision 1.16 2004/05/25 20:52:16 oetiker - * fix spelling and syntax, especially in messages that are printed -- Mike Slifcak - * - * Revision 1.15 2004/05/25 20:51:49 oetiker - * Update displayed copyright messages to be consistent. -- Mike Slifcak - * - * Revision 1.14 2003/11/11 19:46:21 oetiker - * replaced time_value with rrd_time_value as MacOS X introduced a struct of that name in their standard headers - * - * Revision 1.13 2003/11/11 19:38:03 oetiker - * rrd files should NOT change size ever ... bulk update code wa buggy. - * -- David M. Grimes - * - * Revision 1.12 2003/09/04 13:16:12 oetiker - * should not assigne but compare ... grrrrr - * - * Revision 1.11 2003/09/02 21:58:35 oetiker - * be pickier about what we accept in rrd_update. Complain if things do not work out - * - * Revision 1.10 2003/04/29 19:14:12 jake - * Change updatev RRA return from index_number to cf_nam, pdp_cnt. - * Also revert accidental addition of -I to aclocal MakeMakefile. - * - * Revision 1.9 2003/04/25 18:35:08 jake - * Alternate update interface, updatev. Returns info about CDPs written to disk as result of update. Output format is similar to rrd_info, a hash of key-values. - * - * Revision 1.8 2003/03/31 21:22:12 oetiker - * enables RRDtool updates with microsecond or in case of windows millisecond - * precision. This is needed to reduce time measurement error when archive step - * is small. (<30s) -- Sasha Mikheev - * - * Revision 1.7 2003/02/13 07:05:27 oetiker - * Find attached the patch I promised to send to you. Please note that there - * are three new source files (src/rrd_is_thread_safe.h, src/rrd_thread_safe.c - * and src/rrd_not_thread_safe.c) and the introduction of librrd_th. This - * library is identical to librrd, but it contains support code for per-thread - * global variables currently used for error information only. This is similar - * to how errno per-thread variables are implemented. librrd_th must be linked - * alongside of libpthred - * - * There is also a new file "THREADS", holding some documentation. - * - * -- Peter Stamfest - * - * Revision 1.6 2002/02/01 20:34:49 oetiker - * fixed version number and date/time - * - * Revision 1.5 2001/05/09 05:31:01 oetiker - * Bug fix: when update of multiple PDP/CDP RRAs coincided - * with interpolation of multiple PDPs an incorrect value was - * stored as the CDP. Especially evident for GAUGE data sources. - * Minor changes to rrdcreate.pod. -- Jake Brutlag - * - * Revision 1.4 2001/03/10 23:54:41 oetiker - * Support for COMPUTE data sources (CDEF data sources). Removes the RPN - * parser and calculator from rrd_graph and puts then in a new file, - * rrd_rpncalc.c. Changes to core files rrd_create and rrd_update. Some - * clean-up of aberrant behavior stuff, including a bug fix. - * Documentation update (rrdcreate.pod, rrdupdate.pod). Change xml format. - * -- Jake Brutlag - * - * Revision 1.3 2001/03/04 13:01:55 oetiker - * Aberrant Behavior Detection support. A brief overview added to rrdtool.pod. - * Major updates to rrd_update.c, rrd_create.c. Minor update to other core files. - * This is backwards compatible! But new files using the Aberrant stuff are not readable - * by old rrdtool versions. See http://cricket.sourceforge.net/aberrant/rrd_hw.htm - * -- Jake Brutlag - * - * Revision 1.2 2001/03/04 11:14:25 oetiker - * added at-style-time@value:value syntax to rrd_update - * -- Dave Bodenstab - * - * Revision 1.1.1.1 2001/02/25 22:25:06 oetiker - * checkin - * *****************************************************************************/ #include "rrd_tool.h" @@ -92,7 +13,7 @@ #include #endif -#ifdef WIN32 +#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) #include #include #include @@ -102,32 +23,37 @@ #include "rrd_rpncalc.h" #include "rrd_is_thread_safe.h" +#include "unused.h" -#ifdef WIN32 +#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) /* * WIN32 does not have gettimeofday and struct timeval. This is a quick and dirty * replacement. */ #include +#ifndef __MINGW32__ struct timeval { time_t tv_sec; /* seconds */ long tv_usec; /* microseconds */ }; +#endif struct __timezone { int tz_minuteswest; /* minutes W of Greenwich */ int tz_dsttime; /* type of dst correction */ }; -static gettimeofday(struct timeval *t, struct __timezone *tz) { - - struct timeb current_time; +static int gettimeofday(struct timeval *t, struct __timezone *tz) { + + struct _timeb current_time; _ftime(¤t_time); - + t->tv_sec = current_time.time; t->tv_usec = current_time.millitm * 1000; + + return 0; } #endif @@ -148,7 +74,12 @@ int LockRRD(FILE *rrd_file); #ifdef HAVE_MMAP info_t *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, unsigned long *rra_current, - unsigned short CDP_scratch_idx, FILE *rrd_file, + unsigned short CDP_scratch_idx, +#ifndef DEBUG +FILE UNUSED(*rrd_file), +#else +FILE *rrd_file, +#endif info_t *pcdp_summary, time_t *rra_time, void *rrd_mmaped_file); #else info_t *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, @@ -168,7 +99,7 @@ int main(int argc, char **argv){ rrd_update(argc,argv); if (rrd_test_error()) { - printf("RRDtool 1.1.x Copyright (C) 1997-2004 by Tobias Oetiker \n\n" + printf("RRDtool " PACKAGE_VERSION " Copyright by Tobi Oetiker, 1997-2005\n\n" "Usage: rrdupdate filename\n" "\t\t\t[--template|-t ds-name:ds-name:...]\n" "\t\t\ttime|N:value[:value...]\n\n" @@ -188,6 +119,7 @@ info_t *rrd_update_v(int argc, char **argv) char *template = NULL; info_t *result = NULL; infoval rc; + optind = 0; opterr = 0; /* initialize getopt */ while (1) { static struct option long_options[] = @@ -234,6 +166,7 @@ rrd_update(int argc, char **argv) { char *template = NULL; int rc; + optind = 0; opterr = 0; /* initialize getopt */ while (1) { static struct option long_options[] = @@ -323,9 +256,9 @@ _rrd_update(char *filename, char *template, int argc, char **argv, FILE *rrd_file; rrd_t rrd; - time_t current_time; - time_t rra_time; /* time of update for a RRA */ - unsigned long current_time_usec; /* microseconds part of current time */ + time_t current_time = 0; + time_t rra_time = 0; /* time of update for a RRA */ + unsigned long current_time_usec=0;/* microseconds part of current time */ struct timeval tmp_time; /* used for time conversion */ char **updvals; @@ -597,13 +530,15 @@ _rrd_update(char *filename, char *template, int argc, char **argv, double tmp; tmp = strtod(updvals[0], 0); current_time = floor(tmp); - current_time_usec = (long)((tmp - current_time) * 1000000L); + current_time_usec = (long)((tmp-(double)current_time) * 1000000.0); } /* dont do any correction for old version RRDs */ if(version < 3) current_time_usec = 0; - if(current_time <= rrd.live_head->last_up){ + if(current_time < rrd.live_head->last_up || + (current_time == rrd.live_head->last_up && + (long)current_time_usec <= (long)rrd.live_head->last_up_usec)) { rrd_set_error("illegal attempt to update using time %ld when " "last update time is %ld (minimum one second step)", current_time, rrd.live_head->last_up); @@ -632,12 +567,14 @@ _rrd_update(char *filename, char *template, int argc, char **argv, /* when did the last pdp_st occur */ occu_pdp_age = current_time % rrd.stat_head->pdp_step; occu_pdp_st = current_time - occu_pdp_age; + /* interval = current_time - rrd.live_head->last_up; */ - interval = current_time + ((double)current_time_usec - (double)rrd.live_head->last_up_usec)/1000000.0 - rrd.live_head->last_up; - + interval = (double)(current_time - rrd.live_head->last_up) + + (double)((long)current_time_usec - (long)rrd.live_head->last_up_usec)/1000000.0; + if (occu_pdp_st > proc_pdp_st){ /* OK we passed the pdp_st moment*/ - pre_int = occu_pdp_st - rrd.live_head->last_up; /* how much of the input data + pre_int = (long)occu_pdp_st - rrd.live_head->last_up; /* how much of the input data * occurred before the latest * pdp_st moment*/ pre_int -= ((double)rrd.live_head->last_up_usec)/1000000.0; /* adjust usecs */ @@ -666,10 +603,18 @@ _rrd_update(char *filename, char *template, int argc, char **argv, for(i=0;ids_cnt;i++){ enum dst_en dst_idx; dst_idx= dst_conv(rrd.ds_def[i].dst); - /* NOTE: DST_CDEF should never enter this if block, because - * updvals[i+1][0] is initialized to 'U'; unless the caller - * accidently specified a value for the DST_CDEF. To handle - * this case, an extra check is required. */ + + /* make sure we do not build diffs with old last_ds values */ + if(rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt < interval + && ( dst_idx == DST_COUNTER || dst_idx == DST_DERIVE)){ + strncpy(rrd.pdp_prep[i].last_ds,"U",LAST_DS_LEN-1); + } + + /* NOTE: DST_CDEF should never enter this if block, because + * updvals[i+1][0] is initialized to 'U'; unless the caller + * accidently specified a value for the DST_CDEF. To handle + * this case, an extra check is required. */ + if((updvals[i+1][0] != 'U') && (dst_idx != DST_CDEF) && rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt >= interval) { @@ -788,9 +733,14 @@ _rrd_update(char *filename, char *template, int argc, char **argv, for(i=0;ids_cnt;i++){ if(isnan(pdp_new[i])) - rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt += interval; - else - rrd.pdp_prep[i].scratch[PDP_val].u_val+= pdp_new[i]; + rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt += floor(interval+0.5); + else { + if (isnan( rrd.pdp_prep[i].scratch[PDP_val].u_val )){ + rrd.pdp_prep[i].scratch[PDP_val].u_val= pdp_new[i]; + } else { + rrd.pdp_prep[i].scratch[PDP_val].u_val+= pdp_new[i]; + } + } #ifdef DEBUG fprintf(stderr, "NO PDP ds[%lu]\t" @@ -810,24 +760,33 @@ _rrd_update(char *filename, char *template, int argc, char **argv, pdp_temp[] will contain the rate for cdp */ for(i=0;ids_cnt;i++){ - /* update pdp_prep to the current pdp_st */ + /* update pdp_prep to the current pdp_st. */ + if(isnan(pdp_new[i])) - rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt += pre_int; - else - rrd.pdp_prep[i].scratch[PDP_val].u_val += - pdp_new[i]/(double)interval*(double)pre_int; + rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt += floor(pre_int+0.5); + else { + if (isnan( rrd.pdp_prep[i].scratch[PDP_val].u_val )){ + rrd.pdp_prep[i].scratch[PDP_val].u_val= pdp_new[i]/interval*pre_int; + } else { + rrd.pdp_prep[i].scratch[PDP_val].u_val+= pdp_new[i]/interval*pre_int; + } + } + /* if too much of the pdp_prep is unknown we dump it */ - if ((rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt - > rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt) || + if ( + /* removed because this does not agree with the definition + a heart beat can be unknown */ + /* (rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt + > rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt) || */ (occu_pdp_st-proc_pdp_st <= rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt)) { pdp_temp[i] = DNAN; } else { pdp_temp[i] = rrd.pdp_prep[i].scratch[PDP_val].u_val / (double)( occu_pdp_st - - proc_pdp_st - - rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt); + - proc_pdp_st + - rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt); } /* process CDEF data sources; remember each CDEF DS can @@ -852,12 +811,12 @@ _rrd_update(char *filename, char *template, int argc, char **argv, /* make pdp_prep ready for the next run */ if(isnan(pdp_new[i])){ - rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt = post_int; - rrd.pdp_prep[i].scratch[PDP_val].u_val = 0.0; + rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt = floor(post_int + 0.5); + rrd.pdp_prep[i].scratch[PDP_val].u_val = DNAN; } else { rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt = 0; rrd.pdp_prep[i].scratch[PDP_val].u_val = - pdp_new[i]/(double)interval*(double)post_int; + pdp_new[i]/interval*post_int; } #ifdef DEBUG @@ -1462,11 +1421,7 @@ _rrd_update(char *filename, char *template, int argc, char **argv, * critical except during the burning cycles. */ if (schedule_smooth) { -#ifndef WIN32 - rrd_file = fopen(filename,"r+"); -#else rrd_file = fopen(filename,"rb+"); -#endif rra_start = rra_begin; for (i = 0; i < rrd.stat_head -> rra_cnt; ++i) { @@ -1508,15 +1463,7 @@ LockRRD(FILE *rrdfile) rrd_fd = fileno(rrdfile); { -#ifndef WIN32 - struct flock lock; - lock.l_type = F_WRLCK; /* exclusive write lock */ - lock.l_len = 0; /* whole file */ - lock.l_start = 0; /* start of file */ - lock.l_whence = SEEK_SET; /* end of file */ - - rcstat = fcntl(rrd_fd, F_SETLK, &lock); -#else +#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) struct _stat st; if ( _fstat( rrd_fd, &st ) == 0 ) { @@ -1524,6 +1471,14 @@ LockRRD(FILE *rrdfile) } else { rcstat = -1; } +#else + struct flock lock; + lock.l_type = F_WRLCK; /* exclusive write lock */ + lock.l_len = 0; /* whole file */ + lock.l_start = 0; /* start of file */ + lock.l_whence = SEEK_SET; /* end of file */ + + rcstat = fcntl(rrd_fd, F_SETLK, &lock); #endif } @@ -1534,7 +1489,12 @@ LockRRD(FILE *rrdfile) #ifdef HAVE_MMAP info_t *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, unsigned long *rra_current, - unsigned short CDP_scratch_idx, FILE *rrd_file, + unsigned short CDP_scratch_idx, +#ifndef DEBUG +FILE UNUSED(*rrd_file), +#else +FILE *rrd_file, +#endif info_t *pcdp_summary, time_t *rra_time, void *rrd_mmaped_file) #else info_t