]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
First step to really integrate modify into tune. Currently implemented
authorPeter Stamfest <peter@stamfest.at>
Mon, 17 Mar 2014 07:39:00 +0000 (08:39 +0100)
committerPeter Stamfest <peter@stamfest.at>
Mon, 17 Mar 2014 11:03:37 +0000 (12:03 +0100)
by doing all the "tune" conversions in place and doing the "modify"
operations through a temporary RRD file with a followed move to
the original file

src/rrd_modify.c
src/rrd_modify.h [new file with mode: 0644]
src/rrd_tune.c

index 360f56fc93b9de126661a1e76c26c9ecbd09f692..d2d35f97d8042357049f93db3554ade6330589dc 100644 (file)
 #include "rrd_restore.h"   /* write_file */
 #include "rrd_create.h"    /* parseDS */
 #include "rrd_update.h"    /* update_cdp */
+#include "rrd_modify.h"
 #include "unused.h"
 
 #include "fnv.h"
 
 #include <locale.h>
 
-typedef struct {
-    /* the index of the RRA to be changed or -1 if there is no current
-       RRA */
-    int index;
-    /* what operation */
-    char op;  // '+', '-', '=', 'a'
-    /* the number originally specified with the operation (eg. rows to
-       be added) */
-    unsigned int row_count;
-    /* the resulting final row count for the RRA */
-    unsigned int final_row_count;
-    /* An RRA definition in case of an addition */
-    char *def;
-} rra_mod_op_t;
-
 // calculate a % b, guaranteeing a positive result...
 static int positive_mod(int a, int b) {
     int x = a % b;
@@ -1519,6 +1505,178 @@ done:
     return rc;
 }
 
+
+int handle_modify(const rrd_t *in, const char *outfilename,
+                 int argc, char **argv, int optind,
+                 int newstep) {
+    // parse add/remove options
+    int rc = -1;
+    int i;
+
+    const char **remove = NULL, **add = NULL;
+    rra_mod_op_t *rra_ops = NULL;
+    int rcnt = 0, acnt = 0, rraopcnt = 0;
+    
+    for (i = optind ; i < argc ; i++) {
+       if (strncmp("DEL:", argv[i], 4) == 0 && strlen(argv[i]) > 4) {
+           remove = realloc(remove, (rcnt + 2) * sizeof(char*));
+           if (remove == NULL) {
+               rrd_set_error("out of memory");
+               rc = -1;
+               goto done;
+           }
+
+           remove[rcnt] = strdup(argv[i] + 4);
+           if (remove[rcnt] == NULL) {
+               rrd_set_error("out of memory");
+               rc = -1;
+               goto done;
+           }
+
+           rcnt++;
+           remove[rcnt] = NULL;
+       } else if (strncmp("DS:", argv[i], 3) == 0 && strlen(argv[i]) > 3) {
+           add = realloc(add, (acnt + 2) * sizeof(char*));
+           if (add == NULL) {
+               rrd_set_error("out of memory");
+               rc = -1;
+               goto done;
+           }
+
+           add[acnt] = strdup(argv[i]);
+           if (add[acnt] == NULL) {
+               rrd_set_error("out of memory");
+               rc = -1;
+               goto done;
+           }
+
+           acnt++;
+           add[acnt] = NULL;
+       } else if (strncmp("RRA#", argv[i], 4) == 0 && strlen(argv[i]) > 4) {
+           rra_mod_op_t rra_mod = { .def = NULL };
+           char sign;
+           unsigned int number;
+           unsigned int index;
+           
+           if (sscanf(argv[i] + 4, "%u:%c%u", &index, &sign, &number) != 3) {
+               rrd_set_error("Failed to parse RRA# command");
+               rc = -1;
+               goto done;
+           }
+
+           rra_mod.index = index;
+           switch (sign) {
+           case '=':
+           case '-':
+           case '+':
+               rra_mod.index = index;
+               rra_mod.op = sign;
+               rra_mod.row_count = number;
+               rra_mod.final_row_count = 0;
+               break;
+           default:
+               rrd_set_error("Failed to parse RRA# command: invalid operation: %c", sign);
+               rc = -1;
+               goto done;
+           }
+
+           rra_ops = copy_over_realloc(rra_ops, rraopcnt,
+                                       &rra_mod, 0, sizeof(rra_mod));
+           if (rra_ops == NULL) {
+               rrd_set_error("out of memory");
+               rc = -1;
+               goto done;
+           }
+           rraopcnt++;
+       } else if (strncmp("RRA:", argv[i], 4) == 0 && strlen(argv[i]) > 4) {
+           rra_mod_op_t rra_mod;
+           rra_mod.op = 'a';
+           rra_mod.index = -1;
+           rra_mod.def = strdup(argv[i]);
+
+           if (rra_mod.def == NULL) {
+               rrd_set_error("out of memory");
+               rc = -1;
+               goto done;
+           }
+
+           rra_ops = copy_over_realloc(rra_ops, rraopcnt,
+                                       &rra_mod, 0, sizeof(rra_mod));
+           if (rra_ops == NULL) {
+               rrd_set_error("out of memory");
+               rc = -1;
+               goto done;
+           }
+           rraopcnt++;
+       } else if (strncmp("DELRRA:", argv[i], 7) == 0 && strlen(argv[i]) > 7) {
+           rra_mod_op_t rra_mod = { .def = NULL,
+                                    .op = '=', 
+                                    .row_count = 0 // eg. deletion
+           };
+           
+           rra_mod.index = atoi(argv[i] + 7);
+           if (rra_mod.index < 0 ) {
+               rrd_set_error("DELRRA requires a non-negative, integer argument");
+               rc = -1;
+               goto done;
+           }
+
+           rra_ops = copy_over_realloc(rra_ops, rraopcnt,
+                                       &rra_mod, 0, sizeof(rra_mod));
+           if (rra_ops == NULL) {
+               rrd_set_error("out of memory");
+               rc = -1;
+               goto done;
+           }
+           rraopcnt++;
+       } else {
+           rrd_set_error("unparseable argument: %s", argv[i]);
+           rc = -1;
+           goto done;
+       }
+    }
+    
+    if (rcnt > 0 || acnt > 0 || rraopcnt > 0) {
+       unsigned long hashed_name = FnvHash(outfilename);
+       rrd_t *out = rrd_modify_r2(in, remove, add, rra_ops, rraopcnt, newstep, hashed_name);
+    
+       if (out == NULL) {
+           goto done;
+       }
+    
+       rc = write_rrd(outfilename, out);
+       rrd_free(out);
+       free(out);
+
+       if (rc < 0) goto done;
+    }
+    
+    rc = argc;
+
+done:
+    if (remove) {
+       for (const char **c = remove ; *c ; c++) {
+           free((void*) *c);
+       }
+       free(remove);
+    } 
+    if (add) {
+       for (const char **c = add ; *c ; c++) {
+           free((void*) *c);
+       }
+       free(add);
+    }
+    if (rra_ops) {
+       for (i = 0 ; i < rraopcnt ; i++) {
+           if (rra_ops[i].def) free(rra_ops[i].def);
+       }
+       free(rra_ops);
+    }
+
+    return rc;
+}
+
+
 int rrd_modify (
     int argc,
     char **argv)
diff --git a/src/rrd_modify.h b/src/rrd_modify.h
new file mode 100644 (file)
index 0000000..6ef906a
--- /dev/null
@@ -0,0 +1,39 @@
+/****************************************************************************
+ * RRDtool 1.4.8  Copyright by Tobi Oetiker, 1997-2013
+ ****************************************************************************
+ * rrd_create.h
+ ****************************************************************************/
+#ifdef  __cplusplus
+extern    "C" {
+#endif
+
+#ifndef _RRD_MODIFY_H
+#define _RRD_MODIFY_H
+
+#include "rrd.h"
+
+typedef struct {
+    /* the index of the RRA to be changed or -1 if there is no current
+ *        RRA */
+    int index;
+    /* what operation */
+    char op;  // '+', '-', '=', 'a'
+    /* the number originally specified with the operation (eg. rows to
+ *        be added) */
+    unsigned int row_count;
+    /* the resulting final row count for the RRA */
+    unsigned int final_row_count;
+    /* An RRA definition in case of an addition */
+    char *def;
+} rra_mod_op_t;
+
+int handle_modify(const rrd_t *in, const char *outfilename,
+                 int argc, char **argv, int optind,
+                 int newstep);
+
+#endif
+
+
+#ifdef  __cplusplus
+}
+#endif
index 0c2a998b13b05bde427da733c3fe72982f86f4f9..bdb1cb6a414a51a2c593b45fccdab3b027958ccc 100644 (file)
@@ -45,6 +45,7 @@
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
 #include "rrd_hw.h"
+#include "rrd_modify.h"
 
 int       set_hwarg(
     rrd_t *rrd,
@@ -81,6 +82,7 @@ int rrd_tune(
     double    max;
     char      dst[DST_SIZE];
     int       rc = -1;
+    int       opt_newstep = -1;
     rrd_file_t *rrd_file;
     struct option long_options[] = {
         {"heartbeat", required_argument, 0, 'h'},
@@ -112,7 +114,7 @@ int rrd_tune(
     opterr = 0;         /* initialize getopt */
 
     rrd_init(&rrd);
-    rrd_file = rrd_open(argv[1], &rrd, RRD_READWRITE);
+    rrd_file = rrd_open(argv[1], &rrd, RRD_READWRITE | RRD_READVALUES);
     if (rrd_file == NULL) {
        goto done;
     }
@@ -282,6 +284,9 @@ int rrd_tune(
                goto done;
             }
             break;
+       case 't':
+           opt_newstep = atoi(optarg);
+           break;
         case '?':
             if (optopt != 0)
                 rrd_set_error("unknown option '%c'", optopt);
@@ -298,7 +303,20 @@ int rrd_tune(
         /* need to write rra_defs for RRA parameter changes */
         rrd_write(rrd_file, rrd.rra_def,
                   sizeof(rra_def_t) * rrd.stat_head->rra_cnt);
-    } else {
+    }
+    
+    // rrd modify functionality
+    rrd_t in;
+    rrd_init(&in);
+     
+    rrd_file = rrd_open(argv[1], &in, RRD_READWRITE | RRD_READAHEAD | RRD_READVALUES);
+    
+    optind = handle_modify(&in, argv[1], argc, argv, optind + 1, opt_newstep);
+    if (optind < 0) {
+       goto done;
+    }
+    
+    if (optcnt == 0) {
         int       i;
 
         for (i = 0; i < (int) rrd.stat_head->ds_cnt; i++)