1#!/sbin/sh 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22# 23# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24# Use is subject to license terms. 25# 26 27# Start/stop processes required for server NFS 28 29. /lib/svc/share/smf_include.sh 30. /lib/svc/share/ipf_include.sh 31zone=`smf_zonename` 32 33# 34# Handling a corner case here. If we were in offline state due to an 35# unsatisfied dependency, the ipf_method process wouldn't have generated 36# the ipfilter configuration. When we transition to online because the 37# dependency is satisfied, the start method will have to generate the 38# ipfilter configuration. To avoid all possible deadlock scenarios, 39# we restart ipfilter which will regenerate the ipfilter configuration 40# for the entire system. 41# 42# The ipf_method process signals that it didn't generate ipf rules by 43# removing the service's ipf file. Thus we only restart network/ipfilter 44# when the file is missing. 45# 46configure_ipfilter() 47{ 48 ipfile=`fmri_to_file $SMF_FMRI $IPF_SUFFIX` 49 [ -f "$ipfile" ] && return 0 50 51 # 52 # Nothing to do if: 53 # - ipfilter isn't online 54 # - global policy is 'custom' 55 # - service's policy is 'use_global' 56 # 57 service_check_state $IPF_FMRI $SMF_ONLINE || return 0 58 [ "`get_global_def_policy`" = "custom" ] && return 0 59 [ "`get_policy $SMF_FMRI`" = "use_global" ] && return 0 60 61 svcadm restart $IPF_FMRI 62} 63 64case "$1" in 65'start') 66 # The NFS server is not supported in a local zone 67 if smf_is_nonglobalzone; then 68 /usr/sbin/svcadm disable -t svc:/network/nfs/server 69 echo "The NFS server is not supported in a local zone" 70 sleep 5 & 71 exit $SMF_EXIT_OK 72 fi 73 74 # Share all file systems enabled for sharing. sharemgr understands 75 # regular shares and ZFS shares and will handle both. Technically, 76 # the shares would have been started long before getting here since 77 # nfsd has a dependency on them. 78 79 startnfsd=0 80 81 # restart stopped shares from the repository 82 /usr/sbin/sharemgr start -P nfs -a 83 84 # Start up mountd and nfsd if anything is exported. 85 86 if /usr/bin/grep -s nfs /etc/dfs/sharetab >/dev/null; then 87 startnfsd=1 88 fi 89 90 # If auto-enable behavior is disabled, always start nfsd 91 92 if [ `svcprop -p application/auto_enable nfs/server` = "false" ]; then 93 startnfsd=1 94 fi 95 96 # Options for nfsd are now set in /etc/default/nfs 97 if [ $startnfsd -ne 0 ]; then 98 /usr/lib/nfs/mountd 99 rc=$? 100 if [ $rc != 0 ]; then 101 /usr/sbin/svcadm mark -t maintenance svc:/network/nfs/server 102 echo "$0: mountd failed with $rc" 103 sleep 5 & 104 exit $SMF_EXIT_ERR_FATAL 105 fi 106 107 /usr/lib/nfs/nfsd 108 rc=$? 109 if [ $rc != 0 ]; then 110 /usr/sbin/svcadm mark -t maintenance svc:/network/nfs/server 111 echo "$0: nfsd failed with $rc" 112 sleep 5 & 113 exit $SMF_EXIT_ERR_FATAL 114 fi 115 116 configure_ipfilter 117 else 118 /usr/sbin/svcadm disable -t svc:/network/nfs/server 119 echo "No NFS filesystems are shared" 120 sleep 5 & 121 fi 122 123 ;; 124 125'refresh') 126 /usr/sbin/sharemgr start -P nfs -a 127 ;; 128 129'stop') 130 /usr/bin/pkill -x -u 0,1 -z $zone '(nfsd|mountd)' 131 132 # Unshare all shared file systems using NFS 133 134 /usr/sbin/sharemgr stop -P nfs -a 135 136 # 137 # Wait up to 10 seconds for nfslogd to gracefully handle SIGHUP 138 # 139 /usr/bin/pkill -HUP -x -u 0 -z $zone nfslogd 140 wtime=10 141 142 while [ $wtime -gt 0 ]; do 143 /usr/bin/pgrep -x -u 0 -z $zone nfslogd >/dev/null || break 144 wtime=`expr $wtime - 1` 145 sleep 1 146 done 147 148 # 149 # Kill nfslogd more forcefully if it did not shutdown during 150 # the grace period 151 # 152 if [ $wtime -eq 0 ]; then 153 /usr/bin/pkill -TERM -x -u 0 -z $zone nfslogd 154 fi 155 156 # Kill any processes left in service contract 157 smf_kill_contract $2 TERM 1 158 [ $? -ne 0 ] && exit 1 159 ;; 160 161'ipfilter') 162 # 163 # NFS related services are RPC. nfs/server has nfsd which has 164 # well-defined port number but mountd is an RPC daemon. 165 # 166 # Essentially, we generate rules for the following "services" 167 # - nfs/server which has nfsd and mountd 168 # - nfs/rquota 169 # 170 # The following services are enabled for both nfs client and 171 # server so we'll treat them as client services and simply 172 # allow incoming traffic. 173 # - nfs/status 174 # - nfs/nlockmgr 175 # - nfs/cbd 176 # 177 NFS_FMRI="svc:/network/nfs/server:default" 178 RQUOTA_FMRI="svc:/network/nfs/rquota:default" 179 FMRI=$2 180 181 file=`fmri_to_file $FMRI $IPF_SUFFIX` 182 echo "# $FMRI" >$file 183 policy=`get_policy $NFS_FMRI` 184 ip="any" 185 186 # 187 # nfs/server configuration is processed in the start method. 188 # 189 if [ "$FMRI" = "$NFS_FMRI" ]; then 190 service_check_state $FMRI $SMF_ONLINE 191 if [ $? -ne 0 ]; then 192 rm $file 193 exit $SMF_EXIT_OK 194 fi 195 196 nfs_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI 2>/dev/null` 197 tport=`$SERVINFO -p -t -s $nfs_name 2>/dev/null` 198 if [ -n "$tport" ]; then 199 generate_rules $FMRI $policy "tcp" $ip $tport $file 200 fi 201 202 uport=`$SERVINFO -p -u -s $nfs_name 2>/dev/null` 203 if [ -n "$uport" ]; then 204 generate_rules $FMRI $policy "udp" $ip $uport $file 205 fi 206 207 tports=`$SERVINFO -R -p -t -s "mountd" 2>/dev/null` 208 if [ -n "$tports" ]; then 209 for tport in $tports; do 210 generate_rules $FMRI $policy "tcp" $ip \ 211 $tport $file 212 done 213 fi 214 215 uports=`$SERVINFO -R -p -u -s "mountd" 2>/dev/null` 216 if [ -n "$uports" ]; then 217 for uport in $uports; do 218 generate_rules $FMRI $policy "udp" $ip \ 219 $uport $file 220 done 221 fi 222 223 elif [ "$FMRI" = "$RQUOTA_FMRI" ]; then 224 iana_name=`svcprop -p inetd/name $FMRI` 225 226 tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null` 227 if [ -n "$tports" ]; then 228 for tport in $tports; do 229 generate_rules $NFS_FMRI $policy "tcp" \ 230 $ip $tport $file 231 done 232 fi 233 234 uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null` 235 if [ -n "$uports" ]; then 236 for uport in $uports; do 237 generate_rules $NFS_FMRI $policy "udp" \ 238 $ip $uport $file 239 done 240 fi 241 else 242 # 243 # Handle the client services here 244 # 245 restarter=`svcprop -p general/restarter $FMRI 2>/dev/null` 246 if [ "$restarter" = "$INETDFMRI" ]; then 247 iana_name=`svcprop -p inetd/name $FMRI` 248 isrpc=`svcprop -p inetd/isrpc $FMRI` 249 else 250 iana_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI` 251 isrpc=`svcprop -p $FW_CONTEXT_PG/isrpc $FMRI` 252 fi 253 254 if [ "$isrpc" = "true" ]; then 255 tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null` 256 uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null` 257 else 258 tports=`$SERVINFO -p -t -s $iana_name 2>/dev/null` 259 uports=`$SERVINFO -p -u -s $iana_name 2>/dev/null` 260 fi 261 262 if [ -n "$tports" ]; then 263 for tport in $tports; do 264 echo "pass in log quick proto tcp from any" \ 265 "to any port = ${tport} flags S " \ 266 "keep state" >>${file} 267 done 268 fi 269 270 if [ -n "$uports" ]; then 271 for uport in $uports; do 272 echo "pass in log quick proto udp from any" \ 273 "to any port = ${uport}" >>${file} 274 done 275 fi 276 fi 277 278 ;; 279 280*) 281 echo "Usage: $0 { start | stop | refresh }" 282 exit 1 283 ;; 284esac 285exit $SMF_EXIT_OK 286