From 1ddb24da46a41155f8a9102ea7d1f86409e91544 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sat, 29 Jun 2013 18:11:36 +0200 Subject: [PATCH] Groups all the startup options in the new snapraid_option struct. --- check.c | 58 ++++++++++++++++---------------- dry.c | 6 ++-- dup.c | 4 +-- import.c | 4 +-- parity.c | 2 +- pool.c | 4 +-- rehash.c | 2 +- scan.c | 54 +++++++++++++++--------------- scrub.c | 6 ++-- snapraid.c | 97 +++++++++++++++++------------------------------------- state.c | 74 ++++++++++++++++------------------------- state.h | 23 ++++++++++--- sync.c | 10 +++--- 13 files changed, 152 insertions(+), 192 deletions(-) diff --git a/check.c b/check.c index d04b3d16..d221ba37 100644 --- a/check.c +++ b/check.c @@ -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 */ diff --git a/dry.c b/dry.c index 7f291da1..d00a52e1 100644 --- a/dry.c +++ b/dry.c @@ -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 */ diff --git a/dup.c b/dup.c index 3a3fd389..5bec2b73 100644 --- a/dup.c +++ b/dup.c @@ -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 diff --git a/import.c b/import.c index 1f9e56ff..b3b8533e 100644 --- a/import.c +++ b/import.c @@ -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) { diff --git a/parity.c b/parity.c index d0df73ab..e2ada15f 100644 --- a/parity.c +++ b/parity.c @@ -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); } diff --git a/pool.c b/pool.c index 45211841..3e306a6f 100644 --- a/pool.c +++ b/pool.c @@ -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 diff --git a/rehash.c b/rehash.c index e1edd7d3..be8b9e18 100644 --- a/rehash.c +++ b/rehash.c @@ -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); diff --git a/scan.c b/scan.c index 9403fbfe..5af11387 100644 --- a/scan.c +++ b/scan.c @@ -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); diff --git a/scrub.c b/scrub.c index dd22a10c..e9bdc2e0 100644 --- a/scrub.c +++ b/scrub.c @@ -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); diff --git a/snapraid.c b/snapraid.c index 8f7657dd..70ab277b 100644 --- a/snapraid.c +++ b/snapraid.c @@ -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); diff --git a/state.c b/state.c index 5bee2eed..8edba7a8 100644 --- a/state.c +++ b/state.c @@ -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); } diff --git a/state.h b/state.h index 4891e0ef..389675e5 100644 --- a/state.h +++ b/state.h @@ -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. diff --git a/sync.c b/sync.c index 24b4145b..37a5e5f6 100644 --- a/sync.c +++ b/sync.c @@ -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");