From a93379f672da67724a8978f6d6c4cbe60a74c493 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Wed, 10 Oct 2012 23:32:09 +0200 Subject: [PATCH] Adds a new -d command to filter by disk name. Renames -A to -a for consistency. --- HISTORY | 7 ++++--- Makefile.am | 16 ++++++++-------- TODO | 2 -- elem.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- elem.h | 14 ++++++++++---- scan.c | 8 ++++---- snapraid.1 | 23 +++++++++++++++++------ snapraid.c | 43 ++++++++++++++++++++++++++++--------------- snapraid.d | 14 +++++++++++--- snapraid.txt | 14 +++++++++++--- state.c | 8 ++++---- 11 files changed, 139 insertions(+), 60 deletions(-) diff --git a/HISTORY b/HISTORY index b52f0803..4f3d761c 100644 --- a/HISTORY +++ b/HISTORY @@ -3,8 +3,9 @@ SnapRAID HISTORY 1.13 2012/? =========== - * Added a new -A option to make the 'check' command to only check file hashes + * Added a new -a option to make the 'check' command to only check file hashes without checking the parity data. + * Added a new -d option to filter by disk name. * The file modification time is now saved using nanosecond precision. This allows to restore the exact modification time in 'fix'. The new 'content' files written with this version are not backward compatible, @@ -20,8 +21,8 @@ SnapRAID HISTORY * Always fill the memory after allocating it to avoid the OOM (Out Of Memory) killer in Linux. * Fixed compilation in Solaris for lacking both futimes() and futimens(). - * Now 'sync' ensures that the parity file are not too small to contains the - loaded data. + * Now 'sync' ensures that the parity file are not too small to contain the + just loaded data. 1.12 2012/9 ============= diff --git a/Makefile.am b/Makefile.am index 4e2b6c63..2355b767 100644 --- a/Makefile.am +++ b/Makefile.am @@ -97,16 +97,16 @@ check-local: $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(srcdir)/test-raid6.conf dup $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(srcdir)/test-raid6.conf sync $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -A check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -a check echo --- Create some files, sync raid6 and check $(TESTENV) ./mktest$(EXEEXT) generate 1 3 $(CHECKCOUNT) $(CHECKSIZE) $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf diff $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf dup $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf sync $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf check - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf -A check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf -a check $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -A check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -a check echo --- Create some more files, sync raid5 and check $(TESTENV) ./mktest$(EXEEXT) generate 2 3 $(CHECKCOUNT) $(CHECKSIZE) $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid5.conf diff @@ -296,21 +296,21 @@ check-local: echo --- Corrupt the parity, fix and check with raid5 $(TESTENV) ./mktest$(EXEEXT) damage 1 100 10000 test/parity $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf -A check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf -a check $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf fix 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check echo --- Corrupt the parity and the q-parity, fix and check with raid6 $(TESTENV) ./mktest$(EXEEXT) damage 2 100 10000 test/parity $(TESTENV) ./mktest$(EXEEXT) damage 2 100 10000 test/q-parity $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -A check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -a check $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check echo --- Corrupt some files, fix and check with raid5 $(TESTENV) ./mktest$(EXEEXT) damage 3 1 500 test/disk2/b* $(TESTENV) ./mktest$(EXEEXT) append 3 500 test/disk2/c* $(TESTENV) ./mktest$(EXEEXT) truncate 3 500 test/disk2/d* - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf -A check 2>> test.log + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf -a check 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf check 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf fix 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check @@ -323,8 +323,8 @@ check-local: $(TESTENV) ./mktest$(EXEEXT) append 4 500 test/disk3/_b/_a/* $(TESTENV) ./mktest$(EXEEXT) truncate 4 500 test/disk2/_b/_b/* $(TESTENV) ./mktest$(EXEEXT) truncate 4 500 test/disk3/_b/_b/* - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf -A check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf -A check 2>> test.log + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf -a check 2>> test.log + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf -a check 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-unrecoverable -c $(srcdir)/test-raid5.conf check 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf check 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix 2>> test.log diff --git a/TODO b/TODO index db42452f..06caff3c 100644 --- a/TODO +++ b/TODO @@ -5,8 +5,6 @@ This is the list of TODO items for SnapRAID. - v1.13 -* Allow to filter the files to check/fix based on the drive where they reside. - * In fix an existing symlink with the same name of a file to be recovered may stop the process making the create() operation to fail. diff --git a/elem.c b/elem.c index 91796a6c..b7d91b83 100644 --- a/elem.c +++ b/elem.c @@ -39,7 +39,7 @@ void content_free(struct snapraid_content* content) free(content); } -struct snapraid_filter* filter_alloc(int direction, const char* pattern) +struct snapraid_filter* filter_alloc_file(int direction, const char* pattern) { struct snapraid_filter* filter; char* i; @@ -61,6 +61,9 @@ struct snapraid_filter* filter_alloc(int direction, const char* pattern) } } + /* it's a file filter */ + filter->is_disk = 0; + if (first == 0) { /* no slash */ filter->is_path = 0; @@ -90,6 +93,28 @@ struct snapraid_filter* filter_alloc(int direction, const char* pattern) return filter; } +struct snapraid_filter* filter_alloc_disk(int direction, const char* pattern) +{ + struct snapraid_filter* filter; + + filter = malloc_nofail(sizeof(struct snapraid_filter)); + pathimport(filter->pattern, sizeof(filter->pattern), pattern); + filter->direction = direction; + + /* it's a disk filter */ + filter->is_disk = 1; + filter->is_path = 0; + filter->is_dir = 0; + + /* no slash allowed in disk names */ + if (strchr(filter->pattern, '/') != 0) { + free(filter); + return 0; + } + + return filter; +} + void filter_free(struct snapraid_filter* filter) { free(filter); @@ -149,7 +174,7 @@ static int filter_recurse(struct snapraid_filter* filter, const char* const_path return 0; } -static int filter_element(tommy_list* filterlist, const char* sub, int is_dir) +static int filter_element(tommy_list* filterlist, const char* disk, const char* sub, int is_dir) { tommy_node* i; @@ -160,7 +185,16 @@ static int filter_element(tommy_list* filterlist, const char* sub, int is_dir) int ret; struct snapraid_filter* filter = i->data; - ret = filter_recurse(filter, sub, is_dir); + if (filter->is_disk) { + /* using fnmatch allows to ignore case in windows */ + if (fnmatch(filter->pattern, disk, 0) == 0) + ret = filter->direction; + else + ret = 0; + } else { + ret = filter_recurse(filter, sub, is_dir); + } + if (ret > 0) { /* include the file */ return 0; @@ -186,14 +220,14 @@ static int filter_element(tommy_list* filterlist, const char* sub, int is_dir) return 0; } -int filter_path(tommy_list* filterlist, const char* sub) +int filter_path(tommy_list* filterlist, const char* disk, const char* sub) { - return filter_element(filterlist, sub, 0); + return filter_element(filterlist, disk, sub, 0); } -int filter_dir(tommy_list* filterlist, const char* sub) +int filter_dir(tommy_list* filterlist, const char* disk, const char* sub) { - return filter_element(filterlist, sub, 1); + return filter_element(filterlist, disk, sub, 1); } int filter_content(tommy_list* contentlist, const char* path) @@ -205,7 +239,7 @@ int filter_content(tommy_list* contentlist, const char* path) char tmp[PATH_MAX]; /* FNM_PATHNAME because we are comparing full path */ - /* FNM_NOESCAPE because we are comparing paths */ + /* FNM_NOESCAPE because the pattern is also a path, surely without escape chars */ /* using fnmatch allows to ignore case in windows */ if (fnmatch(content->content, path, FNM_PATHNAME | FNM_NOESCAPE) == 0) return -1; diff --git a/elem.h b/elem.h index baba9e06..c0983f93 100644 --- a/elem.h +++ b/elem.h @@ -58,6 +58,7 @@ struct snapraid_content { */ struct snapraid_filter { char pattern[PATH_MAX]; /**< Filter pattern. */ + int is_disk; /**< If the pattern is a disk one. */ int is_path; /**< If the pattern is only for the complete path. */ int is_dir; /**< If the pattern is only for dir. */ int direction; /**< If it's an inclusion (=1) or an exclusion (=-1). */ @@ -215,9 +216,14 @@ struct snapraid_content* content_alloc(const char* path, uint64_t dev); void content_free(struct snapraid_content* content); /** - * Allocates an exclusion. + * Allocates a filter pattern for files and directories. */ -struct snapraid_filter* filter_alloc(int is_include, const char* pattern); +struct snapraid_filter* filter_alloc_file(int is_include, const char* pattern); + +/** + * Allocates a filter pattern for disks. + */ +struct snapraid_filter* filter_alloc_disk(int is_include, const char* pattern); /** * Deallocates an exclusion. @@ -242,14 +248,14 @@ static inline int filter_hidden(int enable, struct dirent* dd, struct stat* st) * For each element of the path all the filters are applied, until the first one that matches. * Return !=0 if it matches and it should be excluded. */ -int filter_path(tommy_list* filterlist, const char* sub); +int filter_path(tommy_list* filterlist, const char* disk, const char* sub); /** * 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. * Return !=0 if it matches and it should be excluded. */ -int filter_dir(tommy_list* filterlist, const char* sub); +int filter_dir(tommy_list* filterlist, const char* disk, const char* sub); /** * Filters a path if it's a content file. diff --git a/scan.c b/scan.c index 02d88177..5693cc63 100644 --- a/scan.c +++ b/scan.c @@ -489,7 +489,7 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, i if (S_ISREG(st.st_mode)) { if (filter_hidden(state->filter_hidden, dd, &st) == 0 && filter_content(&state->contentlist, path_next) == 0 - && filter_path(&state->filterlist, sub_next) == 0 + && filter_path(&state->filterlist, disk->name, sub_next) == 0 ) { /* check for read permission */ if (access(path_next, R_OK) != 0) { @@ -514,7 +514,7 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, i } } else if (S_ISLNK(st.st_mode)) { if (filter_hidden(state->filter_hidden, dd, &st) == 0 - && filter_path(&state->filterlist, sub_next) == 0 + && filter_path(&state->filterlist, disk->name, sub_next) == 0 ) { char subnew[PATH_MAX]; int ret; @@ -540,7 +540,7 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, i } } else if (S_ISDIR(st.st_mode)) { if (filter_hidden(state->filter_hidden, dd, &st) == 0 - && filter_dir(&state->filterlist, sub_next) == 0 + && filter_dir(&state->filterlist, disk->name, sub_next) == 0 ) { pathslash(path_next, sizeof(path_next)); pathslash(sub_next, sizeof(sub_next)); @@ -553,7 +553,7 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, i } else { if (filter_hidden(state->filter_hidden, dd, &st) == 0 && filter_content(&state->contentlist, path_next) == 0 - && filter_path(&state->filterlist, sub_next) == 0 + && filter_path(&state->filterlist, disk->name, sub_next) == 0 ) { fprintf(stderr, "warning: Ignoring special '%s' file '%s'\n", stat_desc(&st), path_next); } else { diff --git a/snapraid.1 b/snapraid.1 index be0908cd..7eb1580a 100644 --- a/snapraid.1 +++ b/snapraid.1 @@ -2,17 +2,21 @@ .SH NAME snapraid \(hy SnapRAID Backup For Disk Arrays .SH SYNOPSIS -snapraid [\(hyc, \(hy\(hyconf CONFIG] [\(hyf, \(hy\(hyfilter PATTERN] [\(hyH, \(hy\(hyfilter\(hynohidden] +snapraid [\(hyc, \(hy\(hyconf CONFIG] +.PD 0 +.PP +.PD + [\(hyf, \(hy\(hyfilter PATTERN] [\(hyd, \(hy\(hyfilter\(hydisk NAME] [\(hyH, \(hy\(hyfilter\(hynohidden] +.PD 0 +.PP +.PD + [\(hya, \(hy\(hyaudit\(hyonly] .PD 0 .PP .PD [\(hyN, \(hy\(hyfind\(hyby\(hyname] .PD 0 .PP -.PD - [\(hyA, \(hy\(hyaudit\(hyonly] -.PD 0 -.PP .PD [\(hyZ, \(hy\(hyforce\(hyzero] [\(hyE, \(hy\(hyforce\(hyempty] .PD 0 @@ -368,12 +372,19 @@ pattern specifications. This option can be used many times. In Unix, ensure to quote globbing chars if used. .TP +.B \(hyd, \(hy\(hyfilter\(hydisk NAME +Filters the files to operate on with the \(a"check\(a" and \(a"fix\(a" +commands. +This option cannot be used with the \(a"sync\(a" command. +You must specify a disk name as named in the configuration +file. +.TP .B \(hyH, \(hy\(hyfilter\(hynohidden Filters out hidden files and directory. In Unix hidden files are the ones starting with \(cq.\(cq. In Windows they are the ones with the hidden attribute. .TP -.B \(hyA, \(hy\(hyaudit\(hyonly +.B \(hya, \(hy\(hyaudit\(hyonly When checking, only verify the hash of the files, without doing any kind of check on the redundancy data. This option can be used only with the \(a"check\(a" command. diff --git a/snapraid.c b/snapraid.c index b0d1edd3..6e0b9d2d 100644 --- a/snapraid.c +++ b/snapraid.c @@ -55,17 +55,18 @@ void usage(void) printf(" fix Fix the array of disks\n"); printf("\n"); printf("Options:\n"); - printf(" " SWITCH_GETOPT_LONG("-c, --conf FILE ", "-c") " Configuration file (default " CONF ")\n"); - printf(" " SWITCH_GETOPT_LONG("-f, --filter PATTERN", "-f") " Filter the files to processs\n"); - printf(" " SWITCH_GETOPT_LONG("-A, --audit-only ", "-A") " Check only file data and not parity\n"); - printf(" " SWITCH_GETOPT_LONG("-N, --find-by-name ", "-N") " Find the file by name instead than by inode\n"); - printf(" " SWITCH_GETOPT_LONG("-Z, --force-zero ", "-Z") " Force synching of files that get zero size\n"); - printf(" " SWITCH_GETOPT_LONG("-E, --force-empty ", "-E") " Force synching of disks that get empty\n"); - printf(" " SWITCH_GETOPT_LONG("-s, --start BLKSTART", "-s") " Start from the specified block number\n"); - printf(" " SWITCH_GETOPT_LONG("-t, --count BLKCOUNT", "-t") " Count of block to process\n"); - printf(" " SWITCH_GETOPT_LONG("-v, --verbose ", "-v") " Verbose\n"); - printf(" " SWITCH_GETOPT_LONG("-h, --help ", "-h") " Help\n"); - printf(" " SWITCH_GETOPT_LONG("-V, --version ", "-V") " Version\n"); + printf(" " SWITCH_GETOPT_LONG("-c, --conf FILE ", "-c") " Configuration file (default " CONF ")\n"); + printf(" " SWITCH_GETOPT_LONG("-f, --filter PATTERN ", "-f") " Filter the files to process with a pattern\n"); + printf(" " SWITCH_GETOPT_LONG("-d, --filter-dist NAME", "-f") " Filter the files to process with a disk name\n"); + printf(" " SWITCH_GETOPT_LONG("-a, --audit-only ", "-A") " Check only file data and not parity\n"); + printf(" " SWITCH_GETOPT_LONG("-N, --find-by-name ", "-N") " Find the files by name instead than by inode\n"); + printf(" " SWITCH_GETOPT_LONG("-Z, --force-zero ", "-Z") " Force synching of files that get zero size\n"); + printf(" " SWITCH_GETOPT_LONG("-E, --force-empty ", "-E") " Force synching of disks that get empty\n"); + printf(" " SWITCH_GETOPT_LONG("-s, --start BLKSTART ", "-s") " Start from the specified block number\n"); + printf(" " SWITCH_GETOPT_LONG("-t, --count BLKCOUNT ", "-t") " Count of block to process\n"); + printf(" " SWITCH_GETOPT_LONG("-v, --verbose ", "-v") " Verbose\n"); + printf(" " SWITCH_GETOPT_LONG("-h, --help ", "-h") " Help\n"); + printf(" " SWITCH_GETOPT_LONG("-V, --version ", "-V") " Version\n"); } #define OPT_TEST_SKIP_SELF 256 @@ -78,13 +79,14 @@ void usage(void) struct option long_options[] = { { "conf", 1, 0, 'c' }, { "filter", 1, 0, 'f' }, + { "filter-disk", 1, 0, 'd' }, { "filter-nohidden", 0, 0, 'H' }, { "start", 1, 0, 's' }, { "count", 1, 0, 't' }, { "force-zero", 0, 0, 'Z' }, { "force-empty", 0, 0, 'E' }, { "find-by-name", 0, 0, 'N' }, - { "audit-only", 0, 0, 'A' }, + { "audit-only", 0, 0, 'a' }, { "speed-test", 0, 0, 'T' }, { "verbose", 0, 0, 'v' }, { "gui", 0, 0, 'G' }, /* undocumented GUI interface command */ @@ -100,7 +102,7 @@ struct option long_options[] = { }; #endif -#define OPTIONS "c:f:Hs:t:ZENATvhVG" +#define OPTIONS "c:f:d:Hs:t:ZENaTvhVG" volatile int global_interrupt = 0; @@ -177,7 +179,15 @@ int main(int argc, char* argv[]) conf = optarg; break; case 'f' : { - struct snapraid_filter* filter = filter_alloc(1, optarg); + struct snapraid_filter* filter = filter_alloc_file(1, optarg); + if (!filter) { + fprintf(stderr, "Invalid filter specification '%s'\n", optarg); + exit(EXIT_FAILURE); + } + tommy_list_insert_tail(&filterlist, &filter->node, filter); + } break; + case 'd' : { + struct snapraid_filter* filter = filter_alloc_disk(1, optarg); if (!filter) { fprintf(stderr, "Invalid filter specification '%s'\n", optarg); exit(EXIT_FAILURE); @@ -210,7 +220,7 @@ int main(int argc, char* argv[]) case 'N' : find_by_name = 1; break; - case 'A' : + case 'a' : audit_only = 1; break; case 'v' : @@ -336,6 +346,7 @@ int main(int argc, char* argv[]) } else if (operation == OPERATION_DRY) { state_read(&state); + /* apply the command line filter */ state_filter(&state, &filterlist); /* intercept Ctrl+C */ @@ -345,12 +356,14 @@ int main(int argc, char* argv[]) } else if (operation == OPERATION_DUP) { state_read(&state); + /* apply the command line filter */ state_filter(&state, &filterlist); state_dup(&state); } else { state_read(&state); + /* apply the command line filter */ state_filter(&state, &filterlist); /* intercept Ctrl+C */ diff --git a/snapraid.d b/snapraid.d index ec6ee876..41f44640 100644 --- a/snapraid.d +++ b/snapraid.d @@ -2,9 +2,10 @@ Name{number} snapraid - SnapRAID Backup For Disk Arrays Synopsis - :snapraid [-c, --conf CONFIG] [-f, --filter PATTERN] [-H, --filter-nohidden] + :snapraid [-c, --conf CONFIG] + : [-f, --filter PATTERN] [-d, --filter-disk NAME] [-H, --filter-nohidden] + : [-a, --audit-only] : [-N, --find-by-name] - : [-A, --audit-only] : [-Z, --force-zero] [-E, --force-empty] : [-s, --start BLKSTART] [-t, --count BLKCOUNT] : [-v, --verbose] @@ -245,12 +246,19 @@ Options This option can be used many times. In Unix, ensure to quote globbing chars if used. + -d, --filter-disk NAME + Filters the files to operate on with the "check" and "fix" + commands. + This option cannot be used with the "sync" command. + You must specify a disk name as named in the configuration + file. + -H, --filter-nohidden Filters out hidden files and directory. In Unix hidden files are the ones starting with '.'. In Windows they are the ones with the hidden attribute. - -A, --audit-only + -a, --audit-only When checking, only verify the hash of the files, without doing any kind of check on the redundancy data. This option can be used only with the "check" command. diff --git a/snapraid.txt b/snapraid.txt index 48b0e47a..c4b50dff 100644 --- a/snapraid.txt +++ b/snapraid.txt @@ -6,9 +6,10 @@ 1 SYNOPSIS ========== -snapraid [-c, --conf CONFIG] [-f, --filter PATTERN] [-H, --filter-nohidden] +snapraid [-c, --conf CONFIG] + [-f, --filter PATTERN] [-d, --filter-disk NAME] [-H, --filter-nohidden] + [-a, --audit-only] [-N, --find-by-name] - [-A, --audit-only] [-Z, --force-zero] [-E, --force-empty] [-s, --start BLKSTART] [-t, --count BLKCOUNT] [-v, --verbose] @@ -274,12 +275,19 @@ SnapRAID provides the following options: This option can be used many times. In Unix, ensure to quote globbing chars if used. + -d, --filter-disk NAME + Filters the files to operate on with the "check" and "fix" + commands. + This option cannot be used with the "sync" command. + You must specify a disk name as named in the configuration + file. + -H, --filter-nohidden Filters out hidden files and directory. In Unix hidden files are the ones starting with '.'. In Windows they are the ones with the hidden attribute. - -A, --audit-only + -a, --audit-only When checking, only verify the hash of the files, without doing any kind of check on the redundancy data. This option can be used only with the "check" command. diff --git a/state.c b/state.c index d06af7b8..64807bb0 100644 --- a/state.c +++ b/state.c @@ -398,7 +398,7 @@ void state_config(struct snapraid_state* state, const char* path, int verbose, i exit(EXIT_FAILURE); } - filter = filter_alloc(-1, buffer); + filter = filter_alloc_file(-1, buffer); if (!filter) { fprintf(stderr, "Invalid 'exclude' specification '%s' in '%s' at line %u\n", buffer, path, line); exit(EXIT_FAILURE); @@ -413,7 +413,7 @@ void state_config(struct snapraid_state* state, const char* path, int verbose, i exit(EXIT_FAILURE); } - filter = filter_alloc(1, buffer); + filter = filter_alloc_file(1, buffer); if (!filter) { fprintf(stderr, "Invalid 'include' specification '%s' in '%s' at line %u\n", buffer, path, line); exit(EXIT_FAILURE); @@ -1538,7 +1538,7 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist) for(j=tommy_list_head(&disk->filelist);j!=0;j=j->next) { struct snapraid_file* file = j->data; - if (filter_path(filterlist, file->sub) != 0) { + if (filter_path(filterlist, disk->name, file->sub) != 0) { file_flag_set(file, FILE_IS_EXCLUDED); } @@ -1551,7 +1551,7 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist) for(j=tommy_list_head(&disk->linklist);j!=0;j=j->next) { struct snapraid_link* link = j->data; - if (filter_path(filterlist, link->sub) != 0) { + if (filter_path(filterlist, disk->name, link->sub) != 0) { link_flag_set(link, FILE_IS_EXCLUDED); }