xref: /illumos-gate/usr/src/cmd/initpkg/mountall.sh (revision b6805bf78d2bbbeeaea8909a05623587b42d58b3)
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, Version 1.0 only
7# (the "License").  You may not use this file except in compliance
8# with the License.
9#
10# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11# or http://www.opensolaris.org/os/licensing.
12# See the License for the specific language governing permissions
13# and limitations under the License.
14#
15# When distributing Covered Code, include this CDDL HEADER in each
16# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17# If applicable, add the following below this CDDL HEADER, with the
18# fields enclosed by brackets "[]" replaced with your own identifying
19# information: Portions Copyright [yyyy] [name of copyright owner]
20#
21# CDDL HEADER END
22#
23
24#
25# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
26# Use is subject to license terms.
27#
28#	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
29#	  All Rights Reserved
30#
31
32usage () {
33	if [ -n "$1" ]; then
34		echo "mountall: $1" 1>&2
35	fi
36	echo "Usage:\nmountall [-F FSType] [-l|-r|-g] [file_system_table]" 1>&2
37	exit 2
38}
39
40PATH=/usr/sbin:/usr/bin
41TYPES=all
42FSTAB=/etc/vfstab
43err=0
44
45# Clear these in case they were already set in our environment.
46FSType=
47GFLAG=
48RFLAG=
49LFLAG=
50SFLAG=
51RemoteFSTypes=
52
53#	checkmessage "fsck_device | mount_point"
54#
55# Simple auxilary routine to the shell function checkfs. Prints out
56# instructions for a manual file system check before entering the shell.
57#
58checkmessage() {
59	echo "" > /dev/console
60	if [ "$1" != "" ] ; then
61		echo "WARNING - Unable to repair one or more \c" > /dev/console
62		echo "of the following filesystem(s):" > /dev/console
63		echo "\t$1" > /dev/console
64	else
65		echo "WARNING - Unable to repair one or more filesystems." \
66			> /dev/console
67	fi
68	echo "Run fsck manually (fsck filesystem...)." > /dev/console
69	echo "" > /dev/console
70}
71
72#
73#	checkfs raw_device fstype mountpoint
74#
75# Check the file system specified. The return codes from fsck have the
76# following meanings.
77#	 0 - file system is unmounted and okay
78#	32 - file system is unmounted and needs checking (fsck -m only)
79#	33 - file system is already mounted
80#	34 - cannot stat device
81#	36 - uncorrectable errors detected - terminate normally (4.1 code 8)
82#	37 - a signal was caught during processing (4.1 exit 12)
83#	39 - uncorrectable errors detected - terminate rightaway (4.1 code 8)
84#	40 - for root, same as 0 (used by rcS to remount root)
85#
86checkfs() {
87	/usr/sbin/fsck -F $2 -m $1  >/dev/null 2>&1
88
89	if [ $? -ne 0 ]
90	then
91		# Determine fsck options by file system type
92		case "$2" in
93		ufs)	foptions="-o p"
94			;;
95		*)	foptions="-y"
96			;;
97		esac
98
99		echo "The "$3" file system ("$1") is being checked."
100		/usr/sbin/fsck -F $2 ${foptions} $1
101
102		case $? in
103		0|40)	# file system OK
104			;;
105
106		*)	# couldn't fix the file system
107			echo "/usr/sbin/fsck failed with exit code "$?"."
108			checkmessage "$1"
109			;;
110		esac
111	fi
112}
113
114#
115# Used to save an entry that we will want to mount either in
116# a command file or as a mount point list.
117#
118# saveentry fstype options special mountp
119#
120saveentry() {
121	if [ "$ALTM" ]; then
122		echo "/sbin/mount -F $1 $2 $3 $4" >> $ALTM
123	else
124		mntlist="$mntlist $4"
125	fi
126}
127
128# Do the passed mount options include "global"?
129isglobal() {
130	case ",${1}," in
131	*,global,*)
132		return 0
133		;;
134	esac
135	return 1
136}
137
138# Is the passed fstype a "remote" one?
139# Essentially: /usr/bin/grep "^$1" /etc/dfs/fstypes
140isremote() {
141	for t in $RemoteFSTypes
142	do
143		[ "$t" = "$1" ] && return 0
144	done
145	return 1
146}
147
148# Get list of remote FS types (just once)
149RemoteFSTypes=`while read t junk; do echo $t; done < /etc/dfs/fstypes`
150
151
152#
153# Process command line args
154#
155while getopts ?grlsF: c
156do
157	case $c in
158	g)	GFLAG="g";;
159	r)	RFLAG="r";;
160	l)	LFLAG="l";;
161	s)	SFLAG="s";;
162	F)	FSType="$OPTARG";
163		if [ "$TYPES" = "one" ]
164		then
165			echo "mountall: more than one FSType specified"
166			exit 2
167		fi
168		TYPES="one";
169
170		case $FSType in
171		?????????*)
172			echo "mountall: FSType $FSType exceeds 8 characters"
173			exit 2
174		esac
175		;;
176	\?)	usage "";;
177	esac
178done
179
180shift `/usr/bin/expr $OPTIND - 1`	# get past the processed args
181
182if [ $# -gt 1 ]; then
183	usage "multiple arguments not supported"
184fi
185
186# get file system table name and make sure file exists
187if [ $# = 1 ]; then
188	case $1 in
189	"-")	FSTAB=""
190		;;
191	*)	FSTAB=$1
192		;;
193	esac
194fi
195#
196# if an alternate vfstab file is used or serial mode is specified, then
197# use a mount command file
198#
199if [ $# = 1 -o "$SFLAG" ]; then
200	ALTM=/var/tmp/mount$$
201	rm -f $ALTM
202fi
203
204if [ "$FSTAB" != ""  -a  ! -s "$FSTAB" ]
205then
206	echo "mountall: file system table ($FSTAB) not found"
207	exit 1
208fi
209
210#
211# Check for incompatible args
212#
213if [ "$GFLAG" = "g" -a "$RFLAG$LFLAG" != "" -o \
214     "$RFLAG" = "r" -a "$GFLAG$LFLAG" != "" -o \
215     "$LFLAG" = "l" -a "$RFLAG$GFLAG" != "" ]
216then
217	usage "options -g, -r and -l are mutually exclusive"
218fi
219
220if [ "$LFLAG" = "l" -a -n "$FSType" ]; then
221	# remote FSType not allowed
222	isremote "$FSType" &&
223	usage "option -l and FSType are incompatible"
224fi
225
226if [ "$RFLAG" = "r" -a -n "$FSType" ]; then
227	# remote FSType required
228	isremote "$FSType" ||
229	usage "option -r and FSType are incompatible"
230fi
231
232#	file-system-table format:
233#
234#	column 1:	special- block special device or resource name
235#	column 2: 	fsckdev- char special device for fsck
236#	column 3:	mountp- mount point
237#	column 4:	fstype- File system type
238#	column 5:	fsckpass- number if to be checked automatically
239#	column 6:	automnt-	yes/no for automatic mount
240#	column 7:	mntopts- -o specific mount options
241
242#	White-space separates columns.
243#	Lines beginning with \"#\" are comments.  Empty lines are ignored.
244#	a '-' in any field is a no-op.
245
246#
247# Read FSTAB, fsck'ing appropriate filesystems:
248#
249exec < $FSTAB
250while  read special fsckdev mountp fstype fsckpass automnt mntopts
251do
252	case $special in
253	'#'* | '')	#  Ignore comments, empty lines
254			continue ;;
255	'-')		#  Ignore no-action lines
256			continue
257	esac
258
259	if [ "$automnt" != "yes" ]; then
260		continue
261	fi
262	if [ "$FSType" -a "$FSType" != "$fstype" ]; then
263		# ignore different fstypes
264		continue
265	fi
266
267	# The -g option is not in the man page, but according to
268	# PSARC/1998/255 it's used by Sun Cluster (via contract) to
269	# mount disk-based filesystems with the "global" option.
270	# Also, the -l option now skips those "global" mounts.
271	#
272	# Note: options -g -l -r are mutually exclusive
273	#
274	if [ -n "$GFLAG" ]; then
275		# Mount "local" filesystems that have
276		# the "global" option in mntopts.
277		isremote "$fstype" && continue
278		isglobal "$mntopts" || continue
279	fi
280	if [ -n "$LFLAG" ]; then
281		# Mount "local" filesystems, excluding
282		# those marked "global".
283		isremote "$fstype" && continue
284		isglobal "$mntopts" && continue
285	fi
286	if [ -n "$RFLAG" ]; then
287		# Mount "remote" filesystems.
288		isremote "$fstype" || continue
289	fi
290
291	if [ "$fstype" = "-" ]; then
292		echo "mountall: FSType of $special cannot be identified" 1>&2
293		continue
294	fi
295
296	if [ "$ALTM" -a "$mntopts" != "-" ]; then
297		OPTIONS="-o $mntopts"		# Use mount options if any
298	else
299		OPTIONS=""
300	fi
301
302	#
303	# Ignore entries already mounted
304	#
305	/usr/bin/grep "	$mountp	" /etc/mnttab >/dev/null 2>&1 && continue
306
307	#
308	# Can't fsck if no fsckdev is specified
309	#
310	if [ "$fsckdev" = "-" ]; then
311		saveentry $fstype "$OPTIONS" $special $mountp
312		continue
313	fi
314	#
315	# For fsck purposes, we make a distinction between file systems
316	# that have a /usr/lib/fs/<fstyp>/fsckall script and those
317	# that don't.  For those that do, just keep a list of them
318	# and pass the list to the fsckall script for that file
319	# file system type.
320	#
321	if [ -x /usr/lib/fs/$fstype/fsckall ]; then
322
323		#
324		# add fstype to the list of fstypes for which
325		# fsckall should be called, if it's not already
326		# in the list.
327		#
328		found=no
329		if [ "$fsckall_fstypes" != "" ] ; then
330			for fst in $fsckall_fstypes; do
331				if [ "$fst" = "$fstype" ] ; then
332					found=yes
333					break
334				fi
335			done
336		fi
337		if [ $found = no ] ; then
338			fsckall_fstypes="$fsckall_fstypes ${fstype}"
339		fi
340
341		#
342		# add the device to the name of devices to be passed
343		# to the fsckall program for this file system type
344		#
345		cmd="${fstype}_fscklist=\"\$${fstype}_fscklist $fsckdev\""
346		eval $cmd
347		saveentry $fstype "$OPTIONS" $special $mountp
348		continue
349	fi
350	#
351	# fsck everything else:
352 	#
353 	# fsck -m simply returns true if the filesystem is suitable for
354 	# mounting.
355 	#
356	/usr/sbin/fsck -m -F $fstype $fsckdev >/dev/null 2>&1
357	case $? in
358	0|40)	saveentry $fstype "$OPTIONS" $special $mountp
359		continue
360		;;
361	32)	checkfs $fsckdev $fstype $mountp
362		saveentry $fstype "$OPTIONS" $special $mountp
363		continue
364		;;
365	33)	# already mounted
366		echo "$special already mounted"
367		;;
368	34)	# bogus special device
369		echo "Cannot stat $fsckdev - ignoring"
370		err=1
371		;;
372	*)	# uncorrectable errors
373		echo "$fsckdev uncorrectable error"
374		err=1
375		;;
376	esac
377done
378
379#
380# Call the fsckall programs
381#
382for fst in $fsckall_fstypes
383do
384	cmd="/usr/lib/fs/$fst/fsckall \$${fst}_fscklist"
385	eval $cmd
386
387	case $? in
388	0)	# file systems OK
389			;;
390
391	*)	# couldn't fix some of the filesystems
392		echo "fsckall failed with exit code "$?"."
393		checkmessage
394		;;
395	esac
396done
397
398if [ "$ALTM" ]; then
399	if [ ! -f "$ALTM" ]; then
400		exit
401	fi
402	/sbin/sh $ALTM		# run the saved mount commands
403	/usr/bin/rm -f $ALTM
404	exit
405fi
406
407if [ -n "$FSType" ]; then
408	/sbin/mount -a -F $FSType
409	exit
410fi
411
412# Some remote filesystems (e.g. cachefs or autofs) shouldn't be be mounted
413# with mountall, so the list here is explicit (not from /etc/dfs/fstypes)
414if [ "$RFLAG" ]; then
415	/sbin/mount -a -F nfs
416	/sbin/mount -a -F smbfs
417	exit
418fi
419
420if [ "$LFLAG" -o "$GFLAG" -o $err != 0 ]; then
421	[ -z "$mntlist" ] || /sbin/mount -a $mntlist
422	exit
423fi
424
425# else mount them all
426
427/sbin/mount -a
428