]> git.ipfire.org Git - thirdparty/dracut.git/blame - modules.d/99fs-lib/fs-lib.sh
fix(fs-lib): remove quoting form the first argument of the e2fsck call
[thirdparty/dracut.git] / modules.d / 99fs-lib / fs-lib.sh
CommitLineData
fefab84f 1#!/bin/sh
fefab84f 2
9a52c3fd 3type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
fefab84f
MS
4
5fsck_ask_reboot() {
6 info "note - fsck suggests reboot, if you"
7 info "leave shell, booting will continue normally"
d6dfde78 8 emergency_shell -n "(reboot ?)"
fefab84f
MS
9}
10
11fsck_ask_err() {
12 warn "*** An error occurred during the file system check."
13 warn "*** Dropping you to a shell; the system will try"
14 warn "*** to mount the filesystem(s), when you leave the shell."
d6dfde78 15 emergency_shell -n "(Repair filesystem)"
fefab84f
MS
16}
17
18# inherits: _ret _drv _out
19fsck_tail() {
82d9fbf1
HH
20 [ "$_ret" -gt 0 ] && warn "$_drv returned with $_ret"
21 if [ "$_ret" -ge 4 ]; then
9a52c3fd 22 [ -n "$_out" ] && echo "$_out" | vwarn
fefab84f
MS
23 fsck_ask_err
24 else
9a52c3fd 25 [ -n "$_out" ] && echo "$_out" | vinfo
82d9fbf1 26 [ "$_ret" -ge 2 ] && fsck_ask_reboot
fefab84f
MS
27 fi
28}
29
30# note: this function sets _drv of the caller
31fsck_able() {
32 case "$1" in
1594d0bf
HH
33 xfs)
34 # {
35 # type xfs_db &&
36 # type xfs_repair &&
37 # type xfs_check &&
38 # type mount &&
39 # type umount
40 # } >/dev/null 2>&1 &&
41 # _drv="_drv=none fsck_drv_xfs" &&
42 # return 0
43 return 1
fefab84f
MS
44 ;;
45 ext?)
9a52c3fd
HH
46 type e2fsck > /dev/null 2>&1 \
47 && _drv="fsck_drv_com e2fsck" \
48 && return 0
fefab84f 49 ;;
9f521f76 50 f2fs)
9a52c3fd
HH
51 type fsck.f2fs > /dev/null 2>&1 \
52 && _drv="fsck_drv_com fsck.f2fs" \
53 && return 0
54 ;;
fefab84f 55 jfs)
9a52c3fd
HH
56 type jfs_fsck > /dev/null 2>&1 \
57 && _drv="fsck_drv_com jfs_fsck" \
58 && return 0
fefab84f
MS
59 ;;
60 reiserfs)
9a52c3fd
HH
61 type reiserfsck > /dev/null 2>&1 \
62 && _drv="fsck_drv_com reiserfsck" \
63 && return 0
fefab84f 64 ;;
1afa0cb6 65 btrfs)
1594d0bf
HH
66 # type btrfsck >/dev/null 2>&1 &&
67 # _drv="_drv=none fsck_drv_btrfs" &&
68 # return 0
69 return 1
1afa0cb6 70 ;;
f74775ba
HH
71 nfs*)
72 # nfs can be a nop, returning success
9a52c3fd
HH
73 _drv=":" \
74 && return 0
f74775ba 75 ;;
fefab84f 76 *)
9a52c3fd
HH
77 type fsck > /dev/null 2>&1 \
78 && _drv="fsck_drv_std fsck" \
79 && return 0
fefab84f
MS
80 ;;
81 esac
82
83 return 1
84}
85
86# note: all drivers inherit: _drv _fop _dev
87
88fsck_drv_xfs() {
b65bde04
HH
89 # xfs fsck is not necessary... Either it mounts or not
90 return 0
fefab84f
MS
91}
92
662ed0a1 93fsck_drv_btrfs() {
b65bde04
HH
94 # btrfs fsck is not necessary... Either it mounts or not
95 return 0
662ed0a1
HH
96}
97
fefab84f
MS
98# common code for checkers that follow usual subset of options and return codes
99fsck_drv_com() {
43c8c4ce 100 local _drv="$1"
fefab84f
MS
101 local _ret
102 local _out
103
63755f4d 104 if ! strglobin "$_fop" "-[ynap]"; then
82d9fbf1 105 _fop="-a${_fop:+ "$_fop"}"
fefab84f
MS
106 fi
107
108 info "issuing $_drv $_fop $_dev"
109 # we enforce non-interactive run, so $() is fine
9aa332ca
LG
110 # shellcheck disable=SC2086
111 _out=$($_drv $_fop "$_dev")
fefab84f
MS
112 _ret=$?
113 fsck_tail
114
115 return $_ret
116}
117
118# code for generic fsck, if the filesystem checked is "unknown" to us
119fsck_drv_std() {
120 local _ret
121 local _out
122 unset _out
123
124 info "issuing fsck $_fop $_dev"
125 # note, we don't enforce -a here, thus fsck is being run (in theory)
126 # interactively; otherwise some tool might complain about lack of terminal
127 # (and using -a might not be safe)
82d9fbf1 128 # shellcheck disable=SC2086
9a52c3fd 129 fsck $_fop "$_dev" > /dev/console 2>&1
fefab84f
MS
130 _ret=$?
131 fsck_tail
132
133 return $_ret
134}
135
136# checks single filesystem, relying on specific "driver"; we don't rely on
137# automatic checking based on fstab, so empty one is passed;
840d8e47 138# takes 4 arguments - device, filesystem, filesystem options, additional fsck options;
fefab84f
MS
139# first 2 arguments are mandatory (fs may be auto or "")
140# returns 255 if filesystem wasn't checked at all (e.g. due to lack of
141# necessary tools or insufficient options)
142fsck_single() {
25b45979 143 local FSTAB_FILE=/etc/fstab.empty
fefab84f
MS
144 local _dev="$1"
145 local _fs="${2:-auto}"
840d8e47 146 local _fop="$4"
fefab84f
MS
147 local _drv
148
149 [ $# -lt 2 ] && return 255
d40617f7 150 _dev=$(readlink -f "$(label_uuid_to_dev "$_dev")")
1939a4f9 151 [ -e "$_dev" ] || return 255
fefab84f
MS
152 _fs=$(det_fs "$_dev" "$_fs")
153 fsck_able "$_fs" || return 255
154
155 info "Checking $_fs: $_dev"
156 export FSTAB_FILE
d0658098 157 eval "$_drv"
fefab84f
MS
158 return $?
159}
160
161# takes list of filesystems to check in parallel; we don't rely on automatic
162# checking based on fstab, so empty one is passed
163fsck_batch() {
25b45979 164 local FSTAB_FILE=/etc/fstab.empty
fefab84f
MS
165 local _drv=fsck
166 local _dev
167 local _ret
168 local _out
169
9a52c3fd 170 [ $# -eq 0 ] || ! type fsck > /dev/null 2>&1 && return 255
fefab84f
MS
171
172 info "Checking filesystems (fsck -M -T -a):"
173 for _dev in "$@"; do
174 info " $_dev"
175 done
176
f07aaccd 177 export FSTAB_FILE
fefab84f
MS
178 _out="$(fsck -M -T "$@" -- -a)"
179 _ret=$?
180
fefab84f
MS
181 fsck_tail
182
183 return $_ret
184}
185
186# verify supplied filesystem type:
187# if user provided the fs and we couldn't find it, assume user is right
188# if we found the fs, assume we're right
189det_fs() {
190 local _dev="$1"
191 local _orig="${2:-auto}"
192 local _fs
193
f7079e77 194 _fs=$(udevadm info --query=property --name="$_dev" \
82d9fbf1
HH
195 | while read -r line || [ -n "$line" ]; do
196 if str_starts "$line" "ID_FS_TYPE="; then
197 echo "${line#ID_FS_TYPE=}"
9a52c3fd
HH
198 break
199 fi
200 done)
fefab84f
MS
201 _fs=${_fs:-auto}
202
203 if [ "$_fs" = "auto" ]; then
204 _fs="$_orig"
205 fi
206 echo "$_fs"
207}
a1084c02
HH
208
209write_fs_tab() {
210 local _o
211 local _rw
212 local _root
213 local _rootfstype
214 local _rootflags
215 local _fspassno
216
217 _fspassno="0"
218 _root="$1"
219 _rootfstype="$2"
220 _rootflags="$3"
221 [ -z "$_rootfstype" ] && _rootfstype=$(getarg rootfstype=)
222 [ -z "$_rootflags" ] && _rootflags=$(getarg rootflags=)
223
224 [ -z "$_rootfstype" ] && _rootfstype="auto"
225
226 if [ -z "$_rootflags" ]; then
b37398dc 227 _rootflags="ro,x-initrd.mount"
a1084c02 228 else
b37398dc 229 _rootflags="ro,$_rootflags,x-initrd.mount"
a1084c02
HH
230 fi
231
232 _rw=0
8d3d72a6
HH
233
234 CMDLINE=$(getcmdline)
a1084c02
HH
235 for _o in $CMDLINE; do
236 case $_o in
237 rw)
9a52c3fd
HH
238 _rw=1
239 ;;
a1084c02 240 ro)
9a52c3fd
HH
241 _rw=0
242 ;;
a1084c02
HH
243 esac
244 done
245 if [ "$_rw" = "1" ]; then
246 _rootflags="$_rootflags,rw"
247 if ! getargbool 0 rd.skipfsck; then
248 _fspassno="1"
249 fi
250 fi
251
b12f8188
JJ
252 if grep -q "$_root /sysroot" /etc/fstab; then
253 echo "$_root /sysroot $_rootfstype $_rootflags $_fspassno 0" >> /etc/fstab
254 else
255 return
256 fi
a1084c02 257
9a52c3fd 258 if type systemctl > /dev/null 2> /dev/null; then
a1084c02 259 systemctl daemon-reload
db43f56d 260 systemctl --no-block start initrd-root-fs.target
a1084c02
HH
261 fi
262}