1# $FreeBSD$ 2 3atf_test_case run_latest_genid cleanup 4run_latest_genid_head() 5{ 6 atf_set "descr" \ 7 "Ensure that we properly select components (latest genid) during STARTING." 8 atf_set "require.user" "root" 9} 10run_latest_genid_body() 11{ 12 . $(atf_get_srcdir)/conf.sh 13 14 f1=$(mktemp ${base}.XXXXXX) 15 f2=$(mktemp ${base}.XXXXXX) 16 f3=$(mktemp ${base}.XXXXXX) 17 rnd1=$(mktemp ${base}.XXXXXX) 18 rnd2=$(mktemp ${base}.XXXXXX) 19 20 atf_check truncate -s 2M $f1 21 atf_check truncate -s 2M $f2 22 atf_check truncate -s 2M $f3 23 dd if=/dev/urandom bs=512 count=1 of="$rnd1" 24 dd if=/dev/urandom bs=512 count=1 of="$rnd2" 25 26 md1=$(attach_md -t vnode -f ${f1}) 27 md2=$(attach_md -t vnode -f ${f2}) 28 md3=$(attach_md -t vnode -f ${f3}) 29 30 # Use a gnop for md1 just for consistency; it's not used for anything. 31 atf_check gnop create $md1 32 atf_check gnop create $md2 33 atf_check gnop create $md3 34 # Hardcode component names so that the non-.nop device isn't tasted 35 # instead. 36 atf_check gmirror label -h $name ${md1}.nop 37 devwait 38 39 atf_check gmirror insert -h $name ${md2}.nop 40 atf_check gmirror insert -h $name ${md3}.nop 41 syncwait 42 43 # Fail mirror 3, writing known contents to mirror 1+2 block 1 44 atf_check -s exit:0 -e empty -o empty \ 45 gnop configure -w 100 ${md3}.nop 46 atf_check -s exit:0 dd if="$rnd1" bs=512 count=1 oseek=1 conv=notrunc \ 47 of=/dev/mirror/$name status=none 48 49 disconnectwait nop "${md3}.nop" 50 51 # Should have two mirrors remaining after md3 was evicted 52 atf_check [ $(gmirror status -s $name | wc -l) -eq 2 ] 53 atf_check -s exit:0 -o match:"DEGRADED ${md1}.nop \(ACTIVE\)" \ 54 gmirror status -s $name 55 atf_check -s exit:0 -o match:"DEGRADED ${md2}.nop \(ACTIVE\)" \ 56 gmirror status -s $name 57 58 # Repeat: 59 # Fail mirror 2, writing known contents to mirror 1 block 2 60 atf_check -s exit:0 -e empty -o empty \ 61 gnop configure -w 100 ${md2}.nop 62 atf_check -s exit:0 dd if="$rnd2" bs=512 count=2 oseek=1 conv=notrunc \ 63 of=/dev/mirror/$name status=none 64 65 disconnectwait nop "${md2}.nop" 66 67 # Should have one mirror remaining after md2 was evicted 68 atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ] 69 atf_check -s exit:0 -o match:"DEGRADED ${md1}.nop \(ACTIVE\)" \ 70 gmirror status -s $name 71 72 # Stop the mirror and remove the pieces so gmirror can't see them. 73 atf_check gmirror stop $name 74 atf_check gnop destroy ${md1}.nop 75 atf_check gnop destroy ${md2}.nop 76 atf_check gnop destroy ${md3}.nop 77 78 # Rebuild; spin up "disk" with lowest genid 79 atf_check gnop create $md3 80 md3gen=$(gmirror dump /dev/${md3}.nop | grep genid | cut -d: -f2) 81 # Assert gmirror is referencing this component for now: 82 atf_check [ $(consumerrefs nop ${md3}.nop) = "r1w1e1" ] 83 84 # Adding newer genid should kick out old component 85 atf_check gnop create $md2 86 md2gen=$(gmirror dump /dev/${md2}.nop | grep genid | cut -d: -f2) 87 atf_check [ $md2gen -gt $md3gen ] 88 89 disconnectwait nop "${md3}.nop" 90 91 # Can't test this because 'status' doesn't exist until RUNNING: 92 #atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ] 93 # But as a substitute, assert gmirror has dropped reference to staler 94 # component in favor of newer component: 95 atf_check [ $(consumerrefs nop ${md2}.nop) = "r1w1e1" ] 96 97 # ditto 98 atf_check gnop create $md1 99 md1gen=$(gmirror dump /dev/${md1}.nop | grep genid | cut -d: -f2) 100 atf_check [ $md1gen -gt $md2gen ] 101 102 disconnectwait nop "${md2}.nop" 103 104 # Assert gmirror has dropped reference to stale component in favor of 105 # newer component: 106 atf_check [ $(consumerrefs nop ${md1}.nop) = "r1w1e1" ] 107 108 # gmirror won't start the mirror automatically with only one component 109 # ($md0) of configured three, so this waits out the 110 # kern.geom.mirror.timeout: 111 devwait 112 113 atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ] 114 atf_check -s exit:0 -o match:"DEGRADED ${md1}.nop \(ACTIVE\)" \ 115 gmirror status -s $name 116} 117run_latest_genid_cleanup() 118{ 119 . $(atf_get_srcdir)/conf.sh 120 121 if [ -f "$TEST_MDS_FILE" ]; then 122 while read test_md; do 123 echo "# Removing test gnop: ${test_md}.nop" 124 gnop destroy -f "${test_md}.nop" 2>/dev/null || : 125 done < "$TEST_MDS_FILE" 126 fi 127 gmirror_test_cleanup 128} 129 130atf_init_test_cases() 131{ 132 atf_add_test_case run_latest_genid 133} 134