Last active
October 16, 2020 06:58
-
-
Save dreamcat4/b175c96dfefd82aa73aef06926e7aaff to your computer and use it in GitHub Desktop.
For luks zfs root pool on ubuntu. Patches for - dual disks, v1.04, for ubuntu 19.04+
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# /usr/local/bin/update-boot2 | |
# | |
# Summary: | |
# | |
# For luks zfs root pool on ubuntu. Patches for - dual disks, v1.04, for ubuntu 19.04+ | |
# | |
# a) This patches initrd to remove certain error messages at boot time, that would otherwise | |
# interfere and prevent the system booting correctly. | |
# b) Regenerates the contents /boot2 on the 2nd boot drive, for example after kernel updates. | |
# | |
# Details: | |
# | |
# * patch the 'cryptroot' script in initramfs | |
# * in the event of a failed boot drive, attempt to continue booting off the other good disk | |
# * enabled with a new boot arg 'cryptroot_nofail', does not check the existing crypttab 'nofail' | |
# * does not fail if other boot disk is also missing, it assumes they don't fail simultaneously | |
# | |
# * patch 'grub-mkconfig' script. when generating 'grub.cfg' menu file | |
# * do not always assume the target boot partition is mounted to /boot (might be /boot2 etc) | |
# * instead get the boot partition from the target directory where 'grub.cfg' is being written to | |
# * grub.cfg is then generated with correct boot disk uuids, for grub booting off 2nd boot disk | |
# | |
# * copy over new kernel files to /boot2 | |
# | |
# * update-initramfs | |
# | |
# * grub-mkconfig -o /boot2/grub/grub.cfg | |
# | |
# | |
unset _not_patched | |
_home="$(eval echo ~$USER)" | |
cat_patch_cryptroot () | |
{ | |
# cd /tmp | |
# mkdir -p a/usr/share/initramfs-tools/scripts/local-top | |
# mkdir -p b/usr/share/initramfs-tools/scripts/local-top | |
# cp /usr/share/initramfs-tools/scripts/local-top/cryptroot a/usr/share/initramfs-tools/scripts/local-top/cryptroot | |
# cp /usr/share/initramfs-tools/scripts/local-top/cryptroot b/usr/share/initramfs-tools/scripts/local-top/cryptroot | |
# nano b/usr/share/initramfs-tools/scripts/local-top/cryptroot | |
# diff -crB a/usr/share/initramfs-tools/scripts/local-top/cryptroot b/usr/share/initramfs-tools/scripts/local-top/cryptroot > cryptroot.patch | |
# cat cryptroot.patch | |
cat <<- "EOF" | |
diff -crB a/usr/share/initramfs-tools/scripts/local-top/cryptroot b/usr/share/initramfs-tools/scripts/local-top/cryptroot | |
*** a/usr/share/initramfs-tools/scripts/local-top/cryptroot 2019-05-20 11:31:59.904908630 +0100 | |
--- b/usr/share/initramfs-tools/scripts/local-top/cryptroot 2019-05-22 20:52:45.612925860 +0100 | |
*************** | |
*** 86,91 **** | |
--- 86,96 ---- | |
crypttab_parse_options --export --missing-path=fail || return 1 | |
if ! wait_for_source; then | |
+ if [ "${CRYPTROOT_NOFAIL}" -o "${cryptroot_nofail}" ]; then | |
+ cryptsetup_message "ERROR: Skipping target $CRYPTTAB_NAME: device not found, and cryptroot_nofail=true" | |
+ return 1 | |
+ fi | |
+ | |
# we've given up | |
if [ -n "$panic" ]; then | |
panic "ALERT! encrypted source device $CRYPTTAB_SOURCE does not exist, can't unlock $CRYPTTAB_NAME." | |
EOF | |
} | |
_patch_cryptroot () | |
{ | |
_cryptroot=/usr/share/initramfs-tools/scripts/local-top/cryptroot | |
if ! grep -q -i 'cryptroot_nofail' $_cryptroot; then | |
cat_patch_cryptroot | patch -p1 --forward --directory=/ --ignore-whitespace --reject-file=- $_cryptroot | |
_not_patched=true | |
if [ -e "${_cryptroot}.orig" ]; then | |
echo "Moving ${_cryptroot}.orig to ${_home}/" | |
mv "${_cryptroot}.orig" $_home | |
fi | |
if [ -e "${_cryptroot}.rej" ]; then | |
echo "Moving ${_cryptroot}.rej to ${_home}/" | |
mv "${_cryptroot}.rej" $_home | |
fi | |
else | |
echo "cryptroot: already patched" | |
fi | |
} | |
cat_patch_cryptroot_hooks () | |
{ | |
# cd /tmp | |
# mkdir -p a/usr/share/initramfs-tools/hooks | |
# mkdir -p b/usr/share/initramfs-tools/hooks | |
# cp /usr/share/initramfs-tools/hooks/cryptroot a/usr/share/initramfs-tools/hooks/cryptroot | |
# cp /usr/share/initramfs-tools/hooks/cryptroot b/usr/share/initramfs-tools/hooks/cryptroot | |
# nano b/usr/share/initramfs-tools/hooks/cryptroot | |
# diff -crB a/usr/share/initramfs-tools/hooks/cryptroot b/usr/share/initramfs-tools/hooks/cryptroot > cryptroot.patch | |
# cat cryptroot.patch | |
cat <<- "EOF" | |
diff -crB a/usr/share/initramfs-tools/hooks/cryptroot b/usr/share/initramfs-tools/hooks/cryptroot | |
*** a/usr/share/initramfs-tools/hooks/cryptroot 2019-05-22 18:34:12.116097472 +0100 | |
--- b/usr/share/initramfs-tools/hooks/cryptroot 2019-05-22 20:13:02.159138688 +0100 | |
*************** | |
*** 70,88 **** | |
# take the last mountpoint if used several times (shadowed) | |
unset -v devnos | |
spec="$(printf '%b' "$spec")" | |
- resolve_device "$spec" || continue # resolve_device() already warns on error | |
fstype="$(printf '%b' "$fstype")" | |
! if [ "$fstype" = "btrfs" ]; then | |
! # btrfs can span over multiple devices | |
! if uuid="$(device_uuid "$DEV")"; then | |
! for dev in "/sys/fs/$fstype/$uuid/devices"/*/dev; do | |
! devnos="${devnos:+$devnos }$(cat "$dev")" | |
! done | |
! else | |
! cryptsetup_message "ERROR: $spec: Couldn't determine UUID" | |
fi | |
- elif [ -n "$fstype" ]; then | |
- devnos="$MAJ:$MIN" | |
fi | |
fi | |
done </proc/mounts | |
--- 70,97 ---- | |
# take the last mountpoint if used several times (shadowed) | |
unset -v devnos | |
spec="$(printf '%b' "$spec")" | |
fstype="$(printf '%b' "$fstype")" | |
! if [ "$fstype" = "zfs" ]; then | |
! # zfs can span over multiple devices | |
! for dev in $(zpool status -L -P | grep -o "/dev/[^ ]*"); do | |
! MAJ="$(printf "%d\n" 0x$(stat -L -c"%t" -- "$dev"))" | |
! MIN="$(printf "%d\n" 0x$(stat -L -c"%T" -- "$dev"))" | |
! devnos="${devnos:+$devnos }$MAJ:$MIN" | |
! done | |
! else | |
! resolve_device "$spec" || continue # resolve_device() already warns on error | |
! if [ "$fstype" = "btrfs" ]; then | |
! # btrfs can span over multiple devices | |
! if uuid="$(device_uuid "$DEV")"; then | |
! for dev in "/sys/fs/$fstype/$uuid/devices"/*/dev; do | |
! devnos="${devnos:+$devnos }$(cat "$dev")" | |
! done | |
! else | |
! cryptsetup_message "ERROR: $spec: Couldn't determine UUID" | |
! fi | |
! elif [ -n "$fstype" ]; then | |
! devnos="$MAJ:$MIN" | |
fi | |
fi | |
fi | |
done </proc/mounts | |
EOF | |
} | |
_patch_cryptroot_hooks () | |
{ | |
_cryptroot_hooks=/usr/share/initramfs-tools/hooks/cryptroot | |
if ! grep -q -i 'zpool status -L -P | grep -o' $_cryptroot_hooks; then | |
cat_patch_cryptroot_hooks | patch -p1 --forward --directory=/ --ignore-whitespace --reject-file=- $_cryptroot_hooks | |
_not_patched=true | |
if [ -e "${_cryptroot_hooks}.orig" ]; then | |
echo "Moving ${_cryptroot_hooks}.orig to ${_home}/cryptroot_hooks.orig" | |
mv "${_cryptroot_hooks}.orig" ${_home}/cryptroot_hooks.orig | |
fi | |
if [ -e "${_cryptroot_hooks}.rej" ]; then | |
echo "Moving ${_cryptroot_hooks}.rej to ${_home}/cryptroot_hooks.rej" | |
mv "${_cryptroot_hooks}.rej" ${_home}/cryptroot_hooks.rej | |
fi | |
else | |
echo "cryptroot_hooks: already patched" | |
fi | |
} | |
cat_patch_grub_mkconfig () | |
{ | |
# cd /tmp | |
# mkdir -p a/usr/sbin | |
# mkdir -p b/usr/sbin | |
# cp /usr/sbin/grub-mkconfig a/usr/sbin/grub-mkconfig | |
# cp /usr/sbin/grub-mkconfig b/usr/sbin/grub-mkconfig | |
# nano b/usr/sbin/grub-mkconfig | |
# diff -crB a/usr/sbin/grub-mkconfig b/usr/sbin/grub-mkconfig > grub-mkconfig.patch | |
# cat grub-mkconfig.patch | |
cat <<- "EOF" | |
*** a/usr/sbin/grub-mkconfig 2017-04-28 20:29:30.444342042 +0100 | |
--- b/usr/sbin/grub-mkconfig 2017-04-28 20:31:03.388384589 +0100 | |
*************** | |
*** 139,146 **** | |
GRUB_DEVICE="`${grub_probe} --target=device /`" | |
GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true | |
! # Device containing our /boot partition. Usually the same as GRUB_DEVICE. | |
! GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`" | |
GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true | |
# Filesystem for the device containing our userland. Used for stuff like | |
--- 139,153 ---- | |
GRUB_DEVICE="`${grub_probe} --target=device /`" | |
GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true | |
! if [ "x${grub_cfg}" = "x" ]; then | |
! # Device containing our /boot partition. Usually the same as GRUB_DEVICE. | |
! GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`" | |
! else | |
! # Device where we are outputting our grub configuration file | |
! grub_cfg_dir="`dirname ${grub_cfg}`" | |
! GRUB_DEVICE_BOOT="`${grub_probe} --target=device $grub_cfg_dir`" | |
! fi | |
! | |
GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true | |
# Filesystem for the device containing our userland. Used for stuff like | |
EOF | |
} | |
_patch_grub_mkconfig () | |
{ | |
_grub_mkconfig=/usr/sbin/grub-mkconfig | |
if ! grep -q '${grub_probe} --target=device $grub_cfg_dir' $_grub_mkconfig; then | |
cat_patch_grub_mkconfig | patch -p1 --forward --directory=/ --ignore-whitespace --reject-file=- $_grub_mkconfig | |
_not_patched=true | |
if [ -e "${_grub_mkconfig}.orig" ]; then | |
echo "Moving ${_grub_mkconfig}.orig to ${_home}/" | |
mv "${_grub_mkconfig}.orig" ${_home} | |
fi | |
if [ -e "${_grub_mkconfig}.rej" ]; then | |
echo "Moving ${_grub_mkconfig}.rej to ${_home}/" | |
mv "${_grub_mkconfig}.rej" ${_home} | |
fi | |
else | |
echo "grub_mkconfig: already patched" | |
fi | |
} | |
_update_initrd () | |
{ | |
if [ "$_not_patched" ]; then | |
update-initramfs -c -k all | |
update-grub | |
# reinstall grub | |
[ -d /boot/efi ] && _grub_args_boot_efi="--efi-directory=/boot/efi" | |
grub-install --target=x86_64-efi --recheck --no-floppy --boot-directory=/boot $_grub_args_boot_efi | |
fi | |
} | |
_sync_boot2 () | |
{ | |
_boot2_folder="/boot2" | |
_mounts="$(mount)" | |
_boot2_drive="$(echo $_mounts | grep "on $_boot2_folder " | cut -d' ' -f1 | sed -e 's/[0-9]*$//')" | |
if [ "$_boot2_drive" ]; then | |
echo "$0: syncing /boot to $_boot2_folder" | |
rsync -avu --delete "/boot/" "$_boot2_folder" | |
# update-initramfs -b ${_boot2_folder} -c -k all | |
# generate a /boot2 tailored version of grub.cfg | |
grub-mkconfig -o ${_boot2_folder}/grub/grub.cfg | |
# reinstall grub | |
[ -d ${_boot2_folder}/efi ] && _grub_args_boot2_efi="--efi-directory=${_boot2_folder}/efi" | |
grub-install --target=x86_64-efi --recheck --no-floppy --boot-directory=${_boot2_folder} $_grub_args_boot2_efi $_boot2_drive | |
else | |
echo "$0: warning: couldn't find any $_boot2_folder to update. Skipping." | |
fi | |
} | |
# Begin: | |
echo "$0: updating..." | |
_patch_cryptroot; | |
_patch_cryptroot_hooks; | |
_patch_grub_mkconfig; | |
_update_initrd; | |
_sync_boot2; | |
echo "$0: done." | |
# End. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment