diff options
Diffstat (limited to 'usr/src/cmd/svc/shell/fs_include.sh')
-rw-r--r-- | usr/src/cmd/svc/shell/fs_include.sh | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/usr/src/cmd/svc/shell/fs_include.sh b/usr/src/cmd/svc/shell/fs_include.sh new file mode 100644 index 0000000000..9d0b6d3512 --- /dev/null +++ b/usr/src/cmd/svc/shell/fs_include.sh @@ -0,0 +1,309 @@ +#!/bin/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 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T. +# All rights reserved. +# +# +#ident "%Z%%M% %I% %E% SMI" + +vfstab=${vfstab:=/etc/vfstab} + +# +# readvfstab mount_point +# -> (special, fsckdev, mountp, fstype, fsckpass, automnt, mntopts) +# +# A vfstab-like input stream is scanned for the mount point specified +# as $1. Returns the fields of vfstab in the following shell +# variables: +# +# special block device +# fsckdev raw device +# mountp mount point (must match $1, if found) +# fstype file system type +# fsckpass fsck(1M) pass number +# automnt automount flag (yes or no) +# mntopts file system-specific mount options. +# +# If the mount point can not be found in the standard input stream, +# then all fields are set to empty values. This function assumes that +# stdin is already set /etc/vfstab (or other appropriate input +# stream). +# +readvfstab() { + while read special fsckdev mountp fstype fsckpass automnt mntopts; do + case "$special" in + '' ) # Ignore empty lines. + continue + ;; + + '#'* ) # Ignore comment lines. + continue + ;; + + '-') # Ignore "no-action" lines. + continue + ;; + esac + + [ "x$mountp" = "x$1" ] && break + done +} + +cecho() { + echo $* + echo $* >/dev/msglog +} + +# +# checkmessage raw_device fstype mountpoint +# checkmessage2 raw_device fstype mountpoint +# +# Two simple auxilary routines to the shell function checkfs. Both +# display instructions for a manual file system check. +# +checkmessage() { + cecho "" + cecho "WARNING - Unable to repair the $3 filesystem. Run fsck" + cecho "manually (fsck -F $2 $1)." + cecho "" +} + +checkmessage2() { + cecho "" + cecho "WARNING - fatal error from fsck - error $4" + cecho "Unable to repair the $3 filesystem. Run fsck manually" + cecho "(fsck -F $2 $1)." + cecho "" +} + +# +# 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 here to remount root) +# +checkfs() { + # skip checking if the fsckdev is "-" + [ "x$1" = x- ] && return + + # if fsck isn't present, it is probably because either the mount of + # /usr failed or the /usr filesystem is badly damanged. In either + # case, there is not much to be done automatically. Fail with + # a message to the user. + + if [ ! -x /usr/sbin/fsck ]; then + cecho "" + cecho "WARNING - /usr/sbin/fsck not found. Most likely the" + cecho "mount of /usr failed or the /usr filesystem is badly" + cecho "damaged." + cecho "" + return 1 + fi + + /usr/sbin/fsck -F $2 -m $1 >/dev/null 2>&1 + + if [ $? -ne 0 ]; then + # Determine fsck options by file system type + case $2 in + ufs) foptions="-o p" + ;; + *) foptions="-y" + ;; + esac + + cecho "The $3 file system ($1) is being checked." + /usr/sbin/fsck -F $2 $foptions $1 + + case $? in + 0|40) # File system OK + ;; + + 1|34|36|37|39) # couldn't fix the file system - fail + checkmessage "$1" "$2" "$3" + return 1 + ;; + + *) # fsck child process killed (+ error code 35) + checkmessage2 "$1" "$2" "$3" "$?" + return 1 + ;; + esac + fi + + return 0 +} + +# +# checkopt option option-string +# -> ($option, $otherops) +# +# Check to see if a given mount option is present in the comma +# separated list gotten from vfstab. +# +# Returns: +# ${option} : the option if found the empty string if not found +# ${otherops} : the option string with the found option deleted +# +checkopt() { + option= + otherops= + + [ "x$2" = x- ] && return + + searchop="$1" + set -- `IFS=, ; echo $2` + + while [ $# -gt 0 ]; do + if [ "x$1" = "x$searchop" ]; then + option="$1" + else + if [ -z "$otherops" ]; then + otherops="$1" + else + otherops="${otherops},$1" + fi + fi + shift + done +} + +# +# hasopts $opts $allopts +# +# Check if all options from the list $opts are present in $allopts. +# Both $opts and $allopts should be in comma separated format. +# +# Return 0 on success, and 1 otherwise. +# +hasopts() { + opts="$1" + allopts="$2" + + set -- `IFS=, ; echo $opts` + while [ $# -gt 0 ]; do + if [ "$1" != "remount" ]; then + checkopt $1 $allopts + # + # Don't report errors if the filesystem is already + # read-write when mounting it as read-only. + # + [ -z "$option" ] && [ "$1" = "ro" ] && \ + checkopt rw $allopts + [ -z "$option" ] && return 1 + fi + shift + done + return 0 +} + +# +# mounted $path $fsopts $fstype +# +# Check whether the specified file system of the given type is currently +# mounted with all required filesystem options by going through /etc/mnttab +# in our standard input. +# +# Return values: +# 0 Success. +# 1 The filesystem is not currently mounted, or mounted without required +# options, or a filesystem of a different type is mounted instead. +# +mounted() { + path="$1" + fsopts="$2" + fstype="$3" + + while read mntspec mntpath mnttype mntopts on; do + [ "$mntpath" = "$path" ] || continue + [ "$fstype" != "-" ] && [ "$mnttype" != "$fstype" ] && return 1 + [ "$fsopts" = "-" ] && return 0 + hasopts $fsopts $mntopts && return 0 + done + return 1 +} + +# +# mountfs $opts $path $type $fsopts $special +# +# Try to mount a filesystem. If failed, display our standard error +# message on the console and print more details about what happened +# to our service log. +# +# Arguments: +# $opts - options for mount(1M) [optional] +# $path - mount point +# $type - file system type [optional] +# $fsopts - file system specific options (-o) [optional] +# $special - device on which the file system resides [optional] +# +# Return codes: +# 0 - success. +# otherwise - error code returned by mount(1M). +# +mountfs() { + opts="$1" + path="$2" + special="$5" + + # + # Take care of optional arguments + # + [ "$opts" = "-" ] && opts="" + [ "$special" = "-" ] && special="" + [ "$3" = "-" ] && type="" + [ "$3" != "-" ] && type="-F $3" + [ "$4" = "-" ] && fsopts="" + [ "$4" != "-" ] && fsopts="-o $4" + + cmd="/sbin/mount $opts $type $fsopts $special $path" + msg=`$cmd 2>&1` + err=$? + + [ $err = 0 ] && return 0 + + # + # If the specified file system is already mounted with all + # required options, and has the same filesystem type + # then ignore errors and return success + # + mounted $path $4 $3 < /etc/mnttab && return 0 + + echo "ERROR: $SMF_FMRI failed to mount $path "\ + "(see 'svcs -x' for details)" > /dev/msglog + echo "ERROR: $cmd failed, err=$err" + echo $msg + return $err +} |