mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
More precise error listing for unrecoverable files.
The "Stopping" message is now always in stdout.
This commit is contained in:
parent
b82f5c0aa9
commit
46fb4a311a
3 changed files with 44 additions and 38 deletions
6
TODO
6
TODO
|
|
@ -19,7 +19,11 @@ messages in check/fix.
|
|||
|
||||
* Easy way to find files using a specified block.
|
||||
|
||||
* Implements a restore command to recover files, without the integrity check.
|
||||
* Implements an undelete command to recover missing files, without the
|
||||
integrity check of the existing ones.
|
||||
|
||||
* Rename sync->backup and fix->restore. It seems to me a naming expressing
|
||||
better the meaning of the commands. But not yet sure.
|
||||
|
||||
* Allow to filter the files to check/fix based on the drive where they reside.
|
||||
|
||||
|
|
|
|||
58
check.c
58
check.c
|
|
@ -173,6 +173,7 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
unsigned error;
|
||||
unsigned unrecoverable_error;
|
||||
unsigned recovered_error;
|
||||
struct failed_struct* failed;
|
||||
|
||||
/* we need disk + 2 for each parity level buffers + 1 zero buffer */
|
||||
buffermax = diskmax + state->level * 2 + 1;
|
||||
|
|
@ -184,6 +185,8 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
}
|
||||
memset(buffer[buffermax-1], 0, state->block_size);
|
||||
|
||||
failed = malloc_nofail(diskmax * sizeof(struct failed_struct));
|
||||
|
||||
handle = malloc_nofail(diskmax * sizeof(struct snapraid_handle));
|
||||
for(i=0;i<diskmax;++i) {
|
||||
handle[i].disk = tommy_array_get(&state->diskarr, i);
|
||||
|
|
@ -224,7 +227,6 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
start = time(0);
|
||||
last = start;
|
||||
for(i=blockstart;i<blockmax;++i) {
|
||||
struct failed_struct failed[2];
|
||||
unsigned failed_count;
|
||||
int one_tocheck;
|
||||
int all_parity;
|
||||
|
|
@ -284,7 +286,7 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
ret = handle_close_if_different(&handle[j], block_file_get(block));
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "DANGER! Unexpected close error in a data disk, it isn't possible to sync.\n");
|
||||
fprintf(stderr, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -298,7 +300,7 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
} else {
|
||||
fprintf(stderr, "DANGER! Without a working data disk, it isn't possible to fix errors on it.\n");
|
||||
}
|
||||
fprintf(stderr, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -313,12 +315,10 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
/* if checking, open the file for reading */
|
||||
ret = handle_open(&handle[j], block_file_get(block));
|
||||
if (ret == -1) {
|
||||
/* save the failed block for the parity check */
|
||||
if (failed_count < 2) {
|
||||
failed[failed_count].index = j;
|
||||
failed[failed_count].block = block;
|
||||
failed[failed_count].handle = &handle[j];
|
||||
}
|
||||
/* save the failed block for the check/fix */
|
||||
failed[failed_count].index = j;
|
||||
failed[failed_count].block = block;
|
||||
failed[failed_count].handle = &handle[j];
|
||||
++failed_count;
|
||||
|
||||
fprintf(stderr, "%u: Open error for file %s at position %u\n", i, block_file_get(block)->sub, block_file_pos(block));
|
||||
|
|
@ -333,6 +333,7 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
fprintf(stderr, "File '%s' is larger than expected.\n", handle[j].path);
|
||||
|
||||
/* if fragmented, it may be reopened, so store the notification */
|
||||
/* to prevent to signal and count the error more than one time */
|
||||
file_flag_set(block_file_get(block), FILE_IS_LARGER);
|
||||
|
||||
/* this is always a recoverable error */
|
||||
|
|
@ -342,12 +343,10 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
|
||||
read_size = handle_read(&handle[j], block, buffer[j], state->block_size);
|
||||
if (read_size == -1) {
|
||||
/* save the failed block for the parity check */
|
||||
if (failed_count < 2) {
|
||||
failed[failed_count].index = j;
|
||||
failed[failed_count].block = block;
|
||||
failed[failed_count].handle = &handle[j];
|
||||
}
|
||||
/* save the failed block for the check/fix */
|
||||
failed[failed_count].index = j;
|
||||
failed[failed_count].block = block;
|
||||
failed[failed_count].handle = &handle[j];
|
||||
++failed_count;
|
||||
|
||||
fprintf(stderr, "%u: Read error for file %s at position %u\n", i, block_file_get(block)->sub, block_file_pos(block));
|
||||
|
|
@ -360,12 +359,10 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
|
||||
/* compare the hash */
|
||||
if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
|
||||
/* save the failed block for the parity check */
|
||||
if (failed_count < 2) {
|
||||
failed[failed_count].index = j;
|
||||
failed[failed_count].block = block;
|
||||
failed[failed_count].handle = &handle[j];
|
||||
}
|
||||
/* save the failed block for the check/fix */
|
||||
failed[failed_count].index = j;
|
||||
failed[failed_count].block = block;
|
||||
failed[failed_count].handle = &handle[j];
|
||||
++failed_count;
|
||||
|
||||
fprintf(stderr, "%u: Data error for file %s at position %u\n", i, block_file_get(block)->sub, block_file_pos(block));
|
||||
|
|
@ -420,8 +417,12 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
if (ret > 0)
|
||||
error += ret;
|
||||
|
||||
fprintf(stderr, "%u: UNRECOVERABLE error for this block\n", i);
|
||||
++unrecoverable_error;
|
||||
|
||||
/* print a list of all the errors in files */
|
||||
for(j=0;j<failed_count;++j) {
|
||||
fprintf(stderr, "%u: Unrecoverable error for file %s at position %u\n", i, block_file_get(failed[j].block)->sub, block_file_pos(failed[j].block));
|
||||
}
|
||||
} else {
|
||||
/* check parity and q-parity only if all the blocks have it computed */
|
||||
/* if you check/fix after a partial sync, it's OK to have parity errors on the blocks with invalid parity */
|
||||
|
|
@ -457,10 +458,10 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
if (errno == EACCES) {
|
||||
fprintf(stderr, "WARNING! Please give write permission to the file.\n");
|
||||
} else {
|
||||
/* we do not use DANGER because for ENOSPC which is not always correctly reported */
|
||||
/* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
|
||||
fprintf(stderr, "WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
|
||||
}
|
||||
fprintf(stderr, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -477,9 +478,9 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
if (buffer_parity == 0 && parity_f != -1) {
|
||||
ret = parity_write(state->parity, parity_f, i, buffer[diskmax], state->block_size);
|
||||
if (ret == -1) {
|
||||
/* we do not use DANGER because for ENOSPC which is not always correctly reported */
|
||||
/* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
|
||||
fprintf(stderr, "WARNING! Without a working Parity disk, it isn't possible to fix errors on it.\n");
|
||||
fprintf(stderr, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -493,9 +494,9 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
if (buffer_qarity == 0 && qarity_f != -1) {
|
||||
ret = parity_write(state->qarity, qarity_f, i, buffer[diskmax + 1], state->block_size);
|
||||
if (ret == -1) {
|
||||
/* we do not use DANGER because for ENOSPC which is not always correctly reported */
|
||||
/* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
|
||||
fprintf(stderr, "WARNING! Without a working Q-Parity disk, it isn't possible to fix errors on it.\n");
|
||||
fprintf(stderr, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -552,6 +553,7 @@ bail:
|
|||
printf("No error\n");
|
||||
}
|
||||
|
||||
free(failed);
|
||||
free(handle);
|
||||
free(buffer_alloc);
|
||||
free(buffer);
|
||||
|
|
|
|||
18
sync.c
18
sync.c
|
|
@ -124,7 +124,7 @@ static int state_sync_process(struct snapraid_state* state, int parity_f, int qa
|
|||
/* This one is really an unexpected error, because we are only reading */
|
||||
/* and closing a descriptor should never fail */
|
||||
fprintf(stderr, "DANGER! Unexpected close error in a data disk, it isn't possible to sync.\n");
|
||||
fprintf(stderr, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -134,14 +134,14 @@ static int state_sync_process(struct snapraid_state* state, int parity_f, int qa
|
|||
if (errno == ENOENT) {
|
||||
fprintf(stderr, "Missing file '%s'.\n", handle[j].path);
|
||||
fprintf(stderr, "WARNING! You cannot modify data disk during a sync. Rerun the sync command when finished.\n");
|
||||
fprintf(stderr, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
} else if (errno == EACCES) {
|
||||
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, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
} else {
|
||||
fprintf(stderr, "DANGER! Unexpected open error in a data disk, it isn't possible to sync.\n");
|
||||
fprintf(stderr, "Stopping to allow recovery. Try with 'snapraid check'\n");
|
||||
printf("Stopping to allow recovery. Try with 'snapraid check'\n");
|
||||
}
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
|
|
@ -159,7 +159,7 @@ static int state_sync_process(struct snapraid_state* state, int parity_f, int qa
|
|||
else
|
||||
fprintf(stderr, "Unexpected inode change from %"PRIu64" to %"PRIu64" at file '%s'.\n", block_file_get(block)->inode, handle[j].st.st_ino, handle[j].path);
|
||||
fprintf(stderr, "WARNING! You cannot modify files during a sync. Rerun the sync command when finished.\n");
|
||||
fprintf(stderr, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -167,7 +167,7 @@ static int state_sync_process(struct snapraid_state* state, int parity_f, int qa
|
|||
read_size = handle_read(&handle[j], block, buffer[j], state->block_size);
|
||||
if (read_size == -1) {
|
||||
fprintf(stderr, "DANGER! Unexpected read error in a data disk, it isn't possible to sync.\n");
|
||||
fprintf(stderr, "Stopping to allow recovery. Try with 'snapraid check'\n");
|
||||
printf("Stopping to allow recovery. Try with 'snapraid check'\n");
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -180,7 +180,7 @@ static int state_sync_process(struct snapraid_state* state, int parity_f, int qa
|
|||
if (memcmp(hash, block->hash, HASH_SIZE) != 0) {
|
||||
fprintf(stderr, "%u: Data error for file %s at position %u\n", i, block_file_get(block)->sub, block_file_pos(block));
|
||||
fprintf(stderr, "DANGER! Unexpected data error in a data disk, it isn't possible to sync.\n");
|
||||
fprintf(stderr, "Stopping to allow recovery. Try with 'snapraid -s %u check'\n", i);
|
||||
printf("Stopping to allow recovery. Try with 'snapraid -s %u check'\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -200,7 +200,7 @@ static int state_sync_process(struct snapraid_state* state, int parity_f, int qa
|
|||
ret = parity_write(state->parity, parity_f, i, buffer[diskmax], state->block_size);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "DANGER! Write error in the Parity disk, it isn't possible to sync.\n");
|
||||
fprintf(stderr, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -210,7 +210,7 @@ static int state_sync_process(struct snapraid_state* state, int parity_f, int qa
|
|||
ret = parity_write(state->qarity, qarity_f, i, buffer[diskmax+1], state->block_size);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "DANGER! Write error in the Q-Parity disk, it isn't possible to sync.\n");
|
||||
fprintf(stderr, "Stopping at block %u\n", i);
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue