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