]> git.ipfire.org Git - thirdparty/dracut.git/blame_incremental - modules.d/99fs-lib/fs-lib.sh
fix(zfcp_rules): correct shellcheck regression when parsing ccw args
[thirdparty/dracut.git] / modules.d / 99fs-lib / fs-lib.sh
... / ...
CommitLineData
1#!/bin/sh
2
3type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
4
5fsck_ask_reboot() {
6 info "note - fsck suggests reboot, if you"
7 info "leave shell, booting will continue normally"
8 emergency_shell -n "(reboot ?)"
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."
15 emergency_shell -n "(Repair filesystem)"
16}
17
18# inherits: _ret _drv _out
19fsck_tail() {
20 [ "$_ret" -gt 0 ] && warn "$_drv returned with $_ret"
21 if [ "$_ret" -ge 4 ]; then
22 [ -n "$_out" ] && echo "$_out" | vwarn
23 fsck_ask_err
24 else
25 [ -n "$_out" ] && echo "$_out" | vinfo
26 [ "$_ret" -ge 2 ] && fsck_ask_reboot
27 fi
28}
29
30# note: this function sets _drv of the caller
31fsck_able() {
32 case "$1" in
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
44 ;;
45 ext?)
46 type e2fsck > /dev/null 2>&1 \
47 && _drv="fsck_drv_com e2fsck" \
48 && return 0
49 ;;
50 f2fs)
51 type fsck.f2fs > /dev/null 2>&1 \
52 && _drv="fsck_drv_com fsck.f2fs" \
53 && return 0
54 ;;
55 jfs)
56 type jfs_fsck > /dev/null 2>&1 \
57 && _drv="fsck_drv_com jfs_fsck" \
58 && return 0
59 ;;
60 reiserfs)
61 type reiserfsck > /dev/null 2>&1 \
62 && _drv="fsck_drv_com reiserfsck" \
63 && return 0
64 ;;
65 btrfs)
66 # type btrfsck >/dev/null 2>&1 &&
67 # _drv="_drv=none fsck_drv_btrfs" &&
68 # return 0
69 return 1
70 ;;
71 nfs*)
72 # nfs can be a nop, returning success
73 _drv=":" \
74 && return 0
75 ;;
76 *)
77 type fsck > /dev/null 2>&1 \
78 && _drv="fsck_drv_std fsck" \
79 && return 0
80 ;;
81 esac
82
83 return 1
84}
85
86# note: all drivers inherit: _drv _fop _dev
87
88fsck_drv_xfs() {
89 # xfs fsck is not necessary... Either it mounts or not
90 return 0
91}
92
93fsck_drv_btrfs() {
94 # btrfs fsck is not necessary... Either it mounts or not
95 return 0
96}
97
98# common code for checkers that follow usual subset of options and return codes
99fsck_drv_com() {
100 local _drv="$1"
101 local _ret
102 local _out
103
104 if ! strglobin "$_fop" "-[ynap]"; then
105 _fop="-a${_fop:+ "$_fop"}"
106 fi
107
108 info "issuing $_drv $_fop $_dev"
109 # we enforce non-interactive run, so $() is fine
110 # shellcheck disable=SC2086
111 _out=$($_drv $_fop "$_dev")
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)
128 # shellcheck disable=SC2086
129 fsck $_fop "$_dev" > /dev/console 2>&1
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;
138# takes 4 arguments - device, filesystem, filesystem options, additional fsck options;
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() {
143 local FSTAB_FILE=/etc/fstab.empty
144 local _dev="$1"
145 local _fs="${2:-auto}"
146 local _fop="$4"
147 local _drv
148
149 [ $# -lt 2 ] && return 255
150 _dev=$(readlink -f "$(label_uuid_to_dev "$_dev")")
151 [ -e "$_dev" ] || return 255
152 _fs=$(det_fs "$_dev" "$_fs")
153 fsck_able "$_fs" || return 255
154
155 info "Checking $_fs: $_dev"
156 export FSTAB_FILE
157 eval "$_drv"
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() {
164 local FSTAB_FILE=/etc/fstab.empty
165 local _drv=fsck
166 local _dev
167 local _ret
168 local _out
169
170 [ $# -eq 0 ] || ! type fsck > /dev/null 2>&1 && return 255
171
172 info "Checking filesystems (fsck -M -T -a):"
173 for _dev in "$@"; do
174 info " $_dev"
175 done
176
177 export FSTAB_FILE
178 _out="$(fsck -M -T "$@" -- -a)"
179 _ret=$?
180
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
194 _fs=$(udevadm info --query=property --name="$_dev" \
195 | while read -r line || [ -n "$line" ]; do
196 if str_starts "$line" "ID_FS_TYPE="; then
197 echo "${line#ID_FS_TYPE=}"
198 break
199 fi
200 done)
201 _fs=${_fs:-auto}
202
203 if [ "$_fs" = "auto" ]; then
204 _fs="$_orig"
205 fi
206 echo "$_fs"
207}
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
227 _rootflags="ro,x-initrd.mount"
228 else
229 _rootflags="ro,$_rootflags,x-initrd.mount"
230 fi
231
232 _rw=0
233
234 CMDLINE=$(getcmdline)
235 for _o in $CMDLINE; do
236 case $_o in
237 rw)
238 _rw=1
239 ;;
240 ro)
241 _rw=0
242 ;;
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
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
257
258 if type systemctl > /dev/null 2> /dev/null; then
259 systemctl daemon-reload
260 systemctl --no-block start initrd-root-fs.target
261 fi
262}