case DST_ABSOLUTE:
case DST_GAUGE:
case DST_DERIVE:
- parseGENERIC_DS(def + offset, ds_def);
+ case DST_DCOUNTER:
+ case DST_DDERIVE:
+ strncpy(ds_def->dst, dst_tmp, DST_SIZE);
+ parseGENERIC_DS(dst_args, ds_def);
break;
case DST_CDEF:
- parseCDEF_DS(def + offset, ds_def, key_hash, lookup);
+ strncpy(ds_def->dst, dst_tmp, DST_SIZE);
+ parseCDEF_DS(dst_args, ds_def, key_hash, lookup);
break;
default:
- rrd_set_error("invalid DS type specified");
- return -1;
+ rrd_set_error("invalid DS type specified (%s)", dst_tmp);
+ goto done;
}
- return 0;
+
+ // mapping, but only if we are interested in it...
+ if (mapping) {
+ char *endptr;
+ g_match_info_fetch_pos(mi, MAPPED_DS_NAME_SUBGROUP, &s, &e);
+
+ mapping->ds_nam = strdup(ds_def->ds_nam);
+ mapping->mapped_name = strndup(def + s, e - s);
+
+ if (mapping->ds_nam == NULL || mapping->mapped_name == NULL) {
+ rrd_set_error("Cannot allocate memory");
+ goto done;
+ }
+ g_match_info_fetch_pos(mi, OPT_MAPPED_INDEX_SUBGROUP, &s, &e);
+
+ /* we do not have to check for errors: invalid indices will be checked later,
+ * and syntactically, the RE has done the job for us already*/
+ mapping->index = s != e ? strtol(def + s, &endptr, 10) : -1;
+ }
+ rc = 0;
+
+ done:
+ if (re) {
+ g_match_info_free(mi);
+ g_regex_unref(re);
+ }
+
+ if (dst_tmp) free(dst_tmp);
+ if (dst_args) free(dst_args);
+ return rc;
}
-
int parseRRA(const char *def,
rra_def_t *rra_def,
rrd_t *rrd,
{
unsigned long ds_idx;
int ii;
- double rate, newval, oldval;
- char *old_locale;
- double rate;
- double tmp;
++ double rate, newval, oldval, tmp;
enum dst_en dst_idx;
for (ds_idx = 0; ds_idx < rrd->stat_head->ds_cnt; ds_idx++) {
}
break;
case DST_ABSOLUTE:
- old_locale = setlocale(LC_NUMERIC, "C");
- if (rrd_get_double(updvals[ds_idx + 1], &newval) != 0) {
- setlocale(LC_NUMERIC, old_locale);
+ if( rrd_strtodbl(updvals[ds_idx + 1], NULL, &pdp_new[ds_idx], "Function update_pdp_prep, case DST_ABSOLUTE" ) != 2 ) {
return -1;
}
- setlocale(LC_NUMERIC, old_locale);
+ pdp_new[ds_idx] = newval;
rate = pdp_new[ds_idx] / interval;
break;
case DST_GAUGE:
- old_locale = setlocale(LC_NUMERIC, "C");
- if (rrd_get_double(updvals[ds_idx + 1], &newval) != 0) {
- setlocale(LC_NUMERIC, old_locale);
- if( rrd_strtodbl( updvals[ds_idx + 1], NULL, &tmp, "Function update_pdp_prep, case DST_GAUGE") == 2 ) {
- pdp_new[ds_idx] = tmp * interval;
- } else {
++ if( rrd_strtodbl( updvals[ds_idx + 1], NULL, &newval, "Function update_pdp_prep, case DST_GAUGE") != 2 ) {
return -1;
}
- setlocale(LC_NUMERIC, old_locale);
- rate = pdp_new[ds_idx] / interval;
+ pdp_new[ds_idx] = newval * interval;
+ rate = newval;
break;
- old_locale = setlocale(LC_NUMERIC, NULL);
- setlocale(LC_NUMERIC, "C");
- if (rrd_get_double(updvals[ds_idx + 1], &newval) != 0) {
- setlocale(LC_NUMERIC, old_locale);
+ case DST_DCOUNTER:
+ case DST_DDERIVE:
+ if (rrd->pdp_prep[ds_idx].last_ds[0] != 'U') {
- if (rrd_get_double(rrd->pdp_prep[ds_idx].last_ds, &oldval) != 0) {
- setlocale(LC_NUMERIC, old_locale);
++ const char *e_msg;
++
++ if (dst_idx == DST_DCOUNTER) {
++ e_msg = "Function update_pdp_prep, case DST_DCOUNTER";
++ } else {
++ e_msg = "Function update_pdp_prep, case DST_DDERIVE";
++ }
++ if (rrd_strtodbl(updvals[ds_idx + 1], NULL, &newval, e_msg) != 2) {
+ return -1;
+ }
- setlocale(LC_NUMERIC, old_locale);
++ if (rrd_strtodbl(rrd->pdp_prep[ds_idx].last_ds, NULL, &oldval, e_msg) != 2) {
+ return -1;
+ }
+ if (dst_idx == DST_DCOUNTER) {
+ /*
+ * DST_DCOUNTER is always signed, so it can count either up,
+ * or down, but not both at the same time. Changing direction
+ * considered a "reset".
+ */
+ if ((newval > 0 && oldval > newval) ||
+ (newval < 0 && newval > oldval)) {
+ /* Counter reset detected */
+ pdp_new[ds_idx] = DNAN;
+ break;
+ }
+ }
+ pdp_new[ds_idx] = newval - oldval;
+ rate = pdp_new[ds_idx] / interval;
+ } else {
+ pdp_new[ds_idx] = DNAN;
+ }
+ break;
default:
rrd_set_error("rrd contains unknown DS type : '%s'",
rrd->ds_def[ds_idx].dst);