summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: aa840c7)
raw | patch | inline | side by side (parent: aa840c7)
author | Sebastian Harl <sh@tokkee.org> | |
Sat, 20 Sep 2008 18:47:58 +0000 (20:47 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sat, 20 Sep 2008 18:54:56 +0000 (20:54 +0200) |
This fixes data corruption when updating multiple values in one go.
Closes: #499350
Closes: #499350
debian/changelog | patch | blob | history | |
debian/patches/bts499350-data-corruption | [new file with mode: 0644] | patch | blob |
debian/patches/series | patch | blob | history |
diff --git a/debian/changelog b/debian/changelog
index 702068c65a6d4d390da93583463de05fdda02f59..8ad64ff90597e713ca995a5d3e547615f9c3e8d4 100644 (file)
--- a/debian/changelog
+++ b/debian/changelog
+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 <sh@tokkee.org> 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
--- /dev/null
@@ -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 cd2055ff4d695918576215725094f431f4bcfec6..a900298d1986ff063b94b9c8cf0facde178da40d 100644 (file)
--- a/debian/patches/series
+++ b/debian/patches/series
no-rpath-for-ruby
no-rpath-for-perl
implicit-decl-fix
+bts499350-data-corruption