• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:=4.2}
8NFILES=${NFILES:=1000}
9SOCKET_TYPE="${SOCKET_TYPE:-tcp}"
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	local nfs_opts
172
173	if [ "$(stat -f . | grep "Type: nfs")" ]; then
174		tst_brk TCONF "Cannot run nfs-stress test on mounted NFS"
175	fi
176
177	if tst_cmd_available pgrep; then
178		for i in rpc.mountd rpc.statd; do
179			pgrep $i > /dev/null || tst_brk TCONF "$i not running"
180		done
181	fi
182
183	tst_res TINFO "$(mount.nfs -V)"
184
185	for i in $VERSION; do
186		type=$(get_socket_type $n)
187		tst_res TINFO "setup NFSv$i, socket type $type"
188
189		if [ "$type" = "udp" -o "$type" = "udp6" ] && ! nfs_server_udp_enabled; then
190			tst_brk TCONF "UDP support disabled on NFS server"
191		fi
192
193		remote_dir="$(get_remote_dir $i $type)"
194		nfs_setup_server "$remote_dir" "$(($$ + n))"
195		local_dir="$(get_local_dir $i $n)"
196		nfs_opts="-o proto=$type,vers=$i"
197
198		if [ -n "$NFS_MOUNT_OPTS" ]; then
199			nfs_opts="$nfs_opts,$NFS_MOUNT_OPTS"
200		fi
201
202		tst_res TINFO "Mounting $local_dir"
203		nfs_mount "$local_dir" "$remote_dir" "$nfs_opts"
204
205		n=$(( n + 1 ))
206	done
207}
208
209nfs_cleanup()
210{
211	tst_res TINFO "Cleaning up testcase"
212	cd $LTPROOT
213
214	local i
215	local type
216	local local_dir
217	local remote_dir
218
219	local n=0
220	for i in $VERSION; do
221		local_dir="$(get_local_dir $i $n)"
222		if grep -q "$local_dir" /proc/mounts; then
223			tst_res TINFO "Unmounting $local_dir"
224			umount $local_dir || tst_res TWARN "Unmount failed"
225		fi
226		n=$(( n + 1 ))
227	done
228	sleep 2
229
230	n=0
231	for i in $VERSION; do
232		type=$(get_socket_type $n)
233		remote_dir="$(get_remote_dir $i $type)"
234
235		if tst_net_use_netns; then
236			if test -d $remote_dir; then
237				exportfs -u *:$remote_dir
238				sleep 1
239				rm -rf $remote_dir
240			fi
241		else
242			tst_rhost_run -c "test -d $remote_dir && exportfs -u *:$remote_dir"
243			sleep 1
244			tst_rhost_run -c "test -d $remote_dir && rm -rf $remote_dir"
245		fi
246
247		n=$(( n + 1 ))
248	done
249}
250
251. tst_net.sh
252