From: oetiker Date: Mon, 11 Oct 2010 07:48:45 +0000 (+0000) Subject: * introduce a new rrd_create_r2 call to fix the no-overwrite api mess X-Git-Url: https://git.octo.it/?p=rrdtool.git;a=commitdiff_plain;h=bb124879717bdb65640cd50ce99e3569cb0a9a3f * introduce a new rrd_create_r2 call to fix the no-overwrite api mess * various fixes to new rrd_cached comands as suggested by kevin 1. Remove opt_no_overwrite and the rrd_create_set_no_overwrite function as they are ugly. Make opt_no_overwrite a local var. 2. Add 'no_overwrite' param to the rrd_create_r and rename as rrd_create_r2, add rrd_create_r that calls rrd_create_r2 with a 0 for the no_overwrite function, preserving the API parameter format but allowing an extended arg list that can be used by rrd_create and rrd_handle_request_create 3. Add -O option to rrdcached command line to force no-overwrite on any creates 4. Add -O option on create via rrdcached to optionally add no-overwrite (cannot remove it is it was previously set at start) 5. Fix rrd_handle_request_last to check the queue instead of forcing a flush. Remove -no-flush option from LAST command since it is now no longer relevant as we're querying the cache chain 6. Fix ulong/unsigned long issue for compilation under windows 7. Change rrd_handle_request_create to only accept timestamp parameters, not at-syntax, in order to be threadsafe. This is no loss since the rrd_client already pre-parses any at-style syntax 8. Reinstate missing free() in rrd_info.c and rrd_last.c -- steve shipway git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@2136 a5681a0c-68f1-0310-ab6d-d61299d08faa --- diff --git a/src/librrd.sym.in.in b/src/librrd.sym.in.in index 458601f..442c8b3 100644 --- a/src/librrd.sym.in.in +++ b/src/librrd.sym.in.in @@ -6,7 +6,7 @@ rrd_clear_error rrd_close rrd_create rrd_create_r -rrd_create_set_no_overwrite +rrd_create_r2 rrd_dontneed rrd_dump rrd_dump_r diff --git a/src/rrd.h b/src/rrd.h index 331339d..7e63110 100644 --- a/src/rrd.h +++ b/src/rrd.h @@ -143,8 +143,6 @@ extern "C" { int rrd_create( int, char **); - void rrd_create_set_no_overwrite( - int); rrd_info_t *rrd_info( int, char **); @@ -228,6 +226,14 @@ extern "C" { const char *filename, unsigned long pdp_step, time_t last_up, + /* int no_overwrite, */ + int argc, + const char **argv); + int rrd_create_r2( + const char *filename, + unsigned long pdp_step, + time_t last_up, + int no_overwrite, int argc, const char **argv); rrd_info_t *rrd_info_r( diff --git a/src/rrd_create.c b/src/rrd_create.c index 707e601..f221c99 100644 --- a/src/rrd_create.c +++ b/src/rrd_create.c @@ -14,7 +14,6 @@ #include "rrd_client.h" #include "rrd_is_thread_safe.h" -static int opt_no_overwrite = 0; #ifdef WIN32 # include @@ -34,12 +33,6 @@ void parseGENERIC_DS( static void rrd_free2( rrd_t *rrd); /* our onwn copy, immmune to mmap */ -void rrd_create_set_no_overwrite( - int opt ) -{ - opt_no_overwrite = (opt?1:0); -} - int rrd_create( int argc, char **argv) @@ -60,6 +53,7 @@ int rrd_create( long long_tmp; int rc; char * opt_daemon = NULL; + int opt_no_overwrite = 0; optind = 0; opterr = 0; /* initialize getopt */ @@ -135,8 +129,8 @@ int rrd_create( pdp_step, last_up, opt_no_overwrite, argc - optind - 1, (const char **) (argv + optind + 1)); } else { - rc = rrd_create_r(argv[optind], - pdp_step, last_up, + rc = rrd_create_r2(argv[optind], + pdp_step, last_up, opt_no_overwrite, argc - optind - 1, (const char **) (argv + optind + 1)); } @@ -144,6 +138,8 @@ int rrd_create( } /* #define DEBUG */ +/* For backwards compatibility with previous API. Use rrd_create_r2 if you + need to have the no_overwrite parameter. */ int rrd_create_r( const char *filename, unsigned long pdp_step, @@ -151,6 +147,16 @@ int rrd_create_r( int argc, const char **argv) { + return rrd_create_r2(filename,pdp_step,last_up,0,argc,argv); +} +int rrd_create_r2( + const char *filename, + unsigned long pdp_step, + time_t last_up, + int no_overwrite, + int argc, + const char **argv) +{ rrd_t rrd; long i; int offset; @@ -584,7 +590,7 @@ int rrd_create_r( rrd_free2(&rrd); return (-1); } - return rrd_create_fn(filename, &rrd); + return rrd_create_fn(filename, &rrd, no_overwrite); } void parseGENERIC_DS( @@ -708,7 +714,8 @@ int create_hw_contingent_rras( int rrd_create_fn( const char *file_name, - rrd_t *rrd) + rrd_t *rrd, + int no_overwrite ) { unsigned long i, ii; rrd_value_t *unknown; @@ -717,7 +724,7 @@ int rrd_create_fn( rrd_t rrd_dn; unsigned rrd_flags = RRD_READWRITE | RRD_CREAT; - if (opt_no_overwrite) { + if (no_overwrite) { rrd_flags |= RRD_EXCL ; } diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c index bfcf6a3..9062927 100644 --- a/src/rrd_daemon.c +++ b/src/rrd_daemon.c @@ -71,7 +71,7 @@ #endif #endif -#include "rrd.h" +#include "rrd_tool.h" #include "rrd_client.h" #include "unused.h" @@ -275,7 +275,7 @@ static uint64_t stats_journal_bytes = 0; static uint64_t stats_journal_rotate = 0; static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER; -static int opt_no_overwrite = 0; +static int opt_no_overwrite = 0; /* default for the daemon */ /* Journaled updates */ #define JOURNAL_REPLAY(s) ((s) == NULL) @@ -1776,13 +1776,17 @@ static int handle_request_first (HANDLER_PROTO) /* {{{ */ return send_response(sock, RESP_ERR, "RRD Error: %s\n", rrd_get_error()); } return send_response(sock, RESP_OK, "%lu\n",(unsigned)t); -} /* }}} static int handle_request_last */ +} /* }}} static int handle_request_first */ + static int handle_request_last (HANDLER_PROTO) /* {{{ */ { char *file, file_tmp[PATH_MAX]; int status; - time_t t; + time_t t, from_file, step; + rrd_file_t * rrd_file; + cache_item_t * ci; + rrd_t rrd; /* obtain filename */ status = buffer_get_field(&buffer, &buffer_size, &file); @@ -1793,12 +1797,27 @@ static int handle_request_last (HANDLER_PROTO) /* {{{ */ if (!check_file_access(file, sock)) { return send_response(sock, RESP_ERR, "Cannot read: %s\n", file); } - /* get data */ - rrd_clear_error (); - t = rrd_last_r(file); - if(t<1) { + rrd_clear_error(); + rrd_init(&rrd); + rrd_file = rrd_open(file,&rrd,RRD_READONLY); + if(!rrd_file) { return send_response(sock, RESP_ERR, "RRD Error: %s\n", rrd_get_error()); } + from_file = rrd.live_head->last_up; + step = rrd.stat_head->pdp_step; + rrd_close(rrd_file); + pthread_mutex_lock(&cache_lock); + ci = g_tree_lookup(cache_tree, file); + if (ci) + t = ci->last_update_stamp; + else + t = from_file; + pthread_mutex_unlock(&cache_lock); + t -= t % step; + rrd_free(&rrd); + if(t<1) { + return send_response(sock, RESP_ERR, "Error: rrdcached: Invalid timestamp returned\n"); + } return send_response(sock, RESP_OK, "%lu\n",(unsigned)t); } /* }}} static int handle_request_last */ @@ -1809,10 +1828,8 @@ static int handle_request_create (HANDLER_PROTO) /* {{{ */ int ac = 0; char *av[128]; int status; - ulong step = 300; + unsigned long step = 300; time_t last_up = time(NULL)-10; - rrd_time_value_t last_up_tv; - char *parsetime_error = NULL; int no_overwrite = opt_no_overwrite; @@ -1827,19 +1844,11 @@ static int handle_request_create (HANDLER_PROTO) /* {{{ */ } RRDD_LOG(LOG_INFO, "rrdcreate request for %s",file); - status = buffer_get_field(&buffer, &buffer_size, &tok ); - for(;(tok && !status);status = buffer_get_field(&buffer, &buffer_size, &tok )) { + while ((status = buffer_get_field(&buffer, &buffer_size, &tok)) == 0 && tok) { if( ! strncmp(tok,"-b",2) ) { status = buffer_get_field(&buffer, &buffer_size, &tok ); if (status != 0) return syntax_error(sock,cmd); - if ((parsetime_error = rrd_parsetime(tok, &last_up_tv))) - return send_response(sock, RESP_ERR, "start time: %s\n", parsetime_error); - if (last_up_tv.type == RELATIVE_TO_END_TIME || - last_up_tv.type == RELATIVE_TO_START_TIME) { - return send_response(sock, RESP_ERR, "Cannot specify time relative to start or end here.\n"); - } - last_up = mktime(&last_up_tv.tm) +last_up_tv.offset; - + last_up = (time_t) atol(tok); continue; } if( ! strncmp(tok,"-s",2) ) { @@ -1863,9 +1872,8 @@ static int handle_request_create (HANDLER_PROTO) /* {{{ */ return send_response(sock, RESP_ERR, "The first entry must be after 1980.\n"); } - rrd_create_set_no_overwrite(no_overwrite); rrd_clear_error (); - status = rrd_create_r(file,step,last_up,ac,(const char **)av); + status = rrd_create_r2(file,step,last_up,no_overwrite,ac,(const char **)av); if(!status) { return send_response(sock, RESP_OK, "RRD created OK\n"); @@ -2062,6 +2070,8 @@ static command_t list_of_commands[] = { /* {{{ */ "CREATE [-b start] [-s step] [-O] \n", "The CREATE command will create an RRD file, overwriting any existing file\n" "unless the -O option is given or rrdcached was started with the -O option.\n" + "The start parameter needs to be in seconds since 1/1/70 (AT-style syntax is\n" + "not acceptable) and the step is in seconds (default is 300).\n" "The DS and RRA definitions are as for the 'rrdtool create' command.\n" }, { diff --git a/src/rrd_info.c b/src/rrd_info.c index d86a907..2f6c07f 100644 --- a/src/rrd_info.c +++ b/src/rrd_info.c @@ -152,6 +152,7 @@ rrd_info_t *rrd_info( else info = rrd_info_r(argv[optind]); + if (opt_daemon) free(opt_daemon); return (info); } /* rrd_info_t *rrd_info */ diff --git a/src/rrd_last.c b/src/rrd_last.c index 7fb3cb8..90bcae7 100644 --- a/src/rrd_last.c +++ b/src/rrd_last.c @@ -14,9 +14,7 @@ time_t rrd_last( char **argv) { char *opt_daemon = NULL; - int status; time_t lastupdate; - int flushfirst = 1; optind = 0; opterr = 0; /* initialize getopt */ @@ -26,11 +24,10 @@ time_t rrd_last( int option_index = 0; static struct option long_options[] = { {"daemon", required_argument, 0, 'd'}, - {"noflush", no_argument, 0, 'F'}, {0, 0, 0, 0} }; - opt = getopt_long(argc, argv, "d:F", long_options, &option_index); + opt = getopt_long(argc, argv, "d:", long_options, &option_index); if (opt == EOF) break; @@ -47,12 +44,8 @@ time_t rrd_last( } break; - case 'F': - flushfirst = 0; - break; - default: - rrd_set_error ("Usage: rrdtool %s [--daemon [--noflush]] ", + rrd_set_error ("Usage: rrdtool %s [--daemon ] ", argv[0]); return (-1); break; @@ -60,16 +53,11 @@ time_t rrd_last( } /* while (42) */ if ((argc - optind) != 1) { - rrd_set_error ("Usage: rrdtool %s [--daemon [--noflush]] ", + rrd_set_error ("Usage: rrdtool %s [--daemon ] ", argv[0]); return (-1); } - if(flushfirst) { - status = rrdc_flush_if_daemon(opt_daemon, argv[optind]); - if (status) return (-1); - } - rrdc_connect (opt_daemon); if (rrdc_is_connected (opt_daemon)) lastupdate = rrdc_last (argv[optind]); @@ -77,6 +65,7 @@ time_t rrd_last( else lastupdate = rrd_last_r(argv[optind]); + if (opt_daemon) free(opt_daemon); return (lastupdate); } diff --git a/src/rrd_tool.h b/src/rrd_tool.h index 7d8368a..de35e46 100644 --- a/src/rrd_tool.h +++ b/src/rrd_tool.h @@ -82,7 +82,8 @@ extern "C" { int rrd_create_fn( const char *file_name, - rrd_t *rrd); + rrd_t *rrd, + int no_overwrite); int rrd_fetch_fn (const char *filename, enum cf_en cf_idx, time_t *start,