Skip to content

Instantly share code, notes, and snippets.

@loli10K
Created June 26, 2017 18:12
Show Gist options
  • Save loli10K/af70fb0f1aae7b174822aa5657e07c28 to your computer and use it in GitHub Desktop.
Save loli10K/af70fb0f1aae7b174822aa5657e07c28 to your computer and use it in GitHub Desktop.
Corruption in incremental send without -L flag on large_blocks-enabled pool
#!/bin/bash
# misc functions
function inum() {
stat -c '%i' "$1"
}
function is_linux() {
if [[ "$(uname)" == "Linux" ]]; then
return 0
else
return 1
fi
}
# setup
POOLNAME='testpool'
if is_linux; then
TMPDIR='/var/tmp'
mountpoint -q $TMPDIR || mount -t tmpfs tmpfs $TMPDIR
zpool destroy $POOLNAME
fallocate -l 128m $TMPDIR/zpool.dat
zpool create -O mountpoint=/mnt/$POOLNAME $POOLNAME $TMPDIR/zpool.dat
else
TMPDIR='/tmp'
zpool destroy $POOLNAME
mkfile 128m $TMPDIR/zpool.dat
zpool create -O mountpoint=/mnt/$POOLNAME $POOLNAME $TMPDIR/zpool.dat
fi
# send first full stream with large blocks (-L)
zfs create -o recordsize=1M $POOLNAME/source
dd if=/dev/urandom of=/mnt/$POOLNAME/source/file1.dat bs=1M count=5
zfs snapshot $POOLNAME/source@snap1
zfs send -L $POOLNAME/source@snap1 > $TMPDIR/full.dat
cat $TMPDIR/full.dat | zstreamdump -v | grep "object = `inum /mnt/$POOLNAME/source/file1.dat`"
cat $TMPDIR/full.dat | zfs receive -F $POOLNAME/target
cp /mnt/$POOLNAME/source/file1.dat /mnt/$POOLNAME/source/full.dat
#
du -sh /mnt/$POOLNAME/*/*
# send second incr stream without large blocks (-i)
zfs snapshot $POOLNAME/source@snap2
zfs send -i $POOLNAME/source@snap1 $POOLNAME/source@snap2 > $TMPDIR/incr.dat
cat $TMPDIR/incr.dat | zstreamdump -v | grep "object = `inum /mnt/$POOLNAME/source/file1.dat`"
cat $TMPDIR/incr.dat | zfs receive -F $POOLNAME/target
#
du -sh /mnt/$POOLNAME/*/*
# data is gone, the whole file is a single HOLE
zdb -ddddddd -bbbbbbb $POOLNAME/target `inum /mnt/$POOLNAME/target/file1.dat`
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment