summaryrefslogtreecommitdiff
path: root/tests/common.convert
blob: 1e00d389a4e2419d16424cb4a34e65f70ab8993f (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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#!/bin/bash
# helpers for btrfs-convert tests

# how many files to create.
DATASET_SIZE=50

generate_dataset() {

	dataset_type="$1"
	dirpath=$TEST_MNT/$dataset_type
	run_check $SUDO_HELPER mkdir -p $dirpath

	case $dataset_type in
		small)
			for num in $(seq 1 $DATASET_SIZE); do
				run_check $SUDO_HELPER dd if=/dev/urandom of=$dirpath/$dataset_type.$num bs=10K \
				count=1 >/dev/null 2>&1
			done
			;;

		hardlink)
			for num in $(seq 1 $DATASET_SIZE); do
				run_check $SUDO_HELPER touch $dirpath/$dataset_type.$num
				run_check $SUDO_HELPER ln $dirpath/$dataset_type.$num $dirpath/hlink.$num
			done
			;;

		symlink)
			for num in $(seq 1 $DATASET_SIZE); do
				run_check $SUDO_HELPER touch $dirpath/$dataset_type.$num
				run_check $SUDO_HELPER ln -s $dirpath/$dataset_type.$num $dirpath/slink.$num
			done
			;;

		brokenlink)
			for num in $(seq 1 $DATASET_SIZE); do
				run_check $SUDO_HELPER ln -s $dirpath/$dataset_type.$num $dirpath/blink.$num
			done
			;;

		perm)
			for modes in 777 775 755 750 700 666 664 644 640 600 444 440 400 000		\
				1777 1775 1755 1750 1700 1666 1664 1644 1640 1600 1444 1440 1400 1000	\
				2777 2775 2755 2750 2700 2666 2664 2644 2640 2600 2444 2440 2400 2000	\
				4777 4775 4755 4750 4700 4666 4664 4644 4640 4600 4444 4440 4400 4000; do
				if [[ "$modes" == *9* ]] || [[ "$modes" == *8* ]]
				then
					continue;
				else
					run_check $SUDO_HELPER touch $dirpath/$dataset_type.$modes
					run_check $SUDO_HELPER chmod $modes $dirpath/$dataset_type.$modes
				fi
			done
			;;

		sparse)
			for num in $(seq 1 $DATASET_SIZE); do
				run_check $SUDO_HELPER dd if=/dev/urandom of=$dirpath/$dataset_type.$num bs=10K \
				count=1 >/dev/null 2>&1
				run_check $SUDO_HELPER truncate -s 500K $dirpath/$dataset_type.$num
				run_check $SUDO_HELPER dd if=/dev/urandom of=$dirpath/$dataset_type.$num bs=10K \
				oflag=append conv=notrunc count=1 >/dev/null 2>&1
				run_check $SUDO_HELPER truncate -s 800K $dirpath/$dataset_type.$num
			done
			;;

		acls)
			for num in $(seq 1 $DATASET_SIZE); do
				run_check $SUDO_HELPER touch $dirpath/$dataset_type.$num
				run_check $SUDO_HELPER setfacl -m "u:root:x" $dirpath/$dataset_type.$num
				run_check $SUDO_HELPER setfattr -n user.foo -v bar$num $dirpath/$dataset_type.$num
			done
			;;
	esac
}

populate_fs() {

        for dataset_type in 'small' 'hardlink' 'symlink' 'brokenlink' 'perm' 'sparse' 'acls'; do
		generate_dataset "$dataset_type"
	done
}

# verbose message before the test, same arguments as convert_test
convert_test_preamble() {
	local features
	local msg

	features="$1"
	msg="$2"
	shift 3
	echo "    [TEST/conv]     $msg, btrfs" "${features:-defaults}"
	echo "creating ext image with: $@" >> $RESULTS
}

#  prepare TEST_DEV before conversion, create filesystem and mount it, image
#  size is 512MB
#  $@: free form, command to create the filesystem, with appended -F
convert_test_prep_fs() {
	# TEST_DEV not removed as the file might have special permissions, eg.
	# when test image is on NFS and would not be writable for root
	run_check truncate -s 0 $TEST_DEV
	# 256MB is the smallest acceptable btrfs image.
	run_check truncate -s 512M $TEST_DEV
	run_check "$@" -F $TEST_DEV

	# create a file to check btrfs-convert can convert regular file correct
	run_check_mount_test_dev

	# create a file inside the fs before convert, to make sure there is
	# data covering btrfs backup superblock range (64M)
	run_check $SUDO_HELPER dd if=/dev/zero bs=1M count=64 \
		of=$TEST_MNT/convert_space_holder
}

# generate md5 checksums of files on $TEST_MNT
# $1: path where the checksums will be stored
convert_test_gen_checksums() {
	local CHECKSUMTMP
	CHECKSUMTMP="$1"

	run_check $SUDO_HELPER dd if=/dev/zero of=$TEST_MNT/test bs=$nodesize \
		count=1 >/dev/null 2>&1
	run_check_stdout $SUDO_HELPER find $TEST_MNT -type f ! -name 'image' -exec md5sum {} \+ > "$CHECKSUMTMP"
}
# list $TEST_MNT data set file permissions.
# $1: path where the permissions will be stored
convert_test_perm() {
	local PERMTMP
	PERMTMP="$1"
	FILES_LIST=$(mktemp --tmpdir btrfs-progs-convert.fileslistXXXXXX)

	run_check $SUDO_HELPER dd if=/dev/zero of=$TEST_MNT/test bs=$nodesize \
		count=1 >/dev/null 2>&1
	run_check_stdout $SUDO_HELPER find $TEST_MNT -type f ! -name 'image' -fprint $FILES_LIST
	# Fix directory entries order
	sort $FILES_LIST -o $FILES_LIST
	for file in `cat $FILES_LIST` ;do
		run_check_stdout $SUDO_HELPER getfacl --absolute-names $file >> "$PERMTMP"
	done
	rm -- $FILES_LIST
}
# list acls of files on $TEST_MNT
# $1: path where the acls will be stored
convert_test_acl() {
	local ACLSTMP
	ACLTMP="$1"
	FILES_LIST=$(mktemp --tmpdir btrfs-progs-convert.fileslistXXXXXX)

	run_check_stdout $SUDO_HELPER find $TEST_MNT/acls -type f -fprint $FILES_LIST
	# Fix directory entries order
	sort $FILES_LIST -o $FILES_LIST
	for file in `cat $FILES_LIST`;do
		run_check_stdout $SUDO_HELPER getfattr --absolute-names -d $file >> "$ACLTMP"
	done
	rm -- $FILES_LIST
}

# do conversion with given features and nodesize, fsck afterwards
# $1: features, argument of -O, can be empty
# $2: nodesize, argument of -N, can be empty
convert_test_do_convert() {
	run_check $TOP/btrfs-convert ${1:+-O "$1"} ${2:+-N "$2"} $TEST_DEV
	run_check $TOP/btrfs check $TEST_DEV
	run_check $TOP/btrfs-show-super -Ffa $TEST_DEV
}

# post conversion check, verify file permissions.
# $1: file with ext permissions.
convert_test_post_check_permissions() {
	local EXT_PERMTMP
	local BTRFS_PERMTMP

	EXT_PERMTMP="$1"
	BTRFS_PERMTMP=$(mktemp --tmpdir btrfs-progs-convert.permXXXXXX)
	convert_test_perm "$BTRFS_PERMTMP"

	btrfs_perm=`md5sum $BTRFS_PERMTMP | cut -f1 -d' '`
	ext_perm=`md5sum $EXT_PERMTMP | cut -f1 -d' '`

	if [ "$btrfs_perm" != "$ext_perm" ];
	then
		btrfs_perm_file=`md5sum $BTRFS_PERMTMP | cut -f2 -d' '`
		ext_perm_file=`md5sum $EXT_PERMTMP | cut -f2 -d' '`
		_fail "file permission failed. Mismatched BTRFS:$btrfs_perm_file:$btrfs_perm EXT:$ext_perm_file:$ext_perm"
	fi

	rm -- $BTRFS_PERMTMP
}
# post conversion check, compare BTRFS file acls against EXT.
# $1: file with ext acls.
convert_test_post_check_acl() {
	local EXT_ACLTMP
	local BTRFS_ACLTMP

	EXT_ACLTMP="$1"
	BTRFS_ACLTMP=$(mktemp --tmpdir btrfs-progs-convert.aclsXXXXXXX)
	convert_test_acl "$BTRFS_ACLTMP"

	btrfs_acl=`md5sum $BTRFS_ACLTMP | cut -f1 -d' '`
	ext_acl=`md5sum $EXT_ACLTMP | cut -f1 -d' '`

	if [ "$btrfs_acl" != "$ext_acl" ]
	then
		btrfs_acl_file=`md5sum $BTRFS_ACLTMP | cut -f2 -d' '`
		ext_acl_file=`md5sum $EXT_ACLTMP | cut -f2 -d' '`
		_fail "file acl failed. Mismatched BTRFS:$btrfs_acl_file:$btrfs_acl EXT:$ext_acl_file:$ext_acl"
	fi

	rm -- $BTRFS_ACLTMP
}
# post conversion checks, verify md5sums
# $1: file with checksums
# $2: file with permissions.
# $3: file with acl entries.
convert_test_post_check() {
	local CHECKSUMTMP
	local EXT_PERMTMP
	local EXT_ACLTMP

	CHECKSUMTMP="$1"
	EXT_PERMTMP="$2"
	EXT_ACLTMP="$3"

	run_check_mount_test_dev
	run_check_stdout $SUDO_HELPER md5sum -c "$CHECKSUMTMP" |
		grep -q 'FAILED' && _fail "file validation failed"
	convert_test_post_check_permissions "$EXT_PERMTMP"
	convert_test_post_check_acl "$EXT_ACLTMP"
	run_check_umount_test_dev
}

# do rollback and fsck
convert_test_post_rollback() {
	run_check $TOP/btrfs-convert --rollback $TEST_DEV
	run_check fsck -n -t ext2,ext3,ext4 $TEST_DEV
}

# simple wrapper for a convert test
# $1: btrfs features, argument to -O
# $2: description of the test "ext2 8k nodesize"
# $3: nodesize value
# $4 + rest: command to create the ext2 image
convert_test() {
	local features
	local nodesize
	local msg
	local CHECKSUMTMP
	local EXT_PERMTMP
	local EXT_ACLTMP

	features="$1"
	msg="$2"
	nodesize="$3"
	shift 3
	convert_test_preamble "$features" "$msg" "$nodesize" "$@"
	convert_test_prep_fs "$@"
	populate_fs
	CHECKSUMTMP=$(mktemp --tmpdir btrfs-progs-convert.XXXXXXXXXX)
	EXT_PERMTMP=$(mktemp --tmpdir btrfs-progs-convert.permXXXXXX)
	EXT_ACLTMP=$(mktemp --tmpdir btrfs-progs-convert.aclsXXXXXXX)
	convert_test_gen_checksums "$CHECKSUMTMP"
	convert_test_perm "$EXT_PERMTMP"
	convert_test_acl "$EXT_ACLTMP"

	run_check_umount_test_dev

	convert_test_do_convert "$features" "$nodesize"
	convert_test_post_check "$CHECKSUMTMP" "$EXT_PERMTMP" "$EXT_ACLTMP"
	rm $CHECKSUMTMP
	rm $EXT_PERMTMP
	rm $EXT_ACLTMP

	convert_test_post_rollback
}