mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Keeps track of IO errors in scrub like we do for silent errors.
This commit is contained in:
parent
f200a1f6b8
commit
bc4d2dc3f6
7 changed files with 72 additions and 31 deletions
6
HISTORY
6
HISTORY
|
|
@ -1,6 +1,12 @@
|
|||
SnapRAID HISTORY
|
||||
================
|
||||
|
||||
7.1 2014/12 (BETA)
|
||||
==================
|
||||
* In 'scrub' keeps track of Input/Output errors like for silent
|
||||
error to show them in the 'status' report, and to allow to
|
||||
use the -e, --filter-error filter in 'check' and 'fix'.
|
||||
|
||||
7.0 2014/11
|
||||
===========
|
||||
* In 'check' and 'fix' the array is scanned to find any moved files
|
||||
|
|
|
|||
4
TODO
4
TODO
|
|
@ -5,6 +5,10 @@ This is the list of TODO items for SnapRAID.
|
|||
|
||||
- Next
|
||||
|
||||
* copy report in diff is wrong.
|
||||
If "copy" is printed, avoid to print "add" and "remove".
|
||||
Now with "copy" we don't count add, but we cound "remove".
|
||||
|
||||
* Avoid to do optimized move operation if more files with
|
||||
same timestamp/size are present.
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
int ret;
|
||||
unsigned error;
|
||||
unsigned silent_error;
|
||||
unsigned io_error;
|
||||
unsigned l;
|
||||
|
||||
/* maps the disks to handles */
|
||||
|
|
@ -73,6 +74,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
|
||||
error = 0;
|
||||
silent_error = 0;
|
||||
io_error = 0;
|
||||
|
||||
/* first count the number of blocks to process */
|
||||
countmax = 0;
|
||||
|
|
@ -139,6 +141,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
snapraid_info info;
|
||||
int error_on_this_block;
|
||||
int silent_error_on_this_block;
|
||||
int io_error_on_this_block;
|
||||
int block_is_unsynced;
|
||||
int rehash;
|
||||
|
||||
|
|
@ -185,6 +188,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
/* by default process the block, and skip it if something goes wrong */
|
||||
error_on_this_block = 0;
|
||||
silent_error_on_this_block = 0;
|
||||
io_error_on_this_block = 0;
|
||||
|
||||
/* if all the blocks at this address are synced */
|
||||
/* if not, parity is not even checked */
|
||||
|
|
@ -282,9 +286,15 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
|
||||
read_size = handle_read(&handle[j], block, buffer[j], state->block_size, stderr);
|
||||
if (read_size == -1) {
|
||||
fprintf(stdlog, "error:%u:%s:%s: Read error at position %u\n", i, disk->name, handle[j].file->sub, block_file_pos(block));
|
||||
++error;
|
||||
error_on_this_block = 1;
|
||||
if (errno == EIO) {
|
||||
fprintf(stdlog, "error:%u:%s:%s: Input/Output error at position %u. %s\n", i, disk->name, handle[j].file->sub, block_file_pos(block), strerror(errno));
|
||||
++io_error;
|
||||
io_error_on_this_block = 1;
|
||||
} else {
|
||||
fprintf(stdlog, "error:%u:%s:%s: Read error at position %u. %s\n", i, disk->name, handle[j].file->sub, block_file_pos(block), strerror(errno));
|
||||
++error;
|
||||
error_on_this_block = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -327,7 +337,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
}
|
||||
|
||||
/* if we have read all the data required and it's correct, proceed with the parity check */
|
||||
if (!error_on_this_block && !silent_error_on_this_block) {
|
||||
if (!error_on_this_block && !silent_error_on_this_block && !io_error_on_this_block) {
|
||||
unsigned char* buffer_recov[LEV_MAX];
|
||||
|
||||
/* until now is CPU */
|
||||
|
|
@ -344,9 +354,16 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, stdlog);
|
||||
if (ret == -1) {
|
||||
buffer_recov[l] = 0;
|
||||
fprintf(stdlog, "parity_error:%u:%s: Read error\n", i, lev_config_name(l));
|
||||
++error;
|
||||
error_on_this_block = 1;
|
||||
|
||||
if (errno == EIO) {
|
||||
fprintf(stdlog, "parity_error:%u:%s: Input/Output error. %s\n", i, lev_config_name(l), strerror(errno));
|
||||
++io_error;
|
||||
io_error_on_this_block = 1;
|
||||
} else {
|
||||
fprintf(stdlog, "parity_error:%u:%s: Read error. %s\n", i, lev_config_name(l), strerror(errno));
|
||||
++error;
|
||||
error_on_this_block = 1;
|
||||
}
|
||||
|
||||
/* follow */
|
||||
}
|
||||
|
|
@ -379,7 +396,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
}
|
||||
}
|
||||
|
||||
if (silent_error_on_this_block) {
|
||||
if (silent_error_on_this_block || io_error_on_this_block) {
|
||||
/* set the error status keeping the existing time and hash */
|
||||
info_set(&state->infoarr, i, info_set_bad(info));
|
||||
} else if (error_on_this_block) {
|
||||
|
|
@ -439,9 +456,10 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
|
||||
state_usage_print(state);
|
||||
|
||||
if (error || silent_error) {
|
||||
if (error || silent_error || io_error) {
|
||||
printf("\n");
|
||||
printf("%8u read errors\n", error);
|
||||
printf("%8u other errors\n", error);
|
||||
printf("%8u io errors\n", io_error);
|
||||
printf("%8u data errors\n", silent_error);
|
||||
printf("WARNING! There are errors!\n");
|
||||
} else {
|
||||
|
|
@ -450,7 +468,8 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
printf("Everything OK\n");
|
||||
}
|
||||
|
||||
fprintf(stdlog, "summary:error_read:%u\n", error);
|
||||
fprintf(stdlog, "summary:error_other:%u\n", error);
|
||||
fprintf(stdlog, "summary:error_io:%u\n", io_error);
|
||||
fprintf(stdlog, "summary:error_data:%u\n", silent_error);
|
||||
if (error + silent_error == 0)
|
||||
fprintf(stdlog, "summary:exit:ok\n");
|
||||
|
|
@ -476,10 +495,10 @@ bail:
|
|||
free(rehandle_alloc);
|
||||
|
||||
if (state->opt.expect_recoverable) {
|
||||
if (error + silent_error == 0)
|
||||
if (error + silent_error + io_error == 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (error + silent_error != 0)
|
||||
if (error + silent_error + io_error != 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
|
|||
/* file we are processing for error reporting */
|
||||
struct snapraid_file* file = block_file_get(block);
|
||||
if (errno == ENOENT) {
|
||||
fprintf(stdlog, "error:%u:%s:%s: Open missing error\n", i, disk->name, file->sub);
|
||||
fprintf(stdlog, "error:%u:%s:%s: Open missing error. %s\n", i, disk->name, file->sub, strerror(errno));
|
||||
fprintf(stderr, "Missing file '%s'.\n", handle[j].path);
|
||||
fprintf(stderr, "WARNING! You cannot modify data disk during a sync.\n");
|
||||
fprintf(stderr, "Rerun the sync command when finished.\n");
|
||||
|
|
@ -157,7 +157,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
|
|||
continue;
|
||||
}
|
||||
if (errno == EACCES) {
|
||||
fprintf(stdlog, "error:%u:%s:%s: Open access error\n", i, disk->name, file->sub);
|
||||
fprintf(stdlog, "error:%u:%s:%s: Open access error. %s\n", i, disk->name, file->sub, strerror(errno));
|
||||
fprintf(stderr, "No access at file '%s'.\n", handle[j].path);
|
||||
fprintf(stderr, "WARNING! Please fix the access permission in the data disk.\n");
|
||||
fprintf(stderr, "Rerun the sync command when finished.\n");
|
||||
|
|
@ -211,7 +211,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta
|
|||
/* LCOV_EXCL_START */
|
||||
/* file we are processing for error reporting */
|
||||
struct snapraid_file* file = block_file_get(block);
|
||||
fprintf(stdlog, "error:%u:%s:%s: Read error at position %u\n", i, disk->name, file->sub, block_file_pos(block));
|
||||
fprintf(stdlog, "error:%u:%s:%s: Read error at position %u. %s\n", i, disk->name, file->sub, block_file_pos(block), strerror(errno));
|
||||
fprintf(stderr, "DANGER! Unexpected read error in a data disk, it isn't possible to sync.\n");
|
||||
fprintf(stderr, "Ensure that disk '%s' is sane and that file '%s' can be read.\n", disk->dir, handle[j].path);
|
||||
printf("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub);
|
||||
|
|
|
|||
14
snapraid.1
14
snapraid.1
|
|
@ -319,7 +319,7 @@ snapraid scrub
|
|||
.PP
|
||||
This command verifies only the oldest data in your array.
|
||||
Every run of the command checks about 12% of the array,
|
||||
but nothing newer than 10 days.
|
||||
but not 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.
|
||||
For example, to check 5% of the array older than 20 days use:
|
||||
|
|
@ -331,8 +331,8 @@ snapraid \-p 5 \-o 20 scrub
|
|||
.PD
|
||||
.RE
|
||||
.PP
|
||||
If silent errors are found, the corresponding blocks are marked as bad
|
||||
in the \[dq]content\[dq] file, and listed in the \[dq]status\[dq] command.
|
||||
If a silent or input error is found, the corresponding block is marked
|
||||
as bad in the \[dq]content\[dq] file, and listed in the \[dq]status\[dq] command.
|
||||
.PP
|
||||
.RS 4
|
||||
snapraid status
|
||||
|
|
@ -341,8 +341,8 @@ snapraid status
|
|||
.PD
|
||||
.RE
|
||||
.PP
|
||||
To fix them, you can use the \[dq]fix\[dq] command filtering for files
|
||||
containing bad blocks:
|
||||
To fix them, you can use the \[dq]fix\[dq] command filtering for files containing
|
||||
bad blocks:
|
||||
.PP
|
||||
.RS 4
|
||||
snapraid \-e fix
|
||||
|
|
@ -361,6 +361,10 @@ snapraid \-p 0 scrub
|
|||
.PP
|
||||
.PD
|
||||
.RE
|
||||
.PP
|
||||
Take care that running scrub on a not synced array may result in
|
||||
errors caused by removed or modified files. These errors are reported
|
||||
in the \[dq]scrub\[dq] result, but related blocks are not marked as bad.
|
||||
.SS Pooling
|
||||
To have all the files in your array shown in the same directory tree,
|
||||
you can enable \[dq]pooling\[dq], that consists in creating a virtual view of all
|
||||
|
|
|
|||
14
snapraid.d
14
snapraid.d
|
|
@ -179,20 +179,20 @@ Getting Started
|
|||
|
||||
This command verifies only the oldest data in your array.
|
||||
Every run of the command checks about 12% of the array,
|
||||
but nothing newer than 10 days.
|
||||
but not 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.
|
||||
For example, to check 5% of the array older than 20 days use:
|
||||
|
||||
:snapraid -p 5 -o 20 scrub
|
||||
|
||||
If silent errors are found, the corresponding blocks are marked as bad
|
||||
in the "content" file, and listed in the "status" command.
|
||||
If a silent or input error is found, the corresponding block is marked
|
||||
as bad in the "content" file, and listed in the "status" command.
|
||||
|
||||
:snapraid status
|
||||
|
||||
To fix them, you can use the "fix" command filtering for files
|
||||
containing bad blocks:
|
||||
To fix them, you can use the "fix" command filtering for files containing
|
||||
bad blocks:
|
||||
|
||||
:snapraid -e fix
|
||||
|
||||
|
|
@ -202,6 +202,10 @@ Getting Started
|
|||
|
||||
:snapraid -p 0 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
|
||||
in the "scrub" result, but related blocks are not marked as bad.
|
||||
|
||||
Pooling
|
||||
To have all the files in your array shown in the same directory tree,
|
||||
you can enable "pooling", that consists in creating a virtual view of all
|
||||
|
|
|
|||
14
snapraid.txt
14
snapraid.txt
|
|
@ -196,20 +196,20 @@ run the "scrub" command.
|
|||
|
||||
This command verifies only the oldest data in your array.
|
||||
Every run of the command checks about 12% of the array,
|
||||
but nothing newer than 10 days.
|
||||
but not 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.
|
||||
For example, to check 5% of the array older than 20 days use:
|
||||
|
||||
snapraid -p 5 -o 20 scrub
|
||||
|
||||
If silent errors are found, the corresponding blocks are marked as bad
|
||||
in the "content" file, and listed in the "status" command.
|
||||
If a silent or input error is found, the corresponding block is marked
|
||||
as bad in the "content" file, and listed in the "status" command.
|
||||
|
||||
snapraid status
|
||||
|
||||
To fix them, you can use the "fix" command filtering for files
|
||||
containing bad blocks:
|
||||
To fix them, you can use the "fix" command filtering for files containing
|
||||
bad blocks:
|
||||
|
||||
snapraid -e fix
|
||||
|
||||
|
|
@ -219,6 +219,10 @@ marked as bad.
|
|||
|
||||
snapraid -p 0 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
|
||||
in the "scrub" result, but related blocks are not marked as bad.
|
||||
|
||||
4.3 Pooling
|
||||
-----------
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue