summaryrefslogtreecommitdiff
path: root/tests/fsck-tests/012-leaf-corruption/test.sh
blob: edf77193a08dc789401fefc4ac366afb04ece48e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/bin/bash

source $top/tests/common

# Check file list for leaf corruption, no regular/preallocated
# file extent case.
# Corrupted leaf is 20832256, which contains inode 1862~1872
#
# 1862, ref from leaf 20828160 key 24(DIR_ITEM)
# 1863, ref from leaf 605388 item key 11(DIR_ITEM)
# 1864, no ref to rebuild, no need to rebuild
# 1865, ref from leaf 19767296 key 23(DIR_ITEM)
# 1866-1868 no ref to rebuild, all refs in corrupted leaf
# 1869, ref from leaf 4976640 key 22(DIR_ITEM)
# 1870 no ref to rebuild, all refs in corrupted leaf
# 1871, ref from leaf 19746816 key 38(DIR_ITEM)
# 1872, ref from leaf 19767296 key 14(DIR_ITEM)
# The list format is:
# INO SIZE MODE NAME
# INO: inode number
# SIZE: file size, only checked for regular file
# MODE: raw file mode, get from stat
# NAME: file name
leaf_no_data_ext_list=(
	1862 0 40700 "install.d"
	1862 0 40700 "install.d"
	1863 0 40700 "gdb"
	1865 0 40700 "iptables"
	1869 0 40700 "snmp"
	1871 0 100700 "machine-id"
	1872 0 100700 "adjtime"
)

generate_leaf_corrupt_no_data_ext()
{
	dest=$1
	echo "generating leaf_corrupt_no_data_ext.btrfs-image" >> $RESULT
	tar xJf ./no_data_extent.tar.xz || \
		_fail "failed to extract leaf_corrupt_no_data_ext.btrfs-image"
	btrfs-image -r test.img.btrfs-image $dest || \
		_fail "failed to extract leaf_corrupt_no_data_ext.btrfs-image"

	# leaf at 20832256 contains no regular data extent, clear its csum to
	# corrupt the leaf.
	dd if=/dev/zero of=$dest bs=1 count=32 conv=notrunc seek=20832256 \
		1>/dev/null 2>&1
}

check_inode()
{
	path=$1
	ino=$2
	size=$3
	mode=$4
	name=$5

	# Check whether the inode exists
	exists=$(find $path -inum $ino)
	if [ -z "$exists" ]; then
		_fail "inode $ino not recovered correctly"
	fi

	# Check inode type
	found_mode=$(printf "%o" 0x$(stat $exists -c %f))
	if [ $found_mode -ne $mode ]; then
		echo "$found_mode"
		_fail "inode $ino modes not recovered"
	fi

	# Check inode size
	found_size=$(stat $exists -c %s)
	if [ $mode -ne 41700 -a $found_size -ne $size ]; then
		_fail "inode $ino size not recovered correctly"
	fi

	# Check inode name
	if [ "$(basename $exists)" != "$name" ]; then
		_fail "inode $ino name not recovered correctly"
	else
		return 0
	fi
}

# Check salvaged data in the recovered image
check_leaf_corrupt_no_data_ext()
{
	image=$1
	if [ $UID -ne 0 ]; then
		echo "     [NOTRUN] verify recovery. need root privilege"
		exit 0
	fi
	if [ -z $TEST_MNT ]; then
		echo "\$TEST_MNT not set, use $(pwd)/tmp as fallback"
		TEST_MNT="$(pwd)/tmp"
	fi
	mkdir -p $TEST_MNT || _fail "failed to create mount point"
	mount $image -o ro $TEST_MNT

	i=0
	while [ $i -lt ${#leaf_no_data_ext_list[@]} ]; do
		check_inode $TEST_MNT/lost+found \
			    ${leaf_no_data_ext_list[i]} \
			    ${leaf_no_data_ext_list[i + 1]} \
			    ${leaf_no_data_ext_list[i + 2]} \
			    ${leaf_no_data_ext_list[i + 3]} \
			    ${leaf_no_data_ext_list[i + 4]}
			    ((i+=4))
	done
	umount $TEST_MNT
}

generate_leaf_corrupt_no_data_ext test.img
check_image test.img
check_leaf_corrupt_no_data_ext test.img

rm test.img
rm test.img.btrfs-image
# Not used, its function is the same as generate_leaf_corrupt_no_data_ext()
rm generate_image.sh