Mercurial > illumos > illumos-gate
changeset 13349:06962a3446ee
910 mountall thinks smbfs filesystems are local
Reviewed by: Jason King <jason.brian.king+illumoshg@gmail.com>
Reviewed by: Robert Gordon <rbg@openrbg.com>
Reviewed by: Garrett D'Amore <garrett@nexenta.com>
Approved by: Garrett D'Amore <garrett@nexenta.com>
author | Gordon Ross <gwr@nexenta.com> |
---|---|
date | Mon, 25 Apr 2011 12:59:44 -0400 |
parents | 4389ac5d32c3 |
children | a4d1acb7a7f5 |
files | usr/src/cmd/initpkg/mountall.sh usr/src/cmd/initpkg/umountall.sh |
diffstat | 2 files changed, 141 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/initpkg/mountall.sh Mon Apr 25 12:48:49 2011 -0400 +++ b/usr/src/cmd/initpkg/mountall.sh Mon Apr 25 12:59:44 2011 -0400 @@ -20,16 +20,36 @@ # # CDDL HEADER END # + # -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T # All Rights Reserved # +usage () { + if [ -n "$1" ]; then + echo "mountall: $1" 1>&2 + fi + echo "Usage:\nmountall [-F FSType] [-l|-r|-g] [file_system_table]" 1>&2 + exit 2 +} + +PATH=/usr/sbin:/usr/bin +TYPES=all +FSTAB=/etc/vfstab +err=0 + +# Clear these in case they were already set in our environment. +FSType= +GFLAG= +RFLAG= +LFLAG= +SFLAG= +RemoteFSTypes= + # checkmessage "fsck_device | mount_point" # # Simple auxilary routine to the shell function checkfs. Prints out @@ -105,12 +125,29 @@ fi } +# Do the passed mount options include "global"? +isglobal() { + case ",${1}," in + *,global,*) + return 0 + ;; + esac + return 1 +} -PATH=/usr/sbin:/usr/bin -USAGE="Usage:\nmountall [-F FSType] [-l|-r|-g] [file_system_table]" -TYPES=all -FSTAB=/etc/vfstab -err=0 +# Is the passed fstype a "remote" one? +# Essentially: /usr/bin/grep "^$1" /etc/dfs/fstypes +isremote() { + for t in $RemoteFSTypes + do + [ "$t" = "$1" ] && return 0 + done + return 1 +} + +# Get list of remote FS types (just once) +RemoteFSTypes=`while read t junk; do echo $t; done < /etc/dfs/fstypes` + # # Process command line args @@ -136,16 +173,14 @@ exit 2 esac ;; - \?) echo "$USAGE" 1>&2; exit 2;; + \?) usage "";; esac done shift `/usr/bin/expr $OPTIND - 1` # get past the processed args if [ $# -gt 1 ]; then - echo "mountall: multiple arguments not supported" 1>&2 - echo "$USAGE" 1>&2 - exit 2 + usage "multiple arguments not supported" fi # get file system table name and make sure file exists @@ -179,22 +214,19 @@ "$RFLAG" = "r" -a "$GFLAG$LFLAG" != "" -o \ "$LFLAG" = "l" -a "$RFLAG$GFLAG" != "" ] then - echo "mountall: options -g, -r and -l are mutually exclusive" 1>&2 - echo "$USAGE" 1>&2 - exit 2 + usage "options -g, -r and -l are mutually exclusive" fi -if [ \( "$FSType" = "cachefs" -o "$FSType" = "nfs" \) -a "$LFLAG" = "l" ] -then - echo "mountall: option -l and FSType are incompatible" 1>&2 - echo "$USAGE" 1>&2 - exit 2 +if [ "$LFLAG" = "l" -a -n "$FSType" ]; then + # remote FSType not allowed + isremote "$FSType" && + usage "option -l and FSType are incompatible" fi -if [ "$FSType" -a "$FSType" != "nfs" -a "$RFLAG" = "r" ] -then - echo "mountall: option -r and FSType are incompatible" 1>&2 - echo "$USAGE" 1>&2 - exit 2 + +if [ "$RFLAG" = "r" -a -n "$FSType" ]; then + # remote FSType required + isremote "$FSType" || + usage "option -r and FSType are incompatible" fi # file-system-table format: @@ -232,25 +264,28 @@ continue fi - if [ "$LFLAG" ]; then - # Skip entries that have the "global" option. - g=`/usr/bin/grep '\<global\>' << EOF - $mntopts - EOF` - if [ "$fstype" = "cachefs" -o "$fstype" = "nfs" -o "$g" ]; then - continue - fi - elif [ "$RFLAG" -a "$fstype" != "nfs" ]; then - continue - elif [ "$GFLAG" ]; then - # Skip entries that have don't the "global" option. - g=`/usr/bin/grep '\<global\>' << EOF - $mntopts - EOF` - if [ "$fstype" = "cachefs" -o "$fstype" = "nfs" -o -z "$g" ] - then - continue - fi + # The -g option is not in the man page, but according to + # PSARC/1998/255 it's used by Sun Cluster (via contract) to + # mount disk-based filesystems with the "global" option. + # Also, the -l option now skips those "global" mounts. + # + # Note: options -g -l -r are mutually exclusive + # + if [ -n "$GFLAG" ]; then + # Mount "local" filesystems that have + # the "global" option in mntopts. + isremote "$fstype" && continue + isglobal "$mntopts" || continue + fi + if [ -n "$LFLAG" ]; then + # Mount "local" filesystems, excluding + # those marked "global". + isremote "$fstype" && continue + isglobal "$mntopts" && continue + fi + if [ -n "$RFLAG" ]; then + # Mount "remote" filesystems. + isremote "$fstype" || continue fi if [ "$fstype" = "-" ]; then @@ -374,8 +409,11 @@ exit fi +# Some remote filesystems (e.g. cachefs or autofs) shouldn't be be mounted +# with mountall, so the list here is explicit (not from /etc/dfs/fstypes) if [ "$RFLAG" ]; then /sbin/mount -a -F nfs + /sbin/mount -a -F smbfs exit fi
--- a/usr/src/cmd/initpkg/umountall.sh Mon Apr 25 12:48:49 2011 -0400 +++ b/usr/src/cmd/initpkg/umountall.sh Mon Apr 25 12:59:44 2011 -0400 @@ -83,8 +83,25 @@ NFLAG= LOCALNAME= UMOUNTFLAG= +RemoteFSTypes= + +# Is the passed fstype a "remote" one? +# Essentially: /usr/bin/grep "^$1" /etc/dfs/fstypes +isremote() { + for t in $RemoteFSTypes + do + [ "$t" = "$1" ] && return 0 + done + return 1 +} + +# Get list of remote FS types (just once) +RemoteFSTypes=`while read t junk; do echo $t; done < /etc/dfs/fstypes` +# +# Process command line args +# while getopts ?rslkF:h:Zn c do case $c in @@ -155,11 +172,15 @@ usage "Specifying local host illegal for -h option" fi -if [ "$FSType" = "nfs" -a "$LFLAG" = "l" ]; then # 6 - usage "option -l and FSType nfs are incompatible" +if [ "$LFLAG" = "l" -a -n "$FSType" ]; then # 6 + # remote FSType not allowed + isremote "$FSType" && + usage "option -l and FSType ${FSType} are incompatible" fi -if [ -n "$FFLAG" -a "$FSType" != "nfs" -a -n "$RFLAG" ]; then # 7 +if [ "$RFLAG" = "r" -a -n "$FSType" ]; then # 7 + # remote FSType required + isremote "$FSType" || usage "option -r and FSType ${FSType} are incompatible" fi @@ -189,7 +210,7 @@ else if [ ! -x /usr/bin/sleep ]; then sleep () { - echo "umountall: sleep after fuser -k skipped (no /usr)" 1>&2 + echo "umountall: sleep after fuser -k skipped (no /usr)" 1>&2 # continue - not fatal } fi @@ -199,14 +220,28 @@ # # Shell function to avoid using /usr/bin/cut. Given a dev from a # fstype=nfs line in mnttab (eg, "host:/export) extract the host -# component. -print_host () { +# component. The dev string looks like: "host:/path" +print_nfs_host () { OIFS=$IFS IFS=":" set -- $* echo $1 IFS=$OIFS } +# +# Similar for smbfs, but tricky due to the optional parts +# of the "device" syntax. The dev strings look like: +# "//server/share" or "//user@server/share" +print_smbfs_host () { + OIFS=$IFS + IFS="/@" + set -- $* + case $# in + 3) echo "$2";; + 2) echo "$1";; + esac + IFS=$OIFS +} # # doumounts echos its return code to stdout, so commands used within @@ -215,7 +250,6 @@ ( rc=0 fslist="" - nfslist="" while read dev mountp fstype mode dummy do case "${mountp}" in @@ -246,24 +280,28 @@ ;; * ) if [ -n "$HFLAG" ]; then + thishost='-' if [ "$fstype" = "nfs" ]; then - thishost=`print_host $dev` - if [ "$HOST" != "$thishost" ]; then - continue - fi - else + thishost=`print_nfs_host $dev` + fi + if [ "$fstype" = "smbfs" ]; then + thishost=`print_smbfs_host $dev` + fi + if [ "$HOST" != "$thishost" ]; then continue fi fi if [ -n "$FFLAG" -a "$FSType" != "$fstype" ]; then continue fi - if [ -n "$LFLAG" -a "$fstype" = "nfs" ]; then - nfslist="$nfslist $mountp" - continue + + if [ -n "$LFLAG" ]; then + # umount local filesystems + isremote "$fstype" && continue fi - # - # This will filter out autofs mounts with nfs file + + # Note: isremote is true for both nfs & autofs, so + # this will filter out autofs mounts with nfs file # system mounted on the top of it. # # WARNING: use of any syscall on a NFS file system has @@ -272,19 +310,11 @@ # down beforehand. # For the reason described above, a simple test like # "df -F nfs $mountp" can't be used to filter out - # nfs-over-autofs mounts. We loop over a list instead: + # nfs-over-autofs mounts. (isremote works OK) # - if [ -n "$LFLAG" -a -n "$nfslist" -a "$fstype" = "autofs" ] - then - for m in $nfslist; do - if [ "$mountp" = "$m" ]; then - # Resume the outer while loop - continue 2 - fi - done - fi - if [ -n "$RFLAG" -a "$fstype" != "nfs" ]; then - continue + if [ -n "$RFLAG" ]; then + # umount remote filesystems + isremote "$fstype" || continue fi if [ "$ZONENAME" != "global" ]; then for option in `echo $mode | tr , '\012'`; do