From: Peter Stamfest Date: Mon, 24 Feb 2014 07:19:44 +0000 (+0100) Subject: Refactor all DS definition parsing code. It was not reusable and tied X-Git-Tag: v1.5.0-rc1~132^2~1^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c73078780e7fb249f952762669967bc43d6ec3b5;p=thirdparty%2Frrdtool-1.x.git Refactor all DS definition parsing code. It was not reusable and tied too much to the rrd_t data structure. --- diff --git a/src/Makefile.am b/src/Makefile.am index 79e3e131..b4b9289d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,7 +64,7 @@ noinst_HEADERS = \ rrd_config_bottom.h rrd_i18n.h \ rrd_format.h rrd_tool.h rrd_xport.h rrd.h rrd_rpncalc.h \ rrd_hw.h rrd_hw_math.h rrd_hw_update.h \ - rrd_restore.h \ + rrd_restore.h rrd_create.h \ fnv.h rrd_graph.h \ rrd_is_thread_safe.h diff --git a/src/rrd_create.c b/src/rrd_create.c index e9094c68..e629a89a 100644 --- a/src/rrd_create.c +++ b/src/rrd_create.c @@ -13,6 +13,7 @@ #include "rrd_hw.h" #include "rrd_client.h" #include "rrd_config.h" +#include "rrd_create.h" #include "rrd_is_thread_safe.h" @@ -28,8 +29,7 @@ int create_hw_contingent_rras( unsigned long hashed_name); void parseGENERIC_DS( const char *def, - rrd_t *rrd, - int ds_idx); + ds_def_t *ds_def); static void rrd_free2( rrd_t *rrd); /* our onwn copy, immmune to mmap */ @@ -138,6 +138,59 @@ int rrd_create( return rc; } + +int parseDS(const char *def, + ds_def_t *ds_def, + void *key_hash, + long (*lookup)(void *, char *) + ) +{ + char dummychar1[2], dummychar2[2]; + int offset; + + /* extract the name and type */ + switch (sscanf(def, + DS_NAM_FMT "%1[:]" DST_FMT "%1[:]%n", + ds_def->ds_nam, + dummychar1, + ds_def->dst, + dummychar2, &offset)) { + case 0: + case 1: + rrd_set_error("Invalid DS name in [%s]", def); + return -1; + case 2: + case 3: + rrd_set_error("Invalid DS type in [%s]", def); + return -1; + case 4: /* (%n may or may not be counted) */ + case 5: + break; + default: + rrd_set_error("invalid DS format"); + return -1; + } + + /* parse the remainder of the arguments */ + switch (dst_conv(ds_def->dst)) { + case DST_COUNTER: + case DST_ABSOLUTE: + case DST_GAUGE: + case DST_DERIVE: + parseGENERIC_DS(def + offset, ds_def); + break; + case DST_CDEF: + parseCDEF_DS(def + offset, ds_def, key_hash, lookup); + break; + default: + rrd_set_error("invalid DS type specified"); + return -1; + } + return 0; +} + + + /* #define DEBUG */ /* For backwards compatibility with previous API. Use rrd_create_r2 if you need to have the no_overwrite parameter. */ @@ -160,9 +213,7 @@ int rrd_create_r2( { rrd_t rrd; long i; - int offset; char *token; - char dummychar1[2], dummychar2[2]; unsigned short token_idx, error_flag, period = 0; unsigned long hashed_name; @@ -205,8 +256,6 @@ int rrd_create_r2( * arrays. */ hashed_name = FnvHash(filename); for (i = 0; i < argc; i++) { - unsigned int ii; - if (strncmp(argv[i], "DS:", 3) == 0) { size_t old_size = sizeof(ds_def_t) * (rrd.stat_head->ds_cnt); @@ -218,61 +267,25 @@ int rrd_create_r2( return (-1); } memset(&rrd.ds_def[rrd.stat_head->ds_cnt], 0, sizeof(ds_def_t)); - /* extract the name and type */ - switch (sscanf(&argv[i][3], - DS_NAM_FMT "%1[:]" DST_FMT "%1[:]%n", - rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam, - dummychar1, - rrd.ds_def[rrd.stat_head->ds_cnt].dst, - dummychar2, &offset)) { - case 0: - case 1: - rrd_set_error("Invalid DS name in [%s]",&argv[i][3]); - break; - case 2: - case 3: - rrd_set_error("Invalid DS type in [%s]",&argv[i][3]); - break; - case 4: /* (%n may or may not be counted) */ - case 5: /* check for duplicate datasource names */ - for (ii = 0; ii < rrd.stat_head->ds_cnt; ii++) - if (strcmp(rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam, - rrd.ds_def[ii].ds_nam) == 0) - rrd_set_error("Duplicate DS name: %s", - rrd.ds_def[ii].ds_nam); - /* DS_type may be valid or not. Checked later */ - break; - default: - rrd_set_error("invalid DS format"); - } - if (rrd_test_error()) { - rrd_free2(&rrd); - return -1; - } - /* parse the remainder of the arguments */ - switch (dst_conv(rrd.ds_def[rrd.stat_head->ds_cnt].dst)) { - case DST_COUNTER: - case DST_ABSOLUTE: - case DST_GAUGE: - case DST_DERIVE: - parseGENERIC_DS(&argv[i][offset + 3], &rrd, - rrd.stat_head->ds_cnt); - break; - case DST_CDEF: - parseCDEF_DS(&argv[i][offset + 3], &rrd, - rrd.stat_head->ds_cnt); - break; - default: - rrd_set_error("invalid DS type specified"); - break; - } + parseDS(argv[i] + 3, rrd.ds_def + rrd.stat_head->ds_cnt, + &rrd, lookup_DS); + + /* check for duplicate DS name */ + + if (lookup_DS(&rrd, rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam) + >= 0) { + rrd_set_error("Duplicate DS name: %s", + rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam); + } + + rrd.stat_head->ds_cnt++; if (rrd_test_error()) { rrd_free2(&rrd); return -1; } - rrd.stat_head->ds_cnt++; + } else if (strncmp(argv[i], "RRA:", 4) == 0) { char *argvcopy; char *tokptr = ""; @@ -618,8 +631,7 @@ int rrd_create_r2( void parseGENERIC_DS( const char *def, - rrd_t *rrd, - int ds_idx) + ds_def_t *ds_def) { char minstr[DS_NAM_SIZE], maxstr[DS_NAM_SIZE]; char *old_locale; @@ -633,23 +645,24 @@ void parseGENERIC_DS( */ old_locale = setlocale(LC_NUMERIC, NULL); setlocale(LC_NUMERIC, "C"); + if (sscanf(def, "%lu:%18[^:]:%18[^:]", - &(rrd->ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt), + &(ds_def->par[DS_mrhb_cnt].u_cnt), minstr, maxstr) == 3) { if (minstr[0] == 'U' && minstr[1] == 0) - rrd->ds_def[ds_idx].par[DS_min_val].u_val = DNAN; + ds_def->par[DS_min_val].u_val = DNAN; else - rrd->ds_def[ds_idx].par[DS_min_val].u_val = atof(minstr); + ds_def->par[DS_min_val].u_val = atof(minstr); if (maxstr[0] == 'U' && maxstr[1] == 0) - rrd->ds_def[ds_idx].par[DS_max_val].u_val = DNAN; + ds_def->par[DS_max_val].u_val = DNAN; else - rrd->ds_def[ds_idx].par[DS_max_val].u_val = atof(maxstr); + ds_def->par[DS_max_val].u_val = atof(maxstr); - if (!isnan(rrd->ds_def[ds_idx].par[DS_min_val].u_val) && - !isnan(rrd->ds_def[ds_idx].par[DS_max_val].u_val) && - rrd->ds_def[ds_idx].par[DS_min_val].u_val - >= rrd->ds_def[ds_idx].par[DS_max_val].u_val) { + if (!isnan(ds_def->par[DS_min_val].u_val) && + !isnan(ds_def->par[DS_max_val].u_val) && + ds_def->par[DS_min_val].u_val + >= ds_def->par[DS_max_val].u_val) { rrd_set_error("min must be less than max in DS definition"); setlocale(LC_NUMERIC, old_locale); return; diff --git a/src/rrd_create.h b/src/rrd_create.h new file mode 100644 index 00000000..89a82f6d --- /dev/null +++ b/src/rrd_create.h @@ -0,0 +1,25 @@ +/**************************************************************************** + * RRDtool 1.4.8 Copyright by Tobi Oetiker, 1997-2013 + **************************************************************************** + * rrd_create.h + ****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _RRD_CREATE_H +#define _RRD_CREATE_H + +#include "rrd.h" + +int parseDS(const char *def, + ds_def_t *ds_def, + void *key_hash, + long (*lookup)(void *, char *)); + +#endif + + +#ifdef __cplusplus +} +#endif diff --git a/src/rrd_restore.c b/src/rrd_restore.c index 1fb02e21..1ab92d8a 100644 --- a/src/rrd_restore.c +++ b/src/rrd_restore.c @@ -859,7 +859,8 @@ static int parse_tag_ds_cdef( if (cdef != NULL){ /* We're always working on the last DS that has been added to the structure * when we get here */ - parseCDEF_DS((char *)cdef, rrd, rrd->stat_head->ds_cnt - 1); + parseCDEF_DS((char *)cdef, rrd->ds_def + rrd->stat_head->ds_cnt - 1, + rrd, lookup_DS); xmlFree(cdef); if (rrd_test_error()) return -1; diff --git a/src/rrd_rpncalc.c b/src/rrd_rpncalc.c index 3ac63872..0da4b071 100644 --- a/src/rrd_rpncalc.c +++ b/src/rrd_rpncalc.c @@ -218,16 +218,17 @@ short addop2str( return 0; } -void parseCDEF_DS( - const char *def, - rrd_t *rrd, - int ds_idx) +void parseCDEF_DS(const char *def, + ds_def_t *ds_def, + void *key_hash, + long (*lookup) (void *, char *) + ) { rpnp_t *rpnp = NULL; rpn_cdefds_t *rpnc = NULL; short count, i; - rpnp = rpn_parse((void *) rrd, def, &lookup_DS); + rpnp = rpn_parse(key_hash, def, lookup); if (rpnp == NULL) { rrd_set_error("failed to parse computed data source"); return; @@ -252,7 +253,7 @@ void parseCDEF_DS( return; } /* copy the compact rpn representation over the ds_def par array */ - memcpy((void *) &(rrd->ds_def[ds_idx].par[DS_cdef]), + memcpy((void *) &(ds_def->par[DS_cdef]), (void *) rpnc, count * sizeof(rpn_cdefds_t)); free(rpnp); free(rpnc); diff --git a/src/rrd_rpncalc.h b/src/rrd_rpncalc.h index dd9f109e..26b52cb4 100644 --- a/src/rrd_rpncalc.h +++ b/src/rrd_rpncalc.h @@ -58,8 +58,10 @@ void rpnstack_free( void parseCDEF_DS( const char *def, - rrd_t *rrd, - int ds_idx); + ds_def_t *ds_def, + void *key_hash, + long (*lookup) (void *, char *)); + long lookup_DS( void *rrd_vptr, char *ds_name);