/*****************************************************************************
- * RRDtool 1.2.23 Copyright by Tobi Oetiker, 1997-2007
+ * RRDtool 1.2.99907080300 Copyright by Tobi Oetiker, 1997-2007
*****************************************************************************
* rrd_update.c RRD Update Function
*****************************************************************************
#include <io.h>
#endif
+#include <locale.h>
+
#include "rrd_hw.h"
#include "rrd_rpncalc.h"
char *tmplt = NULL;
info_t *result = NULL;
infoval rc;
+ struct option long_options[] = {
+ {"template", required_argument, 0, 't'},
+ {0, 0, 0, 0}
+ };
rc.u_int = -1;
optind = 0;
opterr = 0; /* initialize getopt */
while (1) {
- static struct option long_options[] = {
- {"template", required_argument, 0, 't'},
- {0, 0, 0, 0}
- };
int option_index = 0;
int opt;
int argc,
char **argv)
{
+ struct option long_options[] = {
+ {"template", required_argument, 0, 't'},
+ {0, 0, 0, 0}
+ };
+ int option_index = 0;
+ int opt;
char *tmplt = NULL;
int rc;
opterr = 0; /* initialize getopt */
while (1) {
- static struct option long_options[] = {
- {"template", required_argument, 0, 't'},
- {0, 0, 0, 0}
- };
- int option_index = 0;
- int opt;
-
opt = getopt_long(argc, argv, "t:", long_options, &option_index);
if (opt == EOF)
switch (opt) {
case 't':
- tmplt = optarg;
+ tmplt = strdup(optarg);
break;
case '?':
rc = rrd_update_r(argv[optind], tmplt,
argc - optind - 1, (const char **) (argv + optind + 1));
+ free(tmplt);
return rc;
}
if (rrd_file == NULL) {
goto err_free;
}
+ /* We are now at the beginning of the rra's */
+ rra_current = rra_start = rra_begin = rrd_file->header_len;
/* initialize time */
version = atoi(rrd.stat_head->version);
current_time_usec = 0;
}
- rra_current = rra_start = rra_begin = rrd_file->header_len;
- /* This is defined in the ANSI C standard, section 7.9.5.3:
-
- When a file is opened with udpate mode ('+' as the second
- or third character in the ... list of mode argument
- variables), both input and output may be performed on the
- associated stream. However, ... input may not be directly
- followed by output without an intervening call to a file
- positioning function, unless the input operation encounters
- end-of-file. */
-#if 0 //def HAVE_MMAP
- rrd_filesize = rrd_file->file_size;
- fseek(rrd_file->fd, 0, SEEK_END);
- rrd_filesize = ftell(rrd_file->fd);
- fseek(rrd_file->fd, rra_current, SEEK_SET);
-#else
-// fseek(rrd_file->fd, 0, SEEK_CUR);
-#endif
-
-
/* get exclusive lock to whole file.
* lock gets removed when we close the file.
*/
rrd_set_error("allocating pdp_new ...");
goto err_free_tmpl_idx;
}
-#if 0 //def HAVE_MMAP
- rrd_mmaped_file = mmap(0,
- rrd_file->file_len,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, fileno(in_file), 0);
- if (rrd_mmaped_file == MAP_FAILED) {
- rrd_set_error("error mmapping file %s", filename);
- free(updvals);
- free(pdp_temp);
- free(tmpl_idx);
- rrd_free(&rrd);
- rrd_close(rrd_file);
- return (-1);
- }
-#ifdef USE_MADVISE
- /* when we use mmaping we tell the kernel the mmap equivalent
- of POSIX_FADV_RANDOM */
- madvise(rrd_mmaped_file, rrd_filesize, POSIX_MADV_RANDOM);
-#endif
-#endif
/* loop through the arguments. */
for (arg_i = 0; arg_i < argc; arg_i++) {
char *stepper = strdup(argv[arg_i]);
}
/* initialize all ds input to unknown except the first one
which has always got to be set */
- memset(updvals + 1, 'U', rrd.stat_head->ds_cnt);
+ for (ii = 1; ii <= rrd.stat_head->ds_cnt; ii++)
+ updvals[ii] = "U";
updvals[0] = stepper;
/* separate all ds elements; first must be examined separately
due to alternate time syntax */
current_time_usec = tmp_time.tv_usec;
} else {
double tmp;
+ char *old_locale;
+ old_locale = setlocale(LC_NUMERIC, "C");
tmp = strtod(updvals[0], 0);
+ setlocale(LC_NUMERIC, old_locale);
current_time = floor(tmp);
current_time_usec =
(long) ((tmp - (double) current_time) * 1000000.0);
break;
}
-
/* seek to the beginning of the rra's */
if (rra_current != rra_begin) {
#ifndef HAVE_MMAP
(dst_idx != DST_CDEF) &&
rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt >= interval) {
double rate = DNAN;
+ char *old_locale;
/* the data source type defines how to process the data */
/* pdp_new contains rate * time ... eg the bytes
switch (dst_idx) {
case DST_COUNTER:
case DST_DERIVE:
- if (rrd.pdp_prep[i].last_ds[0] != 'U') {
- for (ii = 0; updvals[i + 1][ii] != '\0'; ii++) {
- if ((updvals[i + 1][ii] < '0'
- || updvals[i + 1][ii] > '9') && (ii != 0
- && updvals[i
- +
- 1]
- [ii] !=
- '-')) {
- rrd_set_error("not a simple integer: '%s'",
- updvals[i + 1]);
- break;
- }
- }
- if (rrd_test_error()) {
+ for (ii = 0; updvals[i + 1][ii] != '\0'; ii++) {
+ if ((updvals[i + 1][ii] < '0'
+ || updvals[i + 1][ii] > '9') && (ii != 0
+ && updvals[i
+ + 1]
+ [ii] != '-')) {
+ rrd_set_error("not a simple integer: '%s'",
+ updvals[i + 1]);
break;
}
+ }
+ if (rrd_test_error()) {
+ break;
+ }
+ if (rrd.pdp_prep[i].last_ds[0] != 'U') {
pdp_new[i] =
rrd_diff(updvals[i + 1], rrd.pdp_prep[i].last_ds);
if (dst_idx == DST_COUNTER) {
}
break;
case DST_ABSOLUTE:
+ old_locale = setlocale(LC_NUMERIC, "C");
errno = 0;
pdp_new[i] = strtod(updvals[i + 1], &endptr);
+ setlocale(LC_NUMERIC, old_locale);
if (errno > 0) {
rrd_set_error("converting '%s' to float: %s",
updvals[i + 1], rrd_strerror(errno));
break;
case DST_GAUGE:
errno = 0;
+ old_locale = setlocale(LC_NUMERIC, "C");
pdp_new[i] = strtod(updvals[i + 1], &endptr) * interval;
+ setlocale(LC_NUMERIC, old_locale);
if (errno > 0) {
rrd_set_error("converting '%s' to float: %s",
updvals[i + 1], rrd_strerror(errno));
u_val = seasonal_coef[ii];
break;
case CF_HWPREDICT:
+ case CF_MHWPREDICT:
/* need to update the null_count and last_null_count.
* even do this for non-DNAN pdp_temp because the
* algorithm is not learning from batch updates. */
free(rra_step_cnt);
rpnstack_free(&rpnstack);
-#if 0 //def HAVE_MMAP
- if (munmap(rrd_file->file_start, rrd_file->file_len) == -1) {
- rrd_set_error("error writing(unmapping) file: %s", filename);
- }
-#else
+#if 0
//rrd_flush(rrd_file); //XXX: really needed?
#endif
/* if we got here and if there is an error and if the file has not been
rrd_set_error("seek rrd for live header writeback");
goto err_free_pdp_new;
}
+ /* for mmap, we did already write to the underlying mapping, so we do
+ not need to write again. */
#ifndef HAVE_MMAP
if (version >= 3) {
if (rrd_write(rrd_file, rrd.live_head,
goto err_free_pdp_new;
}
#endif
-#ifdef HAVE_POSIX_FADVISExxx
-
- /* with update we have write ops, so they will probably not be done by now, this means
- the buffers will not get freed. But calling this for the whole file - header
- will let the data off the hook as soon as it is written when if it is from a previous
- update cycle. Calling fdsync to force things is much too hard here. */
- if (0 != posix_fadvise(rrd_file->fd, rra_begin, 0, POSIX_FADV_DONTNEED)) {
- rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s", filename,
- rrd_strerror(errno));
- goto err_free_pdp_new;
- }
-#endif
/* rrd_flush(rrd_file); */
/* calling the smoothing code here guarantees at most
rra_start += rrd.rra_def[i].row_cnt
* rrd.stat_head->ds_cnt * sizeof(rrd_value_t);
}
-#ifdef HAVE_POSIX_FADVISExxx
- /* same procedure as above ... */
- if (0 !=
- posix_fadvise(rrd_file->fd, rra_begin, 0, POSIX_FADV_DONTNEED)) {
- rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s", filename,
- rrd_strerror(errno));
- goto err_free_pdp_new;
- }
-#endif
}
+/* rrd_dontneed(rrd_file,&rrd); */
rrd_free(&rrd);
rrd_close(rrd_file);