]>
Commit | Line | Data |
---|---|---|
fefab84f MS |
1 | #!/bin/sh |
2 | # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- | |
3 | # ex: ts=8 sw=4 sts=4 et filetype=sh | |
4 | ||
5 | type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh | |
6 | ||
7 | fsck_ask_reboot() { | |
8 | info "note - fsck suggests reboot, if you" | |
9 | info "leave shell, booting will continue normally" | |
10 | emergency_shell -n "(reboot ?)" | |
11 | } | |
12 | ||
13 | fsck_ask_err() { | |
14 | warn "*** An error occurred during the file system check." | |
15 | warn "*** Dropping you to a shell; the system will try" | |
16 | warn "*** to mount the filesystem(s), when you leave the shell." | |
17 | emergency_shell -n "(Repair filesystem)" | |
18 | } | |
19 | ||
20 | # inherits: _ret _drv _out | |
21 | fsck_tail() { | |
22 | [ $_ret -gt 0 ] && warn "$_drv returned with $_ret" | |
23 | if [ $_ret -ge 4 ]; then | |
24 | [ -n "$_out" ] && echo "$_out"|vwarn | |
25 | fsck_ask_err | |
26 | else | |
27 | [ -n "$_out" ] && echo "$_out"|vinfo | |
28 | [ $_ret -ge 2 ] && fsck_ask_reboot | |
29 | fi | |
30 | } | |
31 | ||
32 | # note: this function sets _drv of the caller | |
33 | fsck_able() { | |
34 | case "$1" in | |
35 | xfs) { | |
36 | type xfs_db && | |
37 | type xfs_repair && | |
38 | type xfs_check && | |
39 | type mount && | |
40 | type umount | |
41 | } >/dev/null 2>&1 && | |
42 | _drv="_drv=none fsck_drv_xfs" && | |
43 | return 0 | |
44 | ;; | |
45 | ext?) | |
46 | type e2fsck >/dev/null 2>&1 && | |
47 | _drv="_drv=e2fsck fsck_drv_com" && | |
48 | return 0 | |
49 | ;; | |
50 | jfs) | |
51 | type jfs_fsck >/dev/null 2>&1 && | |
52 | _drv="_drv=jfs_fsck fsck_drv_com" && | |
53 | return 0 | |
54 | ;; | |
55 | reiserfs) | |
56 | type reiserfsck >/dev/null 2>&1 && | |
57 | _drv="_drv=reiserfsck fsck_drv_com" && | |
58 | return 0 | |
59 | ;; | |
1afa0cb6 HH |
60 | btrfs) |
61 | type btrfsck >/dev/null 2>&1 && | |
662ed0a1 | 62 | _drv="_drv=none fsck_drv_btrfs" && |
1afa0cb6 HH |
63 | return 0 |
64 | ;; | |
fefab84f MS |
65 | *) |
66 | type fsck >/dev/null 2>&1 && | |
67 | _drv="_drv=fsck fsck_drv_std" && | |
68 | return 0 | |
69 | ;; | |
70 | esac | |
71 | ||
72 | return 1 | |
73 | } | |
74 | ||
75 | # note: all drivers inherit: _drv _fop _dev | |
76 | ||
77 | fsck_drv_xfs() { | |
78 | local _ret | |
79 | ||
80 | # fs must be cleanly mounted (and umounted) first, before attempting any | |
81 | # xfs tools - if this works, nothing else should be needed | |
82 | # note, that user is always dropped into the shell, if the filesystem is | |
83 | # not mountable or if -f flag is found among _fop | |
84 | mkdir -p /tmp/.xfs | |
85 | ||
86 | info "trying to mount $_dev" | |
87 | if mount -t xfs "$_dev" "/tmp/.xfs" >/dev/null 2>&1; then | |
88 | _ret=0 | |
89 | info "xfs: $_dev is clean" | |
90 | umount "$_dev" >/dev/null 2>&1 | |
91 | else | |
92 | _ret=4 | |
93 | warn "*** $_dev is unmountable" | |
94 | fi | |
95 | if [ $_ret -gt 0 ] || strstr "$_fop" "-f"; then | |
96 | warn "*** Dropping you to a shell. You have" | |
97 | warn "*** xfs_repair and xfs_check (xfs_db) available." | |
98 | warn "*** Note that if xfs didn't mount properly, it's" | |
99 | warn "*** probably pretty serious condition." | |
100 | emergency_shell -n "(Repair filesystem)" | |
101 | fi | |
102 | ||
103 | rm -r /tmp/.xfs | |
104 | return $_ret | |
105 | } | |
106 | ||
662ed0a1 HH |
107 | fsck_drv_btrfs() { |
108 | local _ret | |
109 | ||
110 | # fs must be cleanly mounted (and umounted) first, before attempting any | |
111 | # btrfs tools - if this works, nothing else should be needed | |
112 | # note, that user is always dropped into the shell, if the filesystem is | |
113 | # not mountable or if -f flag is found among _fop | |
114 | mkdir -p /tmp/.btrfs | |
115 | ||
116 | info "trying to mount $_dev" | |
117 | if mount -t btrfs "$_dev" "/tmp/.btrfs" >/dev/null 2>&1; then | |
118 | _ret=0 | |
119 | info "btrfs: $_dev is clean" | |
120 | umount "$_dev" >/dev/null 2>&1 | |
121 | else | |
122 | _ret=4 | |
123 | warn "*** $_dev is unmountable" | |
124 | fi | |
125 | if [ $_ret -gt 0 ] || strstr "$_fop" "-f"; then | |
126 | warn "*** Dropping you to a shell. You have" | |
127 | warn "*** btrfsck available." | |
128 | warn "*** Note that if btrfs didn't mount properly, it's" | |
129 | warn "*** probably pretty serious condition." | |
130 | emergency_shell -n "(Repair filesystem)" | |
131 | fi | |
132 | ||
133 | rm -r /tmp/.btrfs | |
134 | return $_ret | |
135 | } | |
136 | ||
137 | ||
fefab84f MS |
138 | # common code for checkers that follow usual subset of options and return codes |
139 | fsck_drv_com() { | |
140 | local _ret | |
141 | local _out | |
142 | ||
143 | if ! strstr "$_fop" "-[ynap]"; then | |
144 | _fop="-a ${_fop}" | |
145 | fi | |
146 | ||
147 | info "issuing $_drv $_fop $_dev" | |
148 | # we enforce non-interactive run, so $() is fine | |
149 | _out=$($_drv $_fop "$_dev") | |
150 | _ret=$? | |
151 | fsck_tail | |
152 | ||
153 | return $_ret | |
154 | } | |
155 | ||
156 | # code for generic fsck, if the filesystem checked is "unknown" to us | |
157 | fsck_drv_std() { | |
158 | local _ret | |
159 | local _out | |
160 | unset _out | |
161 | ||
162 | info "issuing fsck $_fop $_dev" | |
163 | # note, we don't enforce -a here, thus fsck is being run (in theory) | |
164 | # interactively; otherwise some tool might complain about lack of terminal | |
165 | # (and using -a might not be safe) | |
166 | fsck $_fop "$_dev" >/dev/console 2>&1 | |
167 | _ret=$? | |
168 | fsck_tail | |
169 | ||
170 | return $_ret | |
171 | } | |
172 | ||
173 | # checks single filesystem, relying on specific "driver"; we don't rely on | |
174 | # automatic checking based on fstab, so empty one is passed; | |
175 | # takes 3 arguments - device, filesystem, additional fsck options; | |
176 | # first 2 arguments are mandatory (fs may be auto or "") | |
177 | # returns 255 if filesystem wasn't checked at all (e.g. due to lack of | |
178 | # necessary tools or insufficient options) | |
179 | fsck_single() { | |
25b45979 | 180 | local FSTAB_FILE=/etc/fstab.empty |
fefab84f MS |
181 | local _dev="$1" |
182 | local _fs="${2:-auto}" | |
183 | local _fop="$3" | |
184 | local _drv | |
185 | ||
186 | [ $# -lt 2 ] && return 255 | |
187 | ||
188 | _fs=$(det_fs "$_dev" "$_fs") | |
189 | fsck_able "$_fs" || return 255 | |
190 | ||
191 | info "Checking $_fs: $_dev" | |
192 | export FSTAB_FILE | |
193 | eval "$_drv" "\"$_dev\"" "\"$_fop\"" | |
194 | return $? | |
195 | } | |
196 | ||
197 | # takes list of filesystems to check in parallel; we don't rely on automatic | |
198 | # checking based on fstab, so empty one is passed | |
199 | fsck_batch() { | |
25b45979 | 200 | local FSTAB_FILE=/etc/fstab.empty |
fefab84f MS |
201 | local _drv=fsck |
202 | local _dev | |
203 | local _ret | |
204 | local _out | |
205 | ||
25b45979 | 206 | [ $# -eq 0 ] || ! type fsck >/dev/null 2>&1 && return 255 |
fefab84f MS |
207 | |
208 | info "Checking filesystems (fsck -M -T -a):" | |
209 | for _dev in "$@"; do | |
210 | info " $_dev" | |
211 | done | |
212 | ||
f07aaccd | 213 | export FSTAB_FILE |
fefab84f MS |
214 | _out="$(fsck -M -T "$@" -- -a)" |
215 | _ret=$? | |
216 | ||
fefab84f MS |
217 | fsck_tail |
218 | ||
219 | return $_ret | |
220 | } | |
221 | ||
222 | # verify supplied filesystem type: | |
223 | # if user provided the fs and we couldn't find it, assume user is right | |
224 | # if we found the fs, assume we're right | |
225 | det_fs() { | |
226 | local _dev="$1" | |
227 | local _orig="${2:-auto}" | |
228 | local _fs | |
229 | ||
230 | _fs=$(udevadm info --query=env --name="$_dev" | \ | |
231 | while read line; do | |
232 | if str_starts $line "ID_FS_TYPE="; then | |
233 | echo ${line#ID_FS_TYPE=} | |
234 | break | |
235 | fi | |
236 | done) | |
237 | _fs=${_fs:-auto} | |
238 | ||
239 | if [ "$_fs" = "auto" ]; then | |
240 | _fs="$_orig" | |
241 | fi | |
242 | echo "$_fs" | |
243 | } |