14d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause 23b41d99dSChuck Silvers# 33b41d99dSChuck Silvers# Copyright (c) 2020 Netflix, Inc. 43b41d99dSChuck Silvers# 53b41d99dSChuck Silvers# Redistribution and use in source and binary forms, with or without 63b41d99dSChuck Silvers# modification, are permitted provided that the following conditions 73b41d99dSChuck Silvers# are met: 83b41d99dSChuck Silvers# 1. Redistributions of source code must retain the above copyright 93b41d99dSChuck Silvers# notice, this list of conditions and the following disclaimer. 103b41d99dSChuck Silvers# 2. Redistributions in binary form must reproduce the above copyright 113b41d99dSChuck Silvers# notice, this list of conditions and the following disclaimer in the 123b41d99dSChuck Silvers# documentation and/or other materials provided with the distribution. 133b41d99dSChuck Silvers# 143b41d99dSChuck Silvers# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 153b41d99dSChuck Silvers# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 163b41d99dSChuck Silvers# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 173b41d99dSChuck Silvers# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 183b41d99dSChuck Silvers# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 193b41d99dSChuck Silvers# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 203b41d99dSChuck Silvers# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 213b41d99dSChuck Silvers# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 223b41d99dSChuck Silvers# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 233b41d99dSChuck Silvers# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 243b41d99dSChuck Silvers# SUCH DAMAGE. 253b41d99dSChuck Silvers# 263b41d99dSChuck Silvers 273b41d99dSChuck Silvers# 283b41d99dSChuck Silvers# These tests exercise a few basic cases for the sendfile() syscall: 293b41d99dSChuck Silvers# - successful operation. 303b41d99dSChuck Silvers# - sendfile() starts an async disk read but that async I/O fails. 313b41d99dSChuck Silvers# - sendfile() fails to read an indirect block and thus cannot 323b41d99dSChuck Silvers# even start an async I/O. 333b41d99dSChuck Silvers# 343b41d99dSChuck Silvers# In all cases we request some read ahead in addition to 353b41d99dSChuck Silvers# the data to be sent to the socket. 363b41d99dSChuck Silvers# 373b41d99dSChuck Silvers 383b41d99dSChuck SilversMD_DEVS="md.devs" 39683853a9SMark JohnstonMNT=mnt 403b41d99dSChuck SilversFILE=$MNT/file 413b41d99dSChuck SilversHELPER="$(atf_get_srcdir)/sendfile_helper" 423b41d99dSChuck SilversBSIZE=4096 433b41d99dSChuck Silvers 443b41d99dSChuck Silversatf_test_case io_success cleanup 453b41d99dSChuck Silversio_success_head() 463b41d99dSChuck Silvers{ 473b41d99dSChuck Silvers atf_set "descr" "sendfile where all disk I/O succeeds" 483b41d99dSChuck Silvers atf_set "require.user" "root" 493b41d99dSChuck Silvers atf_set "timeout" 15 503b41d99dSChuck Silvers} 513b41d99dSChuck Silversio_success_body() 523b41d99dSChuck Silvers{ 53356deeb2SWarner Losh if [ "$(atf_config_get qemu false)" = "true" ]; then 54356deeb2SWarner Losh atf_skip "Sendfile(4) unimplemented. https://github.com/qemu-bsd-user/qemu-bsd-user/issues/25" 55356deeb2SWarner Losh fi 56356deeb2SWarner Losh 5796950419SGleb Smirnoff alloc_md md 583b41d99dSChuck Silvers common_body_setup $md 593b41d99dSChuck Silvers 603b41d99dSChuck Silvers atf_check $HELPER $FILE 0 0x10000 0x10000 613b41d99dSChuck Silvers} 623b41d99dSChuck Silversio_success_cleanup() 633b41d99dSChuck Silvers{ 643b41d99dSChuck Silvers common_cleanup 653b41d99dSChuck Silvers} 663b41d99dSChuck Silvers 673b41d99dSChuck Silversatf_test_case io_fail_sync cleanup 683b41d99dSChuck Silversio_fail_sync_head() 693b41d99dSChuck Silvers{ 703b41d99dSChuck Silvers atf_set "descr" "sendfile where we fail to start async I/O" 713b41d99dSChuck Silvers atf_set "require.user" "root" 723b41d99dSChuck Silvers atf_set "timeout" 15 733b41d99dSChuck Silvers} 743b41d99dSChuck Silversio_fail_sync_body() 753b41d99dSChuck Silvers{ 76356deeb2SWarner Losh if [ "$(atf_config_get qemu false)" = "true" ]; then 77356deeb2SWarner Losh atf_skip "Sendfile(4) unimplemented. https://github.com/qemu-bsd-user/qemu-bsd-user/issues/25" 78356deeb2SWarner Losh fi 79356deeb2SWarner Losh 8096950419SGleb Smirnoff alloc_md md 813b41d99dSChuck Silvers common_body_setup $md 823b41d99dSChuck Silvers 833b41d99dSChuck Silvers atf_check gnop configure -r 100 -e 5 ${md}.nop 843b41d99dSChuck Silvers atf_check -s exit:3 -e ignore $HELPER $FILE $((12 * $BSIZE)) $BSIZE 0x10000 853b41d99dSChuck Silvers} 863b41d99dSChuck Silversio_fail_sync_cleanup() 873b41d99dSChuck Silvers{ 883b41d99dSChuck Silvers common_cleanup 893b41d99dSChuck Silvers} 903b41d99dSChuck Silvers 913b41d99dSChuck Silversatf_test_case io_fail_async cleanup 923b41d99dSChuck Silversio_fail_async_head() 933b41d99dSChuck Silvers{ 943b41d99dSChuck Silvers atf_set "descr" "sendfile where an async I/O fails" 953b41d99dSChuck Silvers atf_set "require.user" "root" 963b41d99dSChuck Silvers atf_set "timeout" 15 973b41d99dSChuck Silvers} 983b41d99dSChuck Silversio_fail_async_body() 993b41d99dSChuck Silvers{ 100356deeb2SWarner Losh if [ "$(atf_config_get qemu false)" = "true" ]; then 101356deeb2SWarner Losh atf_skip "Sendfile(4) unimplemented. https://github.com/qemu-bsd-user/qemu-bsd-user/issues/25" 102356deeb2SWarner Losh fi 103356deeb2SWarner Losh 10496950419SGleb Smirnoff alloc_md md 1053b41d99dSChuck Silvers common_body_setup $md 1063b41d99dSChuck Silvers 1073b41d99dSChuck Silvers atf_check gnop configure -r 100 -e 5 ${md}.nop 1083b41d99dSChuck Silvers atf_check -s exit:2 -e ignore $HELPER $FILE 0 $BSIZE 0x10000 1093b41d99dSChuck Silvers} 1103b41d99dSChuck Silversio_fail_async_cleanup() 1113b41d99dSChuck Silvers{ 1123b41d99dSChuck Silvers common_cleanup 1133b41d99dSChuck Silvers} 1143b41d99dSChuck Silvers 115*0c0146c3SGleb Smirnoffatf_test_case unix_success cleanup 116*0c0146c3SGleb Smirnoffunix_success_head() 117*0c0146c3SGleb Smirnoff{ 118*0c0146c3SGleb Smirnoff atf_set "descr" "sendfile via unix(4) where all disk I/O succeeds" 119*0c0146c3SGleb Smirnoff atf_set "require.user" "root" 120*0c0146c3SGleb Smirnoff atf_set "timeout" 15 121*0c0146c3SGleb Smirnoff} 122*0c0146c3SGleb Smirnoffunix_success_body() 123*0c0146c3SGleb Smirnoff{ 124*0c0146c3SGleb Smirnoff if [ "$(atf_config_get qemu false)" = "true" ]; then 125*0c0146c3SGleb Smirnoff atf_skip "Sendfile(4) unimplemented. https://github.com/qemu-bsd-user/qemu-bsd-user/issues/25" 126*0c0146c3SGleb Smirnoff fi 127*0c0146c3SGleb Smirnoff 128*0c0146c3SGleb Smirnoff alloc_md md 129*0c0146c3SGleb Smirnoff common_body_setup $md 130*0c0146c3SGleb Smirnoff 131*0c0146c3SGleb Smirnoff atf_check $HELPER -u $FILE 0 0x10000 0x10000 132*0c0146c3SGleb Smirnoff} 133*0c0146c3SGleb Smirnoffunix_success_cleanup() 134*0c0146c3SGleb Smirnoff{ 135*0c0146c3SGleb Smirnoff common_cleanup 136*0c0146c3SGleb Smirnoff} 137*0c0146c3SGleb Smirnoff 1383b41d99dSChuck Silvers 1393b41d99dSChuck Silversatf_init_test_cases() 1403b41d99dSChuck Silvers{ 1413b41d99dSChuck Silvers atf_add_test_case io_success 1423b41d99dSChuck Silvers atf_add_test_case io_fail_sync 1433b41d99dSChuck Silvers atf_add_test_case io_fail_async 144*0c0146c3SGleb Smirnoff atf_add_test_case unix_success 1453b41d99dSChuck Silvers} 1463b41d99dSChuck Silvers 1473b41d99dSChuck Silversalloc_md() 1483b41d99dSChuck Silvers{ 14996950419SGleb Smirnoff local _md 1503b41d99dSChuck Silvers 151ea823622SWarner Losh [ -c /dev/mdctl ] || atf_skip "no /dev/mdctl to create md devices" 15296950419SGleb Smirnoff _md=$(mdconfig -a -t swap -s 256M) || atf_fail "mdconfig -a failed" 15396950419SGleb Smirnoff echo ${_md} >> $MD_DEVS 15496950419SGleb Smirnoff eval "${1}='${_md}'" 1553b41d99dSChuck Silvers} 1563b41d99dSChuck Silvers 1573b41d99dSChuck Silverscommon_body_setup() 1583b41d99dSChuck Silvers{ 1593b41d99dSChuck Silvers us=$1 1603b41d99dSChuck Silvers 161683853a9SMark Johnston atf_check mkdir $MNT 1623b41d99dSChuck Silvers atf_check -o ignore -e ignore newfs -b $BSIZE -U -j /dev/${us} 1633b41d99dSChuck Silvers atf_check mount /dev/${us} $MNT 1643b41d99dSChuck Silvers atf_check -e ignore dd if=/dev/zero of=$FILE bs=1m count=1 165683853a9SMark Johnston atf_check umount $MNT 1663b41d99dSChuck Silvers 1673b41d99dSChuck Silvers load_gnop 1683b41d99dSChuck Silvers atf_check gnop create /dev/${us} 1693b41d99dSChuck Silvers atf_check mount /dev/${us}.nop $MNT 1703b41d99dSChuck Silvers atf_check -o ignore ls -l $MNT/file 1713b41d99dSChuck Silvers} 1723b41d99dSChuck Silvers 1733b41d99dSChuck Silverscommon_cleanup() 1743b41d99dSChuck Silvers{ 1753b41d99dSChuck Silvers umount -f $MNT 1763b41d99dSChuck Silvers if [ -f "$MD_DEVS" ]; then 1773b41d99dSChuck Silvers while read test_md; do 1783b41d99dSChuck Silvers gnop destroy -f ${test_md}.nop 2>/dev/null 1793b41d99dSChuck Silvers mdconfig -d -u $test_md 2>/dev/null 1803b41d99dSChuck Silvers done < $MD_DEVS 1813b41d99dSChuck Silvers rm $MD_DEVS 1823b41d99dSChuck Silvers fi 1833b41d99dSChuck Silvers 1843b41d99dSChuck Silvers true 1853b41d99dSChuck Silvers} 1863b41d99dSChuck Silvers 1873b41d99dSChuck Silversload_gnop() 1883b41d99dSChuck Silvers{ 1893b41d99dSChuck Silvers if ! kldstat -q -m g_nop; then 1903b41d99dSChuck Silvers geom nop load || atf_skip "could not load module for geom nop" 1913b41d99dSChuck Silvers fi 1923b41d99dSChuck Silvers} 193