6777298 umountall(1M) -z ... limit unmounting action(s) to the current zone 6502014 NFS mounts in non-global zones are unmounted if NFS is restarted in the global zone 6512906 Autofs mounts in non-global zones are unmounted when autofs is restarted in the global zone 6777323 smb mounts in non-global zones are unmounted when smb/client is restarted in the global zone
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 2007 Sun Microsystems, Inc. All rights reserved. 24 # Use is subject to license terms. 25 # 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 # 28 # Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T 29 # All Rights Reserved 30 # 31 # 32 33 usage () { 34 if [ -n "$1" ]; then 35 echo "umountall: $1" 1>&2 36 fi 37 echo "Usage:\n\tumountall [-k] [-s] [-F FSType] [-l|-r] [-n]" 1>&2 38 echo "\tumountall [-k] [-s] [-h host] [-n]" 1>&2 39 exit 2 40 } 41 42 MNTTAB=/etc/mnttab 43 44 # This script is installed as both /sbin/umountall (as used in some 45 # /sbin/rc? and /etc/init.d scripts) _and_ as /usr/sbin/umountall (typically 46 # PATHed from the command line). As such it should not depend on /usr 47 # being mounted (if /usr is a separate filesystem). 48 # 49 # /sbin/sh Bourne shell builtins we use: 50 # echo 51 # exit 52 # getopts 53 # test, [ ] 54 # exec 55 # read 56 # 57 # /sbin commands we use: 58 # /sbin/uname 59 # /sbin/umount 60 # 61 # The following /usr based commands may be used by this script (depending on 62 # command line options). We will set our PATH to find them, but where they 63 # are not present (eg, if /usr is not mounted) we will catch references to 64 # them via shell functions conditionally defined after option processing 65 # (don't use any of these commands before then). 66 # 67 # Command Command line option and use 68 # /usr/bin/sleep -k, to sleep after an fuser -c -k on the mountpoint 69 # /usr/sbin/fuser -k, to kill processes keeping a mount point busy 70 # 71 # Copyright 2007 Sun Microsystems, Inc. All rights reserved. 72 # In addition, we use /usr/bin/tail if it is available; if not we use 73 # slower shell constructs to reverse a file. 74 75 PATH=/sbin:/usr/sbin:/usr/bin 76 77 DEFERRED_ACTIVATION_PATCH_FLAG="/var/run/.patch_loopback_mode" 78 SVC_STARTD="/lib/svc/bin/svc.startd" 79 80 # Clear these in case they were already set in our inherited environment. 81 FSType= 82 FFLAG= 83 HOST= 84 HFLAG= 85 RFLAG= 86 LFLAG= 87 SFLAG= 88 KFLAG= 89 NFLAG= 90 LOCALNAME= 91 UMOUNTFLAG= 92 93 94 while getopts ?rslkF:h:n c 95 do 96 case $c in 97 r) RFLAG="r";; 98 l) LFLAG="l";; 99 s) SFLAG="s";; 100 k) KFLAG="k";; 101 h) if [ -n "$HFLAG" ]; then 102 usage "more than one host specified" 103 fi 104 HOST=$OPTARG 105 HFLAG="h" 106 LOCALNAME=`uname -n` 107 ;; 108 F) if [ -n "$FFLAG" ]; then 109 usage "more than one FStype specified" 110 fi 111 FSType=$OPTARG 112 FFLAG="f" 113 case $FSType in 114 ?????????*) 115 usage "FSType ${FSType} exceeds 8 characters" 116 esac; 117 ;; 118 n) NFLAG="n" 119 # Alias any commands that would perform real actions to 120 # something that tells what action would have been performed 121 UMOUNTFLAG="-V" 122 fuser () { 123 echo "fuser $*" 1>&2 124 } 125 sleep () { 126 : # No need to show where we'd sleep 127 } 128 ;; 129 \?) usage "" 130 ;; 131 esac 132 done 133 134 # Sanity checking: 135 # 1) arguments beyond those supported 136 # 2) can't specify both remote and local 137 # 3) can't specify a host with -r or -l 138 # 4) can't specify a fstype with -h 139 # 5) can't specify this host with -h (checks only uname -n) 140 # 6) can't be fstype nfs and local 141 # 7) only fstype nfs is remote 142 143 if [ $# -ge $OPTIND ]; then # 1 144 usage "additional arguments not supported" 145 fi 146 147 if [ -n "$RFLAG" -a -n "$LFLAG" ]; then # 2 148 usage "options -r and -l are incompatible" 149 fi 150 151 if [ \( -n "$RFLAG" -o -n "$LFLAG" \) -a "$HFLAG" = "h" ]; then # 3 152 usage "option -${RFLAG}${LFLAG} incompatible with -h option" 153 fi 154 155 if [ -n "$FFLAG" -a "$HFLAG" = "h" ]; then # 4 156 usage "Specifying FStype incompatible with -h option" 157 fi 158 159 if [ -n "$HFLAG" -a "$HOST" = "$LOCALNAME" ]; then # 5 160 usage "Specifying local host illegal for -h option" 161 fi 162 163 if [ "$FSType" = "nfs" -a "$LFLAG" = "l" ]; then # 6 164 usage "option -l and FSType nfs are incompatible" 165 fi 166 167 if [ -n "$FFLAG" -a "$FSType" != "nfs" -a -n "$RFLAG" ]; then # 7 168 usage "option -r and FSType ${FSType} are incompatible" 169 fi 170 171 ZONENAME=`zonename` 172 173 # Check and if needed sync the boot archive before unmounting everything. 174 # 175 if [ -z "${RFLAG}${NFLAG}${HFLAG}${FSType}" -a "$ZONENAME" = "global" -a \ 176 `uname -p` = "i386" -a -x /sbin/bootadm ] ; then 177 /sbin/bootadm -a update_all 178 fi 179 180 181 # 182 # If we are in deferred activation patching, and the caller is 183 # svc.startd, then exit without unmounting any of the remaining 184 # file systems since the call path is from shutdown. Note that 185 # by the time we get here, smf stop methods for nfs, cachefs 186 # etc, will have run. 187 # 188 if [ -f $DEFERRED_ACTIVATION_PATCH_FLAG ] ; then 189 ppid=`ps -o ppid= -p $$` # parent of umountall will be sh 190 # from system() 191 192 ppid=`ps -o ppid= -p $ppid` # parent of sh will be svc.startd 193 COMM=`ps -o comm= -p $ppid` 194 if [ "$COMM" = "$SVC_STARTD" ] ; then 195 exit 196 fi 197 fi 198 199 # 200 # Take advantage of parallel unmounting at this point if we have no 201 # criteria to match and we are in the global zone 202 # 203 if [ -z "${SFLAG}${LFLAG}${RFLAG}${HFLAG}${KFLAG}${FFLAG}" -a \ 204 "$ZONENAME" = "global" ]; then 205 umount -a ${UMOUNTFLAG} 206 exit # with return code of the umount -a 207 fi 208 209 # 210 # Catch uses of /usr commands when /usr is not mounted 211 if [ -n "$KFLAG" -a -z "$NFLAG" ]; then 212 if [ ! -x /usr/sbin/fuser ]; then 213 fuser () { 214 echo "umountall: fuser -k skipped (no /usr)" 1>&2 215 # continue - not fatal 216 } 217 sleep () { 218 : # no point in sleeping if fuser is doing nothing 219 } 220 else 221 if [ ! -x /usr/bin/sleep ]; then 222 sleep () { 223 echo "umountall: sleep after fuser -k skipped (no /usr)" 1>&2 224 # continue - not fatal 225 } 226 fi 227 fi 228 fi 229 230 # 231 # Shell function to avoid using /usr/bin/cut. Given a dev from a 232 # fstype=nfs line in mnttab (eg, "host:/export) extract the host 233 # component. 234 print_host () { 235 OIFS=$IFS 236 IFS=":" 237 set -- $* 238 echo $1 239 IFS=$OIFS 240 } 241 242 # 243 # doumounts echos its return code to stdout, so commands used within 244 # this function should take care to produce no other output to stdout. 245 doumounts () { 246 ( 247 rc=0 248 fslist="" 249 while read dev mountp fstype mode dummy 250 do 251 case "${mountp}" in 252 / | \ 253 /dev | \ 254 /dev/fd | \ 255 /devices | \ 256 /etc/mnttab | \ 257 /etc/svc/volatile | \ 258 /lib | \ 259 /proc | \ 260 /sbin | \ 261 /system/contract | \ 262 /system/object | \ 263 /tmp | \ 264 /usr | \ 265 /var | \ 266 /var/adm | \ 267 /var/run | \ 268 '' ) 269 # 270 # file systems possibly mounted in the kernel or 271 # in the methods of some of the file system 272 # services 273 # 274 continue 275 ;; 276 * ) 277 if [ -n "$HFLAG" ]; then 278 if [ "$fstype" = "nfs" ]; then 279 thishost=`print_host $dev` 280 if [ "$HOST" != "$thishost" ]; then 281 continue 282 fi 283 else 284 continue 285 fi 286 fi 287 if [ -n "$FFLAG" -a "$FSType" != "$fstype" ]; then 288 continue 289 fi 290 if [ -n "$LFLAG" -a "$fstype" = "nfs" ]; then 291 continue 292 fi 293 if [ -n "$RFLAG" -a "$fstype" != "nfs" ]; then 294 continue 295 fi 296 if [ "$ZONENAME" != "global" ]; then 297 for option in `echo $mode | tr , '\012'`; do 298 # 299 # should not see any zone options 300 # but our own 301 # 302 if [ "$option" = "zone=$ZONENAME" ]; then 303 break 304 fi 305 done 306 if [ "$option" != "zone=$ZONENAME" ]; then 307 continue 308 fi 309 fi 310 if [ -n "${KFLAG}" ]; then 311 fuser -c -k $mountp 1>&2 312 sleep 2 313 fi 314 if [ -n "$SFLAG" ]; then 315 umount ${UMOUNTFLAG} ${mountp} 1>&2 316 trc=$? 317 if [ $trc -ne 0 ]; then 318 rc=$trc 319 fi 320 else 321 # We want to umount in parallel 322 fslist="$fslist $mountp" 323 fi 324 esac 325 done 326 327 if [ -n "$fslist" ]; then 328 umount -a ${UMOUNTFLAG} $fslist 1>&2 329 trc=$? 330 if [ $trc -ne 0 ]; then 331 rc=$trc 332 fi 333 fi 334 335 echo $rc 336 ) 337 } 338 339 # 340 # /etc/mnttab has the most recent mounts last. Reverse it so that we 341 # may umount in opposite order to the original mounts. 342 # 343 344 if [ ! -x /usr/bin/tail ]; then 345 exec < $MNTTAB 346 REVERSED= 347 while read line; do 348 if [ -n "$REVERSED" ]; then 349 REVERSED="$line\n$REVERSED" 350 else 351 REVERSED="$line" 352 fi 353 done 354 355 error=`echo $REVERSED | doumounts` 356 else 357 error=`tail -r $MNTTAB | doumounts` 358 fi 359 360 exit $error --- EOF ---