Merge branch 'master' into ff/rrdd
authorFlorian Forster <octo@leeloo.home.verplant.org>
Sun, 29 Jun 2008 21:38:36 +0000 (23:38 +0200)
committerFlorian Forster <octo@leeloo.home.verplant.org>
Sun, 29 Jun 2008 21:38:36 +0000 (23:38 +0200)
1  2 
doc/rrdgraph.pod
src/rrd_graph.c
src/rrd_update.c

diff --combined doc/rrdgraph.pod
@@@ -248,7 -248,7 +248,7 @@@ to the more robust B<--alt-y-grid> mode
  
  How many digits should rrdtool assume the y-axis labels to be? You
  may have to use this option to make enough space once you start
 -fideling with the y-axis labeling.
 +fiddling with the y-axis labeling.
  
  [B<--units=si>]
  
@@@ -262,20 -262,11 +262,22 @@@ Note that for linear graphs, SI notatio
  
  [B<-z>|B<--lazy>]
  
- Only generate the graph if the current graph is out of date or not
- existent.
+ Only generate the graph if the current graph is out of date or not existent.
+ Note, that only the image size will be returned, if you run with lazy even
+ when using graphv.
  
 +[B<--daemon> I<address>]
 +
 +Address of the L<rrdcached(1)> daemon. If specified, a C<flush> command is sent
 +to the server before reading the RRD files. This allows the graph to contain
 +fresh data even if the daemon is configured to cache values for a long time. To
 +specify a UNIX domain socket use the prefix C<unix:>, see example below. Other
 +addresses are interpreted as normal network addresses, i.E<nbsp>e. IPv4 or IPv6
 +addresses in most cases.
 +
 + rrdtool graph [...] --daemon unix:/var/run/rrdcached.sock [...]
 +
  [B<-f>|B<--imginfo> I<printfstr>]
  
  After the image has been created, the graph function uses printf
@@@ -450,6 -441,8 +452,6 @@@ at least one print statement to generat
  See L<rrdgraph_graph> for the exact format.
  
  
 -=back
 -
  =head2 graphv
  
  Calling rrdtool with the graphv option will return information in the
@@@ -478,21 -471,6 +480,21 @@@ There is more information returned tha
  Especially the 'graph_*' keys are new. They help applications that want to
  know what is where on the graph.
  
 +=head1 ENVIRONMENT VARIABLES
 +
 +The following environment variables may be used to change the behavior of
 +C<rrdtoolE<nbsp>graph>:
 +
 +=over 4
 +
 +=item B<RRDCACHED_ADDRESS>
 +
 +If this environment variable is set it will have the same effect as specifying
 +the C<--daemon> option on the command line. If both are present, the command
 +line argument takes precedence.
 +
 +=back
 +
  =head1 SEE ALSO
  
  L<rrdgraph> gives an overview of how B<rrdtool graph> works.
diff --combined src/rrd_graph.c
@@@ -26,7 -26,6 +26,7 @@@
  #endif
  
  #include "rrd_graph.h"
 +#include "rrd_client.h"
  
  /* some constant definitions */
  
@@@ -303,13 -302,6 +303,13 @@@ int im_free
  
      if (im == NULL)
          return 0;
 +
 +    if (im->use_rrdcached)
 +    {
 +        rrdc_disconnect ();
 +        im->use_rrdcached = 0;
 +    }
 +
      for (i = 0; i < (unsigned) im->gdes_c; i++) {
          if (im->gdes[i].data_first) {
              /* careful here, because a single pointer can occur several times */
@@@ -837,7 -829,6 +837,7 @@@ int data_fetch
                                &im->gdes[i].start,
                                &im->gdes[i].end,
                                &ft_step,
 +                              im->use_rrdcached ? 1 : 0,
                                &im->gdes[i].ds_cnt,
                                &im->gdes[i].ds_namv,
                                &im->gdes[i].data)) == -1) {
@@@ -2960,8 -2951,13 +2960,13 @@@ int graph_paint
      PangoFontMap *font_map = pango_cairo_font_map_get_default();
  
      /* if we are lazy and there is nothing to PRINT ... quit now */
-     if (lazy && im->prt_c == 0)
+     if (lazy && im->prt_c == 0) {
+         info.u_cnt = im->ximg;
+         grinfo_push(im, sprintf_alloc("image_width"), RD_I_CNT, info);
+         info.u_cnt = im->yimg;
+         grinfo_push(im, sprintf_alloc("image_height"), RD_I_CNT, info);
          return 0;
+     }
      /* pull the data from the rrd files ... */
      if (data_fetch(im) == -1)
          return -1;
          return -1;
      /* calculate and PRINT and GPRINT definitions. We have to do it at
       * this point because it will affect the length of the legends
-      * if there are no graph elements we stop here ... 
+      * if there are no graph elements (i==0) we stop here ... 
       * if we are lazy, try to quit ... 
       */
-     i = print_calc(im);
+     i = print_calc(im); 
      if (i < 0)
          return -1;
      if ((i == 0) || lazy)
          return 0;
  /**************************************************************
   *** Calculating sizes and locations became a bit confusing ***
   *** so I moved this into a separate function.              ***
@@@ -3565,7 -3563,11 +3572,11 @@@ int rrd_graph
          walker = walker->next;
      }
      walker = grinfo;
-     while (walker) {
+     *xsize = 0;
+     *ysize = 0;
+     *ymin = 0;
+     *ymax = 0;
+     while (walker) {        
          if (strcmp(walker->key, "image_width") == 0) {
              *xsize = walker->value.u_int;
          } else if (strcmp(walker->key, "image_height") == 0) {
@@@ -3718,7 -3720,6 +3729,7 @@@ void rrd_graph_init
      im->grinfo_current = (rrd_info_t *) NULL;
      im->imgformat = IF_PNG;
      im->imginfo = NULL;
 +    im->use_rrdcached = 0;
      im->lazy = 0;
      im->logarithmic = 0;
      im->maxval = DNAN;
@@@ -3837,7 -3838,6 +3848,7 @@@ void rrd_graph_options
          { "watermark",          required_argument, 0, 'W'},
          { "alt-y-mrtg",         no_argument,       0, 1000},    /* this has no effect it is just here to save old apps from crashing when they use it */
          { "pango-markup",       no_argument,       0, 'P'},
 +        { "daemon",             required_argument, 0, 'd'},
          {  0, 0, 0, 0}
  };
  /* *INDENT-ON* */
          int       col_start, col_end;
  
          opt = getopt_long(argc, argv,
 -                          "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:kP",
 +                          "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:kPd:",
                            long_options, &option_index);
          if (opt == EOF)
              break;
              strncpy(im->watermark, optarg, 100);
              im->watermark[99] = '\0';
              break;
 +        case 'd':
 +        {
 +            int status;
 +            if (im->use_rrdcached)
 +            {
 +                rrd_set_error ("You cannot specify --daemon "
 +                        "more than once.");
 +                return;
 +            }
 +            status = rrdc_connect (optarg);
 +            if (status != 0)
 +            {
 +                rrd_set_error ("rrdc_connect(%s) failed with status %i.",
 +                        optarg, status);
 +                return;
 +            }
 +            im->use_rrdcached = 1;
 +            break;
 +        }
          case '?':
              if (optopt != 0)
                  rrd_set_error("unknown option '%c'", optopt);
                  rrd_set_error("unknown option '%s'", argv[optind - 1]);
              return;
          }
 +    } /* while (1) */
 +
 +    if (im->use_rrdcached == 0)
 +    {
 +        char *temp;
 +
 +        temp = getenv (ENV_RRDCACHED_ADDRESS);
 +        if (temp != NULL)
 +        {
 +            int status;
 +
 +            status = rrdc_connect (temp);
 +            if (status != 0)
 +            {
 +                rrd_set_error ("rrdc_connect(%s) failed with status %i.",
 +                        temp, status);
 +                return;
 +            }
 +            im->use_rrdcached = 1;
 +        }
      }
  
      if (im->logarithmic && im->minval <= 0) {
@@@ -4487,9 -4448,9 +4498,9 @@@ int vdef_calc
      src = &im->gdes[dst->vidx];
      data = src->data + src->ds;
      end =
-         src->end_orig % src->step ==
-         0 ? src->end_orig : (src->end_orig + src->step -
-                              src->end_orig % src->step);
+         src->end_orig % (long)src->step ==
+         0 ? src->end_orig : (src->end_orig + (long)src->step -
+                              src->end_orig % (long)src->step);
  
      steps = (end - src->start) / src->step;
  #if 0
diff --combined src/rrd_update.c
@@@ -1,7 -1,6 +1,7 @@@
  
  /*****************************************************************************
   * RRDtool 1.3.0  Copyright by Tobi Oetiker, 1997-2008
 + *                Copyright by Florian Forster, 2008
   *****************************************************************************
   * rrd_update.c  RRD Update Function
   *****************************************************************************
@@@ -24,8 -23,6 +24,8 @@@
  #include "rrd_is_thread_safe.h"
  #include "unused.h"
  
 +#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
@@@ -377,20 -374,18 +377,20 @@@ int rrd_update
  {
      struct option long_options[] = {
          {"template", required_argument, 0, 't'},
 +        {"daemon",   required_argument, 0, 'd'},
          {0, 0, 0, 0}
      };
      int       option_index = 0;
      int       opt;
      char     *tmplt = NULL;
      int       rc = -1;
 +    char     *daemon = NULL;
  
      optind = 0;
      opterr = 0;         /* initialize getopt */
  
      while (1) {
 -        opt = getopt_long(argc, argv, "t:", long_options, &option_index);
 +        opt = getopt_long(argc, argv, "t:d:", long_options, &option_index);
  
          if (opt == EOF)
              break;
              tmplt = strdup(optarg);
              break;
  
 +        case 'd':
 +            if (daemon != NULL)
 +                free (daemon);
 +            daemon = strdup (optarg);
 +            if (daemon == NULL)
 +            {
 +                rrd_set_error("strdup failed.");
 +                goto out;
 +            }
 +            break;
 +
          case '?':
              rrd_set_error("unknown option '%s'", argv[optind - 1]);
              goto out;
          goto out;
      }
  
 +    if ((tmplt != NULL) && (daemon != NULL))
 +    {
 +        rrd_set_error("The caching daemon cannot be used together with "
 +                "templates yet.");
 +        goto out;
 +    }
 +
 +    if ((tmplt == NULL) && (daemon == NULL))
 +    {
 +        char *temp;
 +
 +        temp = getenv (ENV_RRDCACHED_ADDRESS);
 +        if (temp != NULL)
 +        {
 +            daemon = strdup (temp);
 +            if (daemon == NULL)
 +            {
 +                rrd_set_error("strdup failed.");
 +                goto out;
 +            }
 +        }
 +    }
 +
 +    if (daemon != NULL)
 +    {
 +        int status;
 +
 +        status = rrdc_connect (daemon);
 +        if (status != 0)
 +        {
 +            rrd_set_error("Unable to connect to daemon: %s",
 +                    (status < 0)
 +                    ? "Internal error"
 +                    : rrd_strerror (status));
 +            goto out;
 +        }
 +
 +        status = rrdc_update (/* file = */ argv[optind],
 +                /* values_num = */ argc - optind - 1,
 +                /* values = */ (void *) (argv + optind + 1));
 +        if (status != 0)
 +        {
 +            rrd_set_error("Failed sending the values to the daemon: %s",
 +                    (status < 0)
 +                    ? "Internal error"
 +                    : rrd_strerror (status));
 +        }
 +
 +        rrdc_disconnect ();
 +        goto out;
 +    } /* if (daemon != NULL) */
 +
      rc = rrd_update_r(argv[optind], tmplt,
                        argc - optind - 1, (const char **) (argv + optind + 1));
    out:
 -    free(tmplt);
 +    if (tmplt != NULL)
 +    {
 +        free(tmplt);
 +        tmplt = NULL;
 +    }
 +    if (daemon != NULL)
 +    {
 +        free (daemon);
 +        daemon = NULL;
 +    }
      return rc;
  }
  
@@@ -579,6 -502,15 +579,15 @@@ int _rrd_update
                          rra_step_cnt, updvals, tmpl_idx, tmpl_cnt,
                          &pcdp_summary, version, skip_update,
                          &schedule_smooth) == -1) {
+           if (rrd_test_error()) { /* Should have error string always here */
+               char *save_error;
+               /* Prepend file name to error message */
+               if ((save_error = strdup(rrd_get_error())) != NULL) {
+                   rrd_set_error("%s: %s", filename, save_error);
+                   free(save_error);
+               }
+           }
              free(arg_copy);
              break;
          }