1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) Linux Test Project, 2016-2023 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_ALL_FILESYSTEMS=1 32TST_SKIP_FILESYSTEMS="exfat,ext2,ext3,fuse,ntfs,vfat,tmpfs" 33TST_MOUNT_DEVICE=1 34TST_FORMAT_DEVICE=1 35TST_NEEDS_ROOT=1 36TST_NEEDS_CMDS="$TST_NEEDS_CMDS mount exportfs mount.nfs" 37TST_SETUP="${TST_SETUP:-nfs_setup}" 38TST_CLEANUP="${TST_CLEANUP:-nfs_cleanup}" 39TST_NEEDS_DRIVERS="nfsd" 40 41# When set and test is using netns ($TST_USE_NETNS set) NFS traffic will go 42# through lo interface instead of ltp_ns_veth* netns interfaces (useful for 43# debugging whether test failures are related to veth/netns). 44LTP_NFS_NETNS_USE_LO=${LTP_NFS_NETNS_USE_LO:-} 45 46get_socket_type() 47{ 48 local t 49 local k=0 50 for t in $SOCKET_TYPE; do 51 if [ "$k" -eq "$1" ]; then 52 echo "${t}${TST_IPV6}" 53 return 54 fi 55 k=$(( k + 1 )) 56 done 57} 58 59# directory mounted by NFS client 60get_local_dir() 61{ 62 local v="$1" 63 local n="$2" 64 65 echo "$TST_TMPDIR/$v/$n" 66} 67 68# directory on NFS server 69get_remote_dir() 70{ 71 local v="$1" 72 local n="$2" 73 74 echo "$TST_MNTPOINT/$v/$n" 75} 76 77nfs_get_remote_path() 78{ 79 local v 80 local type=$(get_socket_type ${2:-0}) 81 82 for v in $VERSION; do 83 break; 84 done 85 86 v=${1:-$v} 87 echo "$(get_remote_dir $v $type)" 88} 89 90nfs_server_udp_enabled() 91{ 92 local config f 93 94 tst_rhost_run -c "[ -f /etc/nfs.conf ]" || return 0 95 config=$(tst_rhost_run -c 'for f in $(grep ^include.*= '/etc/nfs.conf' | cut -d = -f2); do [ -f $f ] && printf "$f "; done') 96 97 tst_rhost_run -c "grep -q \"^[# ]*udp *= *y\" /etc/nfs.conf $config" 98} 99 100nfs_setup_server() 101{ 102 local remote_dir="$1" 103 local fsid="$2" 104 local export_cmd="exportfs -i -o fsid=$fsid,no_root_squash,rw *:$remote_dir" 105 106 [ -z "$fsid" ] && tst_brk TBROK "empty fsid" 107 108 if tst_net_use_netns; then 109 if ! test -d $remote_dir; then 110 mkdir -p $remote_dir; $export_cmd 111 fi 112 else 113 if ! tst_rhost_run -c "test -d $remote_dir"; then 114 tst_rhost_run -s -c "mkdir -p $remote_dir; $export_cmd" 115 fi 116 fi 117} 118 119nfs_mount() 120{ 121 local local_dir="$1" 122 local remote_dir="$2" 123 local opts="$3" 124 local host_type=rhost 125 local mount_dir 126 127 mkdir -p "$local_dir" 128 129 tst_net_use_netns && host_type= 130 131 if [ $TST_IPV6 ]; then 132 mount_dir="[$(tst_ipaddr $host_type)]:$remote_dir" 133 else 134 mount_dir="$(tst_ipaddr $host_type):$remote_dir" 135 fi 136 137 local mnt_cmd="mount -v -t nfs $opts $mount_dir $local_dir" 138 139 tst_res TINFO "Mounting NFS: $mnt_cmd" 140 if tst_net_use_netns && [ -z "$LTP_NFS_NETNS_USE_LO" ]; then 141 tst_rhost_run -c "$mnt_cmd" > mount.log 142 else 143 $mnt_cmd > mount.log 144 fi 145 146 if [ $? -ne 0 ]; then 147 cat mount.log 148 149 if [ "$type" = "udp" -o "$type" = "udp6" ] && tst_kvcmp -ge 5.6; then 150 tst_brk TCONF "UDP support disabled with the kernel config NFS_DISABLE_UDP_SUPPORT?" 151 fi 152 153 if grep -iq "Protocol not supported" mount.log; then 154 tst_brk TCONF "Protocol not supported" 155 fi 156 157 tst_brk TBROK "mount command failed" 158 fi 159 160 cd "$local_dir" 161} 162 163nfs_setup() 164{ 165 local i 166 local type 167 local n=0 168 local local_dir 169 local remote_dir 170 local mount_dir 171 172 if [ "$(stat -f . | grep "Type: nfs")" ]; then 173 tst_brk TCONF "Cannot run nfs-stress test on mounted NFS" 174 fi 175 176 if tst_cmd_available pgrep; then 177 for i in rpc.mountd rpc.statd; do 178 pgrep $i > /dev/null || tst_brk TCONF "$i not running" 179 done 180 fi 181 182 tst_res TINFO "$(mount.nfs -V)" 183 184 for i in $VERSION; do 185 type=$(get_socket_type $n) 186 tst_res TINFO "setup NFSv$i, socket type $type" 187 188 if [ "$type" = "udp" -o "$type" = "udp6" ] && ! nfs_server_udp_enabled; then 189 tst_brk TCONF "UDP support disabled on NFS server" 190 fi 191 192 remote_dir="$(get_remote_dir $i $type)" 193 nfs_setup_server "$remote_dir" "$(($$ + n))" 194 local_dir="$(get_local_dir $i $n)" 195 tst_res TINFO "Mounting $local_dir" 196 nfs_mount "$local_dir" "$remote_dir" "-o proto=$type,vers=$i" 197 198 n=$(( n + 1 )) 199 done 200} 201 202nfs_cleanup() 203{ 204 tst_res TINFO "Cleaning up testcase" 205 cd $LTPROOT 206 207 local i 208 local type 209 local local_dir 210 local remote_dir 211 212 local n=0 213 for i in $VERSION; do 214 local_dir="$(get_local_dir $i $n)" 215 if grep -q "$local_dir" /proc/mounts; then 216 tst_res TINFO "Unmounting $local_dir" 217 umount $local_dir 218 fi 219 n=$(( n + 1 )) 220 done 221 sleep 2 222 223 n=0 224 for i in $VERSION; do 225 type=$(get_socket_type $n) 226 remote_dir="$(get_remote_dir $i $type)" 227 228 if tst_net_use_netns; then 229 if test -d $remote_dir; then 230 exportfs -u *:$remote_dir 231 sleep 1 232 rm -rf $remote_dir 233 fi 234 else 235 tst_rhost_run -c "test -d $remote_dir && exportfs -u *:$remote_dir" 236 sleep 1 237 tst_rhost_run -c "test -d $remote_dir && rm -rf $remote_dir" 238 fi 239 240 n=$(( n + 1 )) 241 done 242} 243 244. tst_net.sh 245