Add regression tests and document parity size requirements when adding a parity level

This commit is contained in:
Andrea Mazzoleni
2026-09-08 10:34:26 +02:00
parent 6971bd58c9
commit e8726ce95a
2 changed files with 52 additions and 0 deletions
+47
View File
@@ -1320,6 +1320,53 @@ endif # !HAVE_MEMORY_CHECKER
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) locate > /dev/null
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) check
$(MSG) Test adding a parity level after an interrupted normal shrink
rm -rf bench/realloc-level
mkdir -p bench/realloc-level/disk1
mkdir -p bench/realloc-level/disk2
mkdir -p bench/realloc-level/disk3
mkdir -p bench/realloc-level/disk4
mkdir -p bench/realloc-level/disk5
mkdir -p bench/realloc-level/disk6
dd bs=1024 count=1 if=/dev/urandom of=bench/realloc-level/disk1/data
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL1) sync
dd bs=1024 count=1 if=/dev/urandom of=bench/realloc-level/disk1/tail
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL1) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) -d 2-parity fix
rm bench/realloc-level/disk1/tail
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL1) --test-kill-after-resize sync
cp bench/realloc-level/content bench/realloc-level/content.checkpoint
$(MSG) Accept the new level initialized at the old logical size
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) check
cp bench/realloc-level/content.checkpoint bench/realloc-level/content
$(MSG) Accept the new level initialized at the checkpoint allocation
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) -d 2-parity fix
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) check
cp bench/realloc-level/content.checkpoint bench/realloc-level/content
$(MSG) Accept the checkpoint allocation after adding files since fix
dd bs=1024 count=2 if=/dev/urandom of=bench/realloc-level/disk1/growth
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) check
$(MSG) Test fix leaving pending parity shorter than the checkpoint allocation
cp -p bench/realloc-level/disk1/data bench/realloc-level/disk2/data
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) sync
cp -p bench/realloc-level/disk1/growth bench/realloc-level/disk1/tail
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL1) --test-kill-after-sync sync
rm bench/realloc-level/disk2/data
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL1) fix
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) fix
cp bench/realloc-level/content bench/realloc-level/content.checkpoint
$(MSG) Resume after removing the pending additions
mv bench/realloc-level/disk1/tail bench/realloc-level/tail
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) check
$(MSG) Resume with the pending additions still allocated
mv bench/realloc-level/tail bench/realloc-level/disk1/tail
cp bench/realloc-level/content.checkpoint bench/realloc-level/content
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) check
$(MSG) Test interrupted normal shrink after adding a parity split
rm -rf bench/realloc-split
mkdir -p bench/realloc-split/disk1
+5
View File
@@ -2031,6 +2031,11 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
* A full parity rebuild or reallocation from zero reconstructs truncated
* parity. Tail-only reallocation still relies on the existing prefix, so a
* truncation before parity_tail remains fatal.
*
* New levels need the same physical coverage of valid blocks, not an exact
* match with another level or the allocated extent. After an interrupted
* sync, fix leaves pending parity to sync and may truncate its unwritten
* tail. Sync will resize and regenerate that tail if it is still allocated.
*/
if (!state->opt.force_full && !(state->opt.force_realloc && state->opt.parity_tail == 0)) {
/* if the parities are too small */