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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24# Copyright 2012 Nexenta Systems, Inc. All rights reserved. 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 SMF 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 # Kill any processes left in service contract 137 smf_kill_contract $2 TERM 1 138 [ $? -ne 0 ] && exit 1 139 ;; 140 141'ipfilter') 142 # 143 # NFS related services are RPC. nfs/server has nfsd which has 144 # well-defined port number but mountd is an RPC daemon. 145 # 146 # Essentially, we generate rules for the following "services" 147 # - nfs/server which has nfsd and mountd 148 # - nfs/rquota 149 # 150 # The following services are enabled for both nfs client and 151 # server so we'll treat them as client services and simply 152 # allow incoming traffic. 153 # - nfs/status 154 # - nfs/nlockmgr 155 # - nfs/cbd 156 # 157 NFS_FMRI="svc:/network/nfs/server:default" 158 RQUOTA_FMRI="svc:/network/nfs/rquota:default" 159 FMRI=$2 160 161 file=`fmri_to_file $FMRI $IPF_SUFFIX` 162 echo "# $FMRI" >$file 163 policy=`get_policy $NFS_FMRI` 164 ip="any" 165 166 # 167 # nfs/server configuration is processed in the start method. 168 # 169 if [ "$FMRI" = "$NFS_FMRI" ]; then 170 service_check_state $FMRI $SMF_ONLINE 171 if [ $? -ne 0 ]; then 172 rm $file 173 exit $SMF_EXIT_OK 174 fi 175 176 nfs_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI 2>/dev/null` 177 tport=`$SERVINFO -p -t -s $nfs_name 2>/dev/null` 178 if [ -n "$tport" ]; then 179 generate_rules $FMRI $policy "tcp" $ip $tport $file 180 fi 181 182 uport=`$SERVINFO -p -u -s $nfs_name 2>/dev/null` 183 if [ -n "$uport" ]; then 184 generate_rules $FMRI $policy "udp" $ip $uport $file 185 fi 186 187 tports=`$SERVINFO -R -p -t -s "mountd" 2>/dev/null` 188 if [ -n "$tports" ]; then 189 for tport in $tports; do 190 generate_rules $FMRI $policy "tcp" $ip \ 191 $tport $file 192 done 193 fi 194 195 uports=`$SERVINFO -R -p -u -s "mountd" 2>/dev/null` 196 if [ -n "$uports" ]; then 197 for uport in $uports; do 198 generate_rules $FMRI $policy "udp" $ip \ 199 $uport $file 200 done 201 fi 202 203 elif [ "$FMRI" = "$RQUOTA_FMRI" ]; then 204 iana_name=`svcprop -p inetd/name $FMRI` 205 206 tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null` 207 if [ -n "$tports" ]; then 208 for tport in $tports; do 209 generate_rules $NFS_FMRI $policy "tcp" \ 210 $ip $tport $file 211 done 212 fi 213 214 uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null` 215 if [ -n "$uports" ]; then 216 for uport in $uports; do 217 generate_rules $NFS_FMRI $policy "udp" \ 218 $ip $uport $file 219 done 220 fi 221 else 222 # 223 # Handle the client services here 224 # 225 restarter=`svcprop -p general/restarter $FMRI 2>/dev/null` 226 if [ "$restarter" = "$INETDFMRI" ]; then 227 iana_name=`svcprop -p inetd/name $FMRI` 228 isrpc=`svcprop -p inetd/isrpc $FMRI` 229 else 230 iana_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI` 231 isrpc=`svcprop -p $FW_CONTEXT_PG/isrpc $FMRI` 232 fi 233 234 if [ "$isrpc" = "true" ]; then 235 tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null` 236 uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null` 237 else 238 tports=`$SERVINFO -p -t -s $iana_name 2>/dev/null` 239 uports=`$SERVINFO -p -u -s $iana_name 2>/dev/null` 240 fi 241 242 if [ -n "$tports" ]; then 243 for tport in $tports; do 244 echo "pass in log quick proto tcp from any" \ 245 "to any port = ${tport} flags S " \ 246 "keep state" >>${file} 247 done 248 fi 249 250 if [ -n "$uports" ]; then 251 for uport in $uports; do 252 echo "pass in log quick proto udp from any" \ 253 "to any port = ${uport}" >>${file} 254 done 255 fi 256 fi 257 258 ;; 259 260*) 261 echo "Usage: $0 { start | stop | refresh }" 262 exit 1 263 ;; 264esac 265exit $SMF_EXIT_OK 266