mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Implements full RAIDTP support.
This commit is contained in:
parent
7e0b93caef
commit
142f6ce119
11 changed files with 785 additions and 224 deletions
390
Makefile.am
390
Makefile.am
|
|
@ -71,7 +71,7 @@ EXTRA_DIST = \
|
|||
noautomake.sh \
|
||||
README AUTHORS HISTORY INSTALL COPYING TODO TEST INSTALL.windows \
|
||||
snapraid.d snapraid.1 snapraid.txt \
|
||||
test-raid5.conf test-raid6.conf test-raid6-hole.conf \
|
||||
test-raid5.conf test-raid6.conf test-raidTP.conf test-raidTP-hole.conf \
|
||||
snapraid.conf.example \
|
||||
configure.windows-x86 configure.windows-x64 snapraid.conf.example.windows \
|
||||
acinclude.m4
|
||||
|
|
@ -92,9 +92,14 @@ maintainer-clean-local:
|
|||
|
||||
# Automatic testing
|
||||
|
||||
CHECKFLAGS = --test-skip-device
|
||||
CHECKFLAGS = --test-skip-device --test-skip-self
|
||||
CHECKCOUNT = 2000
|
||||
CHECKSIZE = 4000
|
||||
CONF = $(srcdir)/test-raidTP.conf
|
||||
HOLE = $(srcdir)/test-raidTP-hole.conf
|
||||
RAID5 = $(srcdir)/test-raid5.conf
|
||||
RAID6 = $(srcdir)/test-raid6.conf
|
||||
RAIDTP = $(srcdir)/test-raidTP.conf
|
||||
|
||||
check-local:
|
||||
rm -rf test
|
||||
|
|
@ -103,35 +108,37 @@ check-local:
|
|||
mkdir test/disk1
|
||||
mkdir test/disk2
|
||||
mkdir test/disk3
|
||||
mkdir test/disk4
|
||||
mkdir test/pool
|
||||
echo --- Help
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -h
|
||||
$(TESTENV) ./snapraid$(EXEEXT) --test-skip-device -h
|
||||
echo --- SelfTest
|
||||
$(TESTENV) ./snapraid$(EXEEXT) --test-skip-device -c $(CONF) status
|
||||
echo --- As empty, sync and check forcing murmur3
|
||||
$(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 -c $(srcdir)/test-raid6.conf status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(srcdir)/test-raid6.conf --test-force-murmur3 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(CONF) diff
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(CONF) dup
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-force-murmur3 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status
|
||||
if HAVE_SYMLINK
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf pool
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) pool
|
||||
endif
|
||||
$(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
|
||||
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 > test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf dup
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-order-physical sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -a check
|
||||
echo --- Create some files, sync and check in RAID5/6/TP
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 1 4 $(CHECKCOUNT) $(CHECKSIZE)
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(CONF) diff > test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(CONF) dup
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-force-order-physical sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status
|
||||
if HAVE_SYMLINK
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf pool
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) pool
|
||||
endif
|
||||
$(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-raid6.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -a check
|
||||
echo --- Create some more files, hardlinks and empty directories, sync raid5 and check
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 2 3 $(CHECKCOUNT) $(CHECKSIZE)
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -a check
|
||||
echo --- Create some more files, hardlinks and empty directories, sync RAID5 and check
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 2 4 $(CHECKCOUNT) $(CHECKSIZE)
|
||||
mkdir test/disk1/empty1
|
||||
mkdir test/disk2/empty2
|
||||
mkdir test/disk3/empty3a
|
||||
|
|
@ -146,262 +153,279 @@ endif
|
|||
echo 3 > test/disk3/file_hardlink1
|
||||
ln test/disk3/file_hardlink1 test/disk3/file_hardlink2
|
||||
ln test/disk3/file_hardlink1 test/disk3/file_hardlink3
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid5.conf diff > test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid5.conf dup
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-skip-fallocate -c $(srcdir)/test-raid5.conf --test-force-order-inode sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-skip-sequential -c $(srcdir)/test-raid5.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(RAID5) diff > test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(RAID5) dup
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-fallocate -c $(RAID5) --test-force-order-inode sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-sequential -c $(RAID5) check
|
||||
if HAVE_SYMLINK
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf pool
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) pool
|
||||
endif
|
||||
echo --- Extend raid5 to raid6 with fix and check
|
||||
$(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
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Extend RAID5 to RAIDTP with fix and check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(CONF) check 2>> test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) fix 2>> test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Dry
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf dry
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf dry
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) dry
|
||||
echo --- Scrub some times
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-scrub 100 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-scrub 1000 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-scrub 100000 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-force-scrub 100 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-force-scrub 1000 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-force-scrub 100000 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status
|
||||
echo --- Corrupt one file, scrub and fix filtering for error
|
||||
rm -f test/disk1/content
|
||||
cp test/content test/disk1/content
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 1 10 1 test/disk1/content
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-expect-recoverable --test-force-scrub 100000 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -e
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -p 0 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -o 0 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -p 100 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-expect-recoverable --test-force-scrub 100000 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) fix -e
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -p 0 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -o 0 scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -p 100 scrub
|
||||
rm test/disk1/content
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
echo --- Make a hole in the disk array and sync with --force-empty
|
||||
mv test/disk2 test/disk2.old
|
||||
mkdir test/disk2
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --force-empty sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --force-empty sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Use with the hole
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6-hole.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6-hole.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(HOLE) sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(HOLE) check
|
||||
rm -r test/disk1/_a
|
||||
rm -r test/disk3/_a
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6-hole.conf fix 2>> test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6-hole.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6-hole.conf dry
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(HOLE) fix 2>> test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(HOLE) check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(HOLE) dry
|
||||
echo --- Fill the hole with a new disk
|
||||
rm -r test/disk2
|
||||
mv test/disk2.old test/disk2
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Delete some files, create some new, sync and check
|
||||
rm test/disk1/1*
|
||||
rm test/disk2/2*
|
||||
rm test/disk3/3*
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 3 3 $(CHECKCOUNT) $(CHECKSIZE)
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
rm test/disk4/4*
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 3 4 $(CHECKCOUNT) $(CHECKSIZE)
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Move some files, sync and check
|
||||
mv test/disk1/7* test/disk1/_a/
|
||||
mv test/disk2/7* test/disk2/_a/
|
||||
mv test/disk3/7* test/disk3/_a/
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Delete one disk, fix and check with raid5
|
||||
mv test/disk4/7* test/disk4/_a/
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Delete one disk, fix and check with RAID5
|
||||
rm -r test/disk3
|
||||
mkdir test/disk3
|
||||
$(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
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID5) check 2>> test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) fix 2>> test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Sync after all the fixes with an empty drive to test --force-empty
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --force-empty -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Delete two disks, fix and check with raid6
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --force-empty -c $(CONF) sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Delete two disks, fix and check with RAID6
|
||||
rm -r test/disk1
|
||||
mkdir test/disk1
|
||||
rm -r test/disk2
|
||||
mkdir test/disk2
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-unrecoverable -c $(srcdir)/test-raid5.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf 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 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(RAID5) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID6) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
echo --- Delete theree disks, fix and check with RAIDTP
|
||||
rm -r test/disk1
|
||||
mkdir test/disk1
|
||||
rm -r test/disk2
|
||||
mkdir test/disk2
|
||||
rm -r test/disk3
|
||||
mkdir test/disk3
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(RAID5) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAIDTP) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAIDTP) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
echo --- Delete some files and create some new, sync and check in multiple steps
|
||||
rm test/disk1/4*
|
||||
rm test/disk2/5*
|
||||
rm test/disk3/6*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -t 10 sync --test-force-content-text
|
||||
rm test/disk4/6*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -t 10 sync --test-force-content-text
|
||||
cp test/content test/content.txt
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf test-rewrite
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-content-text test-rewrite
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) test-rewrite
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-force-content-text test-rewrite
|
||||
cmp test/content test/content.txt
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 4 3 $(CHECKCOUNT) $(CHECKSIZE)
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -t 100 sync --test-force-content-text
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check -l test.log
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 4 4 $(CHECKCOUNT) $(CHECKSIZE)
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -t 100 sync --test-force-content-text
|
||||
cp test/content test/content.txt
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf test-rewrite
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-content-text test-rewrite
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) test-rewrite
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-force-content-text test-rewrite
|
||||
cmp test/content test/content.txt
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -t 1000 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -t 1000 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Rehash to spooky2 and rehash even blocks
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-spooky2 rehash
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-scrub-even scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-force-spooky2 rehash
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-force-scrub-even scrub
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Delete files from three disks and fix with import in RAID6
|
||||
rm -r test/disk1/_a
|
||||
rm -r test/disk1/_b
|
||||
rm -r test/disk2/_a
|
||||
rm -r test/disk2/_b
|
||||
mv test/disk3/_a test/_a
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-unrecoverable -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -i test/_a -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -i test/_a -c $(RAID6) fix -l test.log
|
||||
rm -r test/_a
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
echo --- Abort sync late with additions, delete them and recover with RAID6
|
||||
echo --- This triggers the recoving with q using p to check the validity
|
||||
cp -pR test/disk1/_a test/disk1/_c
|
||||
cp -pR test/disk1/_a test/disk1/_d
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-kill-after-sync -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-kill-after-sync -c $(CONF) sync
|
||||
rm -r test/disk1/_c
|
||||
rm -r test/disk1/_d
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
rm -r test/disk1/_c
|
||||
rm -r test/disk1/_d
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
echo --- Abort sync early with additions, delete them and recover with RAID6
|
||||
echo --- This triggers the recoving with q using p to check the validity, but failing for new block being filled with zero
|
||||
cp -pR test/disk1/_a test/disk1/_c
|
||||
cp -pR test/disk1/_a test/disk1/_d
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -t 1 --test-kill-after-sync -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -t 1 --test-kill-after-sync -c $(CONF) sync
|
||||
rm -r test/disk1/_c
|
||||
rm -r test/disk1/_d
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-unrecoverable -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(RAID6) fix -l test.log
|
||||
rm -r test/disk1/_c
|
||||
rm -r test/disk1/_d
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
echo --- Abort sync late with additions and then delete the new additions and sync again
|
||||
cp -pR test/disk1/_a test/disk1/_c
|
||||
cp -pR test/disk2/_a test/disk2/_c
|
||||
cp -pR test/disk3/_a test/disk3/_c
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-kill-after-sync -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-kill-after-sync -c $(CONF) sync
|
||||
rm -r test/disk1/_c
|
||||
rm -r test/disk2/_c
|
||||
rm -r test/disk3/_c
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
echo --- Abort sync late with additions and then delete some unchanged stuff and fix with RAID5 and then with RAID6
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
echo --- Abort sync late with additions and then delete some unchanged stuff and fix with RAID5
|
||||
cp -pR test/disk1/_b test/disk1/_c
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf --test-kill-after-sync sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) --test-kill-after-sync sync
|
||||
rm -r test/disk2
|
||||
mkdir test/disk2
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) fix -l test.log
|
||||
echo --- Fixes again with RAIDTP to restore all the parity
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) fix -l test.log
|
||||
rm -r test/disk1/_c
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
echo --- Abort sync late with more deletions than additions and then delete some unchanged stuff and fix with RAID5
|
||||
cp -pR test/disk1/_a test/disk1/_c
|
||||
mv test/disk1/_a test/_a
|
||||
mv test/disk1/_b test/_b
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-kill-after-sync sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-kill-after-sync sync
|
||||
rm -r test/disk2
|
||||
mkdir test/disk2
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) fix -l test.log
|
||||
echo --- Fixes again with RAIDTP to restore all the parity
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) fix -l test.log
|
||||
-rm -r test/disk1/_a
|
||||
-rm -r test/disk1/_b
|
||||
rm -r test/disk1/_c
|
||||
mv test/_a test/disk1/_a
|
||||
mv test/_b test/disk1/_b
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
echo --- Abort sync early with more deletions than additions and then delete some unchanged stuff and fix with RAID6
|
||||
cp -pR test/disk1/_a test/disk1/_c
|
||||
mv test/disk1/_a test/_a
|
||||
mv test/disk1/_b test/_b
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -t 1 --test-kill-after-sync sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -t 1 --test-kill-after-sync sync
|
||||
rm -r test/disk2
|
||||
mkdir test/disk2
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-unrecoverable -c $(srcdir)/test-raid5.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(RAID5) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
-rm -r test/disk1/_a
|
||||
-rm -r test/disk1/_b
|
||||
rm -r test/disk1/_c
|
||||
mv test/_a test/disk1/_a
|
||||
mv test/_b test/disk1/_b
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
echo --- Delete some files, fix with -m and check with raid5
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
echo --- Delete some files, fix with -m and check with RAID5
|
||||
rm test/disk1/8*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf -m fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Delete some dirs in a disk, fix with -m and check with raid5
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID5) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) -m fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Delete some dirs in a disk, fix with -m and check with RAID5
|
||||
rm -r test/disk2/_a
|
||||
rm -r test/disk2/_b
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf -m fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Delete some dirs in two disks, fix and check with raid6 using the -d option for each disk
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID5) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) -m fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Delete some dirs in two disks, fix and check with RAID6 using the -d option for each disk
|
||||
rm -r test/disk2/_a
|
||||
rm -r test/disk2/_b
|
||||
rm -r test/disk3/_a
|
||||
rm -r test/disk3/_b
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-unrecoverable -c $(srcdir)/test-raid5.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -d disk2 fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -d disk3 fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Delete the parity, fix and check with raid5
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(RAID5) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID6) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) -d disk2 fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) -d disk3 fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Delete the parity, fix and check with RAID5
|
||||
rm test/parity
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Delete the parity and the q-parity, fix and check with raid6
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Delete the parity and the q-parity, fix and check with RAID6
|
||||
rm test/parity
|
||||
rm test/q-parity
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Delete the parity and a disk, fix and check with raid6
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Delete the parity and a disk, fix and check with RAID6
|
||||
rm test/parity
|
||||
rm -r test/disk2/_a
|
||||
rm -r test/disk2/_b
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Delete the q-parity and a disk, fix and check with raid6
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Delete the q-parity and a disk, fix and check with RAID6
|
||||
rm test/q-parity
|
||||
rm -r test/disk3/_a
|
||||
rm -r test/disk3/_b
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Corrupt the parity, fix and check with raid5
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
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 -l 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 fix -l 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) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID5) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) -a check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(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 -l 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 fix -l 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) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID6) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -a check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(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 -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Corrupt some files, fix and check with raid6
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID5) -a check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID5) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID5) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Corrupt some files, fix and check with RAID6
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 4 1 500 test/disk2/_a/_a/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 4 1 500 test/disk3/_a/_a/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 4 1 500 test/disk2/_a/_b/*
|
||||
|
|
@ -410,12 +434,12 @@ endif
|
|||
$(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 -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf -a check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-unrecoverable -c $(srcdir)/test-raid5.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID5) -a check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID6) -a check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(RAID5) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID6) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Another time with different values
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 5 2 50 test/disk2/_a/_a/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 5 2 50 test/disk3/_a/_a/*
|
||||
|
|
@ -427,38 +451,38 @@ endif
|
|||
$(TESTENV) ./mktest$(EXEEXT) append 5 1500 test/disk3/_b/_a/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) truncate 5 1500 test/disk2/_b/_b/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) truncate 5 1500 test/disk3/_b/_b/*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-unrecoverable -c $(srcdir)/test-raid5.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Corrupt the parity and some files, fix and check with raid6
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(RAID5) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID6) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Corrupt the parity and some files, fix and check with RAID6
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 6 100 10000 test/parity
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 6 1 500 test/disk1/_a/_a/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 6 1 500 test/disk1/_a/_b/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) append 6 500 test/disk1/_b/_a/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) truncate 6 500 test/disk1/_b/_b/*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-unrecoverable -c $(srcdir)/test-raid5.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Corrupt the q-parity and some files, fix and check with raid6
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(RAID5) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID6) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Corrupt the q-parity and some files, fix and check with RAID6
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 7 100 10000 test/q-parity
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 7 1 500 test/disk1/_a/_a/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) damage 7 1 500 test/disk1/_a/_b/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) append 7 500 test/disk1/_b/_a/*
|
||||
$(TESTENV) ./mktest$(EXEEXT) truncate 7 500 test/disk1/_b/_b/*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid5.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-recoverable -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID5) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(RAID6) check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(RAID6) fix -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo --- Sync after all the fixes
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
echo Success!
|
||||
|
||||
# Manual testing
|
||||
|
||||
MANUAL = ./snapraid --test-skip-self --test-skip-device -c test-raid5.conf sync
|
||||
MANUAL = ./snapraid --test-skip-device -c test-raid5.conf sync
|
||||
|
||||
valgrind:
|
||||
valgrind \
|
||||
|
|
|
|||
291
check.c
291
check.c
|
|
@ -94,7 +94,7 @@ static int blockcmp(struct snapraid_state* state, int rehash, struct snapraid_bl
|
|||
* Returns <0 if failure for missing strategy, >0 if data is wrong and we cannot rebuild correctly, 0 on success.
|
||||
* If success, the parity and qarity are computed in the buffer variable.
|
||||
*/
|
||||
static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, unsigned char** buffer, unsigned char* buffer_parity, unsigned char* buffer_qarity, unsigned char* buffer_zero)
|
||||
static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, unsigned char** buffer, unsigned char* buffer_parity, unsigned char* buffer_qarity, unsigned char* buffer_rarity, unsigned char* buffer_zero)
|
||||
{
|
||||
unsigned j;
|
||||
int error = 0;
|
||||
|
|
@ -127,7 +127,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
|
|||
hash_checked = 0; /* keep track if we check at least one block */
|
||||
|
||||
/* check if the recovered blocks are OK */
|
||||
for(j=0;j<1;++j) {
|
||||
for(j=0;j<failed_count;++j) {
|
||||
if (block_has_updated_hash(failed[failed_map[j]].block)) { /* if the block can be checked */
|
||||
hash_checked = 1;
|
||||
if (blockcmp(state, rehash, failed[failed_map[j]].block, buffer[failed[failed_map[j]].index], buffer_zero) != 0)
|
||||
|
|
@ -136,7 +136,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
|
|||
}
|
||||
|
||||
/* if we checked something, and no block failed the check */
|
||||
if (hash_checked && j==1) {
|
||||
if (hash_checked && j==failed_count) {
|
||||
/* recompute all the redundancy information */
|
||||
raid_gen(state->level, buffer, diskmax, state->block_size);
|
||||
return 0;
|
||||
|
|
@ -157,7 +157,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
|
|||
hash_checked = 0; /* keep track if we check at least one block */
|
||||
|
||||
/* check if the recovered blocks are OK */
|
||||
for(j=0;j<1;++j) {
|
||||
for(j=0;j<failed_count;++j) {
|
||||
if (block_has_updated_hash(failed[failed_map[j]].block)) { /* if the block can be checked */
|
||||
hash_checked = 1;
|
||||
if (blockcmp(state, rehash, failed[failed_map[j]].block, buffer[failed[failed_map[j]].index], buffer_zero) != 0)
|
||||
|
|
@ -166,7 +166,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
|
|||
}
|
||||
|
||||
/* if we checked something, and no block failed the check */
|
||||
if (hash_checked && j==1) {
|
||||
if (hash_checked && j==failed_count) {
|
||||
/* recompute all the redundancy information */
|
||||
raid_gen(state->level, buffer, diskmax, state->block_size);
|
||||
return 0;
|
||||
|
|
@ -210,7 +210,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
|
|||
hash_checked = 0; /* keep track if we check at least one block */
|
||||
|
||||
/* check if the recovered blocks are OK */
|
||||
for(j=0;j<2;++j) {
|
||||
for(j=0;j<failed_count;++j) {
|
||||
if (block_has_updated_hash(failed[failed_map[j]].block)) { /* if the block can be checked */
|
||||
hash_checked = 1;
|
||||
if (blockcmp(state, rehash, failed[failed_map[j]].block, buffer[failed[failed_map[j]].index], buffer_zero) != 0)
|
||||
|
|
@ -219,7 +219,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
|
|||
}
|
||||
|
||||
/* if we checked something, and no block failed the check */
|
||||
if (hash_checked && j==2) {
|
||||
if (hash_checked && j==failed_count) {
|
||||
/* recompute all the redundancy information */
|
||||
raid_gen(state->level, buffer, diskmax, state->block_size);
|
||||
return 0;
|
||||
|
|
@ -229,6 +229,177 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
|
|||
++error;
|
||||
}
|
||||
|
||||
/* RAIDTP recovering from r, ignoring p,q */
|
||||
if (failed_count == 1 && buffer_rarity != 0 && has_hash) {
|
||||
/* copy the redundancy to use */
|
||||
memcpy(buffer[diskmax+2], buffer_rarity, state->block_size);
|
||||
|
||||
/* recover data */
|
||||
raidTP_recov_datapq(buffer, diskmax, state->block_size, failed[failed_map[0]].index, buffer_zero);
|
||||
|
||||
hash_checked = 0; /* keep track if we check at least one block */
|
||||
|
||||
/* check if the recovered blocks are OK */
|
||||
for(j=0;j<failed_count;++j) {
|
||||
if (block_has_updated_hash(failed[failed_map[j]].block)) { /* if the block can be checked */
|
||||
hash_checked = 1;
|
||||
if (blockcmp(state, rehash, failed[failed_map[j]].block, buffer[failed[failed_map[j]].index], buffer_zero) != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we checked something, and no block failed the check */
|
||||
if (hash_checked && j==failed_count) {
|
||||
/* recompute all the redundancy information */
|
||||
raid_gen(state->level, buffer, diskmax, state->block_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stdlog, "error:%u:rarity: Data error\n", pos);
|
||||
++error;
|
||||
}
|
||||
|
||||
/* RAIDTP recovering from r, using p or q to check the result */
|
||||
if (failed_count == 1 && (buffer_parity != 0 || buffer_qarity != 0) && buffer_rarity != 0 && !has_hash) {
|
||||
/* copy the redundancy to use */
|
||||
memcpy(buffer[diskmax+2], buffer_rarity, state->block_size);
|
||||
|
||||
/* recover data */
|
||||
raidTP_recov_datapq(buffer, diskmax, state->block_size, failed[failed_map[0]].index, buffer_zero);
|
||||
|
||||
/* recompute parity with RAID6 to get p and q from it */
|
||||
raid_gen(2, buffer, diskmax, state->block_size);
|
||||
|
||||
/* if the recovered parity block matches */
|
||||
if ((buffer_parity != 0 && memcmp(buffer[diskmax], buffer_parity, state->block_size) == 0)
|
||||
|| (buffer_qarity != 0 && memcmp(buffer[diskmax+1], buffer_qarity, state->block_size) == 0)
|
||||
) {
|
||||
/* recompute all the redundancy information */
|
||||
raid_gen(state->level, buffer, diskmax, state->block_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stdlog, "error:%u:parity/qarity/rarity: Data error\n", pos);
|
||||
++error;
|
||||
}
|
||||
|
||||
/* RAIDTP recovering from p+r */
|
||||
if (failed_count == 2 && buffer_parity != 0 && buffer_rarity != 0 && has_hash) {
|
||||
/* copy the redundancy to use */
|
||||
memcpy(buffer[diskmax], buffer_parity, state->block_size);
|
||||
memcpy(buffer[diskmax+2], buffer_rarity, state->block_size);
|
||||
|
||||
/* recover 2 data */
|
||||
raidTP_recov_2dataq(buffer, diskmax, state->block_size, failed[failed_map[0]].index, failed[failed_map[1]].index, buffer_zero);
|
||||
|
||||
hash_checked = 0; /* keep track if we check at least one block */
|
||||
|
||||
/* check if the recovered blocks are OK */
|
||||
for(j=0;j<failed_count;++j) {
|
||||
if (block_has_updated_hash(failed[failed_map[j]].block)) { /* if the block can be checked */
|
||||
hash_checked = 1;
|
||||
if (blockcmp(state, rehash, failed[failed_map[j]].block, buffer[failed[failed_map[j]].index], buffer_zero) != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we checked something, and no block failed the check */
|
||||
if (hash_checked && j==failed_count) {
|
||||
/* recompute all the redundancy information */
|
||||
raid_gen(state->level, buffer, diskmax, state->block_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stdlog, "error:%u:parity/rarity: Data error\n", pos);
|
||||
++error;
|
||||
}
|
||||
|
||||
/* RAIDTP recovering from q+r */
|
||||
if (failed_count == 2 && buffer_qarity != 0 && buffer_rarity != 0 && has_hash) {
|
||||
/* copy the redundancy to use */
|
||||
memcpy(buffer[diskmax+1], buffer_qarity, state->block_size);
|
||||
memcpy(buffer[diskmax+2], buffer_rarity, state->block_size);
|
||||
|
||||
/* recover 2 data */
|
||||
raidTP_recov_2datap(buffer, diskmax, state->block_size, failed[failed_map[0]].index, failed[failed_map[1]].index, buffer_zero);
|
||||
|
||||
hash_checked = 0; /* keep track if we check at least one block */
|
||||
|
||||
/* check if the recovered blocks are OK */
|
||||
for(j=0;j<failed_count;++j) {
|
||||
if (block_has_updated_hash(failed[failed_map[j]].block)) { /* if the block can be checked */
|
||||
hash_checked = 1;
|
||||
if (blockcmp(state, rehash, failed[failed_map[j]].block, buffer[failed[failed_map[j]].index], buffer_zero) != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we checked something, and no block failed the check */
|
||||
if (hash_checked && j==failed_count) {
|
||||
/* recompute all the redundancy information */
|
||||
raid_gen(state->level, buffer, diskmax, state->block_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stdlog, "error:%u:qarity/rarity: Data error\n", pos);
|
||||
++error;
|
||||
}
|
||||
|
||||
/* RAIDTP recovering from q+r, using p to check the result */
|
||||
if (failed_count == 2 && buffer_parity != 0 && buffer_qarity != 0 && buffer_rarity != 0 && !has_hash) {
|
||||
/* copy the redundancy to use */
|
||||
memcpy(buffer[diskmax+1], buffer_qarity, state->block_size);
|
||||
memcpy(buffer[diskmax+2], buffer_rarity, state->block_size);
|
||||
|
||||
/* recover data */
|
||||
raidTP_recov_2datap(buffer, diskmax, state->block_size, failed[failed_map[0]].index, failed[failed_map[1]].index, buffer_zero);
|
||||
|
||||
/* recompute parity with RAID5 to get p from it */
|
||||
raid_gen(1, buffer, diskmax, state->block_size);
|
||||
|
||||
/* if the recovered parity block matches */
|
||||
if (buffer_parity != 0 && memcmp(buffer[diskmax], buffer_parity, state->block_size) == 0) {
|
||||
/* recompute all the redundancy information */
|
||||
raid_gen(state->level, buffer, diskmax, state->block_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stdlog, "error:%u:parity/qarity/rarity: Data error\n", pos);
|
||||
++error;
|
||||
}
|
||||
|
||||
/* RAIDTP recovering from p+q+r */
|
||||
if (failed_count == 3 && buffer_parity != 0 && buffer_qarity != 0 && buffer_rarity != 0 && has_hash) {
|
||||
/* copy the redundancy to use */
|
||||
memcpy(buffer[diskmax], buffer_parity, state->block_size);
|
||||
memcpy(buffer[diskmax+1], buffer_qarity, state->block_size);
|
||||
memcpy(buffer[diskmax+2], buffer_rarity, state->block_size);
|
||||
|
||||
/* recover 3 data */
|
||||
raidTP_recov_3data(buffer, diskmax, state->block_size, failed[failed_map[0]].index, failed[failed_map[1]].index, failed[failed_map[2]].index, buffer_zero);
|
||||
|
||||
hash_checked = 0; /* keep track if we check at least one block */
|
||||
|
||||
/* check if the recovered blocks are OK */
|
||||
for(j=0;j<failed_count;++j) {
|
||||
if (block_has_updated_hash(failed[failed_map[j]].block)) { /* if the block can be checked */
|
||||
hash_checked = 1;
|
||||
if (blockcmp(state, rehash, failed[failed_map[j]].block, buffer[failed[failed_map[j]].index], buffer_zero) != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we checked something, and no block failed the check */
|
||||
if (hash_checked && j==failed_count) {
|
||||
/* recompute all the redundancy information */
|
||||
raid_gen(state->level, buffer, diskmax, state->block_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stdlog, "error:%u:parity/qarity/rarity: Data error\n", pos);
|
||||
++error;
|
||||
}
|
||||
|
||||
/* return the number of failed attempts, or -1 if no strategy */
|
||||
if (error)
|
||||
return error;
|
||||
|
|
@ -236,7 +407,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, unsigned char** buffer, unsigned char* buffer_parity, unsigned char* buffer_qarity, unsigned char* buffer_zero)
|
||||
static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, unsigned char** buffer, unsigned char* buffer_parity, unsigned char* buffer_qarity, unsigned char* buffer_rarity, unsigned char* buffer_zero)
|
||||
{
|
||||
int ret;
|
||||
int error;
|
||||
|
|
@ -300,7 +471,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
|
|||
return 0;
|
||||
}
|
||||
|
||||
ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_parity, buffer_qarity, buffer_zero);
|
||||
ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_parity, buffer_qarity, buffer_rarity, buffer_zero);
|
||||
if (ret == 0) {
|
||||
/* reprocess the blocks for NEW and CHG ones, for which we don't have a hash to check */
|
||||
/* if they were BAD we have to use some euristics to ensure that we have recovered */
|
||||
|
|
@ -417,7 +588,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
|
|||
|
||||
/* if nothing to fix, we just don't try */
|
||||
if (something_to_recover) {
|
||||
ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_parity, buffer_qarity, buffer_zero);
|
||||
ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_parity, buffer_qarity, buffer_rarity, buffer_zero);
|
||||
if (ret == 0) {
|
||||
/* we alreay marked as outdated NEW and CHG blocks, we don't need to do it again */
|
||||
return 0;
|
||||
|
|
@ -433,7 +604,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int state_check_process(struct snapraid_state* state, int check, int fix, struct snapraid_parity* parity, struct snapraid_parity* qarity, block_off_t blockstart, block_off_t blockmax)
|
||||
static int state_check_process(struct snapraid_state* state, int check, int fix, struct snapraid_parity* parity, struct snapraid_parity* qarity, struct snapraid_parity* rarity, block_off_t blockstart, block_off_t blockmax)
|
||||
{
|
||||
struct snapraid_handle* handle;
|
||||
unsigned diskmax;
|
||||
|
|
@ -737,15 +908,22 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
|
|||
if (check) {
|
||||
unsigned char* buffer_parity;
|
||||
unsigned char* buffer_qarity;
|
||||
unsigned char* buffer_rarity;
|
||||
unsigned char* buffer_zero;
|
||||
|
||||
/* buffers for parity read and not computed */
|
||||
if (state->level == 1) {
|
||||
buffer_parity = buffer[diskmax + 1];
|
||||
buffer_qarity = 0;
|
||||
} else {
|
||||
buffer_rarity = 0;
|
||||
} else if (state->level == 2) {
|
||||
buffer_parity = buffer[diskmax + 2];
|
||||
buffer_qarity = buffer[diskmax + 3];
|
||||
buffer_rarity = 0;
|
||||
} else {
|
||||
buffer_parity = buffer[diskmax + 3];
|
||||
buffer_qarity = buffer[diskmax + 4];
|
||||
buffer_rarity = buffer[diskmax + 5];
|
||||
}
|
||||
buffer_zero = buffer[buffermax-1];
|
||||
|
||||
|
|
@ -777,8 +955,23 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
|
|||
}
|
||||
}
|
||||
|
||||
/* read the rarity */
|
||||
if (state->level >= 3) {
|
||||
if (rarity) {
|
||||
ret = parity_read(rarity, i, buffer_rarity, state->block_size, stdlog);
|
||||
if (ret == -1) {
|
||||
buffer_rarity = 0; /* no rarity to use */
|
||||
|
||||
fprintf(stdlog, "error:%u:rarity: Read error\n", i);
|
||||
++error;
|
||||
}
|
||||
} else {
|
||||
buffer_rarity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* try all the recovering strategies */
|
||||
ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_parity, buffer_qarity, buffer_zero);
|
||||
ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_parity, buffer_qarity, buffer_rarity, buffer_zero);
|
||||
if (ret != 0) {
|
||||
/* increment the number of errors */
|
||||
if (ret > 0)
|
||||
|
|
@ -835,6 +1028,16 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
|
|||
++error;
|
||||
}
|
||||
}
|
||||
|
||||
/* check the rarity */
|
||||
if (state->level >= 3) {
|
||||
if (buffer_rarity != 0 && memcmp(buffer_rarity, buffer[diskmax + 2], state->block_size) != 0) {
|
||||
buffer_rarity = 0;
|
||||
|
||||
fprintf(stdlog, "error:%u:rarity: Data error\n", i);
|
||||
++error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now writes recovered files */
|
||||
|
|
@ -914,6 +1117,23 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
|
|||
++recovered_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* update the rarity */
|
||||
if (state->level >= 3) {
|
||||
if (buffer_rarity == 0 && rarity) {
|
||||
ret = parity_write(rarity, i, buffer[diskmax + 2], state->block_size);
|
||||
if (ret == -1) {
|
||||
/* we do not use DANGER because it could be ENOSPC which is not always correctly reported */
|
||||
fprintf(stderr, "WARNING! Without a working R-Parity disk, it isn't possible to fix errors on it.\n");
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
fprintf(stdlog, "fixed:%u:rarity: Fixed data error\n", i);
|
||||
++recovered_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* if we are not fixing, we just set the FIXED flag */
|
||||
|
|
@ -1582,8 +1802,10 @@ int state_check(struct snapraid_state* state, int check, int fix, block_off_t bl
|
|||
int ret;
|
||||
struct snapraid_parity parity;
|
||||
struct snapraid_parity qarity;
|
||||
struct snapraid_parity rarity;
|
||||
struct snapraid_parity* parity_ptr;
|
||||
struct snapraid_parity* qarity_ptr;
|
||||
struct snapraid_parity* rarity_ptr;
|
||||
unsigned error;
|
||||
|
||||
printf("Initializing...\n");
|
||||
|
|
@ -1638,6 +1860,23 @@ int state_check(struct snapraid_state* state, int check, int fix, block_off_t bl
|
|||
} else {
|
||||
qarity_ptr = 0;
|
||||
}
|
||||
|
||||
if (state->level >= 3) {
|
||||
rarity_ptr = &rarity;
|
||||
ret = parity_create(rarity_ptr, state->rarity, &out_size, state->opt.skip_sequential);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "WARNING! Without an accessible R-Parity file, it isn't possible to fix any error.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = parity_chsize(rarity_ptr, size, &out_size, state->opt.skip_fallocate);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "WARNING! Without an accessible R-Parity file, it isn't possible to sync.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
rarity_ptr = 0;
|
||||
}
|
||||
} else if (check) {
|
||||
/* 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 */
|
||||
|
|
@ -1660,10 +1899,23 @@ int state_check(struct snapraid_state* state, int check, int fix, block_off_t bl
|
|||
} else {
|
||||
qarity_ptr = 0;
|
||||
}
|
||||
|
||||
if (state->level >= 3) {
|
||||
rarity_ptr = &rarity;
|
||||
ret = parity_open(rarity_ptr, state->rarity, state->opt.skip_sequential);
|
||||
if (ret == -1) {
|
||||
printf("No accessible R-Parity file, only files will be checked.\n");
|
||||
/* continue anyway */
|
||||
rarity_ptr = 0;
|
||||
}
|
||||
} else {
|
||||
rarity_ptr = 0;
|
||||
}
|
||||
} else {
|
||||
/* otherwise don't use any parity */
|
||||
parity_ptr = 0;
|
||||
qarity_ptr = 0;
|
||||
rarity_ptr = 0;
|
||||
}
|
||||
|
||||
if (fix)
|
||||
|
|
@ -1677,7 +1929,7 @@ int state_check(struct snapraid_state* state, int check, int fix, block_off_t bl
|
|||
|
||||
/* skip degenerated cases of empty parity, or skipping all */
|
||||
if (blockstart < blockmax) {
|
||||
ret = state_check_process(state, check, fix, parity_ptr, qarity_ptr, blockstart, blockmax);
|
||||
ret = state_check_process(state, check, fix, parity_ptr, qarity_ptr, rarity_ptr, blockstart, blockmax);
|
||||
if (ret == -1) {
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
|
|
@ -1705,6 +1957,17 @@ int state_check(struct snapraid_state* state, int check, int fix, block_off_t bl
|
|||
}
|
||||
}
|
||||
|
||||
if (state->level >= 3) {
|
||||
if (rarity_ptr) {
|
||||
ret = parity_close(rarity_ptr);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "DANGER! Unexpected close error in R-Parity disk.\n");
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* abort if error are present */
|
||||
if (error != 0)
|
||||
return -1;
|
||||
|
|
|
|||
39
dry.c
39
dry.c
|
|
@ -26,7 +26,7 @@
|
|||
/****************************************************************************/
|
||||
/* dry */
|
||||
|
||||
static int state_dry_process(struct snapraid_state* state, struct snapraid_parity* parity, struct snapraid_parity* qarity, block_off_t blockstart, block_off_t blockmax)
|
||||
static int state_dry_process(struct snapraid_state* state, struct snapraid_parity* parity, struct snapraid_parity* qarity, struct snapraid_parity* rarity, block_off_t blockstart, block_off_t blockmax)
|
||||
{
|
||||
struct snapraid_handle* handle;
|
||||
unsigned diskmax;
|
||||
|
|
@ -117,6 +117,17 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
|
|||
}
|
||||
}
|
||||
|
||||
/* read the rarity */
|
||||
if (state->level >= 3) {
|
||||
if (rarity) {
|
||||
ret = parity_read(rarity, i, buffer_aligned, state->block_size, stdlog);
|
||||
if (ret == -1) {
|
||||
fprintf(stdlog, "error:%u:rarity: Read error\n", i);
|
||||
++error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* count the number of processed block */
|
||||
++countpos;
|
||||
|
||||
|
|
@ -159,8 +170,10 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
int ret;
|
||||
struct snapraid_parity parity;
|
||||
struct snapraid_parity qarity;
|
||||
struct snapraid_parity rarity;
|
||||
struct snapraid_parity* parity_ptr;
|
||||
struct snapraid_parity* qarity_ptr;
|
||||
struct snapraid_parity* rarity_ptr;
|
||||
unsigned error;
|
||||
|
||||
printf("Drying...\n");
|
||||
|
|
@ -199,11 +212,23 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
qarity_ptr = 0;
|
||||
}
|
||||
|
||||
if (state->level >= 3) {
|
||||
rarity_ptr = &rarity;
|
||||
ret = parity_open(rarity_ptr, state->rarity, state->opt.skip_sequential);
|
||||
if (ret == -1) {
|
||||
printf("No accessible R-Parity file.\n");
|
||||
/* continue anyway */
|
||||
rarity_ptr = 0;
|
||||
}
|
||||
} else {
|
||||
rarity_ptr = 0;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
/* skip degenerated cases of empty parity, or skipping all */
|
||||
if (blockstart < blockmax) {
|
||||
ret = state_dry_process(state, parity_ptr, qarity_ptr, blockstart, blockmax);
|
||||
ret = state_dry_process(state, parity_ptr, qarity_ptr, rarity_ptr, blockstart, blockmax);
|
||||
if (ret == -1) {
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
|
|
@ -229,6 +254,16 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
}
|
||||
}
|
||||
|
||||
if (state->level >= 3) {
|
||||
if (rarity_ptr) {
|
||||
ret = parity_close(rarity_ptr);
|
||||
if (ret == -1) {
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* abort if required */
|
||||
if (error != 0)
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
|||
62
scrub.c
62
scrub.c
|
|
@ -35,7 +35,7 @@ struct snapraid_rehash {
|
|||
struct snapraid_block* block;
|
||||
};
|
||||
|
||||
static int state_scrub_process(struct snapraid_state* state, struct snapraid_parity* parity, struct snapraid_parity* qarity, block_off_t blockstart, block_off_t blockmax, time_t timelimit, block_off_t countlimit, time_t now)
|
||||
static int state_scrub_process(struct snapraid_state* state, struct snapraid_parity* parity, struct snapraid_parity* qarity, struct snapraid_parity* rarity, block_off_t blockstart, block_off_t blockmax, time_t timelimit, block_off_t countlimit, time_t now)
|
||||
{
|
||||
struct snapraid_handle* handle;
|
||||
void* rehandle_alloc;
|
||||
|
|
@ -283,14 +283,21 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
if (!error_on_this_block && !silent_error_on_this_block) {
|
||||
unsigned char* buffer_parity;
|
||||
unsigned char* buffer_qarity;
|
||||
unsigned char* buffer_rarity;
|
||||
|
||||
/* buffers for parity read and not computed */
|
||||
if (state->level == 1) {
|
||||
buffer_parity = buffer[diskmax + 1];
|
||||
buffer_qarity = 0;
|
||||
} else {
|
||||
buffer_rarity = 0;
|
||||
} else if (state->level == 2) {
|
||||
buffer_parity = buffer[diskmax + 2];
|
||||
buffer_qarity = buffer[diskmax + 3];
|
||||
buffer_rarity = 0;
|
||||
} else {
|
||||
buffer_parity = buffer[diskmax + 3];
|
||||
buffer_qarity = buffer[diskmax + 4];
|
||||
buffer_rarity = buffer[diskmax + 5];
|
||||
}
|
||||
|
||||
/* read the parity */
|
||||
|
|
@ -313,6 +320,17 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
}
|
||||
}
|
||||
|
||||
/* read the rarity */
|
||||
if (state->level >= 3) {
|
||||
ret = parity_read(rarity, i, buffer_rarity, state->block_size, stdlog);
|
||||
if (ret == -1) {
|
||||
buffer_rarity = 0;
|
||||
fprintf(stdlog, "error:%u:rarity: Read error\n", i);
|
||||
++error;
|
||||
error_on_this_block = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* compute the parity */
|
||||
raid_gen(state->level, buffer, diskmax, state->block_size);
|
||||
|
||||
|
|
@ -329,6 +347,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
silent_error_on_this_block = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->level >= 2) {
|
||||
if (buffer_qarity && memcmp(buffer[diskmax + 1], buffer_qarity, state->block_size) != 0) {
|
||||
fprintf(stdlog, "error:%u:qarity: Data error\n", i);
|
||||
|
|
@ -343,6 +362,21 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state->level >= 3) {
|
||||
if (buffer_rarity && memcmp(buffer[diskmax + 2], buffer_rarity, state->block_size) != 0) {
|
||||
fprintf(stdlog, "error:%u:rarity: Data error\n", i);
|
||||
++error;
|
||||
|
||||
/* it's a silent error only if we are dealing with synched blocks */
|
||||
if (block_is_unsynched) {
|
||||
error_on_this_block = 1;
|
||||
} else {
|
||||
++silent_error;
|
||||
silent_error_on_this_block = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (silent_error_on_this_block) {
|
||||
|
|
@ -440,8 +474,10 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan)
|
|||
int ret;
|
||||
struct snapraid_parity parity;
|
||||
struct snapraid_parity qarity;
|
||||
struct snapraid_parity rarity;
|
||||
struct snapraid_parity* parity_ptr;
|
||||
struct snapraid_parity* qarity_ptr;
|
||||
struct snapraid_parity* rarity_ptr;
|
||||
snapraid_info* infomap;
|
||||
unsigned error;
|
||||
time_t now;
|
||||
|
|
@ -541,11 +577,22 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan)
|
|||
qarity_ptr = 0;
|
||||
}
|
||||
|
||||
if (state->level >= 3) {
|
||||
rarity_ptr = &rarity;
|
||||
ret = parity_open(rarity_ptr, state->rarity, state->opt.skip_sequential);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "WARNING! Without an accessible R-Parity file, it isn't possible to scrub.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
rarity_ptr = 0;
|
||||
}
|
||||
|
||||
printf("Scrubbing...\n");
|
||||
|
||||
error = 0;
|
||||
|
||||
ret = state_scrub_process(state, parity_ptr, qarity_ptr, 0, blockmax, timelimit, countlimit, now);
|
||||
ret = state_scrub_process(state, parity_ptr, qarity_ptr, rarity_ptr, 0, blockmax, timelimit, countlimit, now);
|
||||
if (ret == -1) {
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
|
|
@ -567,6 +614,15 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan)
|
|||
}
|
||||
}
|
||||
|
||||
if (state->level >= 3) {
|
||||
ret = parity_close(rarity_ptr);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "DANGER! Unexpected close error in R-Parity disk.\n");
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
}
|
||||
}
|
||||
|
||||
/* abort if required */
|
||||
if (error != 0)
|
||||
return -1;
|
||||
|
|
|
|||
115
state.c
115
state.c
|
|
@ -34,6 +34,8 @@ void state_init(struct snapraid_state* state)
|
|||
state->parity_device = 0;
|
||||
state->qarity[0] = 0;
|
||||
state->qarity_device = 0;
|
||||
state->rarity[0] = 0;
|
||||
state->rarity_device = 0;
|
||||
state->pool[0] = 0;
|
||||
state->pool_device = 0;
|
||||
state->lockfile[0] = 0;
|
||||
|
|
@ -69,11 +71,21 @@ static void state_config_check(struct snapraid_state* state, const char* path)
|
|||
{
|
||||
tommy_node* i;
|
||||
|
||||
if (state->parity[0] == 0) {
|
||||
if (state->level >= 1 && state->parity[0] == 0) {
|
||||
fprintf(stderr, "No 'parity' specification in '%s'\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->level >= 2 && state->qarity[0] == 0) {
|
||||
fprintf(stderr, "No 'q-parity' specification in '%s'\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->level >= 3 && state->rarity[0] == 0) {
|
||||
fprintf(stderr, "No 'r-parity' specification in '%s'\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (tommy_list_empty(&state->contentlist)) {
|
||||
fprintf(stderr, "No 'content' specification in '%s'\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -89,7 +101,12 @@ static void state_config_check(struct snapraid_state* state, const char* path)
|
|||
}
|
||||
|
||||
if (state->qarity[0] != 0 && pathcmp(state->qarity, content->content) == 0) {
|
||||
fprintf(stderr, "Same path used for 'qarity' and 'content' as '%s'\n", content->content);
|
||||
fprintf(stderr, "Same path used for 'q-parity' and 'content' as '%s'\n", content->content);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->rarity[0] != 0 && pathcmp(state->rarity, content->content) == 0) {
|
||||
fprintf(stderr, "Same path used for 'r-parity' and 'content' as '%s'\n", content->content);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
|
@ -138,7 +155,15 @@ static void state_config_check(struct snapraid_state* state, const char* path)
|
|||
}
|
||||
|
||||
if (state->qarity[0] != 0 && disk->device == state->qarity_device) {
|
||||
fprintf(stderr, "Disk '%s' and parity '%s' are on the same device.\n", disk->dir, state->qarity);
|
||||
fprintf(stderr, "Disk '%s' and q-parity '%s' are on the same device.\n", disk->dir, state->qarity);
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Both have the serial number '%"PRIx64"'.\n", disk->device);
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->rarity[0] != 0 && disk->device == state->rarity_device) {
|
||||
fprintf(stderr, "Disk '%s' and r-parity '%s' are on the same device.\n", disk->dir, state->rarity);
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Both have the serial number '%"PRIx64"'.\n", disk->device);
|
||||
#endif
|
||||
|
|
@ -179,6 +204,14 @@ static void state_config_check(struct snapraid_state* state, const char* path)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->rarity[0] != 0 && state->rarity_device == 0) {
|
||||
fprintf(stderr, "Disk '%s' has a zero serial number.\n", state->rarity);
|
||||
fprintf(stderr, "This is not necessarely wrong, but for using SnapRAID\n");
|
||||
fprintf(stderr, "it's better to change the serial number of the disk.\n");
|
||||
fprintf(stderr, "Try using the 'VolumeID' tool by 'Mark Russinovich'.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->pool[0] != 0 && state->pool_device == 0) {
|
||||
fprintf(stderr, "Disk '%s' has a zero serial number.\n", state->pool);
|
||||
fprintf(stderr, "This is not necessarely wrong, but for using SnapRAID\n");
|
||||
|
|
@ -196,6 +229,22 @@ static void state_config_check(struct snapraid_state* state, const char* path)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->rarity[0] != 0 && state->parity_device == state->rarity_device) {
|
||||
fprintf(stderr, "Parity '%s' and '%s' are on the same device.\n", state->parity, state->rarity);
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Both have the serial number '%"PRIx64"'.\n", state->parity_device);
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->qarity[0] != 0 && state->rarity[0] != 0 && state->qarity_device == state->rarity_device) {
|
||||
fprintf(stderr, "Parity '%s' and '%s' are on the same device.\n", state->qarity, state->rarity);
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Both have the serial number '%"PRIx64"'.\n", state->qarity_device);
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->pool[0] != 0 && state->pool_device == state->parity_device) {
|
||||
fprintf(stderr, "Pool '%s' and parity '%s' are on the same device.\n", state->pool, state->parity);
|
||||
#ifdef _WIN32
|
||||
|
|
@ -208,6 +257,14 @@ static void state_config_check(struct snapraid_state* state, const char* path)
|
|||
fprintf(stderr, "Pool '%s' and parity '%s' are on the same device.\n", state->pool, state->qarity);
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Both have the serial number '%"PRIx64"'.\n", state->pool_device);
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->pool[0] != 0 && state->rarity[0] != 0 && state->pool_device == state->rarity_device) {
|
||||
fprintf(stderr, "Pool '%s' and parity '%s' are on the same device.\n", state->pool, state->rarity);
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Both have the serial number '%"PRIx64"'.\n", state->pool_device);
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
@ -357,6 +414,9 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
|||
/* set lock file */
|
||||
pathcpy(state->lockfile, sizeof(state->lockfile), state->parity);
|
||||
pathcat(state->lockfile, sizeof(state->lockfile), ".lock");
|
||||
|
||||
if (state->level < 1)
|
||||
state->level = 1;
|
||||
} else if (strcmp(tag, "q-parity") == 0) {
|
||||
char device[PATH_MAX];
|
||||
char* slash;
|
||||
|
|
@ -395,7 +455,48 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
|||
state->qarity_device = st.st_dev;
|
||||
|
||||
/* we have two level of parity */
|
||||
state->level = 2;
|
||||
if (state->level < 2)
|
||||
state->level = 2;
|
||||
} else if (strcmp(tag, "r-parity") == 0) {
|
||||
char device[PATH_MAX];
|
||||
char* slash;
|
||||
struct stat st;
|
||||
|
||||
if (*state->rarity) {
|
||||
fprintf(stderr, "Multiple 'r-parity' specification in '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = sgetlasttok(f, buffer, sizeof(buffer));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Invalid 'r-parity' specification in '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!*buffer) {
|
||||
fprintf(stderr, "Empty 'r-parity' specification in '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pathimport(state->rarity, sizeof(state->rarity), buffer);
|
||||
|
||||
/* get the device of the directory containing the qparity file */
|
||||
pathimport(device, sizeof(device), buffer);
|
||||
slash = strrchr(device, '/');
|
||||
if (slash)
|
||||
*slash = 0;
|
||||
else
|
||||
pathcpy(device, sizeof(device), ".");
|
||||
if (stat(device, &st) != 0) {
|
||||
fprintf(stderr, "Error accessing 'rarity' dir '%s' specification in '%s' at line %u\n", device, path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
state->rarity_device = st.st_dev;
|
||||
|
||||
/* we have three level of parity */
|
||||
if (state->level < 3)
|
||||
state->level = 3;
|
||||
} else if (strcmp(tag, "pool") == 0) {
|
||||
struct stat st;
|
||||
|
||||
|
|
@ -651,13 +752,17 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
|||
struct snapraid_disk* disk = i->data;
|
||||
fprintf(stdlog, "disk:%s:%s\n", disk->name, disk->dir);
|
||||
}
|
||||
if (state->qarity[0] != 0)
|
||||
if (state->rarity[0] != 0)
|
||||
fprintf(stdlog, "mode:raidTP\n");
|
||||
else if (state->qarity[0] != 0)
|
||||
fprintf(stdlog, "mode:raid6\n");
|
||||
else
|
||||
fprintf(stdlog, "mode:raid5\n");
|
||||
fprintf(stdlog, "parity:%s\n", state->parity);
|
||||
if (state->qarity[0] != 0)
|
||||
fprintf(stdlog, "qarity:%s\n", state->qarity);
|
||||
if (state->rarity[0] != 0)
|
||||
fprintf(stdlog, "rarity:%s\n", state->rarity);
|
||||
if (state->pool[0] != 0)
|
||||
fprintf(stdlog, "pool:%s\n", state->pool);
|
||||
fflush(stdlog);
|
||||
|
|
|
|||
2
state.h
2
state.h
|
|
@ -70,6 +70,8 @@ struct snapraid_state {
|
|||
uint64_t parity_device; /**< Device identifier of the parity. */
|
||||
char qarity[PATH_MAX]; /**< Path of the qarity file. */
|
||||
uint64_t qarity_device; /**< Device identifier of the qarity. */
|
||||
char rarity[PATH_MAX]; /**< Path of the qarity file. */
|
||||
uint64_t rarity_device; /**< Device identifier of the rarity. */
|
||||
char pool[PATH_MAX]; /**< Path of the pool tree. */
|
||||
uint64_t pool_device; /**< Device identifier of the pool. */
|
||||
unsigned char hashseed[HASH_SIZE]; /**< Hash seed. Just after a uint64 to provide a minimal alignment. */
|
||||
|
|
|
|||
57
sync.c
57
sync.c
|
|
@ -35,7 +35,7 @@ struct snapraid_rehash {
|
|||
struct snapraid_block* block;
|
||||
};
|
||||
|
||||
static int state_sync_process(struct snapraid_state* state, struct snapraid_parity* parity, struct snapraid_parity* qarity, block_off_t blockstart, block_off_t blockmax)
|
||||
static int state_sync_process(struct snapraid_state* state, struct snapraid_parity* parity, struct snapraid_parity* qarity, struct snapraid_parity* rarity, block_off_t blockstart, block_off_t blockmax)
|
||||
{
|
||||
struct snapraid_handle* handle;
|
||||
void* rehandle_alloc;
|
||||
|
|
@ -320,6 +320,17 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
}
|
||||
}
|
||||
|
||||
/* write the rarity */
|
||||
if (state->level >= 3) {
|
||||
ret = parity_write(rarity, i, buffer[diskmax+2], state->block_size);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "DANGER! Write error in the R-Parity disk, it isn't possible to sync.\n");
|
||||
printf("Stopping at block %u\n", i);
|
||||
++unrecoverable_error;
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
||||
/* for each disk, mark the blocks as processed */
|
||||
for(j=0;j<diskmax;++j) {
|
||||
struct snapraid_block* block = BLOCK_EMPTY;
|
||||
|
|
@ -414,8 +425,10 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
int ret;
|
||||
struct snapraid_parity parity;
|
||||
struct snapraid_parity qarity;
|
||||
struct snapraid_parity rarity;
|
||||
struct snapraid_parity* parity_ptr;
|
||||
struct snapraid_parity* qarity_ptr;
|
||||
struct snapraid_parity* rarity_ptr;
|
||||
unsigned unrecoverable_error;
|
||||
|
||||
printf("Initializing...\n");
|
||||
|
|
@ -482,13 +495,37 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
qarity_ptr = 0;
|
||||
}
|
||||
|
||||
if (state->level >= 3) {
|
||||
rarity_ptr = &rarity;
|
||||
ret = parity_create(rarity_ptr, state->rarity, &out_size, state->opt.skip_sequential);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "WARNING! Without an accessible R-Parity file, it isn't possible to sync.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* if the file is too small */
|
||||
if (out_size < loaded_size) {
|
||||
fprintf(stderr, "DANGER! The R-Parity file %s is smaller than the expected %" PRId64 ".\n", state->rarity, loaded_size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = parity_chsize(rarity_ptr, size, &out_size, state->opt.skip_fallocate);
|
||||
if (ret == -1) {
|
||||
parity_overflow(state, out_size);
|
||||
fprintf(stderr, "WARNING! Without an accessible R-Parity file, it isn't possible to sync.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
rarity_ptr = 0;
|
||||
}
|
||||
|
||||
printf("Syncing...\n");
|
||||
|
||||
unrecoverable_error = 0;
|
||||
|
||||
/* skip degenerated cases of empty parity, or skipping all */
|
||||
if (blockstart < blockmax) {
|
||||
ret = state_sync_process(state, parity_ptr, qarity_ptr, blockstart, blockmax);
|
||||
ret = state_sync_process(state, parity_ptr, qarity_ptr, rarity_ptr, blockstart, blockmax);
|
||||
if (ret == -1) {
|
||||
++unrecoverable_error;
|
||||
/* continue, as we are already exiting */
|
||||
|
|
@ -527,6 +564,22 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
}
|
||||
}
|
||||
|
||||
if (state->level >= 3) {
|
||||
ret = parity_sync(rarity_ptr);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "DANGER! Unexpected sync error in R-Parity disk.\n");
|
||||
++unrecoverable_error;
|
||||
/* continue, as we are already exiting */
|
||||
}
|
||||
|
||||
ret = parity_close(rarity_ptr);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "DANGER! Unexpected close error in R-Parity disk.\n");
|
||||
++unrecoverable_error;
|
||||
/* continue, as we are already exiting */
|
||||
}
|
||||
}
|
||||
|
||||
/* abort if required */
|
||||
if (unrecoverable_error != 0)
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ block_size 1
|
|||
parity test/parity
|
||||
content test/content
|
||||
content test/p-content
|
||||
disk disk1 test/disk1/
|
||||
disk disk2 test/disk2/
|
||||
disk disk3 test/disk3/
|
||||
disk disk1 test/disk1/
|
||||
disk disk2 test/disk2/
|
||||
disk disk3 test/disk3/
|
||||
disk disk4 test/disk4/
|
||||
include *.hidden
|
||||
exclude *.unrecoverable
|
||||
pool test/pool
|
||||
autosave 1
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
block_size 1
|
||||
parity test/parity
|
||||
q-parity test/q-parity
|
||||
content test/content
|
||||
content test/p-content
|
||||
content test/q-content
|
||||
disk disk1 test/disk1/
|
||||
disk disk2 test/disk2/
|
||||
disk disk3 test/disk3/
|
||||
block_size 1
|
||||
parity test/parity
|
||||
q-parity test/q-parity
|
||||
content test/content
|
||||
content test/p-content
|
||||
content test/q-content
|
||||
disk disk1 test/disk1/
|
||||
disk disk2 test/disk2/
|
||||
disk disk3 test/disk3/
|
||||
disk disk4 test/disk4/
|
||||
include *.hidden
|
||||
exclude *.unrecoverable
|
||||
autosave 1
|
||||
exclude *.unrecoverable
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
block_size 1
|
||||
parity test/parity
|
||||
q-parity test/q-parity
|
||||
r-parity test/r-parity
|
||||
content test/content
|
||||
content test/p-content
|
||||
content test/q-content
|
||||
content test/r-content
|
||||
disk disk1 test/disk1/
|
||||
disk disk3 test/disk3/
|
||||
disk disk4 test/disk4/
|
||||
include *.hidden
|
||||
exclude *.unrecoverable
|
||||
|
||||
15
test-raidTP.conf
Normal file
15
test-raidTP.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
block_size 1
|
||||
parity test/parity
|
||||
q-parity test/q-parity
|
||||
r-parity test/r-parity
|
||||
content test/content
|
||||
content test/p-content
|
||||
content test/q-content
|
||||
content test/r-content
|
||||
disk disk1 test/disk1/
|
||||
disk disk2 test/disk2/
|
||||
disk disk3 test/disk3/
|
||||
disk disk4 test/disk4/
|
||||
include *.hidden
|
||||
exclude *.unrecoverable
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue