From 2555248645b620c246b4836a19dd8b948aad0984 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sun, 13 Sep 2015 15:48:05 +0200 Subject: [PATCH] Extend the -p option with bad/sync/full arguments --- HISTORY | 6 ++++-- cmdline/scrub.c | 50 ++++++++++++++++++++++++++++++++++++---------- cmdline/snapraid.c | 24 ++++++++++++++-------- cmdline/state.h | 8 ++++++++ snapraid.1 | 42 +++++++++++++++++++++----------------- snapraid.d | 36 ++++++++++++++++++++------------- snapraid.txt | 38 +++++++++++++++++++++-------------- 7 files changed, 137 insertions(+), 67 deletions(-) diff --git a/HISTORY b/HISTORY index 357ee373..e821f011 100644 --- a/HISTORY +++ b/HISTORY @@ -14,15 +14,17 @@ SnapRAID HISTORY parity during sync is really correct. The "status" command reports the amount of scrub necessary to ensure to scrub all the synched blocks. + * The -p, --percentage option supports the new the arguments: + "bad", "sync" and "full" to define the kind of scrub to do. * Update 'best' RAID functions for recent Atom CPUs. * Validate filters specifications rejecting relative paths. 8.1 2015/05 =========== - * Fix build issues in generic Unix platforms, including Mac OS X. + * Fixes build issues in generic Unix platforms, including Mac OS X. * The "diff" command returns with error code 2 if a "sync" is required, to differentiate with the generic error code 1. - * Reduced the effect of SMART attribute 193 on the failure + * Reduces the effect of SMART attribute 193 on the failure probability to avoid some false positive reports. 8.0 2015/04 diff --git a/cmdline/scrub.c b/cmdline/scrub.c index 6795ce96..dbc597f9 100644 --- a/cmdline/scrub.c +++ b/cmdline/scrub.c @@ -559,9 +559,10 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan) block_off_t countlimit; block_off_t lastlimit; block_off_t i; + block_off_t count_unscrubbed; + block_off_t count; time_t timelimit; time_t recentlimit; - unsigned count; int ret; struct snapraid_parity_handle parity[LEV_MAX]; struct snapraid_parity_handle* parity_ptr[LEV_MAX]; @@ -575,6 +576,14 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan) msg_progress("Initializing...\n"); + if ((percentage == SCRUB_BAD || percentage == SCRUB_SYNC || percentage == SCRUB_FULL) + && olderthan >= 0) { + /* LCOV_EXCL_START */ + log_fatal("You cannot specify -o, --older-than only with a numeric percentage.\n"); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } + blockmax = parity_allocated_size(state); if (state->opt.force_scrub_even) { @@ -585,18 +594,26 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan) /* scrub the specified amount of blocks */ countlimit = state->opt.force_scrub_at; recentlimit = now; + } else if (percentage == SCRUB_FULL || percentage == SCRUB_SYNC) { + countlimit = blockmax; + recentlimit = now; + } else if (percentage == SCRUB_BAD) { + countlimit = 0; + recentlimit = now; } else { - /* by default scrub 1/12 of the array */ - countlimit = md(blockmax, 1, 12); - - if (percentage != -1) + if (percentage >= 0) { countlimit = md(blockmax, percentage, 100); + } else { + /* by default scrub 1/12 of the array */ + countlimit = md(blockmax, 1, 12); + } - /* by default use a 10 day time limit */ - recentlimit = now - 10 * 24 * 3600; - - if (olderthan != -1) + if (olderthan >= 0) { recentlimit = now - olderthan * 24 * 3600; + } else { + /* by default use a 10 day time limit */ + recentlimit = now - 10 * 24 * 3600; + } } /* identify the time limit */ @@ -606,15 +623,22 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan) /* copy the info in the temp vector */ count = 0; + count_unscrubbed = 0; log_tag("block_count:%u\n", blockmax); for (i = 0; i < blockmax; ++i) { snapraid_info info = info_get(&state->infoarr, i); + time_t scrub_time; /* skip unused blocks */ if (info == 0) continue; - timemap[count++] = info_get_scrubtime(info); + scrub_time = info_get_scrubtime(info); + + if (scrub_time == 0) + ++count_unscrubbed; + + timemap[count++] = scrub_time; } if (!count) { @@ -638,6 +662,12 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan) i = j; } + /* scrub the number of sync block if required */ + if (percentage == SCRUB_SYNC) { + countlimit = count_unscrubbed; + recentlimit = now; + } + /* no more than the full count */ if (countlimit > count) countlimit = count; diff --git a/cmdline/snapraid.c b/cmdline/snapraid.c index 9d06b3af..2e111ef4 100644 --- a/cmdline/snapraid.c +++ b/cmdline/snapraid.c @@ -441,8 +441,8 @@ int main(int argc, char* argv[]) period = 1000; filter_missing = 0; filter_error = 0; - percentage = -1; - olderthan = -1; + percentage = SCRUB_AUTO; + olderthan = SCRUB_AUTO; import_timestamp = 0; import_content = 0; log = 0; @@ -496,12 +496,20 @@ int main(int argc, char* argv[]) opt.syncedonly = 1; break; case 'p' : - percentage = strtoul(optarg, &e, 10); - if (!e || *e || percentage > 100) { - /* LCOV_EXCL_START */ - log_fatal("Invalid percentage '%s'\n", optarg); - exit(EXIT_FAILURE); - /* LCOV_EXCL_STOP */ + if (strcmp(optarg, "bad") == 0) { + percentage = SCRUB_BAD; + } else if (strcmp(optarg, "sync") == 0) { + percentage = SCRUB_SYNC; + } else if (strcmp(optarg, "full") == 0) { + percentage = SCRUB_FULL; + } else { + percentage = strtoul(optarg, &e, 10); + if (!e || *e || percentage > 100) { + /* LCOV_EXCL_START */ + log_fatal("Invalid percentage '%s'\n", optarg); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } } break; case 'o' : diff --git a/cmdline/state.h b/cmdline/state.h index 6d189c91..13f3a177 100644 --- a/cmdline/state.h +++ b/cmdline/state.h @@ -241,6 +241,14 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t */ void state_rehash(struct snapraid_state* state); +/** + * Scrub levels. + */ +#define SCRUB_AUTO -1 /**< Automatic selection. */ +#define SCRUB_BAD -2 /**< Scrub only the bad blocks. */ +#define SCRUB_SYNC -3 /**< Scub the latest synched data. */ +#define SCRUB_FULL -4 /**< Scrub everything. */ + /** * Scrub the files. */ diff --git a/snapraid.1 b/snapraid.1 index bbc6612d..7c5ce32d 100644 --- a/snapraid.1 +++ b/snapraid.1 @@ -342,11 +342,11 @@ snapraid \-e fix .RE .PP At the next \[dq]scrub\[dq] the errors will disappear from the \[dq]status\[dq] report -if really fixed. To make it fast, you can use \-p 0 to scrub only blocks +if really fixed. To make it fast, you can use \-p bad to scrub only blocks marked as bad. .PP .RS 4 -snapraid \-p 0 scrub +snapraid \-p bad scrub .PD 0 .PP .PD @@ -779,22 +779,26 @@ nothing that was already scrubbed in the last 10 days. This means that scrubbing once a week, every bit of data is checked at least one time every two months. .PP -You can use the \-p, \-\-percentage option to specify a different amount, -and the \-o, \-\-older\-than option to specify a different age in days. -You can have a full scrub with \[dq]\-p 100 \-o 0\[dq]. +You can define a different scrub amount using the \-p, \-\-percentage +option that takes as argument: +bad \- Scrub blocks marked bad. +synch \- Scrub new synced blocks never scrubbed. +full \- Scrub everything. +0\-100 \- Scrub the exact percentage of blocks. .PP -When the selected amout doesn\'t allow a full scrub, the blocks -priority is: -* The blocks already marked as bad, to verify their status. -* The new sycnched blocks never scrubbed, to verify if their -.PP -.RS 4 -parity data was written correctly. -.RE +If you specify a percentage amount, you can also use the \-o, \-\-older\-than +option to define how old the block should be. +If the specified amount doesn\'t allow a full scrub, the blocks are +scrubbed with this priority: .PD 0 .IP \(bu -All the reimainig blocks, but starting from the oldest ones -ensuring an optimal check. +First blocks marked as bad, to verify their status. +.IP \(bu +Then new synced blocks never scrubbed, to verify if their +parity data was written correctly. +.IP \(bu +And finally all the reimainig blocks, starting from ones with the oldest +scrub time. .PD .PP To get the details of the scrub status use the \[dq]status\[dq] command. @@ -804,7 +808,7 @@ are marked as bad in the \[dq]content\[dq] file. These bad blocks are listed in \[dq]status\[dq], and can be fixed with \[dq]fix \-e\[dq]. After the fix, at the next scrub they will be rechecked, and if found corrected, the bad mark will be removed. -To scrub only the bad blocks, you can use the \[dq]scrub \-p 0\[dq] command. +To scrub only the bad blocks, you can use the \[dq]scrub \-p bad\[dq] command. .PP It\'s recommended to run \[dq]scrub\[dq] only on a synced array, to avoid to have reported error caused by unsynced data. These errors are recognized @@ -973,10 +977,12 @@ It processes only the blocks marked with silent or input/output errors during \[dq]sync\[dq] and \[dq]scrub\[dq], and listed in \[dq]status\[dq]. This option can be used only with \[dq]check\[dq] and \[dq]fix\[dq]. .TP -.B \-p, \-\-percentage PERC +.B \-p, \-\-percentage PERC|bad|sync|full Selects the part of the array to process in \[dq]scrub\[dq]. PERC is a numeric value from 0 to 100, default is 12. -When specifying 0, only the blocks marked as bad are scrubbed. +Instead of a percentage, you can also specify the kind of scrub +you want: \[dq]bad\[dq] scrubs bad blocks, \[dq]sync\[dq] the synced block +not yet scrubbed, and \[dq]full\[dq] everything. This option can be used only with \[dq]scrub\[dq]. .TP .B \-o, \-\-older\-than DAYS diff --git a/snapraid.d b/snapraid.d index b33e3929..59e5dd8c 100644 --- a/snapraid.d +++ b/snapraid.d @@ -191,10 +191,10 @@ Getting Started :snapraid -e fix At the next "scrub" the errors will disappear from the "status" report - if really fixed. To make it fast, you can use -p 0 to scrub only blocks + if really fixed. To make it fast, you can use -p bad to scrub only blocks marked as bad. - :snapraid -p 0 scrub + :snapraid -p bad scrub Take care that running "scrub" on a not synced array may result in errors caused by removed or modified files. These errors are reported @@ -487,17 +487,23 @@ Commands This means that scrubbing once a week, every bit of data is checked at least one time every two months. - You can use the -p, --percentage option to specify a different amount, - and the -o, --older-than option to specify a different age in days. - You can have a full scrub with "-p 100 -o 0". + You can define a different scrub amount using the -p, --percentage + option that takes as argument: + bad - Scrub blocks marked bad. + synch - Scrub new synced blocks never scrubbed. + full - Scrub everything. + 0-100 - Scrub the exact percentage of blocks. - When the selected amout doesn't allow a full scrub, the blocks - priority is: - * The blocks already marked as bad, to verify their status. - * The new sycnched blocks never scrubbed, to verify if their + If you specify a percentage amount, you can also use the -o, --older-than + option to define how old the block should be. + If the specified amount doesn't allow a full scrub, the blocks are + scrubbed with this priority: + + * First blocks marked as bad, to verify their status. + * Then new synced blocks never scrubbed, to verify if their parity data was written correctly. - * All the reimainig blocks, but starting from the oldest ones - ensuring an optimal check. + * And finally all the reimainig blocks, starting from ones with the oldest + scrub time. To get the details of the scrub status use the "status" command. @@ -506,7 +512,7 @@ Commands These bad blocks are listed in "status", and can be fixed with "fix -e". After the fix, at the next scrub they will be rechecked, and if found corrected, the bad mark will be removed. - To scrub only the bad blocks, you can use the "scrub -p 0" command. + To scrub only the bad blocks, you can use the "scrub -p bad" command. It's recommended to run "scrub" only on a synced array, to avoid to have reported error caused by unsynced data. These errors are recognized @@ -685,10 +691,12 @@ Options errors during "sync" and "scrub", and listed in "status". This option can be used only with "check" and "fix". - -p, --percentage PERC + -p, --percentage PERC|bad|sync|full Selects the part of the array to process in "scrub". PERC is a numeric value from 0 to 100, default is 12. - When specifying 0, only the blocks marked as bad are scrubbed. + Instead of a percentage, you can also specify the kind of scrub + you want: "bad" scrubs bad blocks, "sync" the synced block + not yet scrubbed, and "full" everything. This option can be used only with "scrub". -o, --older-than DAYS diff --git a/snapraid.txt b/snapraid.txt index 5fd13ad5..fb05c735 100644 --- a/snapraid.txt +++ b/snapraid.txt @@ -206,10 +206,10 @@ the -e, --filter-error options: snapraid -e fix At the next "scrub" the errors will disappear from the "status" report -if really fixed. To make it fast, you can use -p 0 to scrub only blocks +if really fixed. To make it fast, you can use -p bad to scrub only blocks marked as bad. - snapraid -p 0 scrub + snapraid -p bad scrub Take care that running "scrub" on a not synced array may result in errors caused by removed or modified files. These errors are reported @@ -525,17 +525,23 @@ nothing that was already scrubbed in the last 10 days. This means that scrubbing once a week, every bit of data is checked at least one time every two months. -You can use the -p, --percentage option to specify a different amount, -and the -o, --older-than option to specify a different age in days. -You can have a full scrub with "-p 100 -o 0". +You can define a different scrub amount using the -p, --percentage +option that takes as argument: +bad - Scrub blocks marked bad. +synch - Scrub new synced blocks never scrubbed. +full - Scrub everything. +0-100 - Scrub the exact percentage of blocks. -When the selected amout doesn't allow a full scrub, the blocks -priority is: -* The blocks already marked as bad, to verify their status. -* The new sycnched blocks never scrubbed, to verify if their - parity data was written correctly. -* All the reimainig blocks, but starting from the oldest ones - ensuring an optimal check. +If you specify a percentage amount, you can also use the -o, --older-than +option to define how old the block should be. +If the specified amount doesn't allow a full scrub, the blocks are +scrubbed with this priority: + +* First blocks marked as bad, to verify their status. +* Then new synced blocks never scrubbed, to verify if their + parity data was written correctly. +* And finally all the reimainig blocks, starting from ones with the oldest + scrub time. To get the details of the scrub status use the "status" command. @@ -544,7 +550,7 @@ are marked as bad in the "content" file. These bad blocks are listed in "status", and can be fixed with "fix -e". After the fix, at the next scrub they will be rechecked, and if found corrected, the bad mark will be removed. -To scrub only the bad blocks, you can use the "scrub -p 0" command. +To scrub only the bad blocks, you can use the "scrub -p bad" command. It's recommended to run "scrub" only on a synced array, to avoid to have reported error caused by unsynced data. These errors are recognized @@ -744,10 +750,12 @@ SnapRAID provides the following options: errors during "sync" and "scrub", and listed in "status". This option can be used only with "check" and "fix". - -p, --percentage PERC + -p, --percentage PERC|bad|sync|full Selects the part of the array to process in "scrub". PERC is a numeric value from 0 to 100, default is 12. - When specifying 0, only the blocks marked as bad are scrubbed. + Instead of a percentage, you can also specify the kind of scrub + you want: "bad" scrubs bad blocks, "sync" the synced block + not yet scrubbed, and "full" everything. This option can be used only with "scrub". -o, --older-than DAYS