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