Skip to content

Commit

Permalink
zfsbootmenu-core: optimize initramfs search
Browse files Browse the repository at this point in the history
  • Loading branch information
ahesford committed Sep 20, 2023
1 parent b24fdb5 commit 674280c
Showing 1 changed file with 81 additions and 40 deletions.
121 changes: 81 additions & 40 deletions zfsbootmenu/lib/zfsbootmenu-core.sh
Original file line number Diff line number Diff line change
Expand Up @@ -715,13 +715,85 @@ set_default_env() {
fi
}

# arg1: path of the kernel for which the initramfs is sought
# prints: path of a matching initramfs
# returns: 0 if initramfs was found, 1 otherwise

find_be_initramfs() {
local kpath
local kdir kern kver ifile candidates

# Make sure kroot doesn't end in slash, and kpath starts with it
kpath="$1"

if [ ! -r "${kpath}" ]; then
zerror "specified kernel does not exist"
return 1
fi

# Split kernel path into file and directory
kern="${kpath##*/}"
kdir="${kpath%"${kernel}"}"
kdir="${kdir%/}"
zdebug "kernel path: '${kpath}', directory: '${kdir}', file: '${kern}'"

# Kernel "base" extends to first hyphen, "version" follows and may be empty
kver="${kern#"${kern%%-*}"}"
zdebug "kernel version: '${kver}'"

# Try some common cases before doing an exhaustive search

candidates=(
# Void, Arch
"initramfs-${kern}.img"
"initramfs${kver}.img"

# Debian and other initramfs-tools users
"initrd.img-${kern}"
"initrd.img${kver}"

# Alpine
"initramfs-${kern}"
"initramfs${kver}"
)

for ifile in "${candidates[@]}"; do

if [ -e "${kdir}/${ifile}" ]; then
zdebug "short-matching '${ifile}' to '${kern}'"
echo "${kdir}/${ifile}"
return 0
fi
done

# Common cases have failed, try a more exhaustive search

local ext pfx lbl ifile

# Use loops instead of a clever brace-expansion for clarity and control
for ext in {.img,""}{"",.{gz,bz2,xz,lzma,lz4,lzo,zstd}}; do
for pfx in initramfs initrd; do
for lbl in "${kernel}" "${kver}"; do
for ifile in "${pfx}${lbl}${ext}" "${pfx}${ext}${lbl}"; do
[ -e "${kdir}/${ifile}" ] || continue
zdebug "matching '${ifile}' to '${kernel}'"
echo "${kdir}/${ifile}"
return 0
done
done
done
done

return 1
}

# arg1: ZFS filesystem
# prints: nothing
# returns: 0 if kernels were found, 1 otherwise

find_be_kernels() {
local fs mnt
local kpath kdir kernel kernel_base labels version kernel_records
local kpath ipath kernel_records

fs="${1}"
if [ -z "${fs}" ]; then
Expand All @@ -744,47 +816,16 @@ find_be_kernels() {
while read -r kpath; do
# Strip mount point from path
kpath="${kpath#"${mnt}"}"
# Ensure kpath has leading slash
kpath="/${kpath#/}"
zdebug "found kernel: ${mnt}${kpath}"

# Extract base name and kernel directory
kernel="${kpath##*/}"
kdir="${kpath%"${kernel}"}"
# Trim trailing slash (note: kdir will be empty if kernel is at root)
kdir="${kdir%/}"
zdebug "kernel directory: '${kdir}', file: '${kernel}'"

# Kernel "base" extends to first hyphen
kernel_base="${kernel%%-*}"

# Kernel "version" is everything after base and may be empty
version="${kernel#"${kernel_base}"}"
version="${version#-}"
zdebug "kernel base: '${kernel_base}', version: '${version}'"

# initramfs images can take many forms, look for a sensible one
labels=( "$kernel" )
if [ -n "$version" ]; then
labels+=( "$version" )
fi

# Use a mess of loops instead better brace expansions to control priorities
local ext pfx lbl i ipath
for ext in {.img,""}{"",.{gz,bz2,xz,lzma,lz4,lzo,zstd}}; do
for pfx in initramfs initrd; do
for lbl in "${labels[@]}"; do
for i in "${pfx}-${lbl}${ext}" "${pfx}${ext}-${lbl}"; do
ipath="${kdir}/${i}"
[ -e "${mnt}${ipath}" ] || continue
zdebug "matching '${i}' to '${kernel}'"
echo "${fs} ${kpath} ${ipath}" >> "${kernel_records}"
break 4
done
done
done
done

if ipath="$( find_be_initramfs "${mnt}${kpath}" )"; then
zdebug "found kernel: ${mnt}${kpath}, initramfs ${mnt}${ipath}"
ipath="${ipath#"${mnt}"}"
ipath="/${ipath#/}"
echo "${fs} ${kpath} ${ipath}" >> "${kernel_records}"
else
zdebug "kernel ${mnt}${kpath} has no initramfs"
fi
done <<<"$(
for k in "${mnt}/boot"/{{vm,}linu{x,z},kernel}{,-*}; do
[ -e "${k}" ] && echo "${k}"
Expand Down

0 comments on commit 674280c

Please sign in to comment.