• 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-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