Print this page
    
NEX-15279 support NFS server in zone
NEX-15520 online NFS shares cause zoneadm halt to hang in nfs_export_zone_fini
Portions contributed by: Dan Kruchinin dan.kruchinin@nexenta.com
Portions contributed by: Stepan Zastupov stepan.zastupov@gmail.com
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-1704 Clustered NFSv4 could cause I/O errors on clients after failover
Reviewed by:  Evan Layton <evan.layton@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
NEX-4122 All kernel messages seem to come from 'genunix' instead of individual modules after illumos #5272
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
NEX-4036 Unable to enable the nfs/server service when nothing is shared
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/fs.d/nfs/svc/nfs-server
          +++ new/usr/src/cmd/fs.d/nfs/svc/nfs-server
   1    1  #!/sbin/sh
   2    2  #
   3    3  # CDDL HEADER START
   4    4  #
   5    5  # The contents of this file are subject to the terms of the
   6    6  # Common Development and Distribution License (the "License").
   7    7  # You may not use this file except in compliance with the License.
   8    8  #
   9    9  # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10   10  # or http://www.opensolaris.org/os/licensing.
  11   11  # See the License for the specific language governing permissions
  12   12  # and limitations under the License.
  13   13  #
  14   14  # When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
  15   15  # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   16  # If applicable, add the following below this CDDL HEADER, with the
  17   17  # fields enclosed by brackets "[]" replaced with your own identifying
  18   18  # information: Portions Copyright [yyyy] [name of copyright owner]
  19   19  #
  20   20  # CDDL HEADER END
  21   21  #
  22   22  
  23   23  #
  24   24  # Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  25      -# Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  26   25  # Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
       26 +# Copyright 2018 Nexenta Systems, Inc.
  27   27  #
  28   28  
  29   29  # Start/stop processes required for server NFS
  30   30  
  31   31  . /lib/svc/share/smf_include.sh
  32   32  . /lib/svc/share/ipf_include.sh
  33   33  zone=`smf_zonename`
  34   34  
  35   35  #
  36   36  # Handling a corner case here. If we were in offline state due to an
  37   37  # unsatisfied dependency, the ipf_method process wouldn't have generated
  38   38  # the ipfilter configuration. When we transition to online because the
  39   39  # dependency is satisfied, the start method will have to generate the
  40   40  # ipfilter configuration. To avoid all possible deadlock scenarios,
  41   41  # we restart ipfilter which will regenerate the ipfilter configuration
  42   42  # for the entire system.
  43   43  #
  44   44  # The ipf_method process signals that it didn't generate ipf rules by
  45   45  # removing the service's ipf file. Thus we only restart network/ipfilter
  46   46  # when the file is missing.
  47   47  #
  48   48  configure_ipfilter()
  49   49  {
  50   50          ipfile=`fmri_to_file $SMF_FMRI $IPF_SUFFIX`
  51   51          ip6file=`fmri_to_file $SMF_FMRI $IPF6_SUFFIX`
  52   52          [ -f "$ipfile" -a -f "$ip6file" ] && return 0
  53   53  
  54   54          #
  55   55          # Nothing to do if:
  56   56          # - ipfilter isn't online 
  57   57          # - global policy is 'custom'
  58   58          # - service's policy is 'use_global'
  
    | 
      ↓ open down ↓ | 
    22 lines elided | 
    
      ↑ open up ↑ | 
  
  59   59          #
  60   60          service_check_state $IPF_FMRI $SMF_ONLINE || return 0
  61   61          [ "`get_global_def_policy`" = "custom" ] && return 0
  62   62          [ "`get_policy $SMF_FMRI`" = "use_global" ] && return 0
  63   63  
  64   64          svcadm restart $IPF_FMRI
  65   65  }
  66   66  
  67   67  case "$1" in
  68   68  'start')
  69      -        # The NFS server is not supported in a local zone
  70      -        if smf_is_nonglobalzone; then
  71      -                /usr/sbin/svcadm disable -t svc:/network/nfs/server
  72      -                echo "The NFS server is not supported in a local zone"
  73      -                sleep 5 &
  74      -                exit $SMF_EXIT_OK
  75      -        fi
  76      -
  77   69          # Share all file systems enabled for sharing. sharemgr understands
  78   70          # regular shares and ZFS shares and will handle both. Technically,
  79   71          # the shares would have been started long before getting here since
  80   72          # nfsd has a dependency on them.
  81   73  
  82   74          # restart stopped shares from the repository
  83   75          /usr/sbin/sharemgr start -P nfs -a
  84   76  
  85   77          # Options for nfsd are now set in SMF
  86   78  
  87   79          /usr/lib/nfs/mountd
  88   80          rc=$?
  89   81          if [ $rc != 0 ]; then
  90   82                  /usr/sbin/svcadm mark -t maintenance svc:/network/nfs/server
  91   83                  echo "$0: mountd failed with $rc"
  92   84                  sleep 5 &
  93   85                  exit $SMF_EXIT_ERR_FATAL
  94   86          fi
  95   87  
  96      -        /usr/lib/nfs/nfsd
       88 +        NFS_OPTS=
       89 +        if [ -f /opt/HAC/bin/rsf.sh ]; then
       90 +                . /opt/HAC/bin/rsf.sh
       91 +
       92 +                if [ -f "$PRODUCT_CONFIG" ]; then
       93 +                        RSF_MNTS=$(/usr/bin/grep MOUNT_POINT "$PRODUCT_CONFIG" |\
       94 +                            /usr/bin/sed -e 's/^.*MOUNT_POINT.*\"\(.*\)\"$/\1/')
       95 +
       96 +                        for RSF_MNT in $RSF_MNTS; do
       97 +                                MATCH=$(/usr/bin/cat /etc/mnttab |\
       98 +                                    /usr/bin/awk '{print $2}' |\
       99 +                                    /usr/bin/egrep "^$RSF_MNT\$")
      100 +
      101 +                                if [ -n "$MATCH" ]; then
      102 +                                        /usr/bin/mkdir -p "$RSF_MNT/.nfs"
      103 +                                        /usr/bin/chown daemon:daemon "$RSF_MNT/.nfs"
      104 +                                        NFS_OPTS="$NFS_OPTS -s $RSF_MNT/.nfs"
      105 +                                fi
      106 +                        done
      107 +                fi
      108 +        fi
      109 +
      110 +        /usr/lib/nfs/nfsd $NFS_OPTS
  97  111          rc=$?
  98  112          if [ $rc != 0 ]; then
  99  113                  /usr/sbin/svcadm mark -t maintenance svc:/network/nfs/server
 100  114                  echo "$0: nfsd failed with $rc"
 101  115                  sleep 5 &
 102  116                  exit $SMF_EXIT_ERR_FATAL
 103  117          fi
 104  118  
 105  119          configure_ipfilter
 106  120          ;;
 107  121  
 108  122  'refresh')
 109  123          /usr/sbin/sharemgr start -P nfs -a
 110  124          ;;
 111  125  
 112  126  'stop')
 113  127          /usr/bin/pkill -x -u 0,1 -z $zone '(nfsd|mountd)'
 114  128  
 115  129          # Unshare all shared file systems using NFS
 116  130  
 117  131          /usr/sbin/sharemgr stop -P nfs -a
 118  132  
 119  133          # Kill any processes left in service contract
 120  134          smf_kill_contract $2 TERM 1
 121  135          [ $? -ne 0 ] && exit 1
 122  136          ;;
 123  137  
 124  138  'ipfilter')
 125  139          #
 126  140          # NFS related services are RPC. nfs/server has nfsd which has
 127  141          # well-defined port number but mountd is an RPC daemon.
 128  142          #
 129  143          # Essentially, we generate rules for the following "services"
 130  144          #  - nfs/server which has nfsd and mountd
 131  145          #  - nfs/rquota
 132  146          #
 133  147          # The following services are enabled for both nfs client and
 134  148          # server, if nfs/client is enabled we'll treat them as client
 135  149          # services and simply allow incoming traffic.
 136  150          #  - nfs/status
 137  151          #  - nfs/nlockmgr
 138  152          #  - nfs/cbd
 139  153          #
 140  154          NFS_FMRI="svc:/network/nfs/server:default"
 141  155          NFSCLI_FMRI="svc:/network/nfs/client:default"
 142  156          RQUOTA_FMRI="svc:/network/nfs/rquota:default"
 143  157          FMRI=$2
 144  158  
 145  159          file=`fmri_to_file $FMRI $IPF_SUFFIX`
 146  160          file6=`fmri_to_file $FMRI $IPF6_SUFFIX`
 147  161          echo "# $FMRI" >$file
 148  162          echo "# $FMRI" >$file6
 149  163          policy=`get_policy $NFS_FMRI`
 150  164  
 151  165          #
 152  166          # nfs/server configuration is processed in the start method.
 153  167          #
 154  168          if [ "$FMRI" = "$NFS_FMRI" ]; then
 155  169                  service_check_state $FMRI $SMF_ONLINE
 156  170                  if [ $? -ne 0 ]; then
 157  171                          rm  $file
 158  172                          exit $SMF_EXIT_OK
 159  173                  fi
 160  174  
 161  175                  nfs_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI 2>/dev/null`
 162  176                  tport=`$SERVINFO -p -t -s $nfs_name 2>/dev/null`
 163  177                  if [ -n "$tport" ]; then
 164  178                          generate_rules $FMRI $policy "tcp" $tport $file
 165  179                  fi
 166  180  
 167  181                  tport6=`$SERVINFO -p -t6 -s $nfs_name 2>/dev/null`
 168  182                  if [ -n "$tport6" ]; then
 169  183                          generate_rules $FMRI $policy "tcp" $tport6 $file6 _6
 170  184                  fi
 171  185  
 172  186                  uport=`$SERVINFO -p -u -s $nfs_name 2>/dev/null`
 173  187                  if [ -n "$uport" ]; then
 174  188                          generate_rules $FMRI $policy "udp" $uport $file
 175  189                  fi
 176  190  
 177  191                  uport6=`$SERVINFO -p -u6 -s $nfs_name 2>/dev/null`
 178  192                  if [ -n "$uport6" ]; then
 179  193                          generate_rules $FMRI $policy "udp" $uport6 $file6 _6
 180  194                  fi
 181  195  
 182  196                  # mountd IPv6 ports are also reachable through IPv4, so include
 183  197                  # them when generating IPv4 rules.
 184  198                  tports=`$SERVINFO -R -p -t -s "mountd" 2>/dev/null`
 185  199                  tports6=`$SERVINFO -R -p -t6 -s "mountd" 2>/dev/null`
 186  200                  if [ -n "$tports" -o -n "$tports6" ]; then
 187  201                          tports=`unique_ports $tports $tports6`
 188  202                          for tport in $tports; do
 189  203                                  generate_rules $FMRI $policy "tcp" \
 190  204                                      $tport $file
 191  205                          done
 192  206                  fi
 193  207  
 194  208                  if [ -n "$tports6" ]; then
 195  209                          for tport6 in $tports6; do
 196  210                                  generate_rules $FMRI $policy "tcp" \
 197  211                                      $tport6 $file6 _6
 198  212                          done
 199  213                  fi
 200  214  
 201  215                  uports=`$SERVINFO -R -p -u -s "mountd" 2>/dev/null`
 202  216                  uports6=`$SERVINFO -R -p -u6 -s "mountd" 2>/dev/null`
 203  217                  if [ -n "$uports" -o -n "$uports6" ]; then
 204  218                          uports=`unique_ports $uports $uports6`
 205  219                          for uport in $uports; do
 206  220                                  generate_rules $FMRI $policy "udp" \
 207  221                                      $uport $file
 208  222                          done
 209  223                  fi
 210  224  
 211  225                  if [ -n "$uports6" ]; then
 212  226                          for uport6 in $uports6; do
 213  227                                  generate_rules $FMRI $policy "udp" \
 214  228                                      $uport6 $file6 _6
 215  229                          done
 216  230                  fi
 217  231  
 218  232          elif [ "$FMRI" = "$RQUOTA_FMRI" ]; then
 219  233                  iana_name=`svcprop -p inetd/name $FMRI`
 220  234  
 221  235                  # rquota IPv6 ports are also reachable through IPv4, so include
 222  236                  # them when generating IPv4 rules.
 223  237                  tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null`
 224  238                  tports6=`$SERVINFO -R -p -t6 -s $iana_name 2>/dev/null`
 225  239                  if [ -n "$tports" -o -n "$tports6" ]; then
 226  240                          tports=`unique_ports $tports $tports6`
 227  241                          for tport in $tports; do
 228  242                                  generate_rules $NFS_FMRI $policy "tcp" \
 229  243                                      $tport $file
 230  244                          done
 231  245                  fi
 232  246  
 233  247                  if [ -n "$tports6" ]; then
 234  248                          for tport6 in $tports6; do
 235  249                                  generate_rules $NFS_FMRI $policy "tcp" \
 236  250                                      $tport6 $file6 _6
 237  251                          done
 238  252                  fi
 239  253  
 240  254                  uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null`
 241  255                  uports6=`$SERVINFO -R -p -u6 -s $iana_name 2>/dev/null`
 242  256                  if [ -n "$uports" -o -n "$uports6" ]; then
 243  257                          uports=`unique_ports $uports $uports6`
 244  258                          for uport in $uports; do
 245  259                                  generate_rules $NFS_FMRI $policy "udp" \
 246  260                                      $uport $file
 247  261                          done
 248  262                  fi
 249  263  
 250  264                  if [ -n "$uports6" ]; then
 251  265                          for uport6 in $uports6; do
 252  266                                  generate_rules $NFS_FMRI $policy "udp" \
 253  267                                      $uport6 $file6 _6
 254  268                          done
 255  269                  fi
 256  270          else
 257  271                  #
 258  272                  # Handle the client services here
 259  273                  #
 260  274                  if service_check_state $NFSCLI_FMRI $SMF_ONLINE; then
 261  275                          policy=none
 262  276                          ip=any
 263  277                  fi
 264  278  
 265  279                  restarter=`svcprop -p general/restarter $FMRI 2>/dev/null`
 266  280                  if [ "$restarter" = "$INETDFMRI" ]; then
 267  281                          iana_name=`svcprop -p inetd/name $FMRI`
 268  282                          isrpc=`svcprop -p inetd/isrpc $FMRI`
 269  283                  else
 270  284                          iana_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI`
 271  285                          isrpc=`svcprop -p $FW_CONTEXT_PG/isrpc $FMRI`
 272  286                  fi
 273  287  
 274  288                  if [ "$isrpc" = "true" ]; then
 275  289                          tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null`
 276  290                          tports6=`$SERVINFO -R -p -t6 -s $iana_name 2>/dev/null`
 277  291                          uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null`
 278  292                          uports6=`$SERVINFO -R -p -u6 -s $iana_name 2>/dev/null`
 279  293                  else
 280  294                          tports=`$SERVINFO -p -t -s $iana_name 2>/dev/null`
 281  295                          tports6=`$SERVINFO -p -t6 -s $iana_name 2>/dev/null`
 282  296                          uports=`$SERVINFO -p -u -s $iana_name 2>/dev/null`
 283  297                          uports6=`$SERVINFO -p -u6 -s $iana_name 2>/dev/null`
 284  298                  fi
 285  299  
 286  300                  # IPv6 ports are also reachable through IPv4, so include
 287  301                  # them when generating IPv4 rules.
 288  302                  if [ -n "$tports" -o -n "$tports6" ]; then
 289  303                          tports=`unique_ports $tports $tports6`
 290  304                          for tport in $tports; do
 291  305                                  generate_rules $FMRI $policy "tcp" $tport $file
 292  306                          done
 293  307                  fi
 294  308  
 295  309                  if [ -n "$tports6" ]; then
 296  310                          for tport6 in $tports6; do
 297  311                                  generate_rules $FMRI $policy "tcp" $tport6 $file6 _6
 298  312                          done
 299  313                  fi
 300  314  
 301  315                  if [ -n "$uports" -o -n "$uports6" ]; then
 302  316                          uports=`unique_ports $uports $uports6`
 303  317                          for uport in $uports; do
 304  318                                  generate_rules $FMRI $policy "udp" $uport $file
 305  319                          done
 306  320                  fi
 307  321  
 308  322                  if [ -n "$uports6" ]; then
 309  323                          for uport6 in $uports6; do
 310  324                                  generate_rules $FMRI $policy "udp" $uport6 $file6 _6
 311  325                          done
 312  326                  fi
 313  327          fi
 314  328  
 315  329          ;;
 316  330  
 317  331  *)
 318  332          echo "Usage: $0 { start | stop | refresh }"
 319  333          exit 1
 320  334          ;;
 321  335  esac
 322  336  exit $SMF_EXIT_OK
  
    | 
      ↓ open down ↓ | 
    216 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX