1#!/bin/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# Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26# 27# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T. 28# All rights reserved. 29# 30# 31#ident "%Z%%M% %I% %E% SMI" 32 33vfstab=${vfstab:=/etc/vfstab} 34 35# 36# readvfstab mount_point 37# -> (special, fsckdev, mountp, fstype, fsckpass, automnt, mntopts) 38# 39# A vfstab-like input stream is scanned for the mount point specified 40# as $1. Returns the fields of vfstab in the following shell 41# variables: 42# 43# special block device 44# fsckdev raw device 45# mountp mount point (must match $1, if found) 46# fstype file system type 47# fsckpass fsck(1M) pass number 48# automnt automount flag (yes or no) 49# mntopts file system-specific mount options. 50# 51# If the mount point can not be found in the standard input stream, 52# then all fields are set to empty values. This function assumes that 53# stdin is already set /etc/vfstab (or other appropriate input 54# stream). 55# 56readvfstab() { 57 while read special fsckdev mountp fstype fsckpass automnt mntopts; do 58 case "$special" in 59 '' ) # Ignore empty lines. 60 continue 61 ;; 62 63 '#'* ) # Ignore comment lines. 64 continue 65 ;; 66 67 '-') # Ignore "no-action" lines. 68 continue 69 ;; 70 esac 71 72 [ "x$mountp" = "x$1" ] && break 73 done 74} 75 76cecho() { 77 echo $* 78 echo $* >/dev/msglog 79} 80 81# 82# checkmessage raw_device fstype mountpoint 83# checkmessage2 raw_device fstype mountpoint 84# 85# Two simple auxilary routines to the shell function checkfs. Both 86# display instructions for a manual file system check. 87# 88checkmessage() { 89 cecho "" 90 cecho "WARNING - Unable to repair the $3 filesystem. Run fsck" 91 cecho "manually (fsck -F $2 $1)." 92 cecho "" 93} 94 95checkmessage2() { 96 cecho "" 97 cecho "WARNING - fatal error from fsck - error $4" 98 cecho "Unable to repair the $3 filesystem. Run fsck manually" 99 cecho "(fsck -F $2 $1)." 100 cecho "" 101} 102 103# 104# checkfs raw_device fstype mountpoint 105# 106# Check the file system specified. The return codes from fsck have the 107# following meanings. 108# 109# 0 file system is unmounted and okay 110# 32 file system is unmounted and needs checking (fsck -m only) 111# 33 file system is already mounted 112# 34 cannot stat device 113# 35 modified root or something equally dangerous 114# 36 uncorrectable errors detected - terminate normally (4.1 code 8) 115# 37 a signal was caught during processing (4.1 exit 12) 116# 39 uncorrectable errors detected - terminate rightaway (4.1 code 8) 117# 40 for root, same as 0 (used here to remount root) 118# 119checkfs() { 120 # skip checking if the fsckdev is "-" 121 [ "x$1" = x- ] && return 122 123 # if fsck isn't present, it is probably because either the mount of 124 # /usr failed or the /usr filesystem is badly damanged. In either 125 # case, there is not much to be done automatically. Fail with 126 # a message to the user. 127 if [ ! -x /usr/sbin/fsck ]; then 128 cecho "" 129 cecho "WARNING - /usr/sbin/fsck not found. Most likely the" 130 cecho "mount of /usr failed or the /usr filesystem is badly" 131 cecho "damaged." 132 cecho "" 133 return 1 134 fi 135 136 # If a filesystem-specific fsck binary is unavailable, then no 137 # fsck pass is required. 138 [ ! -x /usr/lib/fs/$2/fsck ] && [ ! -x /etc/fs/$2/fsck ] && return 139 140 /usr/sbin/fsck -F $2 -m $1 >/dev/null 2>&1 141 142 if [ $? -ne 0 ]; then 143 # Determine fsck options by file system type 144 case $2 in 145 ufs) foptions="-o p" 146 ;; 147 *) foptions="-y" 148 ;; 149 esac 150 151 cecho "The $3 file system ($1) is being checked." 152 /usr/sbin/fsck -F $2 $foptions $1 153 154 case $? in 155 0|40) # File system OK 156 ;; 157 158 1|34|36|37|39) # couldn't fix the file system - fail 159 checkmessage "$1" "$2" "$3" 160 return 1 161 ;; 162 163 *) # fsck child process killed (+ error code 35) 164 checkmessage2 "$1" "$2" "$3" "$?" 165 return 1 166 ;; 167 esac 168 fi 169 170 return 0 171} 172 173# 174# checkopt option option-string 175# -> ($option, $otherops) 176# 177# Check to see if a given mount option is present in the comma 178# separated list gotten from vfstab. 179# 180# Returns: 181# ${option} : the option if found the empty string if not found 182# ${otherops} : the option string with the found option deleted 183# 184checkopt() { 185 option= 186 otherops= 187 188 [ "x$2" = x- ] && return 189 190 searchop="$1" 191 set -- `IFS=, ; echo $2` 192 193 while [ $# -gt 0 ]; do 194 if [ "x$1" = "x$searchop" ]; then 195 option="$1" 196 else 197 if [ -z "$otherops" ]; then 198 otherops="$1" 199 else 200 otherops="${otherops},$1" 201 fi 202 fi 203 shift 204 done 205} 206 207# 208# hasopts $opts $allopts 209# 210# Check if all options from the list $opts are present in $allopts. 211# Both $opts and $allopts should be in comma separated format. 212# 213# Return 0 on success, and 1 otherwise. 214# 215hasopts() { 216 opts="$1" 217 allopts="$2" 218 219 set -- `IFS=, ; echo $opts` 220 while [ $# -gt 0 ]; do 221 if [ "$1" != "remount" ]; then 222 checkopt $1 $allopts 223 # 224 # Don't report errors if the filesystem is already 225 # read-write when mounting it as read-only. 226 # 227 [ -z "$option" ] && [ "$1" = "ro" ] && \ 228 checkopt rw $allopts 229 [ -z "$option" ] && return 1 230 fi 231 shift 232 done 233 return 0 234} 235 236# 237# mounted $path $fsopts $fstype 238# 239# Check whether the specified file system of the given type is currently 240# mounted with all required filesystem options by going through /etc/mnttab 241# in our standard input. 242# 243# Return values: 244# 0 Success. 245# 1 The filesystem is not currently mounted, or mounted without required 246# options, or a filesystem of a different type is mounted instead. 247# 248mounted() { 249 path="$1" 250 fsopts="$2" 251 fstype="$3" 252 253 while read mntspec mntpath mnttype mntopts on; do 254 [ "$mntpath" = "$path" ] || continue 255 [ "$fstype" != "-" ] && [ "$mnttype" != "$fstype" ] && return 1 256 [ "$fsopts" = "-" ] && return 0 257 hasopts $fsopts $mntopts && return 0 258 done 259 return 1 260} 261 262# 263# mountfs $opts $path $type $fsopts $special 264# 265# Try to mount a filesystem. If failed, display our standard error 266# message on the console and print more details about what happened 267# to our service log. 268# 269# Arguments: 270# $opts - options for mount(1M) [optional] 271# $path - mount point 272# $type - file system type [optional] 273# $fsopts - file system specific options (-o) [optional] 274# $special - device on which the file system resides [optional] 275# 276# Return codes: 277# 0 - success. 278# otherwise - error code returned by mount(1M). 279# 280mountfs() { 281 opts="$1" 282 path="$2" 283 special="$5" 284 285 # 286 # Take care of optional arguments 287 # 288 [ "$opts" = "-" ] && opts="" 289 [ "$special" = "-" ] && special="" 290 [ "$3" = "-" ] && type="" 291 [ "$3" != "-" ] && type="-F $3" 292 [ "$4" = "-" ] && fsopts="" 293 [ "$4" != "-" ] && fsopts="-o $4" 294 295 cmd="/sbin/mount $opts $type $fsopts $special $path" 296 msg=`$cmd 2>&1` 297 err=$? 298 299 [ $err = 0 ] && return 0 300 301 # 302 # If the specified file system is already mounted with all 303 # required options, and has the same filesystem type 304 # then ignore errors and return success 305 # 306 mounted $path $4 $3 < /etc/mnttab && return 0 307 308 echo "ERROR: $SMF_FMRI failed to mount $path "\ 309 "(see 'svcs -x' for details)" > /dev/msglog 310 echo "ERROR: $cmd failed, err=$err" 311 echo $msg 312 return $err 313} 314