Adds a the new -e, --filter-error option for fix and check.

This commit is contained in:
Andrea Mazzoleni 2013-08-18 19:24:55 +02:00
parent 746c829bec
commit 746901d0be
6 changed files with 75 additions and 12 deletions

27
elem.c
View file

@ -248,7 +248,32 @@ int filter_existence(int filter_missing, const char* dir, const char* sub)
exit(EXIT_FAILURE);
}
/* the file is presen, so we filter it out */
/* the file is present, so we filter it out */
return 1;
}
int filter_correctness(int filter_error, tommy_arrayof* infoarr, struct snapraid_file* file)
{
unsigned i;
if (!filter_error)
return 0;
/* check each block of the file */
for(i=0;i<file->blockmax;++i) {
struct snapraid_block* block;
snapraid_info info;
block = &file->blockvec[i];
info = info_get(infoarr, block->parity_pos);
/* if the file has a bad block, don't exclude it */
if (info_get_bad(info))
return 0;
}
/* the file is correct, so we filter it out */
return 1;
}

6
elem.h
View file

@ -363,6 +363,12 @@ int filter_path(tommy_list* filterlist, const char* disk, const char* sub);
*/
int filter_existence(int filter_missing, const char* dir, const char* sub);
/**
* Filter a file if bad.
* Return !=0 if the file is correct and it should be excluded.
*/
int filter_correctness(int filter_error, tommy_arrayof* infoarr, struct snapraid_file* file);
/**
* Filters a dir using a list of filters.
* For each element of the path all the filters are applied, until the first one that matches.

View file

@ -61,7 +61,8 @@ void usage(void)
printf(" " SWITCH_GETOPT_LONG("-c, --conf FILE ", "-c") " Configuration file (default " CONF ")\n");
printf(" " SWITCH_GETOPT_LONG("-f, --filter PATTERN ", "-f") " Process only files matching the pattern\n");
printf(" " SWITCH_GETOPT_LONG("-d, --filter-dist NAME", "-f") " Process only files in the disk\n");
printf(" " SWITCH_GETOPT_LONG("-m, --filter-missing ", "-m") " Process only missing/delete files\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 blocks with silent errors\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");
@ -103,6 +104,7 @@ struct option long_options[] = {
{ "filter", 1, 0, 'f' },
{ "filter-disk", 1, 0, 'd' },
{ "filter-missing", 0, 0, 'm' },
{ "filter-error", 0, 0, 'e' },
{ "start", 1, 0, 's' },
{ "count", 1, 0, 't' },
{ "import", 1, 0, 'i' },
@ -176,7 +178,7 @@ struct option long_options[] = {
};
#endif
#define OPTIONS "c:f:d:ms:t:i:l:ZEUDNaTvhVG"
#define OPTIONS "c:f:d:mes:t:i:l:ZEUDNaTvhVG"
volatile int global_interrupt = 0;
@ -215,6 +217,7 @@ int main(int argc, char* argv[])
tommy_list filterlist_file;
tommy_list filterlist_disk;
int filter_missing;
int filter_error;
char* e;
const char* command;
const char* import;
@ -232,6 +235,7 @@ int main(int argc, char* argv[])
tommy_list_init(&filterlist_file);
tommy_list_init(&filterlist_disk);
filter_missing = 0;
filter_error = 0;
import = 0;
log = 0;
lock = 0;
@ -267,6 +271,9 @@ int main(int argc, char* argv[])
case 'm' :
filter_missing = 1;
break;
case 'e' :
filter_error = 1;
break;
case 's' :
blockstart = strtoul(optarg, &e, 0);
if (!e || *e) {
@ -452,8 +459,27 @@ int main(int argc, char* argv[])
case OPERATION_DRY :
break;
default:
if (!tommy_list_empty(&filterlist_file) || !tommy_list_empty(&filterlist_disk) || filter_missing) {
fprintf(stderr, "You cannot filter with the '%s' command\n", command);
if (!tommy_list_empty(&filterlist_file)) {
fprintf(stderr, "You cannot use -f, --filter with the '%s' command\n", command);
exit(EXIT_FAILURE);
}
if (!tommy_list_empty(&filterlist_disk)) {
fprintf(stderr, "You cannot use -d, --filter-disk with the '%s' command\n", command);
exit(EXIT_FAILURE);
}
if (filter_missing != 0) {
fprintf(stderr, "You cannot use -m, --filter-missing with the '%s' command\n", command);
exit(EXIT_FAILURE);
}
}
switch (operation) {
case OPERATION_CHECK :
case OPERATION_FIX :
break;
default:
if (filter_error != 0) {
fprintf(stderr, "You cannot use -e, --filter-error with the '%s' command\n", command);
exit(EXIT_FAILURE);
}
}
@ -565,7 +591,7 @@ int main(int argc, char* argv[])
state_read(&state);
/* apply the command line filter */
state_filter(&state, &filterlist_file, &filterlist_disk, filter_missing);
state_filter(&state, &filterlist_file, &filterlist_disk, filter_missing, filter_error);
/* intercept Ctrl+C */
signal(SIGINT, &signal_handler);
@ -620,7 +646,7 @@ int main(int argc, char* argv[])
state_import(&state, import);
/* apply the command line filter */
state_filter(&state, &filterlist_file, &filterlist_disk, filter_missing);
state_filter(&state, &filterlist_file, &filterlist_disk, filter_missing, filter_error);
/* intercept Ctrl+C */
signal(SIGINT, &signal_handler);

View file

@ -3318,12 +3318,12 @@ void state_write(struct snapraid_state* state)
state->need_write = 0; /* no write needed anymore */
}
void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tommy_list* filterlist_disk, int filter_missing)
void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tommy_list* filterlist_disk, int filter_missing, int filter_error)
{
tommy_node* i;
/* if no filter, include all */
if (!filter_missing && tommy_list_empty(filterlist_file) && tommy_list_empty(filterlist_disk))
if (!filter_missing && !filter_error && tommy_list_empty(filterlist_file) && tommy_list_empty(filterlist_disk))
return;
printf("Filtering...\n");
@ -3346,6 +3346,8 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tom
}
if (filter_missing)
printf("\t<missing>\n");
if (filter_error)
printf("\t<error>\n");
}
/* for each disk */
@ -3364,6 +3366,7 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tom
if (filter_path(filterlist_disk, disk->name, file->sub) != 0
|| filter_path(filterlist_file, disk->name, file->sub) != 0
|| filter_existence(filter_missing, disk->dir, file->sub) != 0
|| filter_correctness(filter_error, &state->infoarr, file) != 0
) {
file_flag_set(file, FILE_IS_EXCLUDED);
}

View file

@ -172,7 +172,7 @@ void state_pool(struct snapraid_state* state);
* Filter files, symlinks and dirs.
* Apply an additional filter to the list currently loaded.
*/
void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tommy_list* filterlist_disk, int filter_missing);
void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tommy_list* filterlist_disk, int filter_missing, int filter_error);
/**
* Begins the progress visualization.

View file

@ -222,7 +222,7 @@ int state_status(struct snapraid_state* state)
printf("\n");
if (bad) {
printf("DANGER! In the array there are %u failing blocks!\n", bad);
printf("DANGER! In the array there are %u failing blocks!\n\n", bad);
printf("They are:");
@ -238,7 +238,10 @@ int state_status(struct snapraid_state* state)
printf(" %u", i);
}
printf("\n");
printf("\n\n");
printf("To fix them use the command 'snapraid --filter-error fix'.\n");
printf("The errors will disapper from the 'status' at the next 'scrub' command.\n");
} else {
printf("No silent error detected!\n");
}