]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
New rrd_update switch --skip-past-updates
authorTobias Oetiker <tobi@oetiker.ch>
Tue, 13 Nov 2012 14:56:47 +0000 (15:56 +0100)
committerTobias Oetiker <tobi@oetiker.ch>
Tue, 13 Nov 2012 14:56:47 +0000 (15:56 +0100)
When updateing an rrd file with data earlier than the latest update already
applied, rrdtool will issue an error message an abort. This option instructs
rrdtool to silently skip such data. It can be useful when re-playing old
data into an rrd file and you are not sure how many updates have already
been applied.

doc/rrdupdate.pod
src/librrd.sym.in.in
src/rrd.h
src/rrd_tool.c
src/rrd_update.c
src/rrdupdate.c

index 67908d016f986d6d64ee9af32d07160694267d6d..a7d65199494d81b96b43dd487713d905efbd8031 100644 (file)
@@ -60,6 +60,14 @@ function. If this is done accidentally (and this can only be done
 using the template switch), B<RRDtool> will ignore the value specified
 for the COMPUTE B<DST>.
 
+=item B<--skip-past-updates>
+
+When updateing an rrd file with data earlier than the latest update already
+applied, rrdtool will issue an error message an abort. This option instructs
+rrdtool to silently skip such data. It can be useful when re-playing old
+data into an rrd file and you are not sure how many updates have already
+been applied.
+
 =item B<--daemon> I<address>
 
 If given, B<RRDTool> will try to connect to the caching daemon L<rrdcached>
index 442c8b3562eac0cad7063c96ec0636a804103427..dd31b6278f4dd8533561d1c26015e57273942d7c 100644 (file)
@@ -56,6 +56,7 @@ rrd_test_error
 rrd_tune
 rrd_update
 rrd_update_r
+rrd_updatex_r
 rrd_update_v
 rrd_update_v_r
 rrd_version
index dc996695678714e29835102288012936e9fec4e5..256d9fa371c1cf7d895e024959a053cf1ac1a6fc 100644 (file)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -254,6 +254,23 @@ extern    "C" {
     int argc,
     const char **argv,
     rrd_info_t * pcdp_summary);
+
+/* extra flags */
+#define RRD_SKIP_PAST_UPDATES 0x01
+
+    int       rrd_updatex_r(
+    const char *filename,
+    const char *_template,
+    int extra_flags,
+    int argc,
+    const char **argv);
+    int       rrd_updatex_v_r(
+    const char *filename,
+    const char *_template,
+    int extra_flags,
+    int argc,
+    const char **argv,
+    rrd_info_t * pcdp_summary);
     int rrd_fetch_r (
             const char *filename,
             const char *cf,
index 24abcdce9c36a4ad445e4cc9ddd3bd8509fbdf45..8c1b67479b517396d3b5f2739f1af59fb28e00f0 100644 (file)
@@ -99,6 +99,7 @@ void PrintUsage(
         N_("* update - update an RRD\n\n"
            "\trrdtool update filename\n"
            "\t\t[--template|-t ds-name:ds-name:...]\n"
+           "\t\t[--skip-past-updates]\n"
           "\t\t[--daemon <address>]\n"
            "\t\ttime|N:value[:value...]\n\n"
            "\t\tat-time@value[:value...]\n\n"
@@ -109,6 +110,7 @@ void PrintUsage(
            "\treturns information about values, RRAs, and datasources updated\n\n"
            "\trrdtool updatev filename\n"
            "\t\t[--template|-t ds-name:ds-name:...]\n"
+           "\t\t[--skip-past-updates]\n"
            "\t\ttime|N:value[:value...]\n\n"
            "\t\tat-time@value[:value...]\n\n"
            "\t\t[ time:value[:value...] ..]\n");
index c5917c0b93158fb93cb6963b19b1069128685cd9..9e28b2ddf0a3834a3c3c262ade1b7a0d752a6832 100644 (file)
@@ -3,8 +3,6 @@
  *                Copyright by Florian Forster, 2008
  *****************************************************************************
  * rrd_update.c  RRD Update Function
- *****************************************************************************
- * $Id$
  *****************************************************************************/
 
 #include "rrd_tool.h"
@@ -17,6 +15,9 @@
 
 #include <locale.h>
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include "rrd_hw.h"
 #include "rrd_rpncalc.h"
 
@@ -26,6 +27,7 @@
 #include "rrd_client.h"
 
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+
 /*
  * WIN32 does not have gettimeofday    and struct timeval. This is a quick and dirty
  * replacement.
@@ -68,9 +70,10 @@ int       rrd_update_r(
     const char *tmplt,
     int argc,
     const char **argv);
-int       _rrd_update(
+int       _rrd_updatex(
     const char *filename,
     const char *tmplt,
+    int extra_flags,
     int argc,
     const char **argv,
     rrd_info_t *);
@@ -319,11 +322,13 @@ rrd_info_t *rrd_update_v(
     char **argv)
 {
     char     *tmplt = NULL;
+    int      extra_flags = 0;
     rrd_info_t *result = NULL;
     rrd_infoval_t rc;
     char *opt_daemon = NULL;
     struct option long_options[] = {
         {"template", required_argument, 0, 't'},
+        {"skip-past-updates",  no_argument, 0, 's'},
         {0, 0, 0, 0}
     };
 
@@ -335,7 +340,7 @@ rrd_info_t *rrd_update_v(
         int       option_index = 0;
         int       opt;
 
-        opt = getopt_long(argc, argv, "t:", long_options, &option_index);
+        opt = getopt_long(argc, argv, "st:", long_options, &option_index);
 
         if (opt == EOF)
             break;
@@ -367,7 +372,7 @@ rrd_info_t *rrd_update_v(
     }
     rc.u_int = 0;
     result = rrd_info_push(NULL, sprintf_alloc("return_value"), RD_I_INT, rc);
-    rc.u_int = _rrd_update(argv[optind], tmplt,
+    rc.u_int = _rrd_updatex(argv[optind], tmplt,extra_flags,
                            argc - optind - 1,
                            (const char **) (argv + optind + 1), result);
     result->value.u_int = rc.u_int;
@@ -382,11 +387,13 @@ int rrd_update(
     struct option long_options[] = {
         {"template", required_argument, 0, 't'},
         {"daemon",   required_argument, 0, 'd'},
+        {"skip-past-updates",  no_argument, 0, 's'},
         {0, 0, 0, 0}
     };
     int       option_index = 0;
     int       opt;
-    char     *tmplt = NULL;
+    int       extra_flags = 0;
+    char      *tmplt = NULL;
     int       rc = -1;
     char     *opt_daemon = NULL;
 
@@ -394,7 +401,7 @@ int rrd_update(
     opterr = 0;         /* initialize getopt */
 
     while (1) {
-        opt = getopt_long(argc, argv, "t:d:", long_options, &option_index);
+        opt = getopt_long(argc, argv, "t:d:s", long_options, &option_index);
 
         if (opt == EOF)
             break;
@@ -404,6 +411,10 @@ int rrd_update(
             tmplt = strdup(optarg);
             break;
 
+        case 's':
+            extra_flags |= RRD_SKIP_PAST_UPDATES;
+            break;
+
         case 'd':
             if (opt_daemon != NULL)
                 free (opt_daemon);
@@ -435,16 +446,16 @@ int rrd_update(
         }        
     }
 
-    if ((tmplt != NULL) && rrdc_is_connected(opt_daemon))
+    if (((tmplt != NULL) || (extra_flags != 0)) && rrdc_is_connected(opt_daemon))
     {
         rrd_set_error("The caching daemon cannot be used together with "
-                "templates yet.");
+                "templates and skip-past-updates yet.");
         goto out;
     }
 
     if (! rrdc_is_connected(opt_daemon))
     {
-      rc = rrd_update_r(argv[optind], tmplt,
+      rc = rrd_updatex_r(argv[optind], tmplt,extra_flags,
                         argc - optind - 1, (const char **) (argv + optind + 1));
     }
     else /* we are connected */
@@ -477,7 +488,7 @@ int rrd_update_r(
     int argc,
     const char **argv)
 {
-    return _rrd_update(filename, tmplt, argc, argv, NULL);
+    return _rrd_updatex(filename, tmplt, 0, argc, argv, NULL);
 }
 
 int rrd_update_v_r(
@@ -487,12 +498,34 @@ int rrd_update_v_r(
     const char **argv,
     rrd_info_t * pcdp_summary)
 {
-    return _rrd_update(filename, tmplt, argc, argv, pcdp_summary);
+    return _rrd_updatex(filename, tmplt, 0, argc, argv, pcdp_summary);
 }
 
-int _rrd_update(
+int rrd_updatex_r(
     const char *filename,
     const char *tmplt,
+    int extra_flags,
+    int argc,
+    const char **argv)
+{
+    return _rrd_updatex(filename, tmplt, extra_flags, argc, argv, NULL);
+}
+
+int rrd_updatex_v_r(
+    const char *filename,
+    const char *tmplt,
+    int extra_flags,
+    int argc,
+    const char **argv,
+    rrd_info_t * pcdp_summary)
+{
+    return _rrd_updatex(filename, tmplt, extra_flags, argc, argv, pcdp_summary);
+}
+
+int _rrd_updatex(
+    const char *filename,
+    const char *tmplt,
+    int extra_flags,
     int argc,
     const char **argv,
     rrd_info_t * pcdp_summary)
@@ -524,6 +557,7 @@ int _rrd_update(
     rrd_file_t *rrd_file;
     char     *arg_copy; /* for processing the argv */
     unsigned long *skip_update; /* RRAs to advance but not write */
+    int      process_ret;
 
     /* need at least 1 arguments: data. */
     if (argc < 1) {
@@ -563,11 +597,12 @@ int _rrd_update(
             rrd_set_error("failed duplication argv entry");
             break;
         }
-        if (process_arg(arg_copy, &rrd, rrd_file, rra_begin,
+        process_ret = process_arg(arg_copy, &rrd, rrd_file, rra_begin,
                         &current_time, &current_time_usec, pdp_temp, pdp_new,
                         rra_step_cnt, updvals, tmpl_idx, tmpl_cnt,
                         &pcdp_summary, version, skip_update,
-                        &schedule_smooth) == -1) {
+                        &schedule_smooth);
+        if ( ( process_ret == -1 ) || ( ! (extra_flags & RRD_SKIP_PAST_UPDATES) && process_ret == -2 ) ) {
             if (rrd_test_error()) { /* Should have error string always here */
                 char     *save_error;
 
@@ -580,6 +615,9 @@ int _rrd_update(
             free(arg_copy);
             break;
         }
+        if ( process_ret == -2 ){
+            rrd_clear_error();
+        }
         free(arg_copy);
     }
 
@@ -774,7 +812,7 @@ static int parse_template(
  * Parse an update string, updates the primary data points (PDPs)
  * and consolidated data points (CDPs), and writes changes to the RRAs.
  *
- * Returns 0 on success, -1 on error.
+ * Returns 0 on success, -1 on error, -2 on time stamp error.
  */
 static int process_arg(
     char *step_start,
@@ -802,10 +840,10 @@ static int process_arg(
     double    interval, pre_int, post_int;  /* interval between this and
                                              * the last run */
     unsigned long proc_pdp_cnt;
-
-    if (parse_ds(rrd, updvals, tmpl_idx, step_start, tmpl_cnt,
-                 current_time, current_time_usec, version) == -1) {
-        return -1;
+    int ds_ret;
+    if ((ds_ret = parse_ds(rrd, updvals, tmpl_idx, step_start, tmpl_cnt,
+                 current_time, current_time_usec, version)) != 0) {
+        return ds_ret;
     }
 
     interval = (double) (*current_time - rrd->live_head->last_up)
@@ -931,12 +969,9 @@ static int parse_ds(
         return -1;
     }
 
-    if (get_time_from_reading(rrd, timesyntax, updvals,
+    return get_time_from_reading(rrd, timesyntax, updvals,
                               current_time, current_time_usec,
-                              version) == -1) {
-        return -1;
-    }
-    return 0;
+                              version);
 }
 
 /*
@@ -1008,7 +1043,7 @@ static int get_time_from_reading(
         rrd_set_error("illegal attempt to update using time %ld when "
                       "last update time is %ld (minimum one second step)",
                       *current_time, rrd->live_head->last_up);
-        return -1;
+        return -2;
     }
     return 0;
 }
index 5a6301ede83eb6816c24ffa24a206110efd3ac46..cfd1894c3d84d9c79deb02920d36b803d5ca82de 100644 (file)
@@ -53,6 +53,7 @@ int main(
        else {
             printf("Usage: rrdupdate <filename>\n"
                    "\t\t\t[--template|-t ds-name[:ds-name]...]\n"
+                   "\t\t\t[--skip-past-updates]\n"
                    "\t\t\ttime|N:value[:value...]\n\n"
                    "\t\t\tat-time@value[:value...]\n\n"
                    "\t\t\t[ time:value[:value...] ..]\n\n");