]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
Add new version 5 of the RRD format to be activated when either
authorMaksym Sobolyev <sobomax@sippysoft.com>
Wed, 24 Dec 2014 00:58:52 +0000 (16:58 -0800)
committerMaksym Sobolyev <sobomax@sippysoft.com>
Wed, 24 Dec 2014 00:58:52 +0000 (16:58 -0800)
DCOUNTER or DDERIVE data type is requested. This is to provide
useful error output when trying to read new RRDs using old tools.

src/rrd_create.c
src/rrd_create.h
src/rrd_dump.c
src/rrd_format.h
src/rrd_modify.c
src/rrd_open.c
src/rrd_tune.c

index 7a3a213f035919d2ed33cde63cb6f6d9d7c5ba49..b2dc1578c11e01eb1e9f4f37c741429f52eebf1a 100644 (file)
@@ -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");
index 2d9492f14bb16f724f6d4e446c97bfd196d8d777..faea5488f1765f33e41646ecaf45fe38adc9a548 100644 (file)
@@ -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, 
index dd3879d68ef28fc66f1d9aa7f7fe09ac3ee4928f..39abee5376db3a3c0afe8c6353f6cd775b61a601 100644 (file)
@@ -122,7 +122,7 @@ int rrd_dump_cb_r(
     if (atoi(rrd.stat_head->version) <= 3) {
         CB_FMTS("\t<version>%s</version>\n", RRD_VERSION3);
     } else {
-        CB_FMTS("\t<version>%s</version>\n", RRD_VERSION);
+        CB_FMTS("\t<version>%s</version>\n", rrd.stat_head->version);
     }
     
     CB_FMTS("\t<step>%lu</step> <!-- Seconds -->\n",
index 65ef13c45e9b12774ad63aaa505c42c30e467075..9da3954f1b7d4a32c241047e8d4a156dc8bfbcc9 100644 (file)
@@ -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 {
index ae96f8f6c5175ec43232c37bd2a7ec96d9f1ade4..4f5729de17f4d2c0006c39e6d56317fa35427027 100644 (file)
@@ -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,
index af875ccea8229f6ad002196b40ed8c49e5d6d4c2..2591841f62242e2f38960d1096c3d088ef5270c2 100644 (file)
@@ -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;
index 4d73d41081eb9dc52ce8201c94e4405c84eb974d..eeb517ccc218bc7da8f82b04e496163c9bf4c892 100644 (file)
@@ -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)) {