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