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