Groups all the startup options in the new snapraid_option struct.

This commit is contained in:
Andrea Mazzoleni 2013-06-29 18:11:36 +02:00
parent 9d1fbd8bfc
commit 1ddb24da46
13 changed files with 152 additions and 192 deletions

58
check.c
View file

@ -605,7 +605,7 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
/* if fixing, and the file is not excluded, we must open for writing */
if (fix && !file_flag_has(block_file_get(block), FILE_IS_EXCLUDED)) {
/* if fixing, create the file, open for writing and resize if required */
ret = handle_create(&handle[j], block_file_get(block), state->skip_sequential);
ret = handle_create(&handle[j], block_file_get(block), state->opt.skip_sequential);
if (ret == -1) {
if (errno == EACCES) {
fprintf(stderr, "WARNING! Please give write permission to the file.\n");
@ -636,7 +636,7 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
}
} else {
/* if checking or hashing, open the file only for reading */
ret = handle_open(&handle[j], block_file_get(block), stdlog, state->skip_sequential);
ret = handle_open(&handle[j], block_file_get(block), stdlog, state->opt.skip_sequential);
if (ret == -1) {
/* save the failed block for the check/fix */
failed[failed_count].is_bad = 1;
@ -992,9 +992,9 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
goto bail;
}
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "status:unrecoverable:%s:%s\n", handle[j].disk->name, file->sub);
} else if (state->verbose) {
} else if (state->opt.verbose) {
printf("Unrecoverable '%s'\n", path);
}
@ -1008,9 +1008,9 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
goto close_and_continue;
}
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "status:recovered:%s:%s\n", handle[j].disk->name, file->sub);
} else if (state->verbose) {
} else if (state->opt.verbose) {
printf("Recovered '%s'\n", path);
}
@ -1051,28 +1051,28 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
/* print just the final status */
if (file_flag_has(file, FILE_IS_DAMAGED)) {
if (!check) {
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "status:damaged:%s:%s\n", handle[j].disk->name, file->sub);
} else if (state->verbose) {
} else if (state->opt.verbose) {
printf("Damaged '%s'\n", path);
}
} else {
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "status:unrecoverable:%s:%s\n", handle[j].disk->name, file->sub);
} else if (state->verbose) {
} else if (state->opt.verbose) {
printf("Unrecoverable '%s'\n", path);
}
}
} else if (file_flag_has(file, FILE_IS_FIXED)) {
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "status:recoverable:%s:%s\n", handle[j].disk->name, file->sub);
} else if (state->verbose) {
} else if (state->opt.verbose) {
printf("Recoverable '%s'\n", path);
}
} else {
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "status:correct:%s:%s\n", handle[j].disk->name, file->sub);
} else if (state->verbose) {
} else if (state->opt.verbose) {
printf("Correct '%s'\n", path);
}
}
@ -1184,9 +1184,9 @@ close_and_continue:
fprintf(stdlog, "fixed:%s:%s: Fixed empty file\n", disk->name, file->sub);
++recovered_error;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "status:recovered:%s:%s\n", disk->name, file->sub);
} else if (state->verbose) {
} else if (state->opt.verbose) {
printf("Recovered '%s%s'\n", disk->dir, file->sub);
}
}
@ -1342,9 +1342,9 @@ close_and_continue:
++recovered_error;
}
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "status:recovered:%s:%s\n", disk->name, link->sub);
} else if (state->verbose) {
} else if (state->opt.verbose) {
printf("Recovered '%s%s'\n", disk->dir, link->sub);
}
}
@ -1411,9 +1411,9 @@ close_and_continue:
fprintf(stdlog, "dir_fixed:%s:%s: Fixed dir error\n", disk->name, dir->sub);
++recovered_error;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "status:ok:%s:%s\n", disk->name, dir->sub);
} else if (state->verbose) {
} else if (state->opt.verbose) {
printf("Recovered '%s%s'\n", disk->dir, dir->sub);
}
}
@ -1512,7 +1512,7 @@ bail:
/* fails if some error are present after the run */
if (fix) {
if (state->expect_unrecoverable) {
if (state->opt.expect_unrecoverable) {
if (unrecoverable_error == 0)
return -1;
} else {
@ -1520,10 +1520,10 @@ bail:
return -1;
}
} else {
if (state->expect_unrecoverable) {
if (state->opt.expect_unrecoverable) {
if (unrecoverable_error == 0)
return -1;
} else if (state->expect_recoverable) {
} else if (state->opt.expect_recoverable) {
if (error == 0)
return -1;
} else {
@ -1571,13 +1571,13 @@ int state_check(struct snapraid_state* state, int check, int fix, block_off_t bl
/* if fixing, create the file and open for writing */
/* if it fails, we cannot continue */
parity_ptr = &parity;
ret = parity_create(parity_ptr, state->parity, &out_size, state->skip_sequential);
ret = parity_create(parity_ptr, state->parity, &out_size, state->opt.skip_sequential);
if (ret == -1) {
fprintf(stderr, "WARNING! Without an accessible Parity file, it isn't possible to fix any error.\n");
exit(EXIT_FAILURE);
}
ret = parity_chsize(parity_ptr, size, &out_size, state->skip_fallocate);
ret = parity_chsize(parity_ptr, size, &out_size, state->opt.skip_fallocate);
if (ret == -1) {
fprintf(stderr, "WARNING! Without an accessible Parity file, it isn't possible to sync.\n");
exit(EXIT_FAILURE);
@ -1585,13 +1585,13 @@ int state_check(struct snapraid_state* state, int check, int fix, block_off_t bl
if (state->level >= 2) {
qarity_ptr = &qarity;
ret = parity_create(qarity_ptr, state->qarity, &out_size, state->skip_sequential);
ret = parity_create(qarity_ptr, state->qarity, &out_size, state->opt.skip_sequential);
if (ret == -1) {
fprintf(stderr, "WARNING! Without an accessible Q-Parity file, it isn't possible to fix any error.\n");
exit(EXIT_FAILURE);
}
ret = parity_chsize(qarity_ptr, size, &out_size, state->skip_fallocate);
ret = parity_chsize(qarity_ptr, size, &out_size, state->opt.skip_fallocate);
if (ret == -1) {
fprintf(stderr, "WARNING! Without an accessible Q-Parity file, it isn't possible to sync.\n");
exit(EXIT_FAILURE);
@ -1603,7 +1603,7 @@ int state_check(struct snapraid_state* state, int check, int fix, block_off_t bl
/* if checking, open the file for reading */
/* it may fail if the file doesn't exist, in this case we continue to check the files */
parity_ptr = &parity;
ret = parity_open(parity_ptr, state->parity, state->skip_sequential);
ret = parity_open(parity_ptr, state->parity, state->opt.skip_sequential);
if (ret == -1) {
printf("No accessible Parity file, only files will be checked.\n");
/* continue anyway */
@ -1612,7 +1612,7 @@ int state_check(struct snapraid_state* state, int check, int fix, block_off_t bl
if (state->level >= 2) {
qarity_ptr = &qarity;
ret = parity_open(qarity_ptr, state->qarity, state->skip_sequential);
ret = parity_open(qarity_ptr, state->qarity, state->opt.skip_sequential);
if (ret == -1) {
printf("No accessible Q-Parity file, only files will be checked.\n");
/* continue anyway */

6
dry.c
View file

@ -77,7 +77,7 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
}
/* open the file only for reading */
ret = handle_open(&handle[j], block_file_get(block), stdlog, state->skip_sequential);
ret = handle_open(&handle[j], block_file_get(block), stdlog, state->opt.skip_sequential);
if (ret == -1) {
fprintf(stderr, "DANGER! Unexpected open error in a data disk, it isn't possible to rehash.\n");
printf("Stopping at block %u\n", i);
@ -180,7 +180,7 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
/* open the file for reading */
/* it may fail if the file doesn't exist, in this case we continue to dry the files */
parity_ptr = &parity;
ret = parity_open(parity_ptr, state->parity, state->skip_sequential);
ret = parity_open(parity_ptr, state->parity, state->opt.skip_sequential);
if (ret == -1) {
printf("No accessible Parity file.\n");
/* continue anyway */
@ -189,7 +189,7 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
if (state->level >= 2) {
qarity_ptr = &qarity;
ret = parity_open(qarity_ptr, state->qarity, state->skip_sequential);
ret = parity_open(qarity_ptr, state->qarity, state->opt.skip_sequential);
if (ret == -1) {
printf("No accessible Q-Parity file.\n");
/* continue anyway */

4
dup.c
View file

@ -123,7 +123,7 @@ void state_dup(struct snapraid_state* state)
if (dup) {
++count;
size += dup->file->size;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "dup:%s:%s:%s:%s:%"PRIu64": dup\n", disk->name, file->sub, dup->disk->name, dup->file->sub, dup->file->size);
} else {
printf("%"PRIu64" '%s%s'\n", file->size / (1024*1024), disk->dir, file->sub);
@ -140,7 +140,7 @@ void state_dup(struct snapraid_state* state)
tommy_list_foreach(&hashlist, (tommy_foreach_func*)hash_free);
tommy_hashdyn_done(&hashset);
if (!state->gui) {
if (!state->opt.gui) {
if (count)
printf("%u duplicates, for %"PRIu64" MiB.\n", count, size / (1024*1024));
else

View file

@ -62,7 +62,7 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t
/* open for read */
/* O_SEQUENTIAL: opening in sequential mode in Windows */
flags = O_RDONLY | O_BINARY;
if (!state->skip_sequential)
if (!state->opt.skip_sequential)
flags |= O_SEQUENTIAL;
f = open(path, flags);
if (f == -1) {
@ -71,7 +71,7 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t
}
#if HAVE_POSIX_FADVISE
if (!state->skip_sequential) {
if (!state->opt.skip_sequential) {
/* advise sequential access */
ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
if (ret != 0) {

View file

@ -75,7 +75,7 @@ void parity_overflow(struct snapraid_state* state, data_off_t size)
if (file->blockmax > 0) {
if (file->blockvec[0].parity_pos >= blockalloc) {
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "outofparity:%s:%s\n", disk->name, file->sub);
fflush(stdlog);
}

4
pool.c
View file

@ -109,7 +109,7 @@ static int clean_dir(struct snapraid_state* state, const char* dir)
}
} else {
ignored = 1;
if (state->verbose) {
if (state->opt.verbose) {
printf("Ignoring pool file '%s'\n", path_next);
}
}
@ -204,7 +204,7 @@ void state_pool(struct snapraid_state* state)
/* we ignore empty dirs in disk->dir */
}
if (!state->gui) {
if (!state->opt.gui) {
if (count)
printf("%u links created\n", count);
else

View file

@ -124,7 +124,7 @@ static int state_rehash_process(struct snapraid_state* state, block_off_t blocks
}
/* open the file only for reading */
ret = handle_open(&handle[j], block_file_get(block), stdlog, state->skip_sequential);
ret = handle_open(&handle[j], block_file_get(block), stdlog, state->opt.skip_sequential);
if (ret == -1) {
fprintf(stderr, "DANGER! Unexpected open error in a data disk, it isn't possible to rehash.\n");
printf("Stopping at block %u\n", i);

54
scan.c
View file

@ -92,7 +92,7 @@ static void scan_link(struct snapraid_scan* scan, struct snapraid_state* state,
/* it's equal */
++scan->count_equal;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:equal:%s:%s\n", disk->name, link->sub);
fflush(stdlog);
}
@ -101,7 +101,7 @@ static void scan_link(struct snapraid_scan* scan, struct snapraid_state* state,
return;
} else {
/* it's an update */
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:update:%s:%s\n", disk->name, link->sub);
fflush(stdlog);
}
@ -123,7 +123,7 @@ static void scan_link(struct snapraid_scan* scan, struct snapraid_state* state,
/* create the new link */
++scan->count_insert;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:add:%s:%s\n", disk->name, sub);
fflush(stdlog);
}
@ -274,7 +274,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
{
struct snapraid_file* file;
if (state->find_by_name) {
if (state->opt.find_by_name) {
/* check if the file path already exists */
file = tommy_hashdyn_search(&disk->pathset, file_path_compare, sub, file_path_hash(sub));
} else {
@ -325,7 +325,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
exit(EXIT_FAILURE);
}
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:move:%s:%s:%s\n", disk->name, file->sub, sub);
fflush(stdlog);
}
@ -349,7 +349,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
/* like when restoring a backup that restores also the time information */
++scan->count_moved;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:restore:%s:%s\n", disk->name, sub);
fflush(stdlog);
}
@ -372,7 +372,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
/* otherwise it's equal */
++scan->count_equal;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:equal:%s:%s\n", disk->name, file->sub);
fflush(stdlog);
}
@ -389,7 +389,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
/* do the check ONLY if the name is the same */
/* otherwise it could be a deleted and recreated file */
if (strcmp(file->sub, sub) == 0) {
if (!state->force_zero) {
if (!state->opt.force_zero) {
fprintf(stderr, "The file '%s%s' has unexpected zero size! If this an expected state\n", disk->dir, sub);
fprintf(stderr, "you can '%s' anyway usinge 'snapraid --force-zero %s'\n", state->command, state->command);
fprintf(stderr, "Instead, it's possible that after a kernel crash this file was lost,\n");
@ -401,7 +401,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
if (strcmp(file->sub, sub) == 0) {
/* if the name is the same, it's an update */
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:update:%s:%s\n", disk->name, file->sub);
fflush(stdlog);
}
@ -412,7 +412,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
++scan->count_change;
} else {
/* if the name is different, it's an inode reuse */
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:remove:%s:%s\n", disk->name, file->sub);
fprintf(stdlog, "scan:add:%s:%s\n", disk->name, sub);
fflush(stdlog);
@ -435,7 +435,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
/* create the new file */
++scan->count_insert;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:add:%s:%s\n", disk->name, sub);
fflush(stdlog);
}
@ -511,7 +511,7 @@ static void scan_emptydir(struct snapraid_scan* scan, struct snapraid_state* sta
/* it's equal */
++scan->count_equal;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:equal:%s:%s\n", disk->name, dir->sub);
fflush(stdlog);
}
@ -522,7 +522,7 @@ static void scan_emptydir(struct snapraid_scan* scan, struct snapraid_state* sta
/* create the new dir */
++scan->count_insert;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:add:%s:%s\n", disk->name, sub);
fflush(stdlog);
}
@ -594,7 +594,7 @@ static int scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, in
/* exclude hidden files even before calling lstat() */
if (filter_hidden(state->filter_hidden, dd) != 0) {
if (state->verbose) {
if (state->opt.verbose) {
printf("Excluding hidden '%s'\n", path_next);
}
continue;
@ -602,7 +602,7 @@ static int scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, in
/* exclude content files even before calling lstat() */
if (filter_content(&state->contentlist, path_next) != 0) {
if (state->verbose) {
if (state->opt.verbose) {
printf("Excluding content '%s'\n", path_next);
}
continue;
@ -631,7 +631,7 @@ static int scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, in
exit(EXIT_FAILURE);
}
#endif
if (state->force_order == SORT_PHYSICAL) {
if (state->opt.force_order == SORT_PHYSICAL) {
if (filephy(path_next, &st, &physical) != 0) {
fprintf(stderr, "Error in getting the physical offset of file '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
@ -643,7 +643,7 @@ static int scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, in
scan_file(scan, state, output, disk, sub_next, &st, physical);
processed = 1;
} else {
if (state->verbose) {
if (state->opt.verbose) {
printf("Excluding file '%s'\n", path_next);
}
}
@ -669,7 +669,7 @@ static int scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, in
scan_link(scan, state, output, disk, sub_next, subnew, FILE_IS_SYMLINK);
processed = 1;
} else {
if (state->verbose) {
if (state->opt.verbose) {
printf("Excluding link '%s'\n", path_next);
}
}
@ -692,7 +692,7 @@ static int scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, in
processed = 1;
}
} else {
if (state->verbose) {
if (state->opt.verbose) {
printf("Excluding directory '%s'\n", path_next);
}
}
@ -700,7 +700,7 @@ static int scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, in
if (filter_path(&state->filterlist, disk->name, sub_next) == 0) {
fprintf(stderr, "warning: Ignoring special '%s' file '%s'\n", stat_desc(&st), path_next);
} else {
if (state->verbose) {
if (state->opt.verbose) {
printf("Excluding special '%s' file '%s'\n", stat_desc(&st), path_next);
}
}
@ -756,7 +756,7 @@ void state_scan(struct snapraid_state* state, int output)
if (!file_flag_has(file, FILE_IS_PRESENT)) {
++scan->count_remove;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:remove:%s:%s\n", disk->name, file->sub);
fflush(stdlog);
}
@ -780,7 +780,7 @@ void state_scan(struct snapraid_state* state, int output)
if (!link_flag_has(link, FILE_IS_PRESENT)) {
++scan->count_remove;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:remove:%s:%s\n", disk->name, link->sub);
fflush(stdlog);
}
@ -804,7 +804,7 @@ void state_scan(struct snapraid_state* state, int output)
if (!dir_flag_has(dir, FILE_IS_PRESENT)) {
++scan->count_remove;
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "scan:remove:%s:%s\n", disk->name, dir->sub);
fflush(stdlog);
}
@ -817,7 +817,7 @@ void state_scan(struct snapraid_state* state, int output)
}
/* sort the files before inserting them */
switch (state->force_order) {
switch (state->opt.force_order) {
case SORT_PHYSICAL :
tommy_list_sort(&scan->file_insert_list, file_physical_compare);
break;
@ -871,7 +871,7 @@ void state_scan(struct snapraid_state* state, int output)
}
/* checks for disks where all the previously existing files where removed */
if (!state->force_empty) {
if (!state->opt.force_empty) {
int has_empty = 0;
for(i=state->disklist,j=scanlist;i!=0;i=i->next,j=j->next) {
struct snapraid_disk* disk = i->data;
@ -897,7 +897,7 @@ void state_scan(struct snapraid_state* state, int output)
}
}
if (state->verbose || output) {
if (state->opt.verbose || output) {
struct snapraid_scan total;
total.count_equal = 0;
@ -915,7 +915,7 @@ void state_scan(struct snapraid_state* state, int output)
total.count_insert += scan->count_insert;
}
if (state->verbose) {
if (state->opt.verbose) {
printf("\tequal %d\n", total.count_equal);
printf("\tmoved %d\n", total.count_moved);
printf("\tchanged %d\n", total.count_change);

View file

@ -162,7 +162,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
}
}
ret = handle_open(&handle[j], block_file_get(block), stderr, state->skip_sequential);
ret = handle_open(&handle[j], block_file_get(block), stderr, state->opt.skip_sequential);
if (ret == -1) {
fprintf(stdlog, "error:%u:%s:%s: Open error at position %u\n", i, handle[j].disk->name, block_file_get(block)->sub, block_file_pos(block));
++error;
@ -378,7 +378,7 @@ int state_scrub(struct snapraid_state* state)
/* open the file for reading */
parity_ptr = &parity;
ret = parity_open(parity_ptr, state->parity, state->skip_sequential);
ret = parity_open(parity_ptr, state->parity, state->opt.skip_sequential);
if (ret == -1) {
fprintf(stderr, "WARNING! Without an accessible Parity file, it isn't possible to scrub.\n");
exit(EXIT_FAILURE);
@ -386,7 +386,7 @@ int state_scrub(struct snapraid_state* state)
if (state->level >= 2) {
qarity_ptr = &qarity;
ret = parity_open(qarity_ptr, state->qarity, state->skip_sequential);
ret = parity_open(qarity_ptr, state->qarity, state->opt.skip_sequential);
if (ret == -1) {
fprintf(stderr, "WARNING! Without an accessible Q-Parity file, it isn't possible to scrub.\n");
exit(EXIT_FAILURE);

View file

@ -185,25 +185,8 @@ void signal_handler(int signal)
int main(int argc, char* argv[])
{
int c;
int verbose;
int gui;
int force_zero;
int force_empty;
int force_uuid;
int find_by_name;
struct snapraid_option opt;
int audit_only;
int test_kill_after_sync;
int test_expect_unrecoverable;
int test_expect_recoverable;
int test_skip_self;
int test_skip_sign;
int test_skip_fallocate;
int test_skip_sequential;
int test_skip_device;
int test_force_murmur3;
int test_force_spooky2;
int test_skip_lock;
int test_force_order;
const char* conf;
struct snapraid_state state;
int operation;
@ -223,25 +206,8 @@ int main(int argc, char* argv[])
/* defaults */
conf = CONF;
verbose = 0;
gui = 0;
force_zero = 0;
force_empty = 0;
force_uuid = 0;
find_by_name = 0;
memset(&opt, 0, sizeof(opt));
audit_only = 0;
test_kill_after_sync = 0;
test_expect_unrecoverable = 0;
test_expect_recoverable = 0;
test_skip_self = 0;
test_skip_sign = 0;
test_skip_fallocate = 0;
test_skip_sequential = 0;
test_skip_device = 0;
test_force_murmur3 = 0;
test_force_spooky2 = 0;
test_skip_lock = 0;
test_force_order = SORT_PHYSICAL;
blockstart = 0;
blockcount = 0;
tommy_list_init(&filterlist_file);
@ -311,25 +277,25 @@ int main(int argc, char* argv[])
log = optarg;
break;
case 'Z' :
force_zero = 1;
opt.force_zero = 1;
break;
case 'E' :
force_empty = 1;
opt.force_empty = 1;
break;
case 'U' :
force_uuid = 1;
opt.force_uuid = 1;
break;
case 'N' :
find_by_name = 1;
opt.find_by_name = 1;
break;
case 'a' :
audit_only = 1;
break;
case 'v' :
verbose = 1;
opt.verbose = 1;
break;
case 'G' :
gui = 1;
opt.gui = 1;
break;
case 'h' :
usage();
@ -341,49 +307,49 @@ int main(int argc, char* argv[])
speed();
exit(EXIT_SUCCESS);
case OPT_TEST_KILL_AFTER_SYNC :
test_kill_after_sync = 1;
opt.kill_after_sync = 1;
break;
case OPT_TEST_EXPECT_UNRECOVERABLE :
test_expect_unrecoverable = 1;
opt.expect_unrecoverable = 1;
break;
case OPT_TEST_EXPECT_RECOVERABLE :
test_expect_recoverable = 1;
opt.expect_recoverable = 1;
break;
case OPT_TEST_SKIP_SELF :
test_skip_self = 1;
opt.skip_self = 1;
break;
case OPT_TEST_SKIP_SIGN :
test_skip_sign = 1;
opt.skip_sign = 1;
break;
case OPT_TEST_SKIP_FALLOCATE :
test_skip_fallocate = 1;
opt.skip_fallocate = 1;
break;
case OPT_TEST_SKIP_SEQUENTIAL :
test_skip_sequential = 1;
opt.skip_sequential = 1;
break;
case OPT_TEST_SKIP_DEVICE :
test_skip_device = 1;
opt.skip_device = 1;
break;
case OPT_TEST_FORCE_MURMUR3 :
test_force_murmur3 = 1;
opt.force_murmur3 = 1;
break;
case OPT_TEST_FORCE_SPOOKY2 :
test_force_spooky2 = 1;
opt.force_spooky2 = 1;
break;
case OPT_TEST_SKIP_LOCK :
test_skip_lock = 1;
opt.skip_lock = 1;
break;
case OPT_TEST_FORCE_ORDER_PHYSICAL :
test_force_order = SORT_PHYSICAL;
opt.force_order = SORT_PHYSICAL;
break;
case OPT_TEST_FORCE_ORDER_INODE :
test_force_order = SORT_INODE;
opt.force_order = SORT_INODE;
break;
case OPT_TEST_FORCE_ORDER_ALPHA :
test_force_order = SORT_ALPHA;
opt.force_order = SORT_ALPHA;
break;
case OPT_TEST_FORCE_ORDER_DIR :
test_force_order = SORT_DIR;
opt.force_order = SORT_DIR;
break;
default:
fprintf(stderr, "Unknown option '%c'\n", (char)c);
@ -438,7 +404,7 @@ int main(int argc, char* argv[])
case OPERATION_DIFF :
break;
default:
if (find_by_name) {
if (opt.find_by_name) {
fprintf(stderr, "You cannot use -N, --find-by-name with the '%s' command\n", command);
exit(EXIT_FAILURE);
}
@ -469,17 +435,17 @@ int main(int argc, char* argv[])
raid_init();
if (!test_skip_self)
selftest(gui);
if (!opt.skip_self)
selftest(opt.gui);
state_init(&state);
/* read the configuration file */
state_config(&state, conf, command, verbose, gui, force_zero, force_empty, force_uuid, find_by_name, test_expect_unrecoverable, test_expect_recoverable, test_skip_sign, test_skip_fallocate, test_skip_sequential, test_skip_device, test_force_murmur3, test_force_spooky2, test_force_order);
state_config(&state, conf, command, &opt);
#if HAVE_LOCKFILE
/* create the lock file */
if (!test_skip_lock) {
if (!opt.skip_lock) {
lock = lock_lock(state.lockfile);
if (lock == -1) {
if (errno != EWOULDBLOCK) {
@ -492,7 +458,6 @@ int main(int argc, char* argv[])
}
}
#else
(void)test_skip_lock;
(void)lock;
#endif
@ -547,13 +512,13 @@ int main(int argc, char* argv[])
/* The worst case is the FAT filesystem with a two seconds resolution for mtime. */
/* If you don't use FAT, the wait is not needed, because most filesystems have now */
/* at least microseconds resolution, but better to be safe. */
if (!test_skip_self)
if (!opt.skip_self)
sleep(2);
ret = state_sync(&state, blockstart, blockcount);
/* save the new state if required */
if (!test_kill_after_sync && state.need_write)
if (!opt.kill_after_sync && state.need_write)
state_write(&state);
/* abort if required */
@ -639,7 +604,7 @@ int main(int argc, char* argv[])
}
#if HAVE_LOCKFILE
if (!test_skip_lock) {
if (!opt.skip_lock) {
if (lock_unlock(lock) == -1) {
fprintf(stderr, "Error closing the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
exit(EXIT_FAILURE);

74
state.c
View file

@ -25,18 +25,8 @@
void state_init(struct snapraid_state* state)
{
state->verbose = 0;
state->gui = 0;
state->force_zero = 0;
state->force_empty = 0;
state->filter_hidden = 0;
state->find_by_name = 0;
state->autosave = 0;
state->expect_unrecoverable = 0;
state->expect_recoverable = 0;
state->skip_sign = 0;
state->skip_fallocate = 0;
state->skip_sequential = 0;
state->need_write = 0;
state->block_size = 256 * 1024; /* default 256 KiB */
state->parity[0] = 0;
@ -72,7 +62,7 @@ void state_done(struct snapraid_state* state)
/**
* Checks the configuration.
*/
static void state_config_check(struct snapraid_state* state, const char* path, int skip_device)
static void state_config_check(struct snapraid_state* state, const char* path)
{
tommy_node* i;
@ -102,7 +92,7 @@ static void state_config_check(struct snapraid_state* state, const char* path, i
}
/* check if all the data and parity disks are different */
if (!skip_device) {
if (!state->opt.skip_device) {
unsigned diskcount = 0;
for(i=state->disklist;i!=0;i=i->next) {
@ -215,7 +205,7 @@ static void state_config_check(struct snapraid_state* state, const char* path, i
}
/* count the content files */
if (!skip_device) {
if (!state->opt.skip_device) {
unsigned content_count;
content_count = 0;
@ -245,30 +235,22 @@ static void state_config_check(struct snapraid_state* state, const char* path, i
}
}
void state_config(struct snapraid_state* state, const char* path, const char* command, int verbose, int gui, int force_zero, int force_empty, int force_uuid, int find_by_name, int expect_unrecoverable, int expect_recoverable, int skip_sign, int skip_fallocate, int skip_sequential, int skip_device, int force_murmur3, int force_spooky2, int force_order)
void state_config(struct snapraid_state* state, const char* path, const char* command, struct snapraid_option* opt)
{
STREAM* f;
unsigned line;
tommy_node* i;
state->verbose = verbose;
state->gui = gui;
state->force_zero = force_zero;
state->force_empty = force_empty;
state->force_uuid = force_uuid;
state->filter_hidden = 0;
state->find_by_name = find_by_name;
state->expect_unrecoverable = expect_unrecoverable;
state->expect_recoverable = expect_recoverable;
state->skip_sign = skip_sign;
state->skip_fallocate = skip_fallocate;
state->skip_sequential = skip_sequential;
state->command = command;
state->force_murmur3 = force_murmur3;
state->force_spooky2 = force_spooky2;
state->force_order = force_order;
/* copy the options */
state->opt = *opt;
if (state->gui) {
/* if unsed, sort by physical order */
if (!state->opt.force_order)
state->opt.force_order = SORT_PHYSICAL;
state->command = command;
if (state->opt.gui) {
fprintf(stdlog, "version:%s\n", PACKAGE_VERSION);
fprintf(stdlog, "conf:%s\n", path);
fflush(stdlog);
@ -621,12 +603,12 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
sclose(f);
state_config_check(state, path, skip_device);
state_config_check(state, path);
/* select the default hash */
if (state->force_murmur3) {
if (state->opt.force_murmur3) {
state->besthash = HASH_MURMUR3;
} else if (state->force_spooky2) {
} else if (state->opt.force_spooky2) {
state->besthash = HASH_SPOOKY2;
} else {
#if defined(__i386__) || defined(__x86_64__)
@ -648,7 +630,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
/* by default use a random hash seed */
randomize(state->hashseed, HASH_SIZE);
if (state->gui) {
if (state->opt.gui) {
tommy_node* i;
fprintf(stdlog, "blocksize:%u\n", state->block_size);
for(i=state->disklist;i!=0;i=i->next) {
@ -790,7 +772,7 @@ static void state_map(struct snapraid_state* state)
}
}
if (!state->force_uuid && uuid_mismatch > state->level) {
if (!state->opt.force_uuid && uuid_mismatch > state->level) {
fprintf(stderr, "Too many disks have UUID changed from the latest 'sync'.\n");
fprintf(stderr, "If this happens because you really replaced them,\n");
fprintf(stderr, "you can '%s' anyway, using 'snapraid --force-uuid %s'.\n", state->command, state->command);
@ -858,7 +840,7 @@ void state_read(struct snapraid_state* state)
struct snapraid_content* content = node->data;
pathcpy(path, sizeof(path), content->content);
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "content:%s\n", path);
fflush(stdlog);
}
@ -1169,7 +1151,7 @@ void state_read(struct snapraid_state* state)
hash = oathash32(hash, v_mtime_nsec);
/* ignore nanoseconds if asked to find by name */
if (state->find_by_name)
if (state->opt.find_by_name)
v_mtime_nsec = FILE_MTIME_NSEC_INVALID;
c = sgetc(f);
@ -1629,7 +1611,7 @@ void state_read(struct snapraid_state* state)
if (sign != hash) {
fprintf(stderr, "Mismatching 'sign' in '%s' at line %u\n", path, line);
if (!state->skip_sign) {
if (!state->opt.skip_sign) {
fprintf(stderr, "Likely this content file is damaged. Use an alternate copy\n");
exit(EXIT_FAILURE);
}
@ -1693,7 +1675,7 @@ void state_read(struct snapraid_state* state)
state_content_check(state, path);
if (state->verbose) {
if (state->opt.verbose) {
printf("\tfile %u\n", count_file);
printf("\tblock %u\n", count_block);
printf("\thardlink %u\n", count_hardlink);
@ -2096,7 +2078,7 @@ void state_write(struct snapraid_state* state)
i = i->next;
}
if (state->verbose) {
if (state->opt.verbose) {
printf("\tfile %u\n", count_file);
printf("\tblock %u\n", count_block);
printf("\thardlink %u\n", count_hardlink);
@ -2117,7 +2099,7 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tom
printf("Filtering...\n");
if (state->verbose) {
if (state->opt.verbose) {
tommy_node* k;
for(k=tommy_list_head(filterlist_disk);k!=0;k=k->next) {
struct snapraid_filter* filter = k->data;
@ -2186,7 +2168,7 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tom
void state_progress_begin(struct snapraid_state* state, block_off_t blockstart, block_off_t blockmax, block_off_t countmax)
{
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog,"run:begin:%u:%u:%u\n", blockstart, blockmax, countmax);
fflush(stdlog);
} else {
@ -2202,7 +2184,7 @@ void state_progress_begin(struct snapraid_state* state, block_off_t blockstart,
void state_progress_end(struct snapraid_state* state, block_off_t countpos, block_off_t countmax, data_off_t countsize)
{
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "run:end\n");
fflush(stdlog);
} else {
@ -2240,7 +2222,7 @@ void state_progress_restart(struct snapraid_state* state)
int state_progress(struct snapraid_state* state, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize)
{
if (state->gui) {
if (state->opt.gui) {
fprintf(stdlog, "run:pos:%u:%u:%"PRIu64"\n", blockpos, countpos, countsize);
fflush(stdlog);
} else {
@ -2276,7 +2258,7 @@ int state_progress(struct snapraid_state* state, block_off_t blockpos, block_off
/* stop if requested */
if (global_interrupt) {
if (!state->gui) {
if (!state->opt.gui) {
printf("\n");
printf("Stopping for interruption at block %u\n", blockpos);
}

23
state.h
View file

@ -31,23 +31,36 @@ extern volatile int global_interrupt;
#define SORT_ALPHA 3 /**< Sort by alphabetic order. */
#define SORT_DIR 4 /**< Sort by directory order. */
struct snapraid_state {
/**
* Options set only at startup.
* For all these options a value of 0 means nothing set, and to use the default.
*/
struct snapraid_option {
int verbose; /**< Verbose output. */
int gui; /**< Gui output. */
int force_zero; /**< Forced dangerous operations of synching files now with zero size. */
int force_empty; /**< Forced dangerous operations of synching disks now empty. */
int force_uuid; /**< Forced dangerous operations of synching disks with uuid changed. */
int filter_hidden; /**< Filter out hidden files. */
int find_by_name; /**< Forced dangerous operations of synching a rewritten disk. */
uint64_t autosave; /**< Autosave after the specified amount of data. 0 to disable. */
int expect_unrecoverable; /**< Expect presence of unrecoverable error in checking or fixing. */
int expect_recoverable; /**< Expect presence of recoverable error in checking. */
int skip_device; /**< Skip devices matching checks. */
int skip_sign; /**< Skip the sign check for content files. */
int skip_fallocate; /**< Skip the use of fallocate(). */
int skip_sequential; /**< Skip sequential hint. */
int skip_lock; /**< Skip the lock file protection. */
int skip_self; /**< Skip the self-test. */
int kill_after_sync; /**< Kill the process after sync without saving the final state. */
int force_murmur3; /**< Force Murmur3 choice. */
int force_spooky2; /**< Force Spooky2 choice. */
int force_order; /**< Force sorting order. */
int force_order; /**< Force sorting order. One of the SORT_* defines. */
unsigned force_scrub; /**< Force scrub for the specified number of blocks. */
};
struct snapraid_state {
struct snapraid_option opt; /**< Setup options. */
int filter_hidden; /**< Filter out hidden files. */
uint64_t autosave; /**< Autosave after the specified amount of data. 0 to disable. */
int need_write; /**< If the state is changed. */
uint32_t block_size; /**< Block size in bytes. */
char parity[PATH_MAX]; /**< Path of the parity file. */
@ -89,7 +102,7 @@ void state_done(struct snapraid_state* state);
/**
* Reads the configuration file.
*/
void state_config(struct snapraid_state* state, const char* path, const char* command, int verbose, int gui, int force_zero, int force_empty, int force_uuid, int find_by_name, int expect_unrecoverable, int expect_recoverable, int skip_sign, int skip_fallocate, int skip_sequential, int skip_device, int force_murmur3, int force_spooky2, int force_order);
void state_config(struct snapraid_state* state, const char* path, const char* command, struct snapraid_option* opt);
/**
* Reads the state.

10
sync.c
View file

@ -189,7 +189,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
}
}
ret = handle_open(&handle[j], block_file_get(block), stderr, state->skip_sequential);
ret = handle_open(&handle[j], block_file_get(block), stderr, state->opt.skip_sequential);
if (ret == -1) {
if (errno == ENOENT) {
fprintf(stderr, "Missing file '%s'.\n", handle[j].path);
@ -417,7 +417,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
/* create the file and open for writing */
parity_ptr = &parity;
ret = parity_create(parity_ptr, state->parity, &out_size, state->skip_sequential);
ret = parity_create(parity_ptr, state->parity, &out_size, state->opt.skip_sequential);
if (ret == -1) {
fprintf(stderr, "WARNING! Without an accessible Parity file, it isn't possible to sync.\n");
exit(EXIT_FAILURE);
@ -429,7 +429,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
exit(EXIT_FAILURE);
}
ret = parity_chsize(parity_ptr, size, &out_size, state->skip_fallocate);
ret = parity_chsize(parity_ptr, size, &out_size, state->opt.skip_fallocate);
if (ret == -1) {
parity_overflow(state, out_size);
fprintf(stderr, "WARNING! Without an accessible Parity file, it isn't possible to sync.\n");
@ -438,7 +438,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
if (state->level >= 2) {
qarity_ptr = &qarity;
ret = parity_create(qarity_ptr, state->qarity, &out_size, state->skip_sequential);
ret = parity_create(qarity_ptr, state->qarity, &out_size, state->opt.skip_sequential);
if (ret == -1) {
fprintf(stderr, "WARNING! Without an accessible Q-Parity file, it isn't possible to sync.\n");
exit(EXIT_FAILURE);
@ -450,7 +450,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
exit(EXIT_FAILURE);
}
ret = parity_chsize(qarity_ptr, size, &out_size, state->skip_fallocate);
ret = parity_chsize(qarity_ptr, size, &out_size, state->opt.skip_fallocate);
if (ret == -1) {
parity_overflow(state, out_size);
fprintf(stderr, "WARNING! Without an accessible Q-Parity file, it isn't possible to sync.\n");