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# 24# Copyright 2015 Nexenta Systems, Inc. All rights reserved. 25# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 26# 27 28# Start/stop processes required for server NFS 29 30. /lib/svc/share/smf_include.sh 31. /lib/svc/share/ipf_include.sh 32zone=`smf_zonename` 33 34# 35# Handling a corner case here. If we were in offline state due to an 36# unsatisfied dependency, the ipf_method process wouldn't have generated 37# the ipfilter configuration. When we transition to online because the 38# dependency is satisfied, the start method will have to generate the 39# ipfilter configuration. To avoid all possible deadlock scenarios, 40# we restart ipfilter which will regenerate the ipfilter configuration 41# for the entire system. 42# 43# The ipf_method process signals that it didn't generate ipf rules by 44# removing the service's ipf file. Thus we only restart network/ipfilter 45# when the file is missing. 46# 47configure_ipfilter() 48{ 49 ipfile=`fmri_to_file $SMF_FMRI $IPF_SUFFIX` 50 [ -f "$ipfile" ] && return 0 51 52 # 53 # Nothing to do if: 54 # - ipfilter isn't online 55 # - global policy is 'custom' 56 # - service's policy is 'use_global' 57 # 58 service_check_state $IPF_FMRI $SMF_ONLINE || return 0 59 [ "`get_global_def_policy`" = "custom" ] && return 0 60 [ "`get_policy $SMF_FMRI`" = "use_global" ] && return 0 61 62 svcadm restart $IPF_FMRI 63} 64 65case "$1" in 66'start') 67 # The NFS server is not supported in a local zone 68 if smf_is_nonglobalzone; then 69 /usr/sbin/svcadm disable -t svc:/network/nfs/server 70 echo "The NFS server is not supported in a local zone" 71 sleep 5 & 72 exit $SMF_EXIT_OK 73 fi 74 75 # Share all file systems enabled for sharing. sharemgr understands 76 # regular shares and ZFS shares and will handle both. Technically, 77 # the shares would have been started long before getting here since 78 # nfsd has a dependency on them. 79 80 # restart stopped shares from the repository 81 /usr/sbin/sharemgr start -P nfs -a 82 83 # Options for nfsd are now set in SMF 84 85 /usr/lib/nfs/mountd 86 rc=$? 87 if [ $rc != 0 ]; then 88 /usr/sbin/svcadm mark -t maintenance svc:/network/nfs/server 89 echo "$0: mountd failed with $rc" 90 sleep 5 & 91 exit $SMF_EXIT_ERR_FATAL 92 fi 93 94 /usr/lib/nfs/nfsd 95 rc=$? 96 if [ $rc != 0 ]; then 97 /usr/sbin/svcadm mark -t maintenance svc:/network/nfs/server 98 echo "$0: nfsd failed with $rc" 99 sleep 5 & 100 exit $SMF_EXIT_ERR_FATAL 101 fi 102 103 configure_ipfilter 104 ;; 105 106'refresh') 107 /usr/sbin/sharemgr start -P nfs -a 108 ;; 109 110'stop') 111 /usr/bin/pkill -x -u 0,1 -z $zone '(nfsd|mountd)' 112 113 # Unshare all shared file systems using NFS 114 115 /usr/sbin/sharemgr stop -P nfs -a 116 117 # Kill any processes left in service contract 118 smf_kill_contract $2 TERM 1 119 [ $? -ne 0 ] && exit 1 120 ;; 121 122'ipfilter') 123 # 124 # NFS related services are RPC. nfs/server has nfsd which has 125 # well-defined port number but mountd is an RPC daemon. 126 # 127 # Essentially, we generate rules for the following "services" 128 # - nfs/server which has nfsd and mountd 129 # - nfs/rquota 130 # 131 # The following services are enabled for both nfs client and 132 # server so we'll treat them as client services and simply 133 # allow incoming traffic. 134 # - nfs/status 135 # - nfs/nlockmgr 136 # - nfs/cbd 137 # 138 NFS_FMRI="svc:/network/nfs/server:default" 139 RQUOTA_FMRI="svc:/network/nfs/rquota:default" 140 FMRI=$2 141 142 file=`fmri_to_file $FMRI $IPF_SUFFIX` 143 echo "# $FMRI" >$file 144 policy=`get_policy $NFS_FMRI` 145 ip="any" 146 147 # 148 # nfs/server configuration is processed in the start method. 149 # 150 if [ "$FMRI" = "$NFS_FMRI" ]; then 151 service_check_state $FMRI $SMF_ONLINE 152 if [ $? -ne 0 ]; then 153 rm $file 154 exit $SMF_EXIT_OK 155 fi 156 157 nfs_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI 2>/dev/null` 158 tport=`$SERVINFO -p -t -s $nfs_name 2>/dev/null` 159 if [ -n "$tport" ]; then 160 generate_rules $FMRI $policy "tcp" $ip $tport $file 161 fi 162 163 uport=`$SERVINFO -p -u -s $nfs_name 2>/dev/null` 164 if [ -n "$uport" ]; then 165 generate_rules $FMRI $policy "udp" $ip $uport $file 166 fi 167 168 tports=`$SERVINFO -R -p -t -s "mountd" 2>/dev/null` 169 if [ -n "$tports" ]; then 170 for tport in $tports; do 171 generate_rules $FMRI $policy "tcp" $ip \ 172 $tport $file 173 done 174 fi 175 176 uports=`$SERVINFO -R -p -u -s "mountd" 2>/dev/null` 177 if [ -n "$uports" ]; then 178 for uport in $uports; do 179 generate_rules $FMRI $policy "udp" $ip \ 180 $uport $file 181 done 182 fi 183 184 elif [ "$FMRI" = "$RQUOTA_FMRI" ]; then 185 iana_name=`svcprop -p inetd/name $FMRI` 186 187 tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null` 188 if [ -n "$tports" ]; then 189 for tport in $tports; do 190 generate_rules $NFS_FMRI $policy "tcp" \ 191 $ip $tport $file 192 done 193 fi 194 195 uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null` 196 if [ -n "$uports" ]; then 197 for uport in $uports; do 198 generate_rules $NFS_FMRI $policy "udp" \ 199 $ip $uport $file 200 done 201 fi 202 else 203 # 204 # Handle the client services here 205 # 206 restarter=`svcprop -p general/restarter $FMRI 2>/dev/null` 207 if [ "$restarter" = "$INETDFMRI" ]; then 208 iana_name=`svcprop -p inetd/name $FMRI` 209 isrpc=`svcprop -p inetd/isrpc $FMRI` 210 else 211 iana_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI` 212 isrpc=`svcprop -p $FW_CONTEXT_PG/isrpc $FMRI` 213 fi 214 215 if [ "$isrpc" = "true" ]; then 216 tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null` 217 uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null` 218 else 219 tports=`$SERVINFO -p -t -s $iana_name 2>/dev/null` 220 uports=`$SERVINFO -p -u -s $iana_name 2>/dev/null` 221 fi 222 223 if [ -n "$tports" ]; then 224 for tport in $tports; do 225 echo "pass in log quick proto tcp from any" \ 226 "to any port = ${tport} flags S " \ 227 "keep state" >>${file} 228 done 229 fi 230 231 if [ -n "$uports" ]; then 232 for uport in $uports; do 233 echo "pass in log quick proto udp from any" \ 234 "to any port = ${uport}" >>${file} 235 done 236 fi 237 fi 238 239 ;; 240 241*) 242 echo "Usage: $0 { start | stop | refresh }" 243 exit 1 244 ;; 245esac 246exit $SMF_EXIT_OK 247