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