Public feed
#601804
#!/bin/ksh
###################################################################
# zpool-spare-demo
#
# An experiment script to help me understand zfs/zpool better.
#
# Dale Sears
###################################################################
###################################################################
# Set these to something reasonable for your system.
# The rest of this code assumes you're not using spaces in these:
###################################################################
ZPOOL=shallow
DISKDIR=/home/dsk
###################################################################
# Bail out if we have the ZPOOL. We don't want to break it:
###################################################################
HASAPOOL=`/sbin/zpool status | /bin/grep "pool: $ZPOOL"`
if [ ! -z "$HASAPOOL" ]
then
echo "/////////////////////////////////////////////////////////////////"
echo "// WARNING: zpool \"$ZPOOL\" exists! I'm not touching it..."
echo "//"
echo "// WARNING: Removing this check will likely panic the system"
echo "/////////////////////////////////////////////////////////////////"
exit 1
fi
###################################################################
# The directory where we're storing our pretend disks:
###################################################################
/bin/mkdir -p $DISKDIR > /dev/null 2>&1
if [ ! -d $DISKDIR ]
then
echo "Uh, oh... : Could not create DISKDIR: $DISKDIR"
exit 1
fi
###################################################################
# NOTE: I'm using lame disk names here, just in case
# DISKDIR gets set to something terrible like /dev/dsk.
# If you don't understand why that would be bad, please logout.
###################################################################
DISKS="$DISKDIR/disk01 \
$DISKDIR/disk02 \
$DISKDIR/disk03 \
$DISKDIR/disk04 \
$DISKDIR/disk05 \
$DISKDIR/disk06"
SPARES="$DISKDIR/spare01 \
$DISKDIR/spare02"
###################################################################
# We're making 64MB (the minimum size) files to use as disks:
###################################################################
/usr/sbin/mkfile 64m $DISKS $SPARES
###################################################################
# Start an XTerm to watch the scrub process. This may start out
# very boring, with repeating a "no pools available":
###################################################################
/usr/openwin/bin/xterm -T "zpool status" -geom 80x24-0+33 -e /bin/ksh \
'(while :;do zpool status $ZPOOL;sleep 2;done)' &
###################################################################
# Create the zpool:
###################################################################
/sbin/zpool create $ZPOOL raidz $DISKDIR/disk01 \
$DISKDIR/disk02 \
$DISKDIR/disk03 \
$DISKDIR/disk04 \
$DISKDIR/disk05 \
spare $DISKDIR/spare01
###################################################################
# Toss a rock into the pool:
###################################################################
/bin/dd if=/dev/urandom of=/$ZPOOL/rock bs=8192k count=8 &
MD5_BEFORE=`/usr/bin/digest -v -a md5 /$ZPOOL/rock | \
/bin/awk '{print $4}'`
###################################################################
# Corrupt some data. This will not be "noticed" by zfs until the
# checksum on the wasted blocks has been done, so we should still
# have a good 'zpool status' after randomizing a few blocks:
###################################################################
/bin/dd if=/dev/urandom of=$DISKDIR/disk01 bs=8192k count=4 conv=notrunc
/sbin/zpool status
###################################################################
# Check the md5 hash of the file (to show that they're the same.
###################################################################
MD5_AFTER=`/usr/bin/digest -v -a md5 /$ZPOOL/rock | /bin/awk '{print $4}'`
###################################################################
# Now we're going to force zfs to check the integrity of the pool.
# but at this point, we've already read the entire file and we
# expect to see that BOGUSMD5 is the same as MD5 before the disk
# corruption:
###################################################################
/sbin/zpool scrub $ZPOOL
###################################################################
# Read the contents of the file (like the md5 did, but after a
# scrub. The result of reading the file *after* the scrub should
# be some form of spare action or resilvering of the data from
# parity:
###################################################################
/bin/cp /$ZPOOL/rock /$ZPOOL/rock.copy
###################################################################
# Clear the checksum errors and zfs should present a clean status:
###################################################################
zpool clear $ZPOOL
###################################################################
# I think shrinking and randomizing the disk has been successful
# in forcing the spare to kick in. In this corruption, we're not
# going to preserve the size of the disk with "conv=notrunc" This
# will cause zfs to use a spare:
###################################################################
/bin/dd if=/dev/urandom of=$DISKDIR/disk01 bs=8192k count=2
/sbin/zpool scrub $ZPOOL
###################################################################
# Let's replace a disk in the middle of all of this:
###################################################################
zpool replace $ZPOOL $DISKDIR/disk01 $DISKDIR/disk06
###################################################################
# We should still have the same MD5:
###################################################################
MD5_AFTER_SPARE=`/usr/bin/digest -v -a md5 /$ZPOOL/rock | /bin/awk '{print $4}'`
###################################################################
# Did our data get corrupted at given points?:
###################################################################
echo "MD5 before corruption: $MD5_BEFORE"
echo "MD5 after corruption: $MD5_AFTER"
echo "MD5 after spare : $MD5_AFTER_SPARE"