2 # Common btrfs specific functions
10 $BTRFS_UTIL_PROG sub list $mnt | grep $name | awk '{ print $2 }'
13 # _require_btrfs_command <command> [<subcommand>|<option>]
14 # We check for btrfs and (optionally) features of the btrfs command
15 # It can both subfunction like "inspect-internal dump-tree" and
16 # options like "check --qgroup-report"
17 _require_btrfs_command()
23 _require_command "$BTRFS_UTIL_PROG" btrfs
27 $BTRFS_UTIL_PROG $cmd --help &> /dev/null
28 [ $? -eq 0 ] || _notrun "$BTRFS_UTIL_PROG too old (must support $cmd)"
30 test -z "$param" && return
32 # If $param is an option, replace leading "-"s for grep
33 if [ ${param:0:1} == "-" ]; then
34 safe_param=$(echo $param | sed 's/^-*//')
35 $BTRFS_UTIL_PROG $cmd --help | grep -wq $safe_param || \
36 _notrun "$BTRFS_UTIL_PROG too old (must support $cmd $param)"
40 $BTRFS_UTIL_PROG $cmd $param --help &> /dev/null
41 [ $? -eq 0 ] || _notrun "$BTRFS_UTIL_PROG too old (must support $cmd $param)"
44 # Require extra check on btrfs qgroup numbers
45 _require_btrfs_qgroup_report()
47 _require_btrfs_command check --qgroup-report
48 touch ${RESULT_DIR}/require_scratch.require_qgroup_report
51 _require_btrfs_dump_super()
53 if [ ! -x "$BTRFS_SHOW_SUPER_PROG" ]; then
54 _require_command "$BTRFS_UTIL_PROG" btrfs
55 if ! $BTRFS_UTIL_PROG inspect-internal dump-super --help >& /dev/null; then
56 _notrun "Missing btrfs-show-super or inspect-internal dump-super"
58 BTRFS_SHOW_SUPER_PROG="$BTRFS_UTIL_PROG inspect-internal dump-super"
62 _run_btrfs_util_prog()
64 run_check $BTRFS_UTIL_PROG $*
67 _require_btrfs_mkfs_feature()
70 echo "Missing feature name argument for _require_btrfs_mkfs_feature"
74 $MKFS_BTRFS_PROG -O list-all 2>&1 | \
75 grep '^[ \t]*'"$feat"'\b' > /dev/null 2>&1
77 _notrun "Feature $feat not supported in the available version of mkfs.btrfs"
80 _require_btrfs_fs_feature()
83 echo "Missing feature name argument for _require_btrfs_fs_feature"
87 modprobe btrfs > /dev/null 2>&1
88 [ -e /sys/fs/btrfs/features/$feat ] || \
89 _notrun "Feature $feat not supported by the available btrfs version"
92 _require_btrfs_fs_sysfs()
94 modprobe btrfs > /dev/null 2>&1
95 [ -e /sys/fs/btrfs/features ] || \
96 _notrun "Sysfs not supported by the available btrfs version"
100 _check_btrfs_filesystem()
104 # If type is set, we're mounted
105 type=`_fs_type $device`
108 if [ "$type" = "$FSTYP" ]; then
110 mountpoint=`_umount_or_remount_ro $device`
113 if [ -f ${RESULT_DIR}/require_scratch.require_qgroup_report ]; then
114 $BTRFS_UTIL_PROG check $device --qgroup-report > $tmp.qgroup_report 2>&1
115 if grep -qE "Counts for qgroup.*are different" $tmp.qgroup_report ; then
116 _log_err "_check_btrfs_filesystem: filesystem on $device has wrong qgroup numbers"
117 echo "*** qgroup_report.$FSTYP output ***" >>$seqres.full
118 cat $tmp.qgroup_report >>$seqres.full
119 echo "*** qgroup_report.$FSTYP output ***" >>$seqres.full
121 rm -f $tmp.qgroup_report
124 $BTRFS_UTIL_PROG check $device >$tmp.fsck 2>&1
125 if [ $? -ne 0 ]; then
126 _log_err "_check_btrfs_filesystem: filesystem on $device is inconsistent"
127 echo "*** fsck.$FSTYP output ***" >>$seqres.full
128 cat $tmp.fsck >>$seqres.full
129 echo "*** end fsck.$FSTYP output" >>$seqres.full
135 if [ $ok -eq 0 ]; then
136 echo "*** mount output ***" >>$seqres.full
137 _mount >>$seqres.full
138 echo "*** end mount output" >>$seqres.full
139 elif [ "$type" = "$FSTYP" ]; then
141 _mount_or_remount_rw "$MOUNT_OPTIONS" $device $mountpoint
145 if [ $ok -eq 0 ]; then
147 if [ "$iam" != "check" ]; then
156 _require_btrfs_dev_del_by_devid()
158 $BTRFS_UTIL_PROG device delete --help | egrep devid > /dev/null 2>&1
159 [ $? -eq 0 ] || _notrun "$BTRFS_UTIL_PROG too old "\
160 "(must support 'btrfs device delete <devid> /<mnt>')"
163 # get btrfs profile configs being tested
165 # A set of pre-set profile configs are exported via _btrfs_profile_configs
166 # array. Default configs can be overridden by setting BTRFS_PROFILE_CONFIGS
167 # var in the format "metadata_profile:data_profile", multiple configs can be
168 # seperated by space, e.g.
169 # export BTRFS_PROFILE_CONFIGS="raid0:raid0 raid1:raid1 dup:single"
170 _btrfs_get_profile_configs()
172 if [ "$FSTYP" != "btrfs" ]; then
176 if [ -z "$BTRFS_PROFILE_CONFIGS" ]; then
177 # Default configurations to test.
189 # User-provided configurations.
190 local configs=(${BTRFS_PROFILE_CONFIGS[@]})
193 _btrfs_profile_configs=()
194 for cfg in "${configs[@]}"; do
196 local profiles=(${cfg/:/ })
197 if [ "$1" == "replace" ]; then
198 # We can't do replace with these profiles because they
199 # imply only one device ($SCRATCH_DEV), and we need to
200 # keep $SCRATCH_DEV around for _scratch_mount
201 # and _check_scratch_fs.
205 elif [ "$1" == "replace-missing" ]; then
206 # We can't replace missing devices with these profiles
207 # because there isn't enough redundancy.
216 for unsupp in "${unsupported[@]}"; do
217 if [ "${profiles[0]}" == "$unsupp" -o "${profiles[1]}" == "$unsupp" ]; then
218 if [ -z "$BTRFS_PROFILE_CONFIGS" ]; then
219 # For the default config, just omit it.
222 # For user-provided config, don't run the test.
223 _notrun "Profile $unsupp not supported for $1"
227 if "$supported"; then
228 _btrfs_profile_configs+=("-m ${profiles[0]} -d ${profiles[1]}")
231 export _btrfs_profile_configs
234 # stress btrfs by running balance operation in a loop
235 _btrfs_stress_balance()
239 $BTRFS_UTIL_PROG balance start $options
243 # stress btrfs by creating/mounting/umounting/deleting subvolume in a loop
244 _btrfs_stress_subvolume()
253 while [ ! -e $stop_file ]; do
254 $BTRFS_UTIL_PROG subvolume create $btrfs_mnt/$subvol_name
255 $MOUNT_PROG -o subvol=$subvol_name $btrfs_dev $subvol_mnt
256 $UMOUNT_PROG $subvol_mnt
257 $BTRFS_UTIL_PROG subvolume delete $btrfs_mnt/$subvol_name
261 # stress btrfs by running scrub in a loop
262 _btrfs_stress_scrub()
266 $BTRFS_UTIL_PROG scrub start -B $btrfs_mnt
270 # stress btrfs by defragmenting every file/dir in a loop and compress file
271 # contents while defragmenting if second argument is not "nocompress"
272 _btrfs_stress_defrag()
278 if [ "$compress" == "nocompress" ]; then
279 find $btrfs_mnt \( -type f -o -type d \) -exec \
280 $BTRFS_UTIL_PROG filesystem defrag {} \;
282 find $btrfs_mnt \( -type f -o -type d \) -exec \
283 $BTRFS_UTIL_PROG filesystem defrag -clzo {} \;
284 find $btrfs_mnt \( -type f -o -type d \) -exec \
285 $BTRFS_UTIL_PROG filesystem defrag -czlib {} \;
290 # stress btrfs by remounting it with different compression algorithms in a loop
291 # run this with fsstress running at background could exercise the compression
292 # code path and ensure no race when switching compression algorithm with constant
294 _btrfs_stress_remount_compress()
298 for algo in no zlib lzo; do
299 $MOUNT_PROG -o remount,compress=$algo $btrfs_mnt
304 # stress btrfs by replacing devices in a loop
305 # Note that at least 3 devices are needed in SCRATCH_DEV_POOL and the last
306 # device should be free(not used by btrfs)
307 _btrfs_stress_replace()
311 # The device number in SCRATCH_DEV_POOL should be at least 3,
312 # one is SCRATCH_DEV, one is to be replaced, one is free device
313 # we won't replace SCRATCH_DEV, see below for reason
314 if [ "`echo $SCRATCH_DEV_POOL | wc -w`" -lt 3 ]; then
315 echo "_btrfs_stress_replace requires at least 3 devices in SCRATCH_DEV_POOL"
319 # take the last device as the first free_dev
320 local free_dev="`echo $SCRATCH_DEV_POOL | $AWK_PROG '{print $NF}'`"
322 # free_dev should be really free
323 if $BTRFS_UTIL_PROG filesystem show $btrfs_mnt | grep -q "$free_dev"; then
324 echo "_btrfs_stress_replace: $free_dev is used by btrfs"
328 # dev_pool is device list being currently used by btrfs (excluding SCRATCH_DEV)
329 # and can be replaced. We don't replace SCRATCH_DEV because it will be used in
330 # _scratch_mount and _check_scratch_fs etc.
331 local dev_pool=`echo $SCRATCH_DEV_POOL | sed -e "s# *$SCRATCH_DEV *##" \
332 -e "s# *$free_dev *##"`
334 # set the first device in dev_pool as the first src_dev to be replaced
335 local src_dev=`echo $dev_pool | $AWK_PROG '{print $1}'`
337 echo "dev_pool=$dev_pool"
338 echo "free_dev=$free_dev, src_dev=$src_dev"
340 echo "Replacing $src_dev with $free_dev"
341 $BTRFS_UTIL_PROG replace start -fB $src_dev $free_dev $btrfs_mnt
342 if [ $? -ne 0 ]; then
343 # don't update src_dev and free_dev if replace failed
346 dev_pool="$dev_pool $free_dev"
347 dev_pool=`echo $dev_pool | sed -e "s# *$src_dev *##"`
349 src_dev=`echo $dev_pool | $AWK_PROG '{print $1}'`
353 # find the right option to force output in bytes, older versions of btrfs-progs
354 # print that by default, newer print human readable numbers with unit suffix
355 _btrfs_qgroup_units()
357 $BTRFS_UTIL_PROG qgroup show --help 2>&1 | grep -q -- --raw && echo "--raw"
360 _btrfs_compression_algos()
363 for feature in /sys/fs/btrfs/features/compress_*; do
364 echo "${feature#/sys/fs/btrfs/features/compress_}"
368 # run btrfs balance start with required --full-balance if available.
369 _run_btrfs_balance_start()
373 $BTRFS_UTIL_PROG balance start --help | grep -q "full-balance"
374 (( $? == 0 )) && bal_opt="--full-balance"
376 run_check $BTRFS_UTIL_PROG balance start $bal_opt $*
379 #return the sector size of the btrfs scratch fs
380 _scratch_btrfs_sectorsize()
382 $BTRFS_UTIL_PROG inspect-internal dump-super $SCRATCH_DEV |\
383 grep sectorsize | awk '{print $2}'