#!/sbin/sh # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # Copyright 2015 Nexenta Systems, Inc. All rights reserved. # # Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T # All Rights Reserved # proc usage { if test -n $1 { echo "mountall: $1" 1>&2 } echo "Usage:\nmountall [-F FSType] [-l|-r|-g] [file_system_table]" 1>&2 exit 2 } setvar PATH = "/usr/sbin:/usr/bin" setvar TYPES = 'all' setvar FSTAB = '/etc/vfstab' setvar err = '0' # Clear these in case they were already set in our environment. setvar FSType = '' setvar GFLAG = '' setvar RFLAG = '' setvar LFLAG = '' setvar SFLAG = '' setvar RemoteFSTypes = '' # checkmessage "fsck_device | mount_point" # # Simple auxilary routine to the shell function checkfs. Prints out # instructions for a manual file system check before entering the shell. # proc checkmessage { echo "" > /dev/console if test $1 != "" { echo "WARNING - Unable to repair one or more \c" > /dev/console echo "of the following filesystem(s):" > /dev/console echo "\t$1" > /dev/console } else { echo "WARNING - Unable to repair one or more filesystems." \ > /dev/console } echo "Run fsck manually (fsck filesystem...)." > /dev/console echo "" > /dev/console } # # checkfs raw_device fstype mountpoint # # Check the file system specified. The return codes from fsck have the # following meanings. # 0 - file system is unmounted and okay # 32 - file system is unmounted and needs checking (fsck -m only) # 33 - file system is already mounted # 34 - cannot stat device # 36 - uncorrectable errors detected - terminate normally (4.1 code 8) # 37 - a signal was caught during processing (4.1 exit 12) # 39 - uncorrectable errors detected - terminate rightaway (4.1 code 8) # 40 - for root, same as 0 (used by rcS to remount root) # proc checkfs { /usr/sbin/fsck -F $2 -m $1 >/dev/null 2>&1 if test $Status -ne 0 { # Determine fsck options by file system type match $2 { with ufs setvar foptions = ""-o p"" with * setvar foptions = ""-y"" } echo "The "$3" file system ("$1") is being checked." /usr/sbin/fsck -F $2 ${foptions} $1 match $Status { with 0|40 # file system OK with * # couldn't fix the file system echo "/usr/sbin/fsck failed with exit code "$Status"." checkmessage $1 } } } # # Used to save an entry that we will want to mount either in # a command file or as a mount point list. # # saveentry fstype options special mountp # proc saveentry { if test $ALTM { echo "/sbin/mount -F $1 $2 $3 $4" >> $ALTM } else { setvar mntlist = ""$mntlist $4"" } } # Do the passed mount options include "global"? proc isglobal { match ",${1}," { with *,global,* return 0 } return 1 } # Is the passed fstype a "remote" one? # Essentially: /usr/bin/grep "^$1" /etc/dfs/fstypes proc isremote { for t in [$RemoteFSTypes] { test $t = $1 && return 0 } return 1 } # Get list of remote FS types (just once) setvar RemoteFSTypes = $(while read t junk { echo $t; }) # # Process command line args # while getopts ?grlsF: c { match $c { with g setvar GFLAG = ""g"" with r setvar RFLAG = ""r"" with l setvar LFLAG = ""l"" with s setvar SFLAG = ""s"" with F setvar FSType = "$OPTARG"; if test $TYPES = "one" { echo "mountall: more than one FSType specified" exit 2 } setvar TYPES = ""one""; match $FSType { with ?????????* echo "mountall: FSType $FSType exceeds 8 characters" exit 2 } with \? usage "" } } shift $(/usr/bin/expr $OPTIND - 1) # get past the processed args if test $Argc -gt 1 { usage "multiple arguments not supported" } # get file system table name and make sure file exists if test $Argc = 1 { match $1 { with "-" setvar FSTAB = """" with * setvar FSTAB = "$1" } } # # if an alternate vfstab file is used or serial mode is specified, then # use a mount command file # if test $Argc = 1 -o $SFLAG { setvar ALTM = "/var/tmp/mount$Pid" rm -f $ALTM } if test $FSTAB != "" -a ! -s $FSTAB { echo "mountall: file system table ($FSTAB) not found" exit 1 } # # Check for incompatible args # if test $GFLAG = "g" -a "$RFLAG$LFLAG" != "" -o \ $RFLAG = "r" -a "$GFLAG$LFLAG" != "" -o \ $LFLAG = "l" -a "$RFLAG$GFLAG" != "" { usage "options -g, -r and -l are mutually exclusive" } if test $LFLAG = "l" -a -n $FSType { # remote FSType not allowed isremote $FSType && usage "option -l and FSType are incompatible" } if test $RFLAG = "r" -a -n $FSType { # remote FSType required isremote $FSType || usage "option -r and FSType are incompatible" } # file-system-table format: # # column 1: special- block special device or resource name # column 2: fsckdev- char special device for fsck # column 3: mountp- mount point # column 4: fstype- File system type # column 5: fsckpass- number if to be checked automatically # column 6: automnt- yes/no for automatic mount # column 7: mntopts- -o specific mount options # White-space separates columns. # Lines beginning with \"#\" are comments. Empty lines are ignored. # a '-' in any field is a no-op. # # Read FSTAB, fsck'ing appropriate filesystems: # exec < $FSTAB while read special fsckdev mountp fstype fsckpass automnt mntopts { match $special { with '#'* | '' # Ignore comments, empty lines continue with '-' # Ignore no-action lines continue } if test $automnt != "yes" { continue } if test $FSType -a $FSType != $fstype { # ignore different fstypes continue } # 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 test -n $GFLAG { # Mount "local" filesystems that have # the "global" option in mntopts. isremote $fstype && continue isglobal $mntopts || continue } if test -n $LFLAG { # Mount "local" filesystems, excluding # those marked "global". isremote $fstype && continue isglobal $mntopts && continue } if test -n $RFLAG { # Mount "remote" filesystems. isremote $fstype || continue } if test $fstype = "-" { echo "mountall: FSType of $special cannot be identified" 1>&2 continue } if test $ALTM -a $mntopts != "-" { setvar OPTIONS = ""-o $mntopts"" # Use mount options if any } else { setvar OPTIONS = """" } # # Ignore entries already mounted # /usr/bin/grep " $mountp " /etc/mnttab >/dev/null 2>&1 && continue # # Can't fsck if no fsckdev is specified # if test $fsckdev = "-" { saveentry $fstype $OPTIONS $special $mountp continue } # # For fsck purposes, we make a distinction between file systems # that have a /usr/lib/fs//fsckall script and those # that don't. For those that do, just keep a list of them # and pass the list to the fsckall script for that file # file system type. # if test -x /usr/lib/fs/$fstype/fsckall { # # add fstype to the list of fstypes for which # fsckall should be called, if it's not already # in the list. # setvar found = 'no' if test $fsckall_fstypes != "" { for fst in [$fsckall_fstypes] { if test $fst = $fstype { setvar found = 'yes' break } } } if test $found = no { setvar fsckall_fstypes = ""$fsckall_fstypes ${fstype}"" } # # add the device to the name of devices to be passed # to the fsckall program for this file system type # setvar cmd = ""${fstype}_fscklist=\"\$${fstype}_fscklist $fsckdev"\"" eval $cmd saveentry $fstype $OPTIONS $special $mountp continue } # # fsck everything else: # # fsck -m simply returns true if the filesystem is suitable for # mounting. # /usr/sbin/fsck -m -F $fstype $fsckdev >/dev/null 2>&1 match $Status { with 0|40 saveentry $fstype $OPTIONS $special $mountp continue with 32 checkfs $fsckdev $fstype $mountp saveentry $fstype $OPTIONS $special $mountp continue with 33 # already mounted echo "$special already mounted" with 34 # bogus special device echo "Cannot stat $fsckdev - ignoring" setvar err = '1' with * # uncorrectable errors echo "$fsckdev uncorrectable error" setvar err = '1' } } # # Call the fsckall programs # for fst in [$fsckall_fstypes] { setvar cmd = ""/usr/lib/fs/$fst/fsckall \$${fst}_fscklist"" eval $cmd match $Status { with 0 # file systems OK with * # couldn't fix some of the filesystems echo "fsckall failed with exit code "$Status"." checkmessage } } if test $ALTM { if test ! -f $ALTM { exit } /sbin/sh $ALTM # run the saved mount commands /usr/bin/rm -f $ALTM exit } if test -n $FSType { /sbin/mount -a -F $FSType exit } # Some remote filesystems (e.g. autofs) shouldn't be mounted # with mountall, so the list here is explicit (not from /etc/dfs/fstypes) if test $RFLAG { /sbin/mount -a -F nfs /sbin/mount -a -F smbfs exit } if test $LFLAG -o $GFLAG -o $err != 0 { test -z $mntlist || /sbin/mount -a $mntlist exit } # else mount them all /sbin/mount -a