diff --git a/HISTORY b/HISTORY index 9027fc4c..101c0cde 100644 --- a/HISTORY +++ b/HISTORY @@ -3,6 +3,13 @@ SnapRAID HISTORY 8.0 2015/01 BETA ================ + * Allows "sync" and "scrub" to continue after the first + bunch of disk errors. Blocks with errors are marked as bad, + and you can try to fix them with the "fix -e" command. + The fix should then trigger the internal disk firmware to + reallocate the bad sector, and likely fixing the problem. + You can control the number of allowed errors with the new + -L, --error-limit option. The default is 100. * The -e, --filter-error option now doesn't write anymore fixes to unsynced files. This helps in case you are running it on a not synced array, removing the risk to revert some files to an diff --git a/TODO b/TODO index ae91fd88..c7268b0d 100644 --- a/TODO +++ b/TODO @@ -5,6 +5,39 @@ This is the list of TODO items for SnapRAID. - Next +* Improves the fix -e behaviour. At now it reads too mutch data, +as it needs to verify the full files. +This is done just to have confirmation that the file is OK, +and then restore the file timestamp. But other approaches are possible. +Indicatively we can do: +- Read/Write only the marked bad error blocks +- For all the files, owning this block: + - If the file is present and it has the original timestamp + - If yes, Write any fix to it, and keep the timestamp. + - If no, don't write the fix, and assume it as update. +The issue could be that if the error is in a modified file +after sync, it won't be fixed. But at now we detect only silent error, +and they CANNOT be in modified files. +So, if a file is modified, we just don't write it, at the next scrub +the bad flag will be removed. + +Note that this way of checking the timestamp before writing fixes +may have sense also for a generic fix. +We already have the -m, --missing flag. It's already working in this way. +--missing fixes only deleted/missing files. +Like --stable fixes only synced files, but unsure of the use case. + +We have now: +- Lost disk. fix -d DISK +- Deleted files. fix -m / fix -f +- Silent errors on scrub. fix -e +Possible new: +- Disk with failed read, that can be rewritten. + - Scrub could put them in error list, and fix could rewrite the sectors to make them right + This won't work for modified files, in that case the error will remain. + But scrub can report it in the screen and log about the file. + - Sync could proceed anyway, just skip such blocks index, and mark the sector as bad. + * Avoid to do optimized move operation if more files with same timestamp/size are present. diff --git a/cmdline/snapraid.c b/cmdline/snapraid.c index 9d4f4089..bf1ef9ab 100644 --- a/cmdline/snapraid.c +++ b/cmdline/snapraid.c @@ -247,6 +247,7 @@ struct option long_options[] = { { "older-than", 1, 0, 'o' }, { "start", 1, 0, 'S' }, { "count", 1, 0, 'B' }, + { "error-limit", 1, 0, 'L' }, { "import", 1, 0, 'i' }, { "log", 1, 0, 'l' }, { "force-zero", 0, 0, 'Z' }, @@ -257,11 +258,11 @@ struct option long_options[] = { { "force-full", 0, 0, 'F' }, { "audit-only", 0, 0, 'a' }, { "pre-hash", 0, 0, 'h' }, - { "speed-test", 0, 0, 'T' }, + { "speed-test", 0, 0, 'T' }, /* undocumented speed test command */ { "gen-conf", 1, 0, 'C' }, { "verbose", 0, 0, 'v' }, - { "quiet", 0, 0, 'q' }, - { "gui", 0, 0, 'G' }, /* undocumented GUI interface command */ + { "quiet", 0, 0, 'q' }, /* undocumented quiet option */ + { "gui", 0, 0, 'G' }, /* undocumented GUI interface option */ { "help", 0, 0, 'H' }, { "version", 0, 0, 'V' }, @@ -349,7 +350,7 @@ struct option long_options[] = { }; #endif -#define OPTIONS "c:f:d:mep:o:S:B:i:l:ZEUDNFahTC:vqHVG" +#define OPTIONS "c:f:d:mep:o:S:B:L:i:l:ZEUDNFahTC:vqHVG" volatile int global_interrupt = 0; @@ -411,6 +412,7 @@ int main(int argc, char* argv[]) /* defaults */ config(conf, sizeof(conf), argv[0]); memset(&opt, 0, sizeof(opt)); + opt.io_error_limit = 100; blockstart = 0; blockcount = 0; tommy_list_init(&filterlist_file); @@ -506,6 +508,15 @@ int main(int argc, char* argv[]) /* LCOV_EXCL_STOP */ } break; + case 'L' : + opt.io_error_limit = strtoul(optarg, &e, 0); + if (!e || *e) { + /* LCOV_EXCL_START */ + fprintf(stderr, "Invalid error limit number '%s'\n", optarg); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } + break; case 'i' : if (import_timestamp) { /* LCOV_EXCL_START */ diff --git a/snapraid.1 b/snapraid.1 index 40781842..4f973196 100644 --- a/snapraid.1 +++ b/snapraid.1 @@ -21,6 +21,10 @@ snapraid [\-c, \-\-conf CONFIG] [\-p, \-\-percentage PERC] [\-o, \-\-older\-than DAYS] .PD 0 .PP +.PD + [\-l, \-\-log FILE] +.PD 0 +.PP .PD [\-Z, \-\-force\-zero] [\-E, \-\-force\-empty] .PD 0 @@ -34,11 +38,15 @@ snapraid [\-c, \-\-conf CONFIG] .PD 0 .PP .PD - [\-v, \-\-verbose] [\-l, \-\-log FILE] + [\-S, \-\-start BLKSTART] [\-B, \-\-count BLKCOUNT] .PD 0 .PP .PD - [\-S, \-\-start BLKSTART] [\-B, \-\-count BLKCOUNT] + [\-L, \-\-error\-limit NUMBER] +.PD 0 +.PP +.PD + [\-v, \-\-verbose] .PD 0 .PP .PD @@ -871,6 +879,16 @@ to enclose the name in \[dq], like \[dq]>>result.log\[dq]. To output the log to standard output or standard error, you can use respectively \[dq]>&1\[dq] and \[dq]>&2\[dq]. .TP +.B \-L, \-\-error\-limit +Sets a new error limit before stopping execution. +By default SnapRAID stops if it encouters more than 100 +Input/Output errors, meaning that likely a disk is going to +die. +This options affects \[dq]sync\[dq] and \[dq]scrub\[dq], that are allowed +to continue after the first bunch of disk errors, to try +to complete at most their operations. +Instead, \[dq]check\[dq] and \[dq]fix\[dq] always stop at the first error. +.TP .B \-S, \-\-start BLKSTART Starts the processing from the specified block number. It could be useful to retry to check diff --git a/snapraid.d b/snapraid.d index c2d469f9..59995b2c 100644 --- a/snapraid.d +++ b/snapraid.d @@ -7,11 +7,13 @@ Synopsis : [-m, --filter-missing] [-e, --filter-error] : [-a, --audit-only] [-h, --pre-hash] [-i, --import DIR] : [-p, --percentage PERC] [-o, --older-than DAYS] + : [-l, --log FILE] : [-Z, --force-zero] [-E, --force-empty] : [-U, --force-uuid] [-D, --force-device] : [-N, --force-nocopy] [-F, --force-full] - : [-v, --verbose] [-l, --log FILE] : [-S, --start BLKSTART] [-B, --count BLKCOUNT] + : [-L, --error-limit NUMBER] + : [-v, --verbose] : status|sync|scrub|fix|check|list|diff|dup|pool|rehash :snapraid [-V, --version] [-H, --help] [-C, --gen-conf CONTENT] @@ -634,6 +636,16 @@ Options To output the log to standard output or standard error, you can use respectively ">&1" and ">&2". + -L, --error-limit + Sets a new error limit before stopping execution. + By default SnapRAID stops if it encouters more than 100 + Input/Output errors, meaning that likely a disk is going to + die. + This options affects "sync" and "scrub", that are allowed + to continue after the first bunch of disk errors, to try + to complete at most their operations. + Instead, "check" and "fix" always stop at the first error. + -S, --start BLKSTART Starts the processing from the specified block number. It could be useful to retry to check diff --git a/snapraid.txt b/snapraid.txt index 3df1377a..f4153b92 100644 --- a/snapraid.txt +++ b/snapraid.txt @@ -11,11 +11,13 @@ snapraid [-c, --conf CONFIG] [-m, --filter-missing] [-e, --filter-error] [-a, --audit-only] [-h, --pre-hash] [-i, --import DIR] [-p, --percentage PERC] [-o, --older-than DAYS] + [-l, --log FILE] [-Z, --force-zero] [-E, --force-empty] [-U, --force-uuid] [-D, --force-device] [-N, --force-nocopy] [-F, --force-full] - [-v, --verbose] [-l, --log FILE] [-S, --start BLKSTART] [-B, --count BLKCOUNT] + [-L, --error-limit NUMBER] + [-v, --verbose] status|sync|scrub|fix|check|list|diff|dup|pool|rehash snapraid [-V, --version] [-H, --help] [-C, --gen-conf CONTENT] @@ -679,6 +681,16 @@ SnapRAID provides the following options: To output the log to standard output or standard error, you can use respectively ">&1" and ">&2". + -L, --error-limit + Sets a new error limit before stopping execution. + By default SnapRAID stops if it encouters more than 100 + Input/Output errors, meaning that likely a disk is going to + die. + This options affects "sync" and "scrub", that are allowed + to continue after the first bunch of disk errors, to try + to complete at most their operations. + Instead, "check" and "fix" always stop at the first error. + -S, --start BLKSTART Starts the processing from the specified block number. It could be useful to retry to check