diff --git a/Makefile.am b/Makefile.am index 249b19ca..4a466b62 100644 --- a/Makefile.am +++ b/Makefile.am @@ -173,7 +173,9 @@ endif $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-expect-recoverable --test-force-scrub 100000 scrub $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf status $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -e - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-scrub 100000 scrub + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -p 0 scrub + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -o 0 scrub + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -p 100 scrub rm test/disk1/content $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync echo --- Make a hole in the disk array diff --git a/scrub.c b/scrub.c index e0afda64..b0ccb9f8 100644 --- a/scrub.c +++ b/scrub.c @@ -434,7 +434,7 @@ bail: return 0; } -int state_scrub(struct snapraid_state* state) +int state_scrub(struct snapraid_state* state, int percentage, int olderthan) { block_off_t blockmax; block_off_t countlimit; @@ -466,6 +466,15 @@ int state_scrub(struct snapraid_state* state) /* scrub the specified amount of blocks */ countlimit = state->opt.force_scrub; recentlimit = now; + } else if (percentage != -1 || olderthan != -1) { + if (percentage != -1) + countlimit = blockmax * percentage / 100; + else + countlimit = blockmax; + if (olderthan != -1) + recentlimit = now - olderthan * 24 * 3600; + else + recentlimit = now; } else { /* by default scrub 1/12 of the array */ countlimit = blockmax / 12; diff --git a/snapraid.1 b/snapraid.1 index d521cc60..0d5399e4 100644 --- a/snapraid.1 +++ b/snapraid.1 @@ -17,6 +17,10 @@ snapraid [\(hyc, \(hy\(hyconf CONFIG] [\(hya, \(hy\(hyaudit\(hyonly] [\(hyi, \(hy\(hyimport DIR] .PD 0 .PP +.PD + [\(hyp, \(hy\(hypercentage PERC] [\(hyo, \(hy\(hyolder\(hythan DAYS] +.PD 0 +.PP .PD [\(hyN, \(hy\(hyfind\(hyby\(hyname] .PD 0 @@ -335,8 +339,17 @@ snapraid scrub As difference than \(a"check\(a" this command verifies only the oldest data in your array. Every run of the command checks about 12% of the data, but nothing newer than 10 days. +You can use the \(hyp, \(hy\(hypercentage option to specify a different amount, +and the \(hyo, \(hy\(hyolder\(hythan option to specify a different age in days: .PP -If a silent error is found, the corresponding blocks are marked as bad +.RS 4 +snapraid \(hyp 5 \(hyo 20 scrub +.PD 0 +.PP +.PD +.RE +.PP +If silent errors are found, the corresponding blocks are marked as bad in the \(a"concent\(a" file, and listed in the \(a"status\(a" command. .PP .RS 4 @@ -357,7 +370,14 @@ snapraid \(hye fix .RE .PP and at the next \(a"scrub\(a" the errors will disappear from the \(a"status\(a" -report. +report. You can use \(hyp 0 to scrub only them. +.PP +.RS 4 +snapraid \(hyp 0 scrub +.PD 0 +.PP +.PD +.RE .SS Pooling To have all the files in your array shown in the same directory tree, you can enable \(a"pooling\(a", that consists in creating a virtual view of all @@ -454,16 +474,24 @@ nothing that it\(cqs more recent than 10 days. This means that scrubbing once a week, every bit of data is checked at least one time every two months. .PP -The oldest blocks are scrubbed first ensuring an optimal check. -.PP -It\(cqs recommended to run \(a"scrub\(a" on a synched array, to avoid to have -reported error caused by unsynched data. These errors are recognized -as not being silent errors, but are reported anyway. +You can use the \(hyp, \(hy\(hypercentage option to specify a different amount, +and the \(hyo, \(hy\(hyolder\(hythan option to specify a different age. +Note that if only one of \(hyp and \(hyo is specified the default value of +the other option is not used. .PP Any silent error identified is recorded in the content file, and it\(cqs listed in the \(a"status\(a" command until it\(cqs fixed calling \(a"fix\(a" and then \(a"scrub\(a". .PP +The oldest blocks are scrubbed first ensuring an optimal check. +Blocks already marked as bad are always checked, and if found +correct, they are automatically unmarked. +.PP +It\(cqs recommended to run \(a"scrub\(a" on a synched array, to avoid to have +reported error caused by unsynched data. These errors are recognized +as not being silent errors, and the blocks are not marked as bad, +but such errros are reported in the output of the command. +.PP The \(a"content\(a" file is modified to update the time of the last check of each block. .SS status @@ -568,6 +596,20 @@ It process only the files containing blocks marked with silent errors during the \(a"scrub\(a" command, and listed in the \(a"status\(a" command. This option can be used only with the \(a"check\(a" and \(a"fix\(a" commands. .TP +.B \(hyp, \(hy\(hypercentage PERC +Selects the part of the array to process in the \(a"scrub\(a" command. +PERC is a numeric value from 0 to 100, default is 12. +When specifing 0, only the blocks marked as bad are scrubbed. +This option can be used only with the \(a"scrub\(a" command. +.TP +.B \(hyo, \(hy\(hyolder\(hythan DAYS +Selects the older the part of the array to process in the +\(a"scrub\(a" command. +DAYS is the minimum age in days for a block to be scrubbed, +default is 10. +Blocks marked as bad are always scrubbed despite this option. +This option can be used only with the \(a"scrub\(a" command. +.TP .B \(hya, \(hy\(hyaudit\(hyonly When checking, only verify the hash of the files, without doing any kind of check on the redundancy data. diff --git a/snapraid.c b/snapraid.c index fbe14f55..a54a6371 100644 --- a/snapraid.c +++ b/snapraid.c @@ -63,6 +63,8 @@ void usage(void) printf(" " SWITCH_GETOPT_LONG("-d, --filter-dist NAME", "-f") " Process only files in the specified disk\n"); printf(" " SWITCH_GETOPT_LONG("-m, --filter-missing ", "-m") " Process only missing/deleted files\n"); printf(" " SWITCH_GETOPT_LONG("-e, --filter-error ", "-e") " Process only files with errors\n"); + printf(" " SWITCH_GETOPT_LONG("-p, --percentage PERC ", "-p") " Process only a part of the array\n"); + printf(" " SWITCH_GETOPT_LONG("-o, --older-than DAYS ", "-o") " Process only the older part of the array\n"); printf(" " SWITCH_GETOPT_LONG("-i, --import DIR ", "-i") " Import deleted files\n"); printf(" " SWITCH_GETOPT_LONG("-l, --log FILE ", "-l") " Log file. Default none\n"); printf(" " SWITCH_GETOPT_LONG("-a, --audit-only ", "-A") " Check only file data and not parity\n"); @@ -105,6 +107,8 @@ struct option long_options[] = { { "filter-disk", 1, 0, 'd' }, { "filter-missing", 0, 0, 'm' }, { "filter-error", 0, 0, 'e' }, + { "percentage", 1, 0, 'p' }, + { "older-than", 1, 0, 'o' }, { "start", 1, 0, 's' }, { "count", 1, 0, 't' }, { "import", 1, 0, 'i' }, @@ -178,7 +182,7 @@ struct option long_options[] = { }; #endif -#define OPTIONS "c:f:d:mes:t:i:l:ZEUDNaTvhVG" +#define OPTIONS "c:f:d:mep:o:s:t:i:l:ZEUDNaTvhVG" volatile int global_interrupt = 0; @@ -218,6 +222,8 @@ int main(int argc, char* argv[]) tommy_list filterlist_disk; int filter_missing; int filter_error; + int percentage; + int olderthan; char* e; const char* command; const char* import; @@ -236,6 +242,8 @@ int main(int argc, char* argv[]) tommy_list_init(&filterlist_disk); filter_missing = 0; filter_error = 0; + percentage = -1; + olderthan = -1; import = 0; log = 0; lock = 0; @@ -274,6 +282,20 @@ int main(int argc, char* argv[]) case 'e' : filter_error = 1; break; + case 'p' : + percentage = strtoul(optarg, &e, 10); + if (!e || *e || percentage > 100) { + fprintf(stderr, "Invalid percentage '%s'\n", optarg); + exit(EXIT_FAILURE); + } + break; + case 'o' : + olderthan = strtoul(optarg, &e, 10); + if (!e || *e || olderthan > 1000) { + fprintf(stderr, "Invalid number of days '%s'\n", optarg); + exit(EXIT_FAILURE); + } + break; case 's' : blockstart = strtoul(optarg, &e, 0); if (!e || *e) { @@ -614,7 +636,7 @@ int main(int argc, char* argv[]) /* intercept Ctrl+C */ signal(SIGINT, &signal_handler); - ret = state_scrub(&state); + ret = state_scrub(&state, percentage, olderthan); /* save the new state if required */ if (state.need_write || state.opt.force_content_write) diff --git a/snapraid.d b/snapraid.d index f4f8638a..1b758de3 100644 --- a/snapraid.d +++ b/snapraid.d @@ -6,6 +6,7 @@ Synopsis : [-f, --filter PATTERN] [-d, --filter-disk NAME] : [-m, --filter-missing] [-e, --filter-error] : [-a, --audit-only] [-i, --import DIR] + : [-p, --percentage PERC] [-o, --older-than DAYS] : [-N, --find-by-name] : [-Z, --force-zero] [-E, --force-empty] : [-U, --force-uuid] [-D, --force-device] @@ -188,8 +189,12 @@ Getting Started As difference than "check" this command verifies only the oldest data in your array. Every run of the command checks about 12% of the data, but nothing newer than 10 days. + 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: - If a silent error is found, the corresponding blocks are marked as bad + :snapraid -p 5 -o 20 scrub + + If silent errors are found, the corresponding blocks are marked as bad in the "concent" file, and listed in the "status" command. :snapraid status @@ -200,7 +205,9 @@ Getting Started :snapraid -e fix and at the next "scrub" the errors will disappear from the "status" - report. + report. You can use -p 0 to scrub only them. + + :snapraid -p 0 scrub Pooling To have all the files in your array shown in the same directory tree, @@ -282,16 +289,24 @@ Commands This means that scrubbing once a week, every bit of data is checked at least one time every two months. - The oldest blocks are scrubbed first ensuring an optimal check. - - It's recommended to run "scrub" on a synched array, to avoid to have - reported error caused by unsynched data. These errors are recognized - as not being silent errors, but are reported anyway. + You can use the -p, --percentage option to specify a different amount, + and the -o, --older-than option to specify a different age. + Note that if only one of -p and -o is specified the default value of + the other option is not used. Any silent error identified is recorded in the content file, and it's listed in the "status" command until it's fixed calling "fix" and then "scrub". + The oldest blocks are scrubbed first ensuring an optimal check. + Blocks already marked as bad are always checked, and if found + correct, they are automatically unmarked. + + It's recommended to run "scrub" on a synched array, to avoid to have + reported error caused by unsynched data. These errors are recognized + as not being silent errors, and the blocks are not marked as bad, + but such errros are reported in the output of the command. + The "content" file is modified to update the time of the last check of each block. @@ -402,6 +417,20 @@ Options errors during the "scrub" command, and listed in the "status" command. This option can be used only with the "check" and "fix" commands. + -p, --percentage PERC + Selects the part of the array to process in the "scrub" command. + PERC is a numeric value from 0 to 100, default is 12. + When specifing 0, only the blocks marked as bad are scrubbed. + This option can be used only with the "scrub" command. + + -o, --older-than DAYS + Selects the older the part of the array to process in the + "scrub" command. + DAYS is the minimum age in days for a block to be scrubbed, + default is 10. + Blocks marked as bad are always scrubbed despite this option. + This option can be used only with the "scrub" command. + -a, --audit-only When checking, only verify the hash of the files, without doing any kind of check on the redundancy data. diff --git a/snapraid.txt b/snapraid.txt index be733c3a..333fb760 100644 --- a/snapraid.txt +++ b/snapraid.txt @@ -10,6 +10,7 @@ snapraid [-c, --conf CONFIG] [-f, --filter PATTERN] [-d, --filter-disk NAME] [-m, --filter-missing] [-e, --filter-error] [-a, --audit-only] [-i, --import DIR] + [-p, --percentage PERC] [-o, --older-than DAYS] [-N, --find-by-name] [-Z, --force-zero] [-E, --force-empty] [-U, --force-uuid] [-D, --force-device] @@ -205,8 +206,12 @@ command. As difference than "check" this command verifies only the oldest data in your array. Every run of the command checks about 12% of the data, but nothing newer than 10 days. +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: -If a silent error is found, the corresponding blocks are marked as bad + snapraid -p 5 -o 20 scrub + +If silent errors are found, the corresponding blocks are marked as bad in the "concent" file, and listed in the "status" command. snapraid status @@ -217,7 +222,9 @@ containing bad blocks: snapraid -e fix and at the next "scrub" the errors will disappear from the "status" -report. +report. You can use -p 0 to scrub only them. + + snapraid -p 0 scrub 4.3 Pooling ----------- @@ -312,16 +319,24 @@ nothing that it's more recent than 10 days. This means that scrubbing once a week, every bit of data is checked at least one time every two months. -The oldest blocks are scrubbed first ensuring an optimal check. - -It's recommended to run "scrub" on a synched array, to avoid to have -reported error caused by unsynched data. These errors are recognized -as not being silent errors, but are reported anyway. +You can use the -p, --percentage option to specify a different amount, +and the -o, --older-than option to specify a different age. +Note that if only one of -p and -o is specified the default value of +the other option is not used. Any silent error identified is recorded in the content file, and it's listed in the "status" command until it's fixed calling "fix" and then "scrub". +The oldest blocks are scrubbed first ensuring an optimal check. +Blocks already marked as bad are always checked, and if found +correct, they are automatically unmarked. + +It's recommended to run "scrub" on a synched array, to avoid to have +reported error caused by unsynched data. These errors are recognized +as not being silent errors, and the blocks are not marked as bad, +but such errros are reported in the output of the command. + The "content" file is modified to update the time of the last check of each block. @@ -445,6 +460,20 @@ SnapRAID provides the following options: errors during the "scrub" command, and listed in the "status" command. This option can be used only with the "check" and "fix" commands. + -p, --percentage PERC + Selects the part of the array to process in the "scrub" command. + PERC is a numeric value from 0 to 100, default is 12. + When specifing 0, only the blocks marked as bad are scrubbed. + This option can be used only with the "scrub" command. + + -o, --older-than DAYS + Selects the older the part of the array to process in the + "scrub" command. + DAYS is the minimum age in days for a block to be scrubbed, + default is 10. + Blocks marked as bad are always scrubbed despite this option. + This option can be used only with the "scrub" command. + -a, --audit-only When checking, only verify the hash of the files, without doing any kind of check on the redundancy data. diff --git a/state.h b/state.h index b3246dab..34eae6cd 100644 --- a/state.h +++ b/state.h @@ -151,7 +151,7 @@ void state_rehash(struct snapraid_state* state); /** * Scrub the files. */ -int state_scrub(struct snapraid_state* state); +int state_scrub(struct snapraid_state* state, int percentage, int olderthan); /** * Print the status.