1# SPDX-License-Identifier: BSD-2-Clause 2# 3# Copyright (c) 2024 Axcient 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26# Not tested 27# * modes other than "Data" and "Desc". We don't support those. 28# * Buffer ID other than 0. We don't support those. 29# * The Mode Specific field. We don't support it. 30 31load_modules() { 32 if ! kldstat -q -m ctl; then 33 kldload ctl || atf_skip "could not load ctl kernel mod" 34 fi 35 if ! ctladm port -o on -p 0; then 36 atf_skip "could not enable the camsim frontend" 37 fi 38} 39 40find_da_device() { 41 SERIAL=$1 42 43 # Rescan camsim 44 # XXX camsim doesn't update when creating a new device. Worse, a 45 # rescan won't look for new devices. So we must disable/re-enable it. 46 # Worse still, enabling it isn't synchronous, so we need a retry loop 47 # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=281000 48 retries=5 49 ctladm port -o off -p 0 >/dev/null 50 ctladm port -o on -p 0 >/dev/null 51 while true; do 52 53 # Find the corresponding da device 54 da=`geom disk list | awk -v serial=$SERIAL ' /Geom name:/ { devname=$NF } /ident:/ && $NF ~ serial { print devname; exit } '` 55 if [ -z "$da" ]; then 56 retries=$(( $retries - 1 )) 57 if [ $retries -eq 0 ]; then 58 cat lun-create.txt 59 geom disk list 60 atf_fail "Could not find da device" 61 fi 62 sleep 0.1 63 continue 64 fi 65 break 66 done 67} 68 69# Create a CTL LUN 70create_ramdisk() { 71 atf_check -o save:lun-create.txt ctladm create -b ramdisk -s 1048576 72 atf_check egrep -q "LUN created successfully" lun-create.txt 73 SERIAL=`awk '/Serial Number:/ {print $NF}' lun-create.txt` 74 if [ -z "$SERIAL" ]; then 75 atf_fail "Could not find serial number" 76 fi 77 find_da_device $SERIAL 78} 79 80cleanup() { 81 if [ -e "lun-create.txt" ]; then 82 lun_id=`awk '/LUN ID:/ {print $NF}' lun-create.txt` 83 ctladm remove -b ramdisk -l $lun_id > /dev/null 84 fi 85} 86 87atf_test_case basic cleanup 88basic_head() 89{ 90 atf_set "descr" "READ BUFFER can retrieve data previously written by WRITE BUFFER" 91 atf_set "require.user" "root" 92 atf_set "require.progs" sg_read_buffer sg_write_buffer 93} 94basic_body() 95{ 96 create_ramdisk 97 98 # Write to its buffer 99 cp /etc/passwd input 100 len=`wc -c input | cut -wf 2` 101 atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$da 102 103 # Read it back 104 atf_check -o save:output sg_read_buffer --mode data -l $len --raw /dev/$da 105 106 # And verify 107 if ! diff -q input output; then 108 atf_fail "Miscompare!" 109 fi 110} 111basic_cleanup() 112{ 113 cleanup 114} 115 116# Read from the Descriptor mode. Along with Data, these are the only two modes 117# we support. 118atf_test_case desc cleanup 119desc_head() 120{ 121 atf_set "descr" "READ BUFFER can retrieve the buffer size via the DESCRIPTOR mode" 122 atf_set "require.user" "root" 123 atf_set "require.progs" sg_read_buffer 124} 125desc_body() 126{ 127 create_ramdisk 128 129 atf_check -o inline:" 00 00 04 00 00\n" sg_read_buffer --hex --mode desc /dev/$da 130} 131desc_cleanup() 132{ 133 cleanup 134} 135 136atf_test_case length cleanup 137length_head() 138{ 139 atf_set "descr" "READ BUFFER can limit its length with the LENGTH field" 140 atf_set "require.user" "root" 141 atf_set "require.progs" sg_read_buffer sg_write_buffer 142} 143length_body() 144{ 145 create_ramdisk 146 147 # Write to its buffer 148 atf_check -o ignore -e ignore dd if=/dev/random of=input bs=4096 count=1 149 atf_check -o ignore -e ignore dd if=input bs=2048 count=1 of=expected 150 atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$da 151 152 # Read it back 153 atf_check -o save:output sg_read_buffer --mode data -l 2048 --raw /dev/$da 154 155 # And verify 156 if ! diff -q expected output; then 157 atf_fail "Miscompare!" 158 fi 159} 160length_cleanup() 161{ 162 cleanup 163} 164 165atf_test_case offset cleanup 166offset_head() 167{ 168 atf_set "descr" "READ BUFFER accepts the BUFFER OFFSET field" 169 atf_set "require.user" "root" 170 atf_set "require.progs" sg_read_buffer sg_write_buffer 171} 172offset_body() 173{ 174 create_ramdisk 175 176 # Write to its buffer 177 atf_check -o ignore -e ignore dd if=/dev/random of=input bs=4096 count=1 178 atf_check -o ignore -e ignore dd if=input iseek=2 bs=512 count=1 of=expected 179 atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$da 180 181 # Read it back 182 atf_check -o save:output sg_read_buffer --mode data -l 512 -o 1024 --raw /dev/$da 183 184 # And verify 185 if ! diff -q expected output; then 186 atf_fail "Miscompare!" 187 fi 188} 189offset_cleanup() 190{ 191 cleanup 192} 193 194atf_test_case uninitialized cleanup 195uninitialized_head() 196{ 197 atf_set "descr" "READ BUFFER buffers are zero-initialized" 198 atf_set "require.user" "root" 199 atf_set "require.progs" sg_read_buffer 200} 201uninitialized_body() 202{ 203 create_ramdisk 204 205 # Read an uninitialized buffer 206 atf_check -o save:output sg_read_buffer --mode data -l 262144 --raw /dev/$da 207 208 # And verify 209 atf_check -o ignore -e ignore dd if=/dev/zero bs=262144 count=1 of=expected 210 if ! diff -q expected output; then 211 atf_fail "Miscompare!" 212 fi 213} 214uninitialized_cleanup() 215{ 216 cleanup 217} 218 219atf_init_test_cases() 220{ 221 atf_add_test_case basic 222 atf_add_test_case desc 223 atf_add_test_case length 224 atf_add_test_case offset 225 atf_add_test_case uninitialized 226} 227