Skip to content

Commit

Permalink
recovery shell: ESP-related tooling
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
zdykstra committed Dec 19, 2023
1 parent 14d8554 commit cd6d101
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/online/recovery-shell.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ Common Commands

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

**mount_esp** *device*

Mount an EFI System Partition at a unique location and print the mount point.

**mount_efivarfs** *mode*

Mount or remount *efivarfs* as read-write or read-only.
Expand Down
3 changes: 3 additions & 0 deletions etc/zfsbootmenu/release.conf.d/common.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ install_optional_items+=" /etc/zbm-commit-hash "

omit_dracutmodules+=" crypt-ssh nfs lunmask "

# kernel modules to allow mounting an ESP
add_drivers+=" fat vfat nls_iso8859_1 nls_cp437 "

# qemu drivers
omit_dracutmodules+=" qemu "

Expand Down
19 changes: 19 additions & 0 deletions zfsbootmenu/bin/mount_esp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

# shellcheck disable=SC1091
sources=(
/lib/kmsg-log-lib.sh
/lib/zfsbootmenu-core.sh
)

for src in "${sources[@]}"; do
# shellcheck disable=SC1090
if ! source "${src}" >/dev/null 2>&1 ; then
echo "<3>ZFSBootMenu: unable to source '${src}' in $0" > /dev/kmsg
exit 1
fi
done

unset src sources

mount_block "${1}"
4 changes: 4 additions & 0 deletions zfsbootmenu/help-files/132/recovery-shell.ansi

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions zfsbootmenu/help-files/52/recovery-shell.ansi

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions zfsbootmenu/help-files/92/recovery-shell.ansi

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions zfsbootmenu/install-helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ zfsbootmenu_essential_modules=(
zfsbootmenu_optional_modules=(
"zlib_deflate"
"zlib_inflate"
"fat"
"vfat"
"nls_iso8859_1"
"nls_cp437"
)

create_zbm_conf() {
Expand Down
17 changes: 17 additions & 0 deletions zfsbootmenu/lib/zfsbootmenu-completions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,23 @@ _mount_zfs() {
}
complete -F _mount_zfs mount_zfs

_mount_esp() {
local ESP dev uuid
COMPREPLY=()

[ "${#COMP_WORDS[@]}" != "2" ] && return

while IFS=' ' read -r dev uuid; do
# magic uuid for an ESP
[ "${uuid,,}" == "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" ] || continue
is_mounted "${dev}" >/dev/null 2>&1 || ESP+=( "${dev}" )
done <<<"$( lsblk -ln -o PATH,PARTTYPE )"

COMPREPLY=( $( compgen -W "${ESP[*]}" -- "${COMP_WORDS[1]}" ) )
}

complete -F _mount_esp mount_esp

_zsnapshots() {
local ZFS
COMPREPLY=()
Expand Down
73 changes: 73 additions & 0 deletions zfsbootmenu/lib/zfsbootmenu-core.sh
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,49 @@ check_for_pools() {
return 1
}

# arg1: device name
# prints: mountpoint
# returns: 0 on success

mount_block() {
local device mnt output

device="${1}"

if [ -z "${device}" ]; then
zerror "device is undefined"
return 1
fi

if [ ! -b "${device}" ]; then
zerror "device does not exist or is not a block device"
return 1
fi

if mnt="$( is_mounted "${device}" )"; then
echo "${mnt}"
return 0
fi

mnt="/mnt/${device##*/}"

if [ -d "${mnt}" ] && is_mountpoint "${mnt}"; then
zerror "mountpoint '${mnt}' already in use"
return 1
fi

mkdir -p "${mnt}" || return 1

if output="$( mount "${device}" "${mnt}" 2>&1 )"; then
echo "${mnt}"
return 0
else
zerror "unable to mount '${device}' at '${mnt}'"
zerror "${output}"
return 1
fi
}

# arg1: ZFS filesystem name
# prints: mountpoint
# returns: 0 on success
Expand Down Expand Up @@ -2063,6 +2106,36 @@ is_mountpoint() {
return 1
}

# arg1: device or dataset name
# prints: mountpoint if mounted
# returns: 0 if the device is mounted, 1 if not

is_mounted() {
local mount_path dev path opts

mount_dev="${1}"

if [ -z "${mount_dev}" ]; then
zerror "mount_dev undefined"
return 1
fi

if [ ! -r /proc/self/mounts ]; then
zerror "unable to read mount database"
return 1
fi

# shellcheck disable=SC2034
while read -r dev path opts; do
if [ "${dev}" = "${mount_dev}" ]; then
echo "${path}"
return 0
fi
done < /proc/self/mounts

return 1
}

# args: none
# prints: nothing
# returns: 0 if EFI is detected, 1 if not
Expand Down

0 comments on commit cd6d101

Please sign in to comment.