xref: /onnv-gate/usr/src/cmd/svc/shell/fs_include.sh (revision 6423:437422a29d3a)
10Sstevel@tonic-gate#!/bin/sh
20Sstevel@tonic-gate#
30Sstevel@tonic-gate# CDDL HEADER START
40Sstevel@tonic-gate#
50Sstevel@tonic-gate# The contents of this file are subject to the terms of the
62716Smishra# Common Development and Distribution License (the "License").
72716Smishra# You may not use this file except in compliance with the License.
80Sstevel@tonic-gate#
90Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate# See the License for the specific language governing permissions
120Sstevel@tonic-gate# and limitations under the License.
130Sstevel@tonic-gate#
140Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate#
200Sstevel@tonic-gate# CDDL HEADER END
210Sstevel@tonic-gate#
220Sstevel@tonic-gate#
236168Shs24103# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate# Use is subject to license terms.
250Sstevel@tonic-gate#
260Sstevel@tonic-gate# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T.
270Sstevel@tonic-gate# All rights reserved.
280Sstevel@tonic-gate#
290Sstevel@tonic-gate#
300Sstevel@tonic-gate#ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate
320Sstevel@tonic-gatevfstab=${vfstab:=/etc/vfstab}
330Sstevel@tonic-gate
340Sstevel@tonic-gate#
350Sstevel@tonic-gate# readvfstab mount_point
360Sstevel@tonic-gate#   -> (special, fsckdev, mountp, fstype, fsckpass, automnt, mntopts)
370Sstevel@tonic-gate#
380Sstevel@tonic-gate#   A vfstab-like input stream is scanned for the mount point specified
390Sstevel@tonic-gate#   as $1.  Returns the fields of vfstab in the following shell
400Sstevel@tonic-gate#   variables:
410Sstevel@tonic-gate#
420Sstevel@tonic-gate#       special		block device
430Sstevel@tonic-gate#       fsckdev		raw device
440Sstevel@tonic-gate#       mountp		mount point (must match $1, if found)
450Sstevel@tonic-gate#       fstype		file system type
460Sstevel@tonic-gate#       fsckpass	fsck(1M) pass number
470Sstevel@tonic-gate#       automnt		automount flag (yes or no)
480Sstevel@tonic-gate#       mntopts		file system-specific mount options.
490Sstevel@tonic-gate#
500Sstevel@tonic-gate#   If the mount point can not be found in the standard input stream,
510Sstevel@tonic-gate#   then all fields are set to empty values.  This function assumes that
520Sstevel@tonic-gate#   stdin is already set /etc/vfstab (or other appropriate input
530Sstevel@tonic-gate#   stream).
540Sstevel@tonic-gate#
550Sstevel@tonic-gatereadvfstab() {
560Sstevel@tonic-gate	while read special fsckdev mountp fstype fsckpass automnt mntopts; do
570Sstevel@tonic-gate		case "$special" in
580Sstevel@tonic-gate			'' )	# Ignore empty lines.
590Sstevel@tonic-gate				continue
600Sstevel@tonic-gate				;;
610Sstevel@tonic-gate
620Sstevel@tonic-gate			'#'* )	# Ignore comment lines.
630Sstevel@tonic-gate				continue
640Sstevel@tonic-gate				;;
650Sstevel@tonic-gate
660Sstevel@tonic-gate			'-')	# Ignore "no-action" lines.
670Sstevel@tonic-gate				continue
680Sstevel@tonic-gate				;;
690Sstevel@tonic-gate		esac
700Sstevel@tonic-gate
710Sstevel@tonic-gate		[ "x$mountp" = "x$1" ] && break
720Sstevel@tonic-gate	done
730Sstevel@tonic-gate}
740Sstevel@tonic-gate
75*6423Sgw25295readswapdev() {
76*6423Sgw25295	while read special fsckdev mountp fstype fsckpass automnt mntopts; do
77*6423Sgw25295		# Ignore comments, empty lines, and no-action lines
78*6423Sgw25295		case "$special" in
79*6423Sgw25295		'#'* | '' | '-') continue;;
80*6423Sgw25295		esac
81*6423Sgw25295
82*6423Sgw25295		[ "$fstype" != swap ] && continue
83*6423Sgw25295
84*6423Sgw25295		[ "x$special" = "x$1" ] && break
85*6423Sgw25295	done
86*6423Sgw25295}
87*6423Sgw25295
886168Shs24103#
896168Shs24103# readmnttab mount_point
906168Shs24103#   -> (special, mountp, fstype, mntopts, mnttime)
916168Shs24103#
926168Shs24103#   A mnttab-like input stream is scanned for the mount point specified
936168Shs24103#   as $1.  Returns the fields of mnttab in the following shell
946168Shs24103#   variables:
956168Shs24103#
966168Shs24103#       special		block device
976168Shs24103#       mountp		mount point (must match $1, if found)
986168Shs24103#       fstype		file system type
996168Shs24103#       mntopts		file system-specific mount options.
1006168Shs24103#	mnttime		time at which file system was mounted
1016168Shs24103#
1026168Shs24103#   If the mount point can not be found in the standard input stream,
1036168Shs24103#   then all fields are set to empty values.  This function assumes that
1046168Shs24103#   stdin is already set to /etc/mnttab (or other appropriate input
1056168Shs24103#   stream).
1066168Shs24103#
1076168Shs24103readmnttab() {
1086168Shs24103	while read special mountp fstype mntopts mnttime; do
1096168Shs24103		[ "x$mountp" = "x$1" ] && break
1106168Shs24103	done
1116168Shs24103}
1126168Shs24103
1130Sstevel@tonic-gatececho() {
1140Sstevel@tonic-gate	echo $*
1150Sstevel@tonic-gate	echo $* >/dev/msglog
1160Sstevel@tonic-gate}
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate#
1190Sstevel@tonic-gate# checkmessage raw_device fstype mountpoint
1200Sstevel@tonic-gate# checkmessage2 raw_device fstype mountpoint
1210Sstevel@tonic-gate#
1220Sstevel@tonic-gate#   Two simple auxilary routines to the shell function checkfs.  Both
1230Sstevel@tonic-gate#   display instructions for a manual file system check.
1240Sstevel@tonic-gate#
1250Sstevel@tonic-gatecheckmessage() {
1260Sstevel@tonic-gate	cecho ""
1270Sstevel@tonic-gate	cecho "WARNING - Unable to repair the $3 filesystem. Run fsck"
1280Sstevel@tonic-gate	cecho "manually (fsck -F $2 $1)."
1290Sstevel@tonic-gate	cecho ""
1300Sstevel@tonic-gate}
1310Sstevel@tonic-gate
1320Sstevel@tonic-gatecheckmessage2() {
1330Sstevel@tonic-gate	cecho ""
1340Sstevel@tonic-gate	cecho "WARNING - fatal error from fsck - error $4"
1350Sstevel@tonic-gate	cecho "Unable to repair the $3 filesystem. Run fsck manually"
1360Sstevel@tonic-gate	cecho "(fsck -F $2 $1)."
1370Sstevel@tonic-gate	cecho ""
1380Sstevel@tonic-gate}
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate#
1410Sstevel@tonic-gate# checkfs raw_device fstype mountpoint
1420Sstevel@tonic-gate#
1430Sstevel@tonic-gate#   Check the file system specified. The return codes from fsck have the
1440Sstevel@tonic-gate#   following meanings.
1450Sstevel@tonic-gate#
1460Sstevel@tonic-gate#	 0	file system is unmounted and okay
1470Sstevel@tonic-gate#	32	file system is unmounted and needs checking (fsck -m only)
1480Sstevel@tonic-gate#	33	file system is already mounted
1490Sstevel@tonic-gate#	34	cannot stat device
150392Sswilcox#	35	modified root or something equally dangerous
1510Sstevel@tonic-gate#	36	uncorrectable errors detected - terminate normally (4.1 code 8)
1520Sstevel@tonic-gate#	37	a signal was caught during processing (4.1 exit 12)
1530Sstevel@tonic-gate#	39	uncorrectable errors detected - terminate rightaway (4.1 code 8)
1540Sstevel@tonic-gate#	40	 for root, same as 0 (used here to remount root)
1550Sstevel@tonic-gate#
1560Sstevel@tonic-gatecheckfs() {
1570Sstevel@tonic-gate	# skip checking if the fsckdev is "-"
1580Sstevel@tonic-gate	[ "x$1" = x- ] && return
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate	# if fsck isn't present, it is probably because either the mount of
1610Sstevel@tonic-gate	# /usr failed or the /usr filesystem is badly damanged.  In either
1620Sstevel@tonic-gate	# case, there is not much to be done automatically.  Fail with
1630Sstevel@tonic-gate	# a message to the user.
1640Sstevel@tonic-gate	if [ ! -x /usr/sbin/fsck ]; then
1650Sstevel@tonic-gate		cecho ""
1660Sstevel@tonic-gate		cecho "WARNING - /usr/sbin/fsck not found.  Most likely the"
1670Sstevel@tonic-gate		cecho "mount of /usr failed or the /usr filesystem is badly"
1680Sstevel@tonic-gate		cecho "damaged."
1690Sstevel@tonic-gate		cecho ""
1700Sstevel@tonic-gate		return 1
1710Sstevel@tonic-gate	fi
1720Sstevel@tonic-gate
173974Ssch	# If a filesystem-specific fsck binary is unavailable, then no
174974Ssch	# fsck pass is required.
175974Ssch	[ ! -x /usr/lib/fs/$2/fsck ] && [ ! -x /etc/fs/$2/fsck ] && return
176974Ssch
1770Sstevel@tonic-gate	/usr/sbin/fsck -F $2 -m $1 >/dev/null 2>&1
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate	if [ $? -ne 0 ]; then
1800Sstevel@tonic-gate		# Determine fsck options by file system type
1810Sstevel@tonic-gate		case $2 in
1820Sstevel@tonic-gate			ufs)	foptions="-o p"
1830Sstevel@tonic-gate				;;
1840Sstevel@tonic-gate			*)	foptions="-y"
1850Sstevel@tonic-gate				;;
1860Sstevel@tonic-gate		esac
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate		cecho "The $3 file system ($1) is being checked."
1890Sstevel@tonic-gate		/usr/sbin/fsck -F $2 $foptions $1
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate		case $? in
1920Sstevel@tonic-gate		0|40)	# File system OK
1930Sstevel@tonic-gate			;;
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate		1|34|36|37|39)	# couldn't fix the file system - fail
1960Sstevel@tonic-gate			checkmessage "$1" "$2" "$3"
1970Sstevel@tonic-gate			return 1
1980Sstevel@tonic-gate			;;
1992716Smishra		33)	# already mounted
2002716Smishra			return 0
2012716Smishra			;;
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate		*)	# fsck child process killed (+ error code 35)
2040Sstevel@tonic-gate			checkmessage2 "$1" "$2" "$3" "$?"
2050Sstevel@tonic-gate			return 1
2060Sstevel@tonic-gate			;;
2070Sstevel@tonic-gate		esac
2080Sstevel@tonic-gate	fi
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate	return 0
2110Sstevel@tonic-gate}
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate#
2140Sstevel@tonic-gate# checkopt option option-string
2150Sstevel@tonic-gate# -> ($option, $otherops)
2160Sstevel@tonic-gate#
2170Sstevel@tonic-gate#   Check to see if a given mount option is present in the comma
2180Sstevel@tonic-gate#   separated list gotten from vfstab.
2190Sstevel@tonic-gate#
2200Sstevel@tonic-gate#	Returns:
2210Sstevel@tonic-gate#	${option}       : the option if found the empty string if not found
2220Sstevel@tonic-gate#	${otherops}     : the option string with the found option deleted
2230Sstevel@tonic-gate#
2240Sstevel@tonic-gatecheckopt() {
2250Sstevel@tonic-gate	option=
2260Sstevel@tonic-gate	otherops=
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate	[ "x$2" = x- ] && return
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate	searchop="$1"
2310Sstevel@tonic-gate	set -- `IFS=, ; echo $2`
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate	while [ $# -gt 0 ]; do
2340Sstevel@tonic-gate		if [ "x$1" = "x$searchop" ]; then
2350Sstevel@tonic-gate			option="$1"
2360Sstevel@tonic-gate		else
2370Sstevel@tonic-gate			if [ -z "$otherops" ]; then
2380Sstevel@tonic-gate				otherops="$1"
2390Sstevel@tonic-gate			else
2400Sstevel@tonic-gate				otherops="${otherops},$1"
2410Sstevel@tonic-gate			fi
2420Sstevel@tonic-gate		fi
2430Sstevel@tonic-gate		shift
2440Sstevel@tonic-gate	done
2450Sstevel@tonic-gate}
2460Sstevel@tonic-gate
2470Sstevel@tonic-gate#
2480Sstevel@tonic-gate# hasopts $opts $allopts
2490Sstevel@tonic-gate#
2500Sstevel@tonic-gate#   Check if all options from the list $opts are present in $allopts.
2510Sstevel@tonic-gate#   Both $opts and $allopts should be in comma separated format.
2520Sstevel@tonic-gate#
2530Sstevel@tonic-gate# Return 0 on success, and 1 otherwise.
2540Sstevel@tonic-gate#
2550Sstevel@tonic-gatehasopts() {
2560Sstevel@tonic-gate	opts="$1"
2570Sstevel@tonic-gate	allopts="$2"
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate	set -- `IFS=, ; echo $opts`
2600Sstevel@tonic-gate	while [ $# -gt 0 ]; do
2610Sstevel@tonic-gate		if [ "$1" != "remount" ]; then
2620Sstevel@tonic-gate			checkopt $1 $allopts
2630Sstevel@tonic-gate			#
2640Sstevel@tonic-gate			# Don't report errors if the filesystem is already
2650Sstevel@tonic-gate			# read-write when mounting it as read-only.
2660Sstevel@tonic-gate			#
2670Sstevel@tonic-gate			[ -z "$option" ] && [ "$1" = "ro" ] && \
2680Sstevel@tonic-gate				checkopt rw $allopts
2690Sstevel@tonic-gate			[ -z "$option" ] && return 1
2700Sstevel@tonic-gate		fi
2710Sstevel@tonic-gate		shift
2720Sstevel@tonic-gate	done
2730Sstevel@tonic-gate	return 0
2740Sstevel@tonic-gate}
2750Sstevel@tonic-gate
2760Sstevel@tonic-gate#
2770Sstevel@tonic-gate# mounted $path $fsopts $fstype
2780Sstevel@tonic-gate#
2790Sstevel@tonic-gate#   Check whether the specified file system of the given type is currently
2800Sstevel@tonic-gate#   mounted with all required filesystem options by going through /etc/mnttab
2810Sstevel@tonic-gate#   in our standard input.
2820Sstevel@tonic-gate#
2830Sstevel@tonic-gate#   Return values:
2840Sstevel@tonic-gate#   0	Success.
2850Sstevel@tonic-gate#   1	The filesystem is not currently mounted, or mounted without required
2860Sstevel@tonic-gate#	options, or a filesystem of a different type is mounted instead.
2870Sstevel@tonic-gate#
2880Sstevel@tonic-gatemounted() {
2890Sstevel@tonic-gate	path="$1"
2900Sstevel@tonic-gate	fsopts="$2"
2910Sstevel@tonic-gate	fstype="$3"
2920Sstevel@tonic-gate
2930Sstevel@tonic-gate	while read mntspec mntpath mnttype mntopts on; do
2940Sstevel@tonic-gate		[ "$mntpath" = "$path" ] || continue
2950Sstevel@tonic-gate		[ "$fstype" != "-" ] && [ "$mnttype" != "$fstype" ] && return 1
2960Sstevel@tonic-gate		[ "$fsopts" = "-" ] && return 0
2970Sstevel@tonic-gate		hasopts $fsopts $mntopts && return 0
2980Sstevel@tonic-gate	done
2990Sstevel@tonic-gate	return 1
3000Sstevel@tonic-gate}
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate#
3030Sstevel@tonic-gate# mountfs $opts $path $type $fsopts $special
3040Sstevel@tonic-gate#
3050Sstevel@tonic-gate#   Try to mount a filesystem.  If failed, display our standard error
3060Sstevel@tonic-gate#   message on the console and print more details about what happened
3070Sstevel@tonic-gate#   to our service log.
3080Sstevel@tonic-gate#
3090Sstevel@tonic-gate# Arguments:
3100Sstevel@tonic-gate#   $opts	- options for mount(1M)				[optional]
3110Sstevel@tonic-gate#   $path	- mount point
3120Sstevel@tonic-gate#   $type	- file system type				[optional]
3130Sstevel@tonic-gate#   $fsopts	- file system specific options (-o)		[optional]
3140Sstevel@tonic-gate#   $special	- device on which the file system resides	[optional]
3150Sstevel@tonic-gate#
3160Sstevel@tonic-gate# Return codes:
3170Sstevel@tonic-gate#   0		- success.
3180Sstevel@tonic-gate#   otherwise	- error code returned by mount(1M).
3190Sstevel@tonic-gate#
3200Sstevel@tonic-gatemountfs() {
3210Sstevel@tonic-gate	opts="$1"
3220Sstevel@tonic-gate	path="$2"
3230Sstevel@tonic-gate	special="$5"
3240Sstevel@tonic-gate
3250Sstevel@tonic-gate	#
3260Sstevel@tonic-gate	# Take care of optional arguments
3270Sstevel@tonic-gate	#
3280Sstevel@tonic-gate	[ "$opts" = "-" ] && opts=""
3290Sstevel@tonic-gate	[ "$special" = "-" ] &&	special=""
3300Sstevel@tonic-gate	[ "$3" = "-" ] && type=""
3310Sstevel@tonic-gate	[ "$3" != "-" ] && type="-F $3"
3320Sstevel@tonic-gate	[ "$4" = "-" ] && fsopts=""
3330Sstevel@tonic-gate	[ "$4" != "-" ] && fsopts="-o $4"
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate	cmd="/sbin/mount $opts $type $fsopts $special $path"
3360Sstevel@tonic-gate	msg=`$cmd 2>&1`
3370Sstevel@tonic-gate	err=$?
3380Sstevel@tonic-gate
3390Sstevel@tonic-gate	[ $err = 0 ] && return 0
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate	#
3420Sstevel@tonic-gate	# If the specified file system is already mounted with all
3430Sstevel@tonic-gate	# required options, and has the same filesystem type
3440Sstevel@tonic-gate	# then ignore errors and return success
3450Sstevel@tonic-gate	#
3460Sstevel@tonic-gate	mounted $path $4 $3 < /etc/mnttab && return 0
3470Sstevel@tonic-gate
3480Sstevel@tonic-gate	echo "ERROR: $SMF_FMRI failed to mount $path "\
3490Sstevel@tonic-gate	     "(see 'svcs -x' for details)" > /dev/msglog
3500Sstevel@tonic-gate	echo "ERROR: $cmd failed, err=$err"
3510Sstevel@tonic-gate	echo $msg
3520Sstevel@tonic-gate	return $err
3530Sstevel@tonic-gate}
354