From abd0096711bdbb04cacce38b68dccda7e7d1fd20 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sat, 3 Sep 2011 22:21:45 +0200 Subject: [PATCH] Save the content files also at the start of the sync process. --- HISTORY | 23 +++++-- Makefile.am | 174 +++++++++++++++++++++++++++------------------------- scan.c | 3 +- snapraid.c | 70 ++++++++++++++------- state.c | 2 + 5 files changed, 160 insertions(+), 112 deletions(-) diff --git a/HISTORY b/HISTORY index 21aef339..d4834ad6 100644 --- a/HISTORY +++ b/HISTORY @@ -1,13 +1,24 @@ SnapRAID HISTORY ================ -1.6 2011/9 -========== -* In "diff" now it recognizes the reuse of inodes. -* Windows hidden files are now backuped like any other files. +1.6 2011/9 - THIS UPDATE IS HIGHLY RECOMMENDED! +=============================================== +* The content file is now saved also at the start of the "sync" command. + This avoids parity errors if the sync process aborted without + saving the content file and you made changes at the disk array before + another "sync" command was done. + More specifically, deletions or truncations of not yet synched files + after the aborted sync, and before the next sync command, may have damaged + the parity data. New file additions were instead safe. + If these conditions may have happened to you a "check" command (also + with older version of the program) is recommended to ensure the correctness + of your parity data. +* The "diff" command now recognizes the reuse of inodes. +* Windows hidden files are now saved like any other files. * Symbolic links are now saved in *nix. Not supported in Windows. -* In fixing the original modification time of the files is also restored. -* The message asking to use the --force-empty option now lists all the empty disks. +* The "fix" command restores also the original modification time. +* The message asking to use the --force-empty option now lists all the + empty disks. 1.5 2011/7 ========== diff --git a/Makefile.am b/Makefile.am index 16164d0c..7017888f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -93,130 +93,140 @@ check-local: echo --- As empty, sync and check $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(srcdir)/test-raid6.conf diff $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(srcdir)/test-raid6.conf sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check echo --- Create some files, sync raid6 and check $(TESTENV) ./mktest$(EXEEXT) generate 1 3 $(CHECKCOUNT) $(CHECKSIZE) - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -v -c $(srcdir)/test-raid6.conf diff - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -v -c $(srcdir)/test-raid6.conf sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf check - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 sync + $(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 --- Create some more files, sync raid5 and check $(TESTENV) ./mktest$(EXEEXT) generate 2 3 $(CHECKCOUNT) $(CHECKSIZE) - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -v -c $(srcdir)/test-raid5.conf diff - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -v -c $(srcdir)/test-raid5.conf sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid5.conf diff + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid5.conf sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf check echo --- Extend raid5 to raid6 with fix and check - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf fix 2>/dev/null - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf check - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf 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>/dev/null + $(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 --- Dry - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf dry - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf 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 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) -S -v -c $(srcdir)/test-raid6.conf sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.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) -S -v -c $(srcdir)/test-raid6.conf sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -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 rm -r test/disk3 mkdir test/disk3 - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 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) -S -U -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf check - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 + $(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 --- Sync after all the fixes with an empty drive to test -E - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -v -E -c $(srcdir)/test-raid6.conf sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -E -c $(srcdir)/test-raid6.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) ./mktest$(EXEEXT) generate 4 3 $(CHECKCOUNT) $(CHECKSIZE) - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -v -c $(srcdir)/test-raid6.conf -t 100 sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -v -c $(srcdir)/test-raid6.conf -t 700 sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -v -c $(srcdir)/test-raid6.conf -t 1000 sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -v -c $(srcdir)/test-raid6.conf sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf -t 100 sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check 2>> test.log + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf -t 700 sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check 2>> test.log + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf -t 1000 sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check 2>> test.log + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check + echo --- Add some files, sync with abort, delete the new files, sync and check + cp -a test/disk1/_a test/disk1/_A + cp -a test/disk2/_a test/disk2/_A + cp -a test/disk3/_a test/disk3/_A + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-kill-after-sync -v -c $(srcdir)/test-raid6.conf sync + rm -r test/disk1/_A + rm -r test/disk2/_A + rm -r test/disk3/_A + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check echo --- Delete some files, fix and check with raid5 rm test/disk1/8* - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 echo --- Delete some dirs, fix and check with raid5 rm -r test/disk2/_a rm -r test/disk2/_b - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 echo --- Delete some dirs, fix and check with raid6 rm -r test/disk2/_a rm -r test/disk2/_b rm -r test/disk3/_a rm -r test/disk3/_b - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -U -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check echo --- Delete the parity, fix and check with raid5 rm test/parity - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -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 echo --- Delete the parity and the q-parity, fix and check with raid6 rm test/parity rm test/q-parity - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf 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 --- 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) -S -c $(srcdir)/test-raid6.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf 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 --- 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) -S -c $(srcdir)/test-raid6.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf 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 the parity, fix and check with raid5 $(TESTENV) ./mktest$(EXEEXT) damage 1 100 10000 test/parity - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 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) -S -R -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf 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-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) -S -R -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid5.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 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/* @@ -226,10 +236,10 @@ 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) -S -U -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.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/* @@ -241,38 +251,38 @@ check-local: $(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) -S -U -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 + $(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) ./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) -S -U -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 + $(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) ./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) -S -R -c $(srcdir)/test-raid5.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -R -c $(srcdir)/test-raid6.conf check 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf fix 2>> test.log - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(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 --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-raid6.conf check echo --- Sync after all the fixes - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -v -c $(srcdir)/test-raid6.conf sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -S -c $(srcdir)/test-raid6.conf check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -v -c $(srcdir)/test-raid6.conf sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check echo Success! # Manual testing -MANUAL = ./snapraid -S -c test-raid5.conf sync +MANUAL = ./snapraid --test-skip-self -c test-raid5.conf sync valgrind: valgrind \ diff --git a/scan.c b/scan.c index ba21a3bd..327add1e 100644 --- a/scan.c +++ b/scan.c @@ -271,7 +271,7 @@ static void scan_link(struct snapraid_scan* scan, struct snapraid_state* state, /* check if the link already exists */ link = tommy_hashdyn_search(&disk->linkset, link_name_compare, sub, link_name_hash(sub)); if (link) { - /* check if multiple files have the same inode */ + /* check if multiple files have the same name */ if (link_flag_has(link, FILE_IS_PRESENT)) { fprintf(stderr, "Internal inconsistency for symlink '%s%s'\n", disk->dir, sub); exit(EXIT_FAILURE); @@ -523,6 +523,7 @@ void state_scan(struct snapraid_state* state, int output) } /* insert all the new files, we insert them only after the deletion */ + /* to reuse the just freed space */ node = scan[i].file_insert_list; while (node) { struct snapraid_file* file = node->data; diff --git a/snapraid.c b/snapraid.c index a3be979e..56c0b810 100644 --- a/snapraid.c +++ b/snapraid.c @@ -72,19 +72,21 @@ struct option long_options[] = { { "count", 1, 0, 't' }, { "force-zero", 0, 0, 'Z' }, { "force-empty", 0, 0, 'E' }, - { "skip-self-test", 0, 0, 'S' }, - { "expect-unrecoverable", 0, 0, 'U' }, - { "expect-recoverable", 0, 0, 'R' }, { "speed-test", 0, 0, 'T' }, { "verbose", 0, 0, 'v' }, - { "gui", 0, 0, 'G' }, + { "gui", 0, 0, 'G' }, /* undocumented GUI interface command */ { "help", 0, 0, 'h' }, { "version", 0, 0, 'V' }, + /* test specific options, DO NOT USE! */ + { "test-skip-self", 0, 0, 'S' }, + { "test-kill-after-sync", 0, 0, 'K' }, + { "test-expect-unrecoverable", 0, 0, 'U' }, + { "test-expect-recoverable", 0, 0, 'R' }, { 0, 0, 0, 0 } }; #endif -#define OPTIONS "c:f:s:t:ZESURTvhVG" +#define OPTIONS "c:f:s:t:ZETvhVG" volatile int global_interrupt = 0; @@ -110,9 +112,10 @@ int main(int argc, char* argv[]) int gui; int force_zero; int force_empty; - int expect_unrecoverable; - int expect_recoverable; - int skip_self_test; + int test_expect_unrecoverable; + int test_expect_recoverable; + int test_kill_after_sync; + int test_skip_self; const char* conf; struct snapraid_state state; int operation; @@ -128,9 +131,10 @@ int main(int argc, char* argv[]) gui = 0; force_zero = 0; force_empty = 0; - expect_unrecoverable = 0; - expect_recoverable = 0; - skip_self_test = 0; + test_expect_unrecoverable = 0; + test_expect_recoverable = 0; + test_kill_after_sync = 0; + test_skip_self = 0; blockstart = 0; blockcount = 0; tommy_list_init(&filterlist); @@ -175,15 +179,6 @@ int main(int argc, char* argv[]) case 'E' : force_empty = 1; break; - case 'S' : - skip_self_test = 1; - break; - case 'U' : - expect_unrecoverable = 1; - break; - case 'R' : - expect_recoverable = 1; - break; case 'v' : verbose = 1; break; @@ -199,6 +194,18 @@ int main(int argc, char* argv[]) case 'T' : speed(); exit(EXIT_SUCCESS); + case 'S' : + test_skip_self = 1; + break; + case 'K' : + test_kill_after_sync = 1; + break; + case 'U' : + test_expect_unrecoverable = 1; + break; + case 'R' : + test_expect_recoverable = 1; + break; default: fprintf(stderr, "Unknown option '%c'\n", (char)c); exit(EXIT_FAILURE); @@ -227,12 +234,12 @@ int main(int argc, char* argv[]) raid_init(); - if (!skip_self_test) + if (!test_skip_self) selftest(gui); state_init(&state); - state_config(&state, conf, verbose, gui, force_zero, force_empty, expect_unrecoverable, expect_recoverable); + state_config(&state, conf, verbose, gui, force_zero, force_empty, test_expect_unrecoverable, test_expect_recoverable); if (operation == OPERATION_DIFF) { state_read(&state); @@ -251,10 +258,27 @@ int main(int argc, char* argv[]) /* intercept Ctrl+C */ signal(SIGINT, &signal_handler); + /* save the new state before the sync */ + /* this allow to recover the case of the changes in the array after an aborted sync. */ + + /* for example, think at this case: */ + /* - add some files at the array */ + /* - run a sync command, it will recompute the parity adding the new files */ + /* - abort the sync command before it stores the new content file */ + /* - delete the not yet synched files from the array */ + /* - run a new sync command */ + + /* the new sync command has now way to know that the parity file was modified */ + /* because the files triggering these changes are now deleted */ + /* and they aren't listed in the content file */ + + if (state.need_write) + state_write(&state); + ret = state_sync(&state, blockstart, blockcount); /* save the new state if required */ - if (state.need_write) + if (!test_kill_after_sync && state.need_write) state_write(&state); /* abort if required by the sync command */ diff --git a/state.c b/state.c index 45dab9ef..0f96087b 100644 --- a/state.c +++ b/state.c @@ -852,6 +852,8 @@ void state_write(struct snapraid_state* state) printf("\tblock %u\n", count_block); printf("\tsymlink %u\n", count_link); } + + state->need_write = 0; /* no write needed anymore */ } void state_filter(struct snapraid_state* state, tommy_list* filterlist)