mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Adds a new -d command to filter by disk name.
Renames -A to -a for consistency.
This commit is contained in:
parent
91e74e91b8
commit
a93379f672
11 changed files with 139 additions and 60 deletions
7
HISTORY
7
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
|
||||
=============
|
||||
|
|
|
|||
16
Makefile.am
16
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
|
||||
|
|
|
|||
2
TODO
2
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.
|
||||
|
||||
|
|
|
|||
50
elem.c
50
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;
|
||||
|
|
|
|||
14
elem.h
14
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.
|
||||
|
|
|
|||
8
scan.c
8
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 {
|
||||
|
|
|
|||
23
snapraid.1
23
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.
|
||||
|
|
|
|||
43
snapraid.c
43
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 */
|
||||
|
|
|
|||
14
snapraid.d
14
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.
|
||||
|
|
|
|||
14
snapraid.txt
14
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.
|
||||
|
|
|
|||
8
state.c
8
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue