xref: /illumos-gate/usr/src/cmd/fs.d/nfs/svc/nfs-server (revision eb1a34638eba7c5add1421327f3eb225a8ea7518)
17c478bd9Sstevel@tonic-gate#!/sbin/sh
27c478bd9Sstevel@tonic-gate#
37c478bd9Sstevel@tonic-gate# CDDL HEADER START
47c478bd9Sstevel@tonic-gate#
57c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the
66927f468Sdp# Common Development and Distribution License (the "License").
76927f468Sdp# You may not use this file except in compliance with the License.
87c478bd9Sstevel@tonic-gate#
97c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate# and limitations under the License.
137c478bd9Sstevel@tonic-gate#
147c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate#
207c478bd9Sstevel@tonic-gate# CDDL HEADER END
217c478bd9Sstevel@tonic-gate#
227c478bd9Sstevel@tonic-gate#
23*eb1a3463STruong Nguyen# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate# Use is subject to license terms.
257c478bd9Sstevel@tonic-gate#
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate# Start/stop processes required for server NFS
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate. /lib/svc/share/smf_include.sh
30*eb1a3463STruong Nguyen. /lib/svc/share/ipf_include.sh
316927f468Sdpzone=`smf_zonename`
327c478bd9Sstevel@tonic-gate
33*eb1a3463STruong Nguyen#
34*eb1a3463STruong Nguyen# Handling a corner case here. If we were in offline state due to an
35*eb1a3463STruong Nguyen# unsatisfied dependency, the ipf_method process wouldn't have generated
36*eb1a3463STruong Nguyen# the ipfilter configuration. When we transition to online because the
37*eb1a3463STruong Nguyen# dependency is satisfied, the start method will have to generate the
38*eb1a3463STruong Nguyen# ipfilter configuration. To avoid all possible deadlock scenarios,
39*eb1a3463STruong Nguyen# we restart ipfilter which will regenerate the ipfilter configuration
40*eb1a3463STruong Nguyen# for the entire system.
41*eb1a3463STruong Nguyen#
42*eb1a3463STruong Nguyen# The ipf_method process signals that it didn't generate ipf rules by
43*eb1a3463STruong Nguyen# removing the service's ipf file. Thus we only restart network/ipfilter
44*eb1a3463STruong Nguyen# when the file is missing.
45*eb1a3463STruong Nguyen#
46*eb1a3463STruong Nguyenconfigure_ipfilter()
47*eb1a3463STruong Nguyen{
48*eb1a3463STruong Nguyen	ipfile=`fmri_to_file $SMF_FMRI $IPF_SUFFIX`
49*eb1a3463STruong Nguyen	[ -f "$ipfile" ] && return 0
50*eb1a3463STruong Nguyen
51*eb1a3463STruong Nguyen        #
52*eb1a3463STruong Nguyen	# Nothing to do if:
53*eb1a3463STruong Nguyen        # - ipfilter isn't online
54*eb1a3463STruong Nguyen	# - global policy is 'custom'
55*eb1a3463STruong Nguyen	# - service's policy is 'use_global'
56*eb1a3463STruong Nguyen        #
57*eb1a3463STruong Nguyen        service_check_state $IPF_FMRI $SMF_ONLINE || return 0
58*eb1a3463STruong Nguyen        [ "`get_global_def_policy`" = "custom" ] && return 0
59*eb1a3463STruong Nguyen	[ "`get_policy $SMF_FMRI`" = "use_global" ] && return 0
60*eb1a3463STruong Nguyen
61*eb1a3463STruong Nguyen	svcadm restart $IPF_FMRI
62*eb1a3463STruong Nguyen}
63*eb1a3463STruong Nguyen
647c478bd9Sstevel@tonic-gatecase "$1" in
657c478bd9Sstevel@tonic-gate'start')
667c478bd9Sstevel@tonic-gate	# The NFS server is not supported in a local zone
676927f468Sdp	if smf_is_nonglobalzone; then
683fd3a04aSthurlow		/usr/sbin/svcadm disable -t svc:/network/nfs/server
697c478bd9Sstevel@tonic-gate		echo "The NFS server is not supported in a local zone"
707c478bd9Sstevel@tonic-gate		sleep 5 &
717c478bd9Sstevel@tonic-gate		exit $SMF_EXIT_OK
727c478bd9Sstevel@tonic-gate	fi
737c478bd9Sstevel@tonic-gate
746185db85Sdougm	# Share all file systems enabled for sharing. sharemgr understands
756185db85Sdougm	# regular shares and ZFS shares and will handle both. Technically,
766185db85Sdougm	# the shares would have been started long before getting here since
776185db85Sdougm	# nfsd has a dependency on them.
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate	startnfsd=0
807c478bd9Sstevel@tonic-gate
816185db85Sdougm	# restart stopped shares from the repository
826185db85Sdougm	/usr/sbin/sharemgr start -P nfs -a
83fa9e4066Sahrens
84fa9e4066Sahrens	# Start up mountd and nfsd if anything is exported.
85fa9e4066Sahrens
867c478bd9Sstevel@tonic-gate	if /usr/bin/grep -s nfs /etc/dfs/sharetab >/dev/null; then
877c478bd9Sstevel@tonic-gate		startnfsd=1
887c478bd9Sstevel@tonic-gate	fi
897c478bd9Sstevel@tonic-gate
9039c23413Seschrock	# If auto-enable behavior is disabled, always start nfsd
9139c23413Seschrock
9239c23413Seschrock	if [ `svcprop -p application/auto_enable nfs/server` = "false" ]; then
9339c23413Seschrock		startnfsd=1
9439c23413Seschrock	fi
9539c23413Seschrock
967c478bd9Sstevel@tonic-gate	# Options for nfsd are now set in /etc/default/nfs
977c478bd9Sstevel@tonic-gate	if [ $startnfsd -ne 0 ]; then
987c478bd9Sstevel@tonic-gate		/usr/lib/nfs/mountd
99250a0733Sth199096		rc=$?
100250a0733Sth199096		if [ $rc != 0 ]; then
101250a0733Sth199096			/usr/sbin/svcadm mark -t maintenance svc:/network/nfs/server
102250a0733Sth199096			echo "$0: mountd failed with $rc"
103250a0733Sth199096			sleep 5 &
104250a0733Sth199096			exit $SMF_EXIT_ERR_FATAL
105250a0733Sth199096		fi
106250a0733Sth199096
1077c478bd9Sstevel@tonic-gate		/usr/lib/nfs/nfsd
108250a0733Sth199096		rc=$?
109250a0733Sth199096		if [ $rc != 0 ]; then
110250a0733Sth199096			/usr/sbin/svcadm mark -t maintenance svc:/network/nfs/server
111250a0733Sth199096			echo "$0: nfsd failed with $rc"
112250a0733Sth199096			sleep 5 &
113250a0733Sth199096			exit $SMF_EXIT_ERR_FATAL
114250a0733Sth199096		fi
115*eb1a3463STruong Nguyen
116*eb1a3463STruong Nguyen		configure_ipfilter
1177c478bd9Sstevel@tonic-gate	else
1183fd3a04aSthurlow		/usr/sbin/svcadm disable -t svc:/network/nfs/server
1197c478bd9Sstevel@tonic-gate		echo "No NFS filesystems are shared"
1207c478bd9Sstevel@tonic-gate		sleep 5 &
1217c478bd9Sstevel@tonic-gate	fi
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate	;;
1247c478bd9Sstevel@tonic-gate
1253fd3a04aSthurlow'refresh')
1266185db85Sdougm	/usr/sbin/sharemgr start -P nfs -a
1273fd3a04aSthurlow	;;
1283fd3a04aSthurlow
1297c478bd9Sstevel@tonic-gate'stop')
1307c478bd9Sstevel@tonic-gate	/usr/bin/pkill -x -u 0,1 -z $zone '(nfsd|mountd)'
1317c478bd9Sstevel@tonic-gate
1326185db85Sdougm	# Unshare all shared file systems using NFS
133fa9e4066Sahrens
1346185db85Sdougm	/usr/sbin/sharemgr stop -P nfs -a
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate	#
1377c478bd9Sstevel@tonic-gate	# Wait up to 10 seconds for nfslogd to gracefully handle SIGHUP
1387c478bd9Sstevel@tonic-gate	#
1397c478bd9Sstevel@tonic-gate	/usr/bin/pkill -HUP -x -u 0 -z $zone nfslogd
1407c478bd9Sstevel@tonic-gate	wtime=10
1417c478bd9Sstevel@tonic-gate
1427c478bd9Sstevel@tonic-gate	while [ $wtime -gt 0 ]; do
1437c478bd9Sstevel@tonic-gate		/usr/bin/pgrep -x -u 0 -z $zone nfslogd >/dev/null || break
1447c478bd9Sstevel@tonic-gate		wtime=`expr $wtime - 1`
1457c478bd9Sstevel@tonic-gate		sleep 1
1467c478bd9Sstevel@tonic-gate	done
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate	#
1497c478bd9Sstevel@tonic-gate	# Kill nfslogd more forcefully if it did not shutdown during
1507c478bd9Sstevel@tonic-gate	# the grace period
1517c478bd9Sstevel@tonic-gate	#
1527c478bd9Sstevel@tonic-gate	if [ $wtime -eq 0 ]; then
1537c478bd9Sstevel@tonic-gate		/usr/bin/pkill -TERM -x -u 0 -z $zone nfslogd
1547c478bd9Sstevel@tonic-gate	fi
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate	# Kill any processes left in service contract
1577c478bd9Sstevel@tonic-gate	smf_kill_contract $2 TERM 1
1587c478bd9Sstevel@tonic-gate	[ $? -ne 0 ] && exit 1
1597c478bd9Sstevel@tonic-gate	;;
1603fd3a04aSthurlow
161*eb1a3463STruong Nguyen'ipfilter')
162*eb1a3463STruong Nguyen	#
163*eb1a3463STruong Nguyen	# NFS related services are RPC. nfs/server has nfsd which has
164*eb1a3463STruong Nguyen	# well-defined port number but mountd is an RPC daemon.
165*eb1a3463STruong Nguyen	#
166*eb1a3463STruong Nguyen	# Essentially, we generate rules for the following "services"
167*eb1a3463STruong Nguyen	#  - nfs/server which has nfsd and mountd
168*eb1a3463STruong Nguyen	#  - nfs/rquota
169*eb1a3463STruong Nguyen	#
170*eb1a3463STruong Nguyen	# The following services are enabled for both nfs client and
171*eb1a3463STruong Nguyen	# server so we'll treat them as client services and simply
172*eb1a3463STruong Nguyen	# allow incoming traffic.
173*eb1a3463STruong Nguyen	#  - nfs/status
174*eb1a3463STruong Nguyen	#  - nfs/nlockmgr
175*eb1a3463STruong Nguyen	#  - nfs/cbd
176*eb1a3463STruong Nguyen	#
177*eb1a3463STruong Nguyen	NFS_FMRI="svc:/network/nfs/server:default"
178*eb1a3463STruong Nguyen	RQUOTA_FMRI="svc:/network/nfs/rquota:default"
179*eb1a3463STruong Nguyen	FMRI=$2
180*eb1a3463STruong Nguyen
181*eb1a3463STruong Nguyen	file=`fmri_to_file $FMRI $IPF_SUFFIX`
182*eb1a3463STruong Nguyen	echo "# $FMRI" >$file
183*eb1a3463STruong Nguyen	policy=`get_policy $NFS_FMRI`
184*eb1a3463STruong Nguyen	ip="any"
185*eb1a3463STruong Nguyen
186*eb1a3463STruong Nguyen	#
187*eb1a3463STruong Nguyen	# nfs/server configuration is processed in the start method.
188*eb1a3463STruong Nguyen	#
189*eb1a3463STruong Nguyen	if [ "$FMRI" = "$NFS_FMRI" ]; then
190*eb1a3463STruong Nguyen		service_check_state $FMRI $SMF_ONLINE
191*eb1a3463STruong Nguyen		if [ $? -ne 0 ]; then
192*eb1a3463STruong Nguyen			rm  $file
193*eb1a3463STruong Nguyen			exit $SMF_EXIT_OK
194*eb1a3463STruong Nguyen		fi
195*eb1a3463STruong Nguyen
196*eb1a3463STruong Nguyen		nfs_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI 2>/dev/null`
197*eb1a3463STruong Nguyen		tport=`$SERVINFO -p -t -s $nfs_name 2>/dev/null`
198*eb1a3463STruong Nguyen		if [ -n "$tport" ]; then
199*eb1a3463STruong Nguyen			generate_rules $FMRI $policy "tcp" $ip $tport $file
200*eb1a3463STruong Nguyen		fi
201*eb1a3463STruong Nguyen
202*eb1a3463STruong Nguyen		uport=`$SERVINFO -p -u -s $nfs_name 2>/dev/null`
203*eb1a3463STruong Nguyen		if [ -n "$uport" ]; then
204*eb1a3463STruong Nguyen			generate_rules $FMRI $policy "udp" $ip $uport $file
205*eb1a3463STruong Nguyen		fi
206*eb1a3463STruong Nguyen
207*eb1a3463STruong Nguyen		tports=`$SERVINFO -R -p -t -s "mountd" 2>/dev/null`
208*eb1a3463STruong Nguyen		if [ -n "$tports" ]; then
209*eb1a3463STruong Nguyen			for tport in $tports; do
210*eb1a3463STruong Nguyen				generate_rules $FMRI $policy "tcp" $ip \
211*eb1a3463STruong Nguyen				    $tport $file
212*eb1a3463STruong Nguyen			done
213*eb1a3463STruong Nguyen		fi
214*eb1a3463STruong Nguyen
215*eb1a3463STruong Nguyen		uports=`$SERVINFO -R -p -u -s "mountd" 2>/dev/null`
216*eb1a3463STruong Nguyen		if [ -n "$uports" ]; then
217*eb1a3463STruong Nguyen			for uport in $uports; do
218*eb1a3463STruong Nguyen				generate_rules $FMRI $policy "udp" $ip \
219*eb1a3463STruong Nguyen				    $uport $file
220*eb1a3463STruong Nguyen			done
221*eb1a3463STruong Nguyen		fi
222*eb1a3463STruong Nguyen
223*eb1a3463STruong Nguyen	elif [ "$FMRI" = "$RQUOTA_FMRI" ]; then
224*eb1a3463STruong Nguyen		iana_name=`svcprop -p inetd/name $FMRI`
225*eb1a3463STruong Nguyen
226*eb1a3463STruong Nguyen		tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null`
227*eb1a3463STruong Nguyen		if [ -n "$tports" ]; then
228*eb1a3463STruong Nguyen			for tport in $tports; do
229*eb1a3463STruong Nguyen				generate_rules $NFS_FMRI $policy "tcp" \
230*eb1a3463STruong Nguyen				    $ip $tport $file
231*eb1a3463STruong Nguyen			done
232*eb1a3463STruong Nguyen		fi
233*eb1a3463STruong Nguyen
234*eb1a3463STruong Nguyen		uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null`
235*eb1a3463STruong Nguyen		if [ -n "$uports" ]; then
236*eb1a3463STruong Nguyen			for uport in $uports; do
237*eb1a3463STruong Nguyen				generate_rules $NFS_FMRI $policy "udp" \
238*eb1a3463STruong Nguyen				    $ip $uport $file
239*eb1a3463STruong Nguyen			done
240*eb1a3463STruong Nguyen		fi
241*eb1a3463STruong Nguyen	else
242*eb1a3463STruong Nguyen		#
243*eb1a3463STruong Nguyen		# Handle the client services here
244*eb1a3463STruong Nguyen		#
245*eb1a3463STruong Nguyen		restarter=`svcprop -p general/restarter $FMRI 2>/dev/null`
246*eb1a3463STruong Nguyen		if [ "$restarter" = "$INETDFMRI" ]; then
247*eb1a3463STruong Nguyen			iana_name=`svcprop -p inetd/name $FMRI`
248*eb1a3463STruong Nguyen			isrpc=`svcprop -p inetd/isrpc $FMRI`
249*eb1a3463STruong Nguyen		else
250*eb1a3463STruong Nguyen			iana_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI`
251*eb1a3463STruong Nguyen			isrpc=`svcprop -p $FW_CONTEXT_PG/isrpc $FMRI`
252*eb1a3463STruong Nguyen		fi
253*eb1a3463STruong Nguyen
254*eb1a3463STruong Nguyen		if [ "$isrpc" = "true" ]; then
255*eb1a3463STruong Nguyen			tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null`
256*eb1a3463STruong Nguyen			uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null`
257*eb1a3463STruong Nguyen		else
258*eb1a3463STruong Nguyen			tports=`$SERVINFO -p -t -s $iana_name 2>/dev/null`
259*eb1a3463STruong Nguyen			uports=`$SERVINFO -p -u -s $iana_name 2>/dev/null`
260*eb1a3463STruong Nguyen		fi
261*eb1a3463STruong Nguyen
262*eb1a3463STruong Nguyen		if [ -n "$tports" ]; then
263*eb1a3463STruong Nguyen			for tport in $tports; do
264*eb1a3463STruong Nguyen				echo "pass in log quick proto tcp from any" \
265*eb1a3463STruong Nguyen				    "to any port = ${tport} flags S " \
266*eb1a3463STruong Nguyen				    "keep state" >>${file}
267*eb1a3463STruong Nguyen			done
268*eb1a3463STruong Nguyen		fi
269*eb1a3463STruong Nguyen
270*eb1a3463STruong Nguyen		if [ -n "$uports" ]; then
271*eb1a3463STruong Nguyen			for uport in $uports; do
272*eb1a3463STruong Nguyen				echo "pass in log quick proto udp from any" \
273*eb1a3463STruong Nguyen				    "to any port = ${uport}" >>${file}
274*eb1a3463STruong Nguyen			done
275*eb1a3463STruong Nguyen		fi
276*eb1a3463STruong Nguyen	fi
277*eb1a3463STruong Nguyen
278*eb1a3463STruong Nguyen	;;
279*eb1a3463STruong Nguyen
2807c478bd9Sstevel@tonic-gate*)
2813fd3a04aSthurlow	echo "Usage: $0 { start | stop | refresh }"
2827c478bd9Sstevel@tonic-gate	exit 1
2837c478bd9Sstevel@tonic-gate	;;
2847c478bd9Sstevel@tonic-gateesac
2857c478bd9Sstevel@tonic-gateexit $SMF_EXIT_OK
286