linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Lakshmipathi.G" <Lakshmipathi.G@giis.co.in>
To: linux-btrfs@vger.kernel.org, quwenruo@cn.fujitsu.com, kreijack@inwind.it
Subject: [PATCH] btrfs-progs: RAID5:Inject data stripe corruption and verify scrub fixes it.
Date: Wed, 15 Feb 2017 14:33:38 +0530	[thread overview]
Message-ID: <20170215090338.GA11666@giis.co.in> (raw)

Signed-off-by: Lakshmipathi.G <Lakshmipathi.G@giis.co.in>
---
 .../020-raid5-datastripe-corruption/test.sh        | 224 +++++++++++++++++++++
 1 file changed, 224 insertions(+)
 create mode 100755 tests/misc-tests/020-raid5-datastripe-corruption/test.sh

diff --git a/tests/misc-tests/020-raid5-datastripe-corruption/test.sh b/tests/misc-tests/020-raid5-datastripe-corruption/test.sh
new file mode 100755
index 0000000..d04c430
--- /dev/null
+++ b/tests/misc-tests/020-raid5-datastripe-corruption/test.sh
@@ -0,0 +1,224 @@
+#!/bin/bash
+#
+# Raid5: Inject data stripe corruption and fix them using scrub.
+# 
+# Script will perform the following:
+# 1) Create Raid5 using 3 loopback devices.
+# 2) Ensure file layout is created in a predictable manner. 
+#    Each data stripe(64KB) should uniquely start with 'DNxxxx',   
+#    where N represents the data stripe number.(ex:D0xxxx,D1xxxx etc)
+# 3) Once file is created with specific layout, gather data stripe details 
+#    like devicename, position and actual on-disk data.
+# 4) Now use 'dd' to verify the data-stripe against its expected value
+#    and inject corruption by zero'ing out contents.
+# 5) After injecting corruption, running online-scrub is expected to fix 
+#    the corrupted data stripe with the help of parity block and 
+#    corresponding data stripe.
+# 6) Finally, validate the data stripe has original un-corrupted value.
+#
+#  Note: This script doesn't handle parity block corruption.
+
+source $TOP/tests/common
+
+check_prereq btrfs
+check_prereq mkfs.btrfs
+
+setup_root_helper
+prepare_test_dev 512M
+
+ndevs=3
+declare -a devs
+device_name=""
+stripe_offset=""
+stripe_content=""
+
+LAYOUT_TMP=$(mktemp --tmpdir btrfs-progs-raid5-file.layoutXXXXXX)
+STRIPEINFO_TMP=$(mktemp --tmpdir btrfs-progs-raid5-file.infoXXXXXX)
+
+prepare_devices()
+{
+	for i in `seq $ndevs`; do
+		touch img$i
+		chmod a+rw img$i
+		truncate -s0 img$i
+		truncate -s512M img$i
+		devs[$i]=`run_check_stdout $SUDO_HELPER losetup --find --show img$i`
+	done
+}
+
+cleanup_devices()
+{
+	for dev in ${devs[@]}; do
+		run_check $SUDO_HELPER losetup -d $dev
+	done
+	for i in `seq $ndevs`; do
+		truncate -s0 img$i
+	done
+	run_check $SUDO_HELPER losetup --all
+}
+
+test_do_mkfs()
+{
+	run_check $SUDO_HELPER $TOP/mkfs.btrfs -f	\
+		$@
+}
+
+test_mkfs_multi()
+{
+	test_do_mkfs $@ ${devs[@]}
+}
+
+#$1 Filename
+#$2 Expected no.of data stripes for the file.
+create_layout(){
+	fname=$1
+	size=$(( $2 * 65536 ))
+	n=0
+	bs_value=1
+	stripe=0
+	while (( $n < $size ))
+	do
+		if [ $(( $n % 65536 )) -eq 0 ]; then
+			val='D'$stripe
+			echo -n $val
+        		stripe=$(( $stripe+1 ))
+			# ensure proper value		
+			bs_value=`echo "${#val}"` 
+        	else
+			echo -n 'x'
+			bs_value=1
+		fi
+        n=$(( $n+$bs_value ))
+	done | dd of="$TEST_MNT"/$fname bs=$bs_value conv=notrunc &> /dev/null
+}
+
+find_data_stripe_details(){
+	for dev in ${devs[@]}; do
+		echo $dev >> $LAYOUT_TMP
+		$SUDO_HELPER cat $dev | hexdump -e '"%010_ad|" 16/1 "%_p" "|\n"' |
+		grep -P 'D[0-9]+xx'  >> $LAYOUT_TMP
+	done
+}
+
+#Collect data stripe information in a readable manner.
+save_data_stripe_details(){
+	devname=""
+	for entry in `cat $LAYOUT_TMP`; do  
+		echo $entry | grep -q '^\/dev\/loop' > /dev/null
+
+		if [ $? -eq 0 ]; then
+			devname=$entry	
+		else
+			echo $devname"|"$entry >> $STRIPEINFO_TMP
+		fi
+	done
+	#Order by data stripe. D0 comes before D1.
+	sort -t'|'  -k3 $STRIPEINFO_TMP -o $STRIPEINFO_TMP
+}
+
+#Corrupt given data stripe
+corrupt_data_stripe(){
+
+	data_stripe_num=$1
+	data_stripe_entry="D"${data_stripe_num}"xxxx"
+	stripe_entry=`grep "${data_stripe_entry}" $STRIPEINFO_TMP`
+
+	#Each entry will have format like "device|position|16-byte content"
+	#Example: /dev/loop1|0063176704|D0xxxxxxxxxxxxxx|
+	device_name=$(echo $stripe_entry | awk -F"|" '{print $1}')
+	stripe_offset=$(echo $stripe_entry | awk -F"|" '{print $2}')
+	#Remove leading zeros
+	stripe_offset=$(echo $stripe_offset | sed 's/^0*//')
+	stripe_content=$(echo $stripe_entry | awk -F"|" '{print $3}')
+
+	echo "Corrupting $device_name at position $stripe_offset \
+	which has $stripe_content" >> "$RESULTS"
+
+	#verify the value at this position 
+	original_value=$($SUDO_HELPER dd 2>/dev/null if=$device_name bs=1 \
+	count=16 skip=$stripe_offset)
+
+	if [ $original_value != $stripe_content ];then
+		 echo "$original_value != $stripe_content"
+		_fail "Data stripe mismatch. Possible use of incorrect block."
+	else
+		echo "Found on-disk value: $original_value " >> "$RESULTS"
+	fi
+
+	#Corrupt the given data stripe
+	$SUDO_HELPER dd if=/dev/zero of=$device_name bs=1 count=4 \
+	seek=$stripe_offset conv=notrunc &> /dev/null
+
+	#Fetch value again.
+	corrupted_value=$($SUDO_HELPER dd 2>/dev/null if=$device_name \
+	bs=1 count=16 skip=$stripe_offset)
+
+	if [ $corrupted_value == $original_value ];then
+		 echo "original:$original_value corrupted:$corrupted_value"
+		_fail "Corruption failed. Possible use of incorrect block."
+	else
+		echo "Corruption completed at $stripe_offset" >> "$RESULTS"
+	fi
+
+# Corruption done.
+}
+
+#Verify data stripe after scrub
+verify_data_stripe(){
+
+	value_after_scrub=$($SUDO_HELPER dd 2>/dev/null if=$device_name bs=1 \
+	count=16 skip=$stripe_offset)
+	if [ $value_after_scrub != $stripe_content ];then
+		_fail "Scrub failed to fix data stripe corruption."
+	else
+		echo "Scrub corrected value: $value_after_scrub" >> "$RESULTS"
+	fi
+}
+
+#$1 Filename
+#$2 File with 'n' no.of data stripes
+#$3 Data stripe to corrupt
+test_raid5_datastripe_corruption(){
+	filename=$1
+	stripe_num=$2
+	test_stripe=$3
+
+	prepare_devices
+	dev1=${devs[1]}
+	dev2=${devs[2]}
+	dev3=${devs[3]}
+
+	test_mkfs_multi -d raid5 -m raid5
+	run_check $SUDO_HELPER mount $dev1 $TEST_MNT
+	create_layout $filename $stripe_num
+	run_check $SUDO_HELPER umount "$TEST_MNT"
+
+	#Gather data stripe informations like specific device,offset 
+	find_data_stripe_details
+	save_data_stripe_details
+	corrupt_data_stripe $test_stripe
+
+	#Mount the device and start scrub
+	run_check $SUDO_HELPER mount $dev1 $TEST_MNT
+	run_check $SUDO_HELPER btrfs scrub start $TEST_MNT
+	#Introduce delay, hopefully scrubbing will be finished.
+	sleep 10 
+
+	#Validate 
+	verify_data_stripe
+
+	#cleanup
+	run_check $SUDO_HELPER umount "$TEST_MNT"
+	cleanup_devices
+	rm -f $LAYOUT_TMP
+	rm -f $STRIPEINFO_TMP
+}
+
+
+test_raid5_datastripe_corruption file128k.txt 2 1 #file with 2 stripe,corrupt 1st.
+test_raid5_datastripe_corruption file192k.txt 3 2 #file with 3 stripe,corrupt 2nd.
+test_raid5_datastripe_corruption file256k.txt 4 3
+test_raid5_datastripe_corruption file512k.txt 8 6
+test_raid5_datastripe_corruption file768k.txt 12 10
+test_raid5_datastripe_corruption file1m.txt 16 14 #1MB file, corrupt 14th stripe.
+test_raid5_datastripe_corruption file1m.txt 32 23 #2MB file, corrupt 23rd stripe
-- 
2.7.4


             reply	other threads:[~2017-02-15  9:04 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-15  9:03 Lakshmipathi.G [this message]
     [not found] ` <e0a04535-80ad-671c-15b7-4a37305c1be4@cn.fujitsu.com>
2017-02-15 20:56   ` [PATCH] btrfs-progs: RAID5:Inject data stripe corruption and verify scrub fixes it Lakshmipathi.G
     [not found]     ` <6fee8854-fc3f-c664-4004-b3579208b234@cn.fujitsu.com>
2017-02-16 15:51       ` Lakshmipathi.G
2017-02-21  9:41       ` Lakshmipathi.G

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170215090338.GA11666@giis.co.in \
    --to=lakshmipathi.g@giis.co.in \
    --cc=kreijack@inwind.it \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=quwenruo@cn.fujitsu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).