aboutsummaryrefslogtreecommitdiff
path: root/init.d/fsck.in
blob: 008b1bca6892c271cf7b9f239e06041539f32567 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!@SBINDIR@/openrc-run
# Copyright (c) 2007-2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/HEAD/AUTHORS
#
# This file is part of OpenRC. It is subject to the license terms in
# the LICENSE file found in the top-level directory of this
# distribution and at https://github.com/OpenRC/openrc/blob/HEAD/LICENSE
# This file may not be copied, modified, propagated, or distributed
# except according to the terms contained in the LICENSE file.

description="Check and repair filesystems according to /etc/fstab"
_IFS="
"

depend()
{
	after clock
	use dev clock modules
	keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -timeout -vserver -uml
}

_abort() {
	yesno ${fsck_abort_on_errors:-yes} && rc-abort
	return 1
}

# We should only reboot when first booting
_reboot() {
	if [ "$RC_RUNLEVEL" = "$RC_BOOTLEVEL" ]; then
		reboot "$@"
		_abort || return 1
	fi
}

_forcefsck()
{
	[ -e /forcefsck ] || get_bootparam forcefsck
}

start()
{
	local fsck_opts= p= check_extra=

	if [ -e /fastboot ]; then
		ewarn "Skipping fsck due to /fastboot"
		return 0
	fi
	if _forcefsck; then
		fsck_opts="$fsck_opts -f"
		check_extra="(check forced)"
	elif ! yesno ${fsck_on_battery:-YES} && ! on_ac_power; then
		ewarn "Skipping fsck due to not being on AC power"
		return 0
	fi

	if [ -n "$fsck_passno" ]; then
		check_extra="[passno $fsck_passno] $check_extra"
		if [ -n "$fsck_mnt" ]; then
			eerror "Only 1 of fsck_passno and fsck_mnt must be set!"
			return 1
		fi
	fi
	ebegin "Checking local filesystems $check_extra"
	# Append passno mounts
	for p in $fsck_passno; do
		local IFS="$_IFS"
		case "$p" in
			[0-9]*) p="=$p";;
		esac
		set -- "$@" $(fstabinfo --passno "$p")
		unset IFS
	done
	# Append custom mounts
	for m in $fsck_mnt ; do
		local IFS="$_IFS"
		set -- "$@" "$m"
		unset IFS
	done

	if [ "$RC_UNAME" = Linux ]; then
		local skiptypes
		skiptypes=$(printf 'no%s,' ${net_fs_list} ${extra_net_fs_list})
		[ "${skiptypes}" = "no," ] && skiptypes=""
		fsck_opts="$fsck_opts -C0 -T -t ${skiptypes}noopts=_netdev"
		if [ -z "$fsck_passno" -a -z "$fsck_mnt" ]; then
			fsck_args=${fsck_args:--A -p}
			if echo 2>/dev/null >/.test.$$; then
				rm -f /.test.$$
				fsck_opts="$fsck_opts -R"
			fi
		fi
	fi

	trap : INT QUIT
	fsck ${fsck_args:--p} $fsck_opts "$@"
	case $? in
	0)	eend 0; return 0;;
	1)	ewend 1 "Filesystems repaired"; return 0;;
	2|3)	if [ "$RC_UNAME" = Linux ]; then
		 	ewend 1 "Filesystems repaired, but reboot needed"
	         	_reboot -f
		else
			ewend 1 "Filesystems still have errors;" \
				"manual fsck required"
			_abort
		fi;;
	4)	if [ "$RC_UNAME" = Linux ]; then
			ewend 1 "Filesystem errors left uncorrected, aborting"
			_abort
		else
		 	ewend 1 "Filesystems repaired, but reboot needed"
			_reboot
		fi;;
	8)	ewend 1 "Operational error"; return 0;;
	12)	ewend 1 "fsck interrupted";;
	*)	eend 2 "Filesystems couldn't be fixed";;
	esac
	_abort || return 1
}

stop()
{
	# Fake function so we always shutdown correctly.
	_abort() { return 0; }
	_reboot() { return 0; }
	_forcefsck() { return 1; }

	yesno $fsck_shutdown && start
	return 0
}