Home | History | Annotate | Line # | Download | only in resize_ffs
      1 
      2 # Common settings and functions for the various resize_ffs tests.
      3 #
      4 
      5 # called from atf_init_test_cases
      6 setupvars()
      7 {
      8 	IMG=fsimage
      9 	TDBASE64=$(atf_get_srcdir)/testdata.tar.gz.base64
     10 	GOODMD5=$(atf_get_srcdir)/testdata.md5
     11 	# set BYTESWAP to opposite-endian.
     12 	if [ $(sysctl -n hw.byteorder) = "1234" ]; then
     13 		BYTESWAP=be
     14 	else
     15 		BYTESWAP=le
     16 	fi
     17 }
     18 
     19 # test_case() taken from the tests/ipf/h_common.sh
     20 # Used to declare the atf goop for a test.
     21 test_case()
     22 {
     23 	local name="${1}"; shift
     24 	local check_function="${1}"; shift
     25 
     26 	atf_test_case "${name}" cleanup
     27 	eval "${name}_head() { \
     28 		atf_set "require.user" "root" ; \
     29 		atf_set "require.progs" "rump_ffs" ; \
     30 	}"
     31 	eval "${name}_body() { \
     32 		${check_function} " "${@}" "; \
     33 	}"
     34 	eval "${name}_cleanup() { \
     35 		umount -f mnt  ; \
     36 		: reset error ; \
     37 	}"
     38 }
     39 
     40 # Used to declare the atf goop for a test expected to fail.
     41 test_case_xfail()
     42 {
     43 	local name="${1}"; shift
     44 	local reason="${1}"; shift
     45 	local check_function="${1}"; shift
     46 
     47 	atf_test_case "${name}" cleanup
     48 	eval "${name}_head() { \
     49 		atf_set "require.user" "root" ; \
     50 	}"
     51 	eval "${name}_body() { \
     52 		atf_expect_fail "${reason}" ; \
     53 		${check_function} " "${@}" "; \
     54 	}"
     55 	eval "${name}_cleanup() { \
     56 		umount -f mnt  ; \
     57 		: reset error ; \
     58 	}"
     59 }
     60 
     61 # copy_data requires the mount already done;  makes one copy of the test data
     62 copy_data ()
     63 {
     64 	uudecode -p ${TDBASE64} | (cd mnt; tar xzf - -s/testdata/TD$1/)
     65 }
     66 
     67 copy_multiple ()
     68 {
     69 	local i
     70 	for i in $(seq $1); do
     71 		copy_data $i
     72 	done
     73 }
     74 
     75 # remove_data removes one directory worth of test data; the purpose
     76 # is to ensure data exists near the end of the fs under test.
     77 remove_data ()
     78 {
     79 	rm -rf mnt/TD$1
     80 }
     81 
     82 remove_multiple ()
     83 {
     84 	local i
     85 	for i in $(seq $1); do
     86 		remove_data $i
     87 	done
     88 }
     89 
     90 # verify that the data in a particular directory is still OK
     91 # generated md5 file doesn't need explicit cleanup thanks to ATF
     92 check_data ()
     93 {
     94 	(cd mnt/TD$1 && md5 *) > TD$1.md5
     95 	atf_check diff -u ${GOODMD5} TD$1.md5
     96 }
     97 
     98 # supply begin and end arguments
     99 check_data_range ()
    100 {
    101 	local i
    102 	for i in $(seq $1 $2); do
    103 		check_data $i
    104 	done
    105 }
    106 
    107 
    108 resize_ffs()
    109 {
    110 	echo "in resize_ffs:" ${@}
    111 	local bs=$1
    112 	local fragsz=$2
    113 	local osize=$3
    114 	local nsize=$4
    115 	local fslevel=$5
    116 	local numdata=$6
    117 	local swap=$7
    118 	local avail=$( df -m . | awk '{if (int($4) > 0) print $4}' )
    119 	# convert MB size to blocks
    120 	avail=$(( $avail \* 2 \* 1024 ))
    121 	if [ $avail -lt $osize ] || [ $avail -lt $nsize ]; then
    122 		atf_skip "not enough free space in working directory"
    123 	fi
    124 	mkdir -p mnt
    125 	echo "bs is ${bs} numdata is ${numdata}"
    126 	echo "****resizing fs with blocksize ${bs}"
    127 
    128 	# we want no more than 16K/inode to allow test files to copy.
    129 	local fpi=$((fragsz * 4))
    130 	local i
    131 	if [ $fpi -gt 16384 ]; then
    132 		i="-i 16384"
    133 	fi
    134 	if [ x$swap != x ]; then
    135 		newfs -B ${BYTESWAP} -O${fslevel} -b ${bs} -f ${fragsz} \
    136 			-s ${osize} ${i} -F ${IMG}
    137 	else
    138 		newfs -O${fslevel} -b ${bs} -f ${fragsz} -s ${osize} ${i} \
    139 			-F ${IMG}
    140 	fi
    141 
    142 	# we're specifying relative paths, so rump_ffs warns - ignore.
    143 	if ! rump_ffs ${IMG} mnt >/dev/null 2>S.Err
    144 	then
    145 		if grep 'puffs_daemon: Operation not supported by device' S.Err >/dev/null
    146 		then
    147 			atf_skip 'No PUFFS available in kernel'
    148 		else
    149 			atf_fail "rump_ffs mount failed: $(tail -r S.Err |
    150 				sed -e '/^$/d' -e p -e q )"
    151 		fi
    152 	fi
    153 
    154 	copy_multiple ${numdata}
    155 
    156 	if [ ${nsize} -lt ${osize} ]; then
    157 	    # how much data to remove so fs can be shrunk
    158 	    local remove=$((numdata-numdata*nsize/osize))
    159 	    local dataleft=$((numdata-remove))
    160 	    echo remove is $remove dataleft is $dataleft
    161 	    remove_multiple ${remove}
    162 	fi
    163 
    164 	umount mnt
    165 	# Check that resize needed
    166 	atf_check -s exit:0 -o ignore resize_ffs -c -y -s ${nsize} ${IMG}
    167 	atf_check -s exit:0 -o ignore resize_ffs -y -s ${nsize} ${IMG}
    168 	atf_check -s exit:0 -o ignore fsck_ffs -f -n -F ${IMG}
    169 	atf_check -s exit:0 -e ignore rump_ffs ${IMG} mnt
    170 	if [ ${nsize} -lt ${osize} ]; then
    171 	    check_data_range $((remove + 1)) ${numdata}
    172 	else
    173 	    # checking everything because we don't delete on grow
    174 	    check_data_range 1 ${numdata}
    175 	fi
    176 	# Check that no resize needed
    177 	atf_check -s exit:1 -o ignore resize_ffs -c -y -s ${nsize} ${IMG}
    178 	umount mnt
    179 }
    180