From: Maksym Sobolyev Date: Wed, 24 Dec 2014 00:58:52 +0000 (-0800) Subject: Add new version 5 of the RRD format to be activated when either X-Git-Tag: v1.5.0-rc1~6^2~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1dc72c8b0bcbc8f1f7555da2c399326ee7eb29ab;p=thirdparty%2Frrdtool-1.x.git Add new version 5 of the RRD format to be activated when either DCOUNTER or DDERIVE data type is requested. This is to provide useful error output when trying to read new RRDs using old tools. --- diff --git a/src/rrd_create.c b/src/rrd_create.c index 7a3a213f..b2dc1578 100644 --- a/src/rrd_create.c +++ b/src/rrd_create.c @@ -271,8 +271,8 @@ int parseDS(const char *def, ds_def_t *ds_def, void *key_hash, long (*lookup)(void *, char *), - mapping_t *mapping - ) + mapping_t *mapping, + const char **require_version) { int rc = -1; char *dst_tmp = NULL; @@ -339,6 +339,11 @@ int parseDS(const char *def, dst_tmp = strndup(def + s, e - s); dst_args = strndup(def + s2, e2 - s2); + if ((dst_conv(dst_tmp) == DST_DCOUNTER || dst_conv(dst_tmp) == DST_DDERIVE) && + (*require_version == NULL || atoi(*require_version) < atoi(RRD_VERSION5))) { + *require_version = RRD_VERSION5; + } + switch (dst_conv(dst_tmp)) { case DST_COUNTER: case DST_ABSOLUTE: @@ -405,14 +410,14 @@ done: int parseRRA(const char *def, rra_def_t *rra_def, rrd_t *rrd, - unsigned long hash) { + unsigned long hash, + const char **require_version) { char *argvcopy; char *tokptr = ""; unsigned short token_idx, error_flag, period = 0; int cf_id = -1; int token_min = 4; const char *parsetime_error = NULL; - char *require_version = NULL; memset(rra_def, 0, sizeof(rra_def_t)); @@ -428,7 +433,9 @@ int parseRRA(const char *def, cf_id = cf_conv(rra_def->cf_nam); switch (cf_id) { case CF_MHWPREDICT: - require_version = RRD_VERSION; /* MHWPREDICT causes Version 4 */ + if (*require_version == NULL || atoi(*require_version) < atoi(RRD_VERSION4)) { + *require_version = RRD_VERSION4; /* MHWPREDICT causes Version 4 */ + } case CF_HWPREDICT: token_min = 5; /* initialize some parameters */ @@ -599,7 +606,9 @@ int parseRRA(const char *def, if (sscanf(token, "smoothing-window=%lf", &(rra_def->par[RRA_seasonal_smoothing_window]. u_val))) { - require_version = RRD_VERSION; /* smoothing-window causes Version 4 */ + if (*require_version == NULL || atoi(require_version) < atoi(RRD_VERSION4)) { + *require_version = RRD_VERSION4; /* smoothing-window causes Version 4 */ + } if (rra_def->par[RRA_seasonal_smoothing_window].u_val < 0.0 || rra_def->par[RRA_seasonal_smoothing_window].u_val > 1.0) { @@ -659,14 +668,6 @@ int parseRRA(const char *def, return(-1); } - // parsing went well. ONLY THEN are we allowed to produce - // additional side effects. - if (require_version != NULL) { - if (rrd) { - strcpy(rrd->stat_head->version, RRD_VERSION); - } - } - #ifdef DEBUG fprintf(stderr, "Creating RRA CF: %s, dep idx %lu\n", @@ -753,6 +754,7 @@ int rrd_create_r2( GList *sources_rrd_files = NULL; mapping_t *mappings = NULL; int mappings_cnt = 0; + const char *require_version = NULL; /* clear any previous errors */ rrd_clear_error(); @@ -854,7 +856,7 @@ int rrd_create_r2( memset(&rrd.ds_def[rrd.stat_head->ds_cnt], 0, sizeof(ds_def_t)); parseDS(argv[i] + 3, rrd.ds_def + rrd.stat_head->ds_cnt, - &rrd, lookup_DS, &m); + &rrd, lookup_DS, &m, &require_version); mappings = realloc(mappings, sizeof(mapping_t) * (mappings_cnt + 1)); if (! mappings) { @@ -888,7 +890,7 @@ int rrd_create_r2( } parseRRA(argv[i], rrd.rra_def + rrd.stat_head->rra_cnt, &rrd, - hashed_name); + hashed_name, &require_version); if (rrd_test_error()) { goto done; @@ -906,7 +908,11 @@ int rrd_create_r2( goto done; } } - + // parsing went well. ONLY THEN are we allowed to produce + // additional side effects. + if (require_version != NULL) { + strcpy(rrd.stat_head->version, require_version); + } if (rrd.stat_head->rra_cnt < 1) { rrd_set_error("you must define at least one Round Robin Archive"); diff --git a/src/rrd_create.h b/src/rrd_create.h index 2d9492f1..faea5488 100644 --- a/src/rrd_create.h +++ b/src/rrd_create.h @@ -23,7 +23,8 @@ int parseDS(const char *def, ds_def_t *ds_def, void *key_hash, long (*lookup)(void *, char *), - mapping_t *mapping); + mapping_t *mapping, + const char **require_version); /* Parse a textual RRA definition into rra_def. The rra_def might be disconnected from any RRD. However, because some definitions cause @@ -38,7 +39,8 @@ int parseDS(const char *def, int parseRRA(const char *def, rra_def_t *rra_def, rrd_t *rrd, - unsigned long hash); + unsigned long hash, + const char **require_version); rra_def_t *handle_dependent_rras(rra_def_t *rra_def_array, long unsigned int *rra_cnt, diff --git a/src/rrd_dump.c b/src/rrd_dump.c index dd3879d6..39abee53 100644 --- a/src/rrd_dump.c +++ b/src/rrd_dump.c @@ -122,7 +122,7 @@ int rrd_dump_cb_r( if (atoi(rrd.stat_head->version) <= 3) { CB_FMTS("\t%s\n", RRD_VERSION3); } else { - CB_FMTS("\t%s\n", RRD_VERSION); + CB_FMTS("\t%s\n", rrd.stat_head->version); } CB_FMTS("\t%lu \n", diff --git a/src/rrd_format.h b/src/rrd_format.h index 65ef13c4..9da3954f 100644 --- a/src/rrd_format.h +++ b/src/rrd_format.h @@ -33,8 +33,9 @@ #define RRD_COOKIE "RRD" /* #define RRD_VERSION "0002" */ /* changed because microsecond precision requires another field */ -#define RRD_VERSION "0004" #define RRD_VERSION3 "0003" +#define RRD_VERSION4 "0004" +#define RRD_VERSION5 "0005" #define FLOAT_COOKIE ((double)8.642135E130) typedef union unival { diff --git a/src/rrd_modify.c b/src/rrd_modify.c index ae96f8f6..4f5729de 100644 --- a/src/rrd_modify.c +++ b/src/rrd_modify.c @@ -334,13 +334,15 @@ static int add_dss(const rrd_t UNUSED(*in), rrd_t *out, int rc = -1; int j; const char *c; + const char *require_version = NULL; + for (j = 0, c = addDS[j] ; c ; j++, c = addDS[j]) { ds_def_t added; // parse DS parseDS(c + 3, &added, // out.ds_def + out.stat_head->ds_cnt, - out, lookup_DS, NULL); + out, lookup_DS, NULL, &require_version); // check if there is a name clash with an existing DS if (lookup_DS(&out, added.ds_nam) >= 0) { @@ -767,8 +769,8 @@ static rrd_t *rrd_modify_structure(const rrd_t *in, files should be modified, a dump/restore cycle should be done.... */ - if (! (strcmp(in->stat_head->version, RRD_VERSION3) == 0 || strcmp(in->stat_head->version, RRD_VERSION) == 0) ) { - rrd_set_error("direct modification is only supported for version 3 or version 4 RRD files. Consider to dump/restore before retrying a modification"); + if (atoi(in->stat_head->version) < atoi(RRD_VERSION3) || atoi(in->stat_head->version) > atoi(RRD_VERSION5)) { + rrd_set_error("direct modification is only supported for version 3, 4 or 5 of RRD files. Consider to dump/restore before retrying a modification"); goto done; } @@ -1184,6 +1186,7 @@ static int add_rras(const rrd_t *in, rrd_t *out, const int *ds_map, unsigned int last_rra_cnt = out->stat_head->rra_cnt; int total_out_rra_rows = 0; int total_cnt_out = 0; + const char *require_version = NULL; memset(&empty_cdp_prep, 0, sizeof(cdp_prep_t)); @@ -1199,7 +1202,7 @@ static int add_rras(const rrd_t *in, rrd_t *out, const int *ds_map, rra_def_t rra_def; // the hash doesn't really matter... - parseRRA(rra_mod_ops[r].def, &rra_def, out, hash); + parseRRA(rra_mod_ops[r].def, &rra_def, out, hash, &require_version); if (rrd_test_error()) { // failed!!! @@ -1220,6 +1223,10 @@ static int add_rras(const rrd_t *in, rrd_t *out, const int *ds_map, } } + if (require_version != NULL && atoi(require_version) < atoi(out->stat_head->version)) { + strcpy(out->stat_head->version, require_version); + } + if (last_rra_cnt < out->stat_head->rra_cnt) { // extend cdp_prep and rra_ptr arrays out->cdp_prep = (cdp_prep_t *) realloc(out->cdp_prep, diff --git a/src/rrd_open.c b/src/rrd_open.c index af875cce..2591841f 100644 --- a/src/rrd_open.c +++ b/src/rrd_open.c @@ -332,7 +332,7 @@ rrd_file_t *rrd_open( version = atoi(rrd->stat_head->version); - if (version > atoi(RRD_VERSION)) { + if (version > atoi(RRD_VERSION5)) { rrd_set_error("can't handle RRD file version %s", rrd->stat_head->version); goto out_nullify_head; diff --git a/src/rrd_tune.c b/src/rrd_tune.c index 4d73d410..eeb517cc 100644 --- a/src/rrd_tune.c +++ b/src/rrd_tune.c @@ -345,14 +345,18 @@ int rrd_tune( } break; case 's': - strcpy(rrd.stat_head->version, RRD_VERSION); /* smoothing_window causes Version 4 */ + if (atoi(rrd.stat_head->version) < atoi(RRD_VERSION4)) { + strcpy(rrd.stat_head->version, RRD_VERSION4); /* smoothing_window causes Version 4 */ + } if (set_hwsmootharg (&rrd, CF_SEASONAL, RRA_seasonal_smoothing_window, optarg)) { goto done; } break; case 'S': - strcpy(rrd.stat_head->version, RRD_VERSION); /* smoothing_window causes Version 4 */ + if (atoi(rrd.stat_head->version) < atoi(RRD_VERSION4)) { + strcpy(rrd.stat_head->version, RRD_VERSION4); /* smoothing_window causes Version 4 */ + } if (set_hwsmootharg (&rrd, CF_DEVSEASONAL, RRA_seasonal_smoothing_window, optarg)) {