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