1 #! /usr/bin/ksh -p
   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 2008 Sun Microsystems, Inc.  All rights reserved.
  25 # Use is subject to license terms.
  26 #
  27 # operate_dir <share|unshare> <directroy> [options]
  28 #
  29 
  30 ZFS=/usr/sbin/zfs
  31 
  32 #
  33 # Check if the specified directory is ZFS filesystem mountpoint
  34 #
  35 # $1 Directory
  36 #
  37 function is_zfs_mntpnt
  38 {
  39         [[ -n $DEBUG ]] && [[ $DEBUG != 0 ]] && set -x
  40 
  41         typeset dir=$1
  42         [[ -z $dir ]] && return 1
  43 
  44         typeset mntpnt=$($ZFS list -H -o mountpoint)
  45         mntpnt=$(echo $mntpnt | tr -s "\n" " ")
  46         if [[ " $mntpnt " == *" $dir "* ]]; then
  47                 return 0
  48         fi
  49 
  50         return 1
  51 }
  52 
  53 #
  54 # According to mountpoint get the ZFS filesystem name.
  55 #
  56 # $1 Directory
  57 #
  58 function getfs_by_mntpnt
  59 {
  60         [[ -n $DEBUG ]] && [[ $DEBUG != 0 ]] && set -x
  61 
  62         typeset dir=$1
  63 
  64         typeset fs=$($ZFS list -H -o name,mountpoint | \
  65                 grep "${dir}$" | awk '{print $1}')
  66         echo $fs
  67 }
  68 
  69 #
  70 # According to env variable to share the specified direcotry
  71 #
  72 # $1 Directory
  73 # $2 Optinal for share
  74 #
  75 function share_dir
  76 {
  77         [[ -n $DEBUG ]] && [[ $DEBUG != 0 ]] && set -x
  78 
  79         typeset dir=$1
  80         typeset opt=${2:-"rw"}
  81 
  82         typeset -i ret=0
  83         typeset tmpfile=/tmp/share_dir.err.$$
  84 
  85         if (( RANDOM % 2 == 0)) && is_zfs_mntpnt $dir ; then
  86                 typeset fs=$(getfs_by_mntpnt $dir)
  87                 echo "# $ZFS set sharenfs=$opt $fs" > $tmpfile 
  88                 $ZFS set sharenfs="$opt" $fs >> $tmpfile 2>&1 
  89                 ret=$?
  90 
  91                 typeset sharedir=$(share | awk '{print $2}' | grep -w "$dir")
  92                 sharedir=$(echo $sharedir | tr -s "\n" " ")
  93                 if [[ " $sharedir " != *" $dir "* ]] && (( ret == 0 )) ; then
  94                         echo "# $ZFS share $fs" >> $tmpfile 
  95                         $ZFS share $fs >> $tmpfile 2>&1
  96                         ((ret |= $?))
  97                 fi
  98 
  99                 #
 100                 # Print shared information for logging in journal file.
 101                 #
 102                 if (( ret == 0 )); then
 103                         echo "SHARE: $this 'zfs share' $opt $dir"
 104                 else
 105                         echo "WARNING: $this 'zfs share' $opt $dir, failed"
 106                         sed 's/^/WARNING: /' $tmpfile 2>&1 
 107                 fi
 108         else
 109                 # share with "-p" option, so that it is persistent when the \
 110                 # smf service is refreshed by "sharectl set" in some subdirs
 111                 echo "# share -F nfs -p -o $opt $dir" > $tmpfile
 112                 share -F nfs -p -o $opt $dir >> $tmpfile 2>&1
 113                 ret=$?
 114                 if (( ret == 0 )); then
 115                         echo "SHARE: $this 'share' $opt $dir"
 116                 else
 117                         echo "ERROR: $this 'share' $opt $dir, failed"
 118                         sed 's/^/ERROR: /' $tmpfile 2>&1 
 119                 fi
 120         fi
 121 
 122         rm -f $tmpfile
 123         return $ret
 124 }
 125 
 126 #
 127 # According to env variable to unshare the directory
 128 #
 129 # $1 Directory
 130 #
 131 function unshare_dir
 132 {
 133         [[ -n $DEBUG ]] && [[ $DEBUG != 0 ]] && set -x
 134 
 135         typeset dir=$1
 136         [[ -z $dir ]] && return 1
 137 
 138         typeset fs=$(getfs_by_mntpnt $dir)
 139         typeset share_status=$($ZFS get -H -o value sharenfs $fs)
 140         typeset -i ret=0
 141         if [[ $share_status != "off" ]] && is_zfs_mntpnt $dir ; then
 142                 $ZFS set sharenfs=off $fs
 143                 ret=$?
 144         else
 145                 unshare -p $dir
 146                 ret=$?
 147         fi
 148 
 149         return $ret
 150 }
 151 
 152 #######################  FUNCTIONS END HERE  ##########################
 153 
 154 [[ -n $DEBUG ]] && [[ $DEBUG != 0 ]] && set -x
 155 
 156 this=$(basename $0)
 157 operate=$1
 158 dir=$2
 159 opt=${3:-"rw"}
 160 if [[ -z $operate || -z $dir ]] ; then
 161         echo "Usage: $this <share|unshare> <directroy> [options]"
 162         exit 1
 163 fi
 164 
 165 case $operate in
 166         share) 
 167                 share_dir $dir $opt
 168                 exit $?
 169                 ;;
 170         unshare) 
 171                 unshare_dir $dir 
 172                 exit $?
 173                 ;;
 174         *) 
 175                 echo "Usage: $this <share|unshare> <directroy> [options]"
 176                 exit 1
 177                 ;;
 178 esac