From 7831eea1399b921a0fc8f7826316aa2974af9ff6 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Sat, 20 Sep 2008 20:47:58 +0200 Subject: [PATCH] Added upstream patch bts499350-data-corruption. This fixes data corruption when updating multiple values in one go. Closes: #499350 --- debian/changelog | 8 ++ debian/patches/bts499350-data-corruption | 158 +++++++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 167 insertions(+) create mode 100644 debian/patches/bts499350-data-corruption diff --git a/debian/changelog b/debian/changelog index 702068c..8ad64ff 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +rrdtool (1.3.1-4) unstable; urgency=low + + * debian/patches: + - Added upstream patch bts499350-data-corruption to fix data corruption + when updating multiple values in one go (Closes: #499350). + + -- Sebastian Harl Sat, 20 Sep 2008 20:41:28 +0200 + rrdtool (1.3.1-3) unstable; urgency=low * Added "libxml2-dev" to librrd-dev's dependencies (Closes: #493342). diff --git a/debian/patches/bts499350-data-corruption b/debian/patches/bts499350-data-corruption new file mode 100644 index 0000000..a2425e4 --- /dev/null +++ b/debian/patches/bts499350-data-corruption @@ -0,0 +1,158 @@ +diff a/src/rrd_update.c b/src/rrd_update.c +--- a/src/rrd_update.c ++++ b/src/rrd_update.c +@@ -780,12 +780,10 @@ static int process_arg( + } + /* seek to the beginning of the rra's */ + if (*rra_current != rra_begin) { +-#ifndef HAVE_MMAP + if (rrd_seek(rrd_file, rra_begin, SEEK_SET) != 0) { + rrd_set_error("seek error in rrd"); + return -1; + } +-#endif + *rra_current = rra_begin; + } + rra_start = rra_begin; +@@ -1868,95 +1866,70 @@ static int write_to_rras( + { + unsigned long rra_idx; + unsigned long rra_start; +- unsigned long rra_pos_tmp; /* temporary byte pointer. */ + time_t rra_time = 0; /* time of update for a RRA */ + ++ unsigned long ds_cnt = rrd->stat_head->ds_cnt; ++ + /* Ready to write to disk */ + rra_start = rra_begin; ++ + for (rra_idx = 0; rra_idx < rrd->stat_head->rra_cnt; rra_idx++) { +- /* skip unless there's something to write */ +- if (rra_step_cnt[rra_idx]) { +- /* write the first row */ ++ rra_def_t *rra_def = &rrd->rra_def[rra_idx]; ++ rra_ptr_t *rra_ptr = &rrd->rra_ptr[rra_idx]; ++ ++ /* for cdp_prep */ ++ unsigned short scratch_idx; ++ unsigned long step_subtract; ++ ++ for (scratch_idx = CDP_primary_val, ++ step_subtract = 1; ++ rra_step_cnt[rra_idx] > 0; ++ rra_step_cnt[rra_idx]--, ++ scratch_idx = CDP_secondary_val, ++ step_subtract = 2) { ++ ++ unsigned long rra_pos_new; + #ifdef DEBUG + fprintf(stderr, " -- RRA Preseek %ld\n", rrd_file->pos); + #endif +- rrd->rra_ptr[rra_idx].cur_row++; +- if (rrd->rra_ptr[rra_idx].cur_row >= +- rrd->rra_def[rra_idx].row_cnt) +- rrd->rra_ptr[rra_idx].cur_row = 0; /* wrap around */ +- /* position on the first row */ +- rra_pos_tmp = rra_start + +- (rrd->stat_head->ds_cnt) * (rrd->rra_ptr[rra_idx].cur_row) * +- sizeof(rrd_value_t); +- if (rra_pos_tmp != *rra_current) { +- if (rrd_seek(rrd_file, rra_pos_tmp, SEEK_SET) != 0) { ++ /* increment, with wrap-around */ ++ if (++rra_ptr->cur_row >= rra_def->row_cnt) ++ rra_ptr->cur_row = 0; ++ ++ /* we know what our position should be */ ++ rra_pos_new = rra_start ++ + ds_cnt * rra_ptr->cur_row * sizeof(rrd_value_t); ++ ++ /* re-seek if the position is wrong or we wrapped around */ ++ if (rra_pos_new != *rra_current || rra_ptr->cur_row == 0) { ++ if (rrd_seek(rrd_file, rra_pos_new, SEEK_SET) != 0) { + rrd_set_error("seek error in rrd"); + return -1; + } +- *rra_current = rra_pos_tmp; ++ *rra_current = rra_pos_new; + } + #ifdef DEBUG + fprintf(stderr, " -- RRA Postseek %ld\n", rrd_file->pos); + #endif +- if (!skip_update[rra_idx]) { +- if (*pcdp_summary != NULL) { +- rra_time = (current_time - current_time +- % (rrd->rra_def[rra_idx].pdp_cnt * +- rrd->stat_head->pdp_step)) +- - +- ((rra_step_cnt[rra_idx] - +- 1) * rrd->rra_def[rra_idx].pdp_cnt * +- rrd->stat_head->pdp_step); +- } +- if (write_RRA_row +- (rrd_file, rrd, rra_idx, rra_current, CDP_primary_val, +- pcdp_summary, rra_time) == -1) +- return -1; +- } + +- /* write other rows of the bulk update, if any */ +- for (; rra_step_cnt[rra_idx] > 1; rra_step_cnt[rra_idx]--) { +- if (++rrd->rra_ptr[rra_idx].cur_row == +- rrd->rra_def[rra_idx].row_cnt) { +-#ifdef DEBUG +- fprintf(stderr, +- "Wraparound for RRA %s, %lu updates left\n", +- rrd->rra_def[rra_idx].cf_nam, +- rra_step_cnt[rra_idx] - 1); +-#endif +- /* wrap */ +- rrd->rra_ptr[rra_idx].cur_row = 0; +- /* seek back to beginning of current rra */ +- if (rrd_seek(rrd_file, rra_start, SEEK_SET) != 0) { +- rrd_set_error("seek error in rrd"); +- return -1; +- } +-#ifdef DEBUG +- fprintf(stderr, " -- Wraparound Postseek %ld\n", +- rrd_file->pos); +-#endif +- *rra_current = rra_start; +- } +- if (!skip_update[rra_idx]) { +- if (*pcdp_summary != NULL) { +- rra_time = (current_time - current_time +- % (rrd->rra_def[rra_idx].pdp_cnt * +- rrd->stat_head->pdp_step)) +- - +- ((rra_step_cnt[rra_idx] - +- 2) * rrd->rra_def[rra_idx].pdp_cnt * +- rrd->stat_head->pdp_step); +- } +- if (write_RRA_row(rrd_file, rrd, rra_idx, rra_current, +- CDP_secondary_val, pcdp_summary, +- rra_time) == -1) +- return -1; +- } ++ if (skip_update[rra_idx]) ++ continue; ++ ++ if (*pcdp_summary != NULL) { ++ unsigned long step_time = rra_def->pdp_cnt * rrd->stat_head->pdp_step; ++ ++ rra_time = (current_time - current_time % step_time) ++ - ((rra_step_cnt[rra_idx] - step_subtract) * step_time); + } ++ ++ if (write_RRA_row ++ (rrd_file, rrd, rra_idx, rra_current, scratch_idx, ++ pcdp_summary, rra_time) == -1) ++ return -1; + } +- rra_start += rrd->rra_def[rra_idx].row_cnt * rrd->stat_head->ds_cnt * +- sizeof(rrd_value_t); +- } /* RRA LOOP */ ++ ++ rra_start += rra_def->row_cnt * ds_cnt * sizeof(rrd_value_t); ++ } /* RRA LOOP */ + + return 0; + } diff --git a/debian/patches/series b/debian/patches/series index cd2055f..a900298 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -4,3 +4,4 @@ setup.py-module-name no-rpath-for-ruby no-rpath-for-perl implicit-decl-fix +bts499350-data-corruption -- 2.30.2