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