prepare for the release of rrdtool-1.3.0
[rrdtool.git] / src / rrd_tune.c
index df22968..3fa33d9 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.23  Copyright by Tobi Oetiker, 1997-2007
+ * RRDtool 1.3.0  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * change header parameters of an rrd
  *****************************************************************************
@@ -42,6 +42,7 @@
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
 #include "rrd_hw.h"
+#include <locale.h>
 
 int       set_hwarg(
     rrd_t *rrd,
@@ -72,6 +73,26 @@ int rrd_tune(
     double    max;
     char      dst[DST_SIZE];
     rrd_file_t *rrd_file;
+    struct option long_options[] = {
+        {"heartbeat", required_argument, 0, 'h'},
+        {"minimum", required_argument, 0, 'i'},
+        {"maximum", required_argument, 0, 'a'},
+        {"data-source-type", required_argument, 0, 'd'},
+        {"data-source-rename", required_argument, 0, 'r'},
+        /* added parameter tuning options for aberrant behavior detection */
+        {"deltapos", required_argument, 0, 'p'},
+        {"deltaneg", required_argument, 0, 'n'},
+        {"window-length", required_argument, 0, 'w'},
+        {"failure-threshold", required_argument, 0, 'f'},
+        {"alpha", required_argument, 0, 'x'},
+        {"beta", required_argument, 0, 'y'},
+        {"gamma", required_argument, 0, 'z'},
+        {"gamma-deviation", required_argument, 0, 'v'},
+        {"smoothing-window", required_argument, 0, 's'},
+        {"smoothing-window-deviation", required_argument, 0, 'S'},
+        {"aberrant-reset", required_argument, 0, 'b'},
+        {0, 0, 0, 0}
+    };
 
     optind = 0;
     opterr = 0;         /* initialize getopt */
@@ -79,30 +100,14 @@ int rrd_tune(
 
     rrd_file = rrd_open(argv[1], &rrd, RRD_READWRITE);
     if (rrd_file == NULL) {
+        rrd_free(&rrd);
         return -1;
     }
 
     while (1) {
-        static struct option long_options[] = {
-            {"heartbeat", required_argument, 0, 'h'},
-            {"minimum", required_argument, 0, 'i'},
-            {"maximum", required_argument, 0, 'a'},
-            {"data-source-type", required_argument, 0, 'd'},
-            {"data-source-rename", required_argument, 0, 'r'},
-            /* added parameter tuning options for aberrant behavior detection */
-            {"deltapos", required_argument, 0, 'p'},
-            {"deltaneg", required_argument, 0, 'n'},
-            {"window-length", required_argument, 0, 'w'},
-            {"failure-threshold", required_argument, 0, 'f'},
-            {"alpha", required_argument, 0, 'x'},
-            {"beta", required_argument, 0, 'y'},
-            {"gamma", required_argument, 0, 'z'},
-            {"gamma-deviation", required_argument, 0, 'v'},
-            {"aberrant-reset", required_argument, 0, 'b'},
-            {0, 0, 0, 0}
-        };
         int       option_index = 0;
         int       opt;
+        char     *old_locale = "";
 
         opt = getopt_long(argc, argv, "h:i:a:d:r:p:n:w:f:x:y:z:v:b:",
                           long_options, &option_index);
@@ -112,33 +117,39 @@ int rrd_tune(
         optcnt++;
         switch (opt) {
         case 'h':
+            old_locale = setlocale(LC_NUMERIC, "C");
             if ((matches =
                  sscanf(optarg, DS_NAM_FMT ":%ld", ds_nam,
                         &heartbeat)) != 2) {
                 rrd_set_error("invalid arguments for heartbeat");
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
+                setlocale(LC_NUMERIC, old_locale);
                 return -1;
             }
+            setlocale(LC_NUMERIC, old_locale);
             if ((ds = ds_match(&rrd, ds_nam)) == -1) {
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
                 return -1;
             }
             rrd.ds_def[ds].par[DS_mrhb_cnt].u_cnt = heartbeat;
             break;
 
         case 'i':
+            old_locale = setlocale(LC_NUMERIC, "C");
             if ((matches =
                  sscanf(optarg, DS_NAM_FMT ":%lf", ds_nam, &min)) < 1) {
                 rrd_set_error("invalid arguments for minimum ds value");
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
+                setlocale(LC_NUMERIC, old_locale);
                 return -1;
             }
+            setlocale(LC_NUMERIC, old_locale);
             if ((ds = ds_match(&rrd, ds_nam)) == -1) {
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
                 return -1;
             }
 
@@ -148,16 +159,19 @@ int rrd_tune(
             break;
 
         case 'a':
+            old_locale = setlocale(LC_NUMERIC, "C");
             if ((matches =
                  sscanf(optarg, DS_NAM_FMT ":%lf", ds_nam, &max)) < 1) {
                 rrd_set_error("invalid arguments for maximum ds value");
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
+                setlocale(LC_NUMERIC, old_locale);
                 return -1;
             }
+            setlocale(LC_NUMERIC, old_locale);
             if ((ds = ds_match(&rrd, ds_nam)) == -1) {
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
                 return -1;
             }
             if (matches == 1)
@@ -170,28 +184,30 @@ int rrd_tune(
                  sscanf(optarg, DS_NAM_FMT ":" DST_FMT, ds_nam, dst)) != 2) {
                 rrd_set_error("invalid arguments for data source type");
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
                 return -1;
             }
             if ((ds = ds_match(&rrd, ds_nam)) == -1) {
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
                 return -1;
             }
             if ((int) dst_conv(dst) == -1) {
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
                 return -1;
             }
-            strncpy(rrd.ds_def[ds].dst, dst, DST_SIZE - 1);
-            rrd.ds_def[ds].dst[DST_SIZE - 1] = '\0';
-
-            rrd.pdp_prep[ds].last_ds[0] = 'U';
-            rrd.pdp_prep[ds].last_ds[1] = 'N';
-            rrd.pdp_prep[ds].last_ds[2] = 'K';
-            rrd.pdp_prep[ds].last_ds[3] = 'N';
-            rrd.pdp_prep[ds].last_ds[4] = '\0';
+            /* only reset when something is changed */
+            if (strncmp(rrd.ds_def[ds].dst, dst, DST_SIZE - 1) != 0) {
+                strncpy(rrd.ds_def[ds].dst, dst, DST_SIZE - 1);
+                rrd.ds_def[ds].dst[DST_SIZE - 1] = '\0';
 
+                rrd.pdp_prep[ds].last_ds[0] = 'U';
+                rrd.pdp_prep[ds].last_ds[1] = 'N';
+                rrd.pdp_prep[ds].last_ds[2] = 'K';
+                rrd.pdp_prep[ds].last_ds[3] = 'N';
+                rrd.pdp_prep[ds].last_ds[4] = '\0';
+            }
             break;
         case 'r':
             if ((matches =
@@ -199,12 +215,12 @@ int rrd_tune(
                         ds_new)) != 2) {
                 rrd_set_error("invalid arguments for data source type");
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
                 return -1;
             }
             if ((ds = ds_match(&rrd, ds_nam)) == -1) {
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
                 return -1;
             }
             strncpy(rrd.ds_def[ds].ds_nam, ds_new, DS_NAM_SIZE - 1);
@@ -236,14 +252,20 @@ int rrd_tune(
             break;
         case 'x':
             if (set_hwarg(&rrd, CF_HWPREDICT, RRA_hw_alpha, optarg)) {
-                rrd_free(&rrd);
-                return -1;
+                if (set_hwarg(&rrd, CF_MHWPREDICT, RRA_hw_alpha, optarg)) {
+                    rrd_free(&rrd);
+                    return -1;
+                }
+                rrd_clear_error();
             }
             break;
         case 'y':
             if (set_hwarg(&rrd, CF_HWPREDICT, RRA_hw_beta, optarg)) {
-                rrd_free(&rrd);
-                return -1;
+                if (set_hwarg(&rrd, CF_MHWPREDICT, RRA_hw_beta, optarg)) {
+                    rrd_free(&rrd);
+                    return -1;
+                }
+                rrd_clear_error();
             }
             break;
         case 'z':
@@ -262,19 +284,36 @@ int rrd_tune(
             if (sscanf(optarg, DS_NAM_FMT, ds_nam) != 1) {
                 rrd_set_error("invalid argument for aberrant-reset");
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
                 return -1;
             }
             if ((ds = ds_match(&rrd, ds_nam)) == -1) {
                 /* ds_match handles it own errors */
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
                 return -1;
             }
             reset_aberrant_coefficients(&rrd, rrd_file, (unsigned long) ds);
             if (rrd_test_error()) {
                 rrd_free(&rrd);
-                close(rrd_file->fd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            break;
+        case 's':
+            strcpy(rrd.stat_head->version, RRD_VERSION);    /* smoothing_window causes Version 4 */
+            if (set_hwarg
+                (&rrd, CF_SEASONAL, RRA_seasonal_smoothing_window, optarg)) {
+                rrd_free(&rrd);
+                return -1;
+            }
+            break;
+        case 'S':
+            strcpy(rrd.stat_head->version, RRD_VERSION);    /* smoothing_window causes Version 4 */
+            if (set_hwarg
+                (&rrd, CF_DEVSEASONAL, RRA_seasonal_smoothing_window,
+                 optarg)) {
+                rrd_free(&rrd);
                 return -1;
             }
             break;
@@ -284,12 +323,11 @@ int rrd_tune(
             else
                 rrd_set_error("unknown option '%s'", argv[optind - 1]);
             rrd_free(&rrd);
-            close(rrd_file->fd);
+            rrd_close(rrd_file);
             return -1;
         }
     }
     if (optcnt > 0) {
-
         rrd_seek(rrd_file, 0, SEEK_SET);
         rrd_write(rrd_file, rrd.stat_head, sizeof(stat_head_t) * 1);
         rrd_write(rrd_file, rrd.ds_def,
@@ -319,7 +357,7 @@ int rrd_tune(
                 free(buffer);
             }
     }
-    close(rrd_file->fd);
+    rrd_close(rrd_file);
     rrd_free(&rrd);
     return 0;
 }