~mclehman/funtoo-zfs-root

4ed5ed516dd586e2d037b6e28ca77693be8ea66a — 0xford 3 years ago master
Initial commit.
3 files changed, 99 insertions(+), 0 deletions(-)

A gen-initramfs.bash
A grub-linux-root-param.patch
A initrd-scripts-zfs.patch
A  => gen-initramfs.bash +62 -0
@@ 1,62 @@
#!/bin/bash

set -o nounset
set -o pipefail
set -e

require () {
    hash "$@" 2>/dev/null || ( echo "Dependency $* not found" ; exit 127 )
}
require_all () {
    for dep in "$@"
    do
        require "$dep"
    done
}
require_all cpio genkernel grep gzip lz4 nproc patch rsync

# Assumption: this script is run from the directory where associated files are located, i.e. this repo
#             I agree, not great
src_dir="$PWD"
root_dir="/tmp/"
mkdir -p "$root_dir"
pushd "$root_dir" || exit

# Assumption: preparing to boot most recently configured linux kernel
base_kernel_ver="$(< /usr/src/linux/.config grep -Poe '# Linux/x86 \K\S*')"
local_kernel_ver="$(< /usr/src/linux/.config grep -Poe 'CONFIG_LOCALVERSION="\K[^"]*')"
kernel_ver="${base_kernel_ver}${local_kernel_ver}"
initramfs="initramfs-genkernel-x86_64-${kernel_ver}"
unpack_dir="$(mktemp -d "$root_dir"/"$initramfs".d.XXXX)"

# make backup of previous initramfs before clobbering
[ -e "/boot/${initramfs}" ] && mv "/boot/${initramfs}" "/boot/${initramfs}.bak"

# generate base (gzipped) initramfs at /boot/$initramfs (implicit)
genkernel initramfs --no-clean --no-mountboot --makeopts=-j"$(($(nproc)+1))" --kernel-config=/usr/src/linux/.config --zfs

# Retrieve generated initramfs from /boot
cp "/boot/${initramfs}" "${initramfs}.gz"

# Decompress and unarchive initramfs into $unpack_dir
echo "Unpacking into $unpack_dir"
pushd "$unpack_dir" || exit
< "${root_dir}/${initramfs}.gz" gzip -dc | cpio --extract --make-directories --format=newc --no-absolute-filenames

# ZFS dynamic libraries are installed into /usr/lib, but only found when moved into /lib
rsync -r ./usr/lib/ ./lib/
rm -r ./usr/lib

# Patch initrd volume loader to
#   a) prompt for encryption keys during boot rather than requiring manual intervention in the rescue shell
#   b) patch import of pools by name to use cachefile /etc/zfs/${pool_name}.cache
patch -up0 < "${src_dir}/initrd-scripts-zfs.patch"

# Put the zpool cache where it's expected during boot
cp /etc/zfs/zpool.cache etc/zfs/

# Repackage initramfs archive, compress, write to /boot
find . -print0 | cpio --null --create --format=newc | lz4 -l > "/boot/${initramfs}"

popd || exit
popd || exit

A  => grub-linux-root-param.patch +11 -0
@@ 1,11 @@
--- /etc/grub.d/10_linux	2020-01-30 01:56:10.000000000 -0000
+++ ./10_linux	2020-02-02 02:00:03.470777089 -0000
@@ -133,7 +133,7 @@
   message="$(gettext_printf "Loading Linux %s ..." ${version})"
   sed "s/^/$submenu_indentation/" << EOF
 	echo	'$(echo "$message" | grub_quote)'
-	linux	${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
+	linux	${rel_dirname}/${basename} rootfstype=ramfs ${args}
 EOF
   if test -n "${initrd}" ; then
     # TRANSLATORS: ramdisk isn't identifier. Should be translated.

A  => initrd-scripts-zfs.patch +26 -0
@@ 1,26 @@
--- etc/initrd.scripts	2020-02-01 23:18:14.628927512 -0000
+++ ../initramfs-0xford+zfs/etc/initrd.scripts	2020-02-01 09:39:31.852051213 -0000
@@ -1186,6 +1117,8 @@
 			if [ "$?" = '0' ]
 			then
 				good_msg "Importing ZFS pools succeeded"
+				good_msg "Loading encryption keys if necessary"
+				zfs load-key -a
 			else
 				bad_msg "Imported ZFS pools failed"
 			fi
@@ -1204,11 +1137,13 @@
 			else
 				good_msg "Importing ZFS pool ${ZFS_POOL}"
 
-				/sbin/zpool import -N ${ZPOOL_FORCE} "${ZFS_POOL}"
+				/sbin/zpool import -N ${ZPOOL_FORCE} -c "/etc/zfs/zpool.cache" "${ZFS_POOL}"
 
 				if [ "$?" = '0' ]
 				then
 					good_msg "Import of ${ZFS_POOL} succeeded"
+					good_msg "Loading encryption keys if necessary"
+					zfs load-key -a
 				else
 					bad_msg "Import of ${ZFS_POOL} failed"
 				fi