149 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
		
			Executable File
		
	
	
	
	
| #!/sbin/runscript
 | |
| # Copyright 2007 Roy Marples
 | |
| # All rights reserved
 | |
| 
 | |
| # Redistribution and use in source and binary forms, with or without
 | |
| # modification, are permitted provided that the following conditions
 | |
| # are met:
 | |
| # 1. Redistributions of source code must retain the above copyright
 | |
| #    notice, this list of conditions and the following disclaimer.
 | |
| # 2. Redistributions in binary form must reproduce the above copyright
 | |
| #    notice, this list of conditions and the following disclaimer in the
 | |
| #    documentation and/or other materials provided with the distribution.
 | |
| #
 | |
| # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 | |
| # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | |
| # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 | |
| # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | |
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | |
| # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | |
| # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | |
| # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | |
| # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | |
| # SUCH DAMAGE.
 | |
| 
 | |
| description="Check the root filesystem according to /etc/fstab for errors \
 | |
| and optionally repair them."
 | |
| 
 | |
| depend() {
 | |
| 	keywords notimeout
 | |
| }
 | |
| 
 | |
| do_mtab() {
 | |
| 	# Don't create mtab if /etc is readonly
 | |
| 	if ! echo 2>/dev/null >/etc/mtab; then
 | |
| 		ewarn "Skipping /etc/mtab initialization (ro root)"
 | |
| 		return 0
 | |
| 	fi
 | |
| 	ebegin "Updating /etc/mtab"
 | |
| 
 | |
| 	# With / as tmpfs we cannot umount -at tmpfs in localmount as that
 | |
| 	# makes / readonly and dismounts all tmpfs even if in use which is
 | |
| 	# not good. Luckily, umount uses /etc/mtab instead of /proc/mounts
 | |
| 	# which allows this hack to work.
 | |
| 	grep -v "^[^ ]* / tmpfs " /proc/mounts > /etc/mtab
 | |
| 
 | |
| 	# Remove stale backups
 | |
| 	rm -f /etc/mtab~ /etc/mtab~~
 | |
| 	eend 0
 | |
| }
 | |
| 
 | |
| root_rw() {
 | |
| 	echo 2>/dev/null >/.test.$$ || return 1
 | |
| 	rm -f /.test.$$
 | |
| }
 | |
| 
 | |
| do_fsck() {
 | |
| 	local retval=0 opts= root=
 | |
| 	case "${RC_UNAME}" in
 | |
| 		FreeBSD) opts="-F";;
 | |
| 		Linux) opts="-T -C0";;
 | |
| 	esac
 | |
| 
 | |
| 	# Don't bother doing a fsck on these
 | |
| 	if [ -n "${CDBOOT}" ] || is_net_fs / || is_union_fs /; then
 | |
| 		return 0
 | |
| 	fi
 | |
| 
 | |
| 	if root_rw; then
 | |
| 		einfo "root filesystem is mounted read-write - skipping"
 | |
| 		return 0
 | |
| 	fi
 | |
| 
 | |
| 	root=$(fstabinfo --blockdevice /)
 | |
| 	[ ! -e "${root}" -a -e /dev/root ] && root=/dev/root
 | |
| 
 | |
| 	# Obey the fs_passno setting for / (see fstab(5))
 | |
| 	local pass=$(fstabinfo --passno /)
 | |
| 	if [ ${pass:-0} != "0" ]; then
 | |
| 		ebegin "Checking root filesystem"
 | |
| 		fsck ${opts} -p "${root}"
 | |
| 		retval=$?
 | |
| 	else
 | |
| 		ebegin "Skipping root filesystem check (fstab's passno == 0)"
 | |
| 		retval=0
 | |
| 	fi
 | |
| 
 | |
| 	if [ ${retval} -eq 0 ]; then
 | |
| 		eend 0
 | |
| 	elif [ ${retval} -eq 1 ]; then
 | |
| 		ewend 1 "Filesystem repaired"
 | |
| 		retval=0
 | |
| 	elif [ ${retval} -eq 8 ]; then
 | |
| 		ewend 1 $"Operational error, continuing"
 | |
| 		retval=0
 | |
| 	elif [ ${retval} -eq 2 -o ${retval} -eq 3 ]; then
 | |
| 		ewend 1 "Filesystem repaired, but reboot needed!"
 | |
| 		if ! yesno ${rc_force_auto:-${RC_FORCE_AUTO}}; then
 | |
| 			printf "\a"; sleep 1; printf "\a"; sleep 1
 | |
| 			printf "\a"; sleep 1; printf "\a"; sleep 1
 | |
| 			ewarn "Rebooting in 10 seconds ..."
 | |
| 			sleep 10
 | |
| 		fi
 | |
| 		einfo "Rebooting"
 | |
| 		reboot -f
 | |
| 	else
 | |
| 		if yesno ${rc_force_auto:-${RC_FORCE_AUTO}}; then
 | |
| 			eend 2 "Rerunning fsck in force mode"
 | |
| 			fsck ${opts} -y "${root}"
 | |
| 			retval=$?
 | |
| 		else
 | |
| 			eend 2 "Filesystem couldn't be fixed :("
 | |
| 			exec rc-abort || exit 1
 | |
| 		fi
 | |
| 		if [ ${retval} != "0" ]; then
 | |
| 			einfo "Unmounting filesystems"
 | |
| 			if [ "${RC_UNAME}" = "Linux" ]; then
 | |
| 				mount -a -o remount,ro /
 | |
| 			else
 | |
| 				mount -u -o ro /
 | |
| 			fi
 | |
| 			einfo "Rebooting"
 | |
| 			reboot -f
 | |
| 		fi
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| start() {
 | |
| 	do_fsck || return 1
 | |
| 
 | |
| 	if ! root_rw; then
 | |
| 		ebegin "Remounting root filesystem read/write"
 | |
| 		if [ "${RC_UNAME}" = "Linux" ]; then
 | |
| 			mount -n -o remount,rw /
 | |
| 		else
 | |
| 			mount -u -o rw /
 | |
| 		fi
 | |
| 		eend $? "Root filesystem could not be mounted read/write" || return $?
 | |
| 	fi
 | |
| 
 | |
| 	# Only Linux has mtab
 | |
| 	[ "${RC_UNAME}" = "Linux" -a -e /proc/mounts ] && do_mtab
 | |
| 
 | |
| 	# We got here, so return 0
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| # vim: set ts=4 :
 |