@@ -715,13 +715,82 @@ set_default_env() {
715
715
fi
716
716
}
717
717
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
+
718
787
# arg1: ZFS filesystem
719
788
# prints: nothing
720
789
# returns: 0 if kernels were found, 1 otherwise
721
790
722
791
find_be_kernels () {
723
792
local fs mnt
724
- local kpath kdir kernel kernel_base labels version kernel_records
793
+ local kpath ipath kernel_records
725
794
726
795
fs=" ${1} "
727
796
if [ -z " ${fs} " ]; then
@@ -740,51 +809,21 @@ find_be_kernels() {
740
809
kernel_records=" ${mnt%/* } /kernels"
741
810
: > " ${kernel_records} "
742
811
743
- # Look for kernels in / and /boot , sorted in version order
812
+ # Look for kernels and matching initramfs , sorted in version order
744
813
while read -r kpath; do
745
814
# Strip mount point from path
815
+ [ -n " ${kpath} " ] || continue ;
746
816
kpath=" ${kpath# " ${mnt} " } "
747
- # Ensure kpath has leading slash
748
817
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
787
818
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
788
827
done <<< " $(
789
828
for k in " ${mnt} /boot" /{{vm,}linu{x,z},kernel}{,-*}; do
790
829
[ -e " ${k} " ] && echo " ${k} "
0 commit comments