1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) Linux Test Project, 2016-2022 4# Copyright (c) 2015-2018 Oracle and/or its affiliates. All Rights Reserved. 5# Copyright (c) International Business Machines Corp., 2001 6 7VERSION=${VERSION:=3} 8NFILES=${NFILES:=1000} 9SOCKET_TYPE="${SOCKET_TYPE:-udp}" 10NFS_TYPE=${NFS_TYPE:=nfs} 11 12nfs_usage() 13{ 14 echo "-t x Socket type, tcp or udp, default is udp" 15 echo "-v x NFS version, default is '3'" 16} 17 18nfs_parse_args() 19{ 20 case "$1" in 21 v) VERSION="$(echo $2 | tr ',' ' ')";; 22 t) SOCKET_TYPE="$(echo $2 | tr ',' ' ')";; 23 *) [ "$NFS_PARSE_ARGS_CALLER" ] && $NFS_PARSE_ARGS_CALLER "$@";; 24 esac 25} 26 27NFS_PARSE_ARGS_CALLER="$TST_PARSE_ARGS" 28TST_OPTS="v:t:$TST_OPTS" 29TST_PARSE_ARGS=nfs_parse_args 30TST_USAGE=nfs_usage 31TST_NEEDS_TMPDIR=1 32TST_NEEDS_ROOT=1 33TST_NEEDS_CMDS="$TST_NEEDS_CMDS mount exportfs mount.nfs" 34TST_SETUP="${TST_SETUP:-nfs_setup}" 35TST_CLEANUP="${TST_CLEANUP:-nfs_cleanup}" 36TST_NEEDS_DRIVERS="nfsd" 37 38# When set and test is using netns ($TST_USE_NETNS set) NFS traffic will go 39# through lo interface instead of ltp_ns_veth* netns interfaces (useful for 40# debugging whether test failures are related to veth/netns). 41LTP_NFS_NETNS_USE_LO=${LTP_NFS_NETNS_USE_LO:-} 42 43get_socket_type() 44{ 45 local t 46 local k=0 47 for t in $SOCKET_TYPE; do 48 if [ "$k" -eq "$1" ]; then 49 echo "${t}${TST_IPV6}" 50 return 51 fi 52 k=$(( k + 1 )) 53 done 54} 55 56nfs_get_remote_path() 57{ 58 local v 59 local type=$(get_socket_type ${2:-0}) 60 61 for v in $VERSION; do 62 break; 63 done 64 65 v=${1:-$v} 66 echo "$TST_TMPDIR/$v/$type" 67} 68 69nfs_server_udp_enabled() 70{ 71 local config f 72 73 tst_rhost_run -c "[ -f /etc/nfs.conf ]" || return 0 74 config=$(tst_rhost_run -c 'for f in $(grep ^include.*= '/etc/nfs.conf' | cut -d = -f2); do [ -f $f ] && printf "$f "; done') 75 76 tst_rhost_run -c "grep -q \"^[# ]*udp *= *y\" /etc/nfs.conf $config" 77} 78 79nfs_setup_server() 80{ 81 82 local fsid="$1" 83 local export_cmd="exportfs -i -o fsid=$fsid,no_root_squash,rw *:$remote_dir" 84 85 [ -z "$fsid" ] && tst_brk TBROK "empty fsid" 86 87 if tst_net_use_netns; then 88 if ! test -d $remote_dir; then 89 mkdir -p $remote_dir; $export_cmd 90 fi 91 else 92 if ! tst_rhost_run -c "test -d $remote_dir"; then 93 tst_rhost_run -s -c "mkdir -p $remote_dir; $export_cmd" 94 fi 95 fi 96} 97 98nfs_mount() 99{ 100 local opts="$1" 101 local host_type=rhost 102 local mount_dir 103 104 tst_net_use_netns && host_type= 105 106 if [ $TST_IPV6 ]; then 107 mount_dir="[$(tst_ipaddr $host_type)]:$remote_dir" 108 else 109 mount_dir="$(tst_ipaddr $host_type):$remote_dir" 110 fi 111 112 local mnt_cmd="mount -v -t nfs $opts $mount_dir $local_dir" 113 114 tst_res TINFO "Mounting NFS: $mnt_cmd" 115 if tst_net_use_netns && [ -z "$LTP_NFS_NETNS_USE_LO" ]; then 116 tst_rhost_run -c "$mnt_cmd" > mount.log 117 else 118 $mnt_cmd > mount.log 119 fi 120 121 if [ $? -ne 0 ]; then 122 cat mount.log 123 124 if [ "$type" = "udp" -o "$type" = "udp6" ] && tst_kvcmp -ge 5.6; then 125 tst_brk TCONF "UDP support disabled with the kernel config NFS_DISABLE_UDP_SUPPORT?" 126 fi 127 128 if grep -iq "Protocol not supported" mount.log; then 129 tst_brk TCONF "Protocol not supported" 130 fi 131 132 tst_brk TBROK "mount command failed" 133 fi 134} 135 136nfs_setup() 137{ 138 local i 139 local type 140 local n=0 141 local local_dir 142 local remote_dir 143 local mount_dir 144 145 if [ "$(stat -f . | grep "Type: nfs")" ]; then 146 tst_brk TCONF "Cannot run nfs-stress test on mounted NFS" 147 fi 148 149 if tst_cmd_available pgrep; then 150 for i in rpc.mountd rpc.statd; do 151 pgrep $i > /dev/null || tst_brk TCONF "$i not running" 152 done 153 fi 154 155 tst_res TINFO "$(mount.nfs -V)" 156 157 for i in $VERSION; do 158 type=$(get_socket_type $n) 159 tst_res TINFO "setup NFSv$i, socket type $type" 160 161 if [ "$type" = "udp" -o "$type" = "udp6" ] && ! nfs_server_udp_enabled; then 162 tst_brk TCONF "UDP support disabled on NFS server" 163 fi 164 165 local_dir="$TST_TMPDIR/$i/$n" 166 remote_dir="$TST_TMPDIR/$i/$type" 167 mkdir -p $local_dir 168 169 nfs_setup_server $(($$ + n)) 170 171 nfs_mount "-o proto=$type,vers=$i" 172 173 n=$(( n + 1 )) 174 done 175 176 if [ "$n" -eq 1 ]; then 177 cd ${VERSION}/0 178 fi 179} 180 181nfs_cleanup() 182{ 183 tst_res TINFO "Cleaning up testcase" 184 cd $LTPROOT 185 186 local i 187 local type 188 local local_dir 189 local remote_dir 190 191 local n=0 192 for i in $VERSION; do 193 local_dir="$TST_TMPDIR/$i/$n" 194 grep -q "$local_dir" /proc/mounts && umount $local_dir 195 n=$(( n + 1 )) 196 done 197 198 n=0 199 for i in $VERSION; do 200 type=$(get_socket_type $n) 201 remote_dir="$TST_TMPDIR/$i/$type" 202 tst_rhost_run -c "test -d $remote_dir && exportfs -u *:$remote_dir" 203 tst_rhost_run -c "test -d $remote_dir && rm -rf $remote_dir" 204 n=$(( n + 1 )) 205 done 206} 207 208. tst_net.sh 209