@@ -715,13 +715,82 @@ set_default_env() {
715715 fi
716716}
717717
718+ # arg1: path of the kernel for which the initramfs is sought
719+ # prints: path of a matching initramfs
720+ # returns: 0 if initramfs was found, 1 otherwise
721+
722+ find_be_initramfs () {
723+ local kpath
724+ local kdir kern kver ifile candidates
725+
726+ kpath=" $1 "
727+ if [ ! -r " ${kpath} " ]; then
728+ zerror " specified kernel does not exist"
729+ return 1
730+ fi
731+
732+ # Split kernel path into file and directory
733+ kern=" ${kpath##*/ } "
734+ kdir=" ${kpath% " ${kern} " } "
735+ kdir=" ${kdir%/ } "
736+ zdebug " kernel path: '${kpath} ', directory: '${kdir} ', file: '${kern} '"
737+
738+ # Kernel "base" extends to first hyphen, "version" follows and may be empty
739+ kver=" ${kern# " ${kern%% -* } " } "
740+ zdebug " kernel version: '${kver} '"
741+
742+ # Try some common cases before doing an exhaustive search
743+
744+ candidates=(
745+ # Void, Arch
746+ " initramfs-${kern} .img"
747+ " initramfs${kver} .img"
748+
749+ # Debian and other initramfs-tools users
750+ " initrd.img-${kern} "
751+ " initrd.img${kver} "
752+
753+ # Alpine
754+ " initramfs-${kern} "
755+ " initramfs${kver} "
756+ )
757+
758+ for ifile in " ${candidates[@]} " ; do
759+ if [ -e " ${kdir} /${ifile} " ]; then
760+ zdebug " short-matching '${ifile} ' to '${kern} '"
761+ echo " ${kdir} /${ifile} "
762+ return 0
763+ fi
764+ done
765+
766+ # Common cases have failed, try a more exhaustive search
767+
768+ local ext pfx lbl ifile
769+
770+ # Use loops instead of a clever brace-expansion for clarity and control
771+ for ext in {.img," " }{" " ,.{gz,bz2,xz,lzma,lz4,lzo,zstd}}; do
772+ for pfx in initramfs initrd; do
773+ for lbl in " ${kern} " " ${kver} " ; do
774+ for ifile in " ${pfx}${lbl}${ext} " " ${pfx}${ext}${lbl} " ; do
775+ [ -e " ${kdir} /${ifile} " ] || continue
776+ zdebug " matching '${ifile} ' to '${kern} '"
777+ echo " ${kdir} /${ifile} "
778+ return 0
779+ done
780+ done
781+ done
782+ done
783+
784+ return 1
785+ }
786+
718787# arg1: ZFS filesystem
719788# prints: nothing
720789# returns: 0 if kernels were found, 1 otherwise
721790
722791find_be_kernels () {
723792 local fs mnt
724- local kpath kdir kernel kernel_base labels version kernel_records
793+ local kpath ipath kernel_records
725794
726795 fs=" ${1} "
727796 if [ -z " ${fs} " ]; then
@@ -740,51 +809,21 @@ find_be_kernels() {
740809 kernel_records=" ${mnt%/* } /kernels"
741810 : > " ${kernel_records} "
742811
743- # Look for kernels in / and /boot , sorted in version order
812+ # Look for kernels and matching initramfs , sorted in version order
744813 while read -r kpath; do
745814 # Strip mount point from path
815+ [ -n " ${kpath} " ] || continue ;
746816 kpath=" ${kpath# " ${mnt} " } "
747- # Ensure kpath has leading slash
748817 kpath=" /${kpath#/ } "
749- zdebug " found kernel: ${mnt}${kpath} "
750-
751- # Extract base name and kernel directory
752- kernel=" ${kpath##*/ } "
753- kdir=" ${kpath% " ${kernel} " } "
754- # Trim trailing slash (note: kdir will be empty if kernel is at root)
755- kdir=" ${kdir%/ } "
756- zdebug " kernel directory: '${kdir} ', file: '${kernel} '"
757-
758- # Kernel "base" extends to first hyphen
759- kernel_base=" ${kernel%% -* } "
760-
761- # Kernel "version" is everything after base and may be empty
762- version=" ${kernel# " ${kernel_base} " } "
763- version=" ${version# -} "
764- zdebug " kernel base: '${kernel_base} ', version: '${version} '"
765-
766- # initramfs images can take many forms, look for a sensible one
767- labels=( " $kernel " )
768- if [ -n " $version " ]; then
769- labels+=( " $version " )
770- fi
771-
772- # Use a mess of loops instead better brace expansions to control priorities
773- local ext pfx lbl i ipath
774- for ext in {.img," " }{" " ,.{gz,bz2,xz,lzma,lz4,lzo,zstd}}; do
775- for pfx in initramfs initrd; do
776- for lbl in " ${labels[@]} " ; do
777- for i in " ${pfx} -${lbl}${ext} " " ${pfx}${ext} -${lbl} " ; do
778- ipath=" ${kdir} /${i} "
779- [ -e " ${mnt}${ipath} " ] || continue
780- zdebug " matching '${i} ' to '${kernel} '"
781- echo " ${fs} ${kpath} ${ipath} " >> " ${kernel_records} "
782- break 4
783- done
784- done
785- done
786- done
787818
819+ if ipath=" $( find_be_initramfs " ${mnt}${kpath} " ) " ; then
820+ zdebug " found kernel: ${mnt}${kpath} , initramfs ${mnt}${ipath} "
821+ ipath=" ${ipath# " ${mnt} " } "
822+ ipath=" /${ipath#/ } "
823+ echo " ${fs} ${kpath} ${ipath} " >> " ${kernel_records} "
824+ else
825+ zdebug " kernel ${mnt}${kpath} has no initramfs"
826+ fi
788827 done <<< " $(
789828 for k in " ${mnt} /boot" /{{vm,}linu{x,z},kernel}{,-*}; do
790829 [ -e " ${k} " ] && echo " ${k} "
0 commit comments