Skip to content

Commit fd4d012

Browse files
committed
recovery shell: ESP-related tooling
Add a mount_esp helper with tab completion. This is a very thin wrapper over the new mount_block function. Add the relevant kernel modules to the optional modules list for both dracut and mkinitcpio images. Explicitly add the same modules to the release/recovery shared config.
1 parent 01a2ce6 commit fd4d012

File tree

9 files changed

+133
-0
lines changed

9 files changed

+133
-0
lines changed

docs/online/recovery-shell.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ Common Commands
4040

4141
Mount the filesystem at a unique location and print the mount point.
4242

43+
**mount_esp** *device*
44+
45+
Mount an EFI System Partition at a unique location and print the mount point.
46+
4347
**mount_efivarfs** *mode*
4448

4549
Mount or remount *efivarfs* as read-write or read-only.

etc/zfsbootmenu/release.conf.d/common.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ install_optional_items+=" /etc/zbm-commit-hash "
55

66
omit_dracutmodules+=" crypt-ssh nfs lunmask "
77

8+
# kernel modules to allow mounting an ESP
9+
add_drivers+=" fat vfat nls_iso8859_1 nls_cp437 "
10+
811
# qemu drivers
912
omit_dracutmodules+=" qemu "
1013

zfsbootmenu/bin/mount_esp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
3+
# shellcheck disable=SC1091
4+
sources=(
5+
/lib/kmsg-log-lib.sh
6+
/lib/zfsbootmenu-core.sh
7+
)
8+
9+
for src in "${sources[@]}"; do
10+
# shellcheck disable=SC1090
11+
if ! source "${src}" >/dev/null 2>&1 ; then
12+
echo "<3>ZFSBootMenu: unable to source '${src}' in $0" > /dev/kmsg
13+
exit 1
14+
fi
15+
done
16+
17+
unset src sources
18+
19+
mount_block "${1}"

zfsbootmenu/help-files/132/recovery-shell.ansi

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

zfsbootmenu/help-files/52/recovery-shell.ansi

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

zfsbootmenu/help-files/92/recovery-shell.ansi

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

zfsbootmenu/install-helpers.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ zfsbootmenu_essential_modules=(
6969
zfsbootmenu_optional_modules=(
7070
"zlib_deflate"
7171
"zlib_inflate"
72+
"fat"
73+
"vfat"
74+
"nls_iso8859_1"
75+
"nls_cp437"
7276
)
7377

7478
create_zbm_conf() {

zfsbootmenu/lib/zfsbootmenu-completions.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,23 @@ _mount_zfs() {
7171
}
7272
complete -F _mount_zfs mount_zfs
7373

74+
_mount_esp() {
75+
local ESP dev uuid
76+
COMPREPLY=()
77+
78+
[ "${#COMP_WORDS[@]}" != "2" ] && return
79+
80+
while IFS=' ' read -r dev uuid; do
81+
# magic uuid for an ESP
82+
[ "${uuid,,}" == "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" ] || continue
83+
is_mounted "${dev}" >/dev/null 2>&1 || ESP+=( "${dev}" )
84+
done <<<"$( lsblk -ln -o PATH,PARTTYPE )"
85+
86+
COMPREPLY=( $( compgen -W "${ESP[*]}" -- "${COMP_WORDS[1]}" ) )
87+
}
88+
89+
complete -F _mount_esp mount_esp
90+
7491
_zsnapshots() {
7592
local ZFS
7693
COMPREPLY=()

zfsbootmenu/lib/zfsbootmenu-core.sh

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,49 @@ check_for_pools() {
244244
return 1
245245
}
246246

247+
# arg1: device name
248+
# prints: mountpoint
249+
# returns: 0 on success
250+
251+
mount_block() {
252+
local device mnt output
253+
254+
device="${1}"
255+
256+
if [ -z "${device}" ]; then
257+
zerror "device is undefined"
258+
return 1
259+
fi
260+
261+
if [ ! -b "${device}" ]; then
262+
zerror "device does not exist or is not a block device"
263+
return 1
264+
fi
265+
266+
if mnt="$( is_mounted "${device}" )"; then
267+
echo "${mnt}"
268+
return 0
269+
fi
270+
271+
mnt="/mnt/${device##*/}"
272+
273+
if [ -d "${mnt}" ] && is_mountpoint "${mnt}"; then
274+
zerror "mountpoint '${mnt}' already in use"
275+
return 1
276+
fi
277+
278+
mkdir -p "${mnt}" || return 1
279+
280+
if output="$( mount "${device}" "${mnt}" 2>&1 )"; then
281+
echo "${mnt}"
282+
return 0
283+
else
284+
zerror "unable to mount '${device}' at '${mnt}'"
285+
zerror "${output}"
286+
return 1
287+
fi
288+
}
289+
247290
# arg1: ZFS filesystem name
248291
# prints: mountpoint
249292
# returns: 0 on success
@@ -2063,6 +2106,36 @@ is_mountpoint() {
20632106
return 1
20642107
}
20652108

2109+
# arg1: device or dataset name
2110+
# prints: mountpoint if mounted
2111+
# returns: 0 if the device is mounted, 1 if not
2112+
2113+
is_mounted() {
2114+
local mount_path dev path opts
2115+
2116+
mount_dev="${1}"
2117+
2118+
if [ -z "${mount_dev}" ]; then
2119+
zerror "mount_dev undefined"
2120+
return 1
2121+
fi
2122+
2123+
if [ ! -r /proc/self/mounts ]; then
2124+
zerror "unable to read mount database"
2125+
return 1
2126+
fi
2127+
2128+
# shellcheck disable=SC2034
2129+
while read -r dev path opts; do
2130+
if [ "${dev}" = "${mount_dev}" ]; then
2131+
echo "${path}"
2132+
return 0
2133+
fi
2134+
done < /proc/self/mounts
2135+
2136+
return 1
2137+
}
2138+
20662139
# args: none
20672140
# prints: nothing
20682141
# returns: 0 if EFI is detected, 1 if not

0 commit comments

Comments
 (0)