From b5a8f509ee07dc56acbb7239d0335e24c74ffe44 Mon Sep 17 00:00:00 2001
From: Recolic K <bensl@microsoft.com>
Date: Mon, 27 Sep 2021 17:26:18 +0800
Subject: [PATCH] code almost finished

---
 PKGBUILD                               | 28 +++++++++++++++++
 README.md                              | 32 ++++++++++++++------
 hook-kernel-rename.sh                  |  3 +-
 shared-bootdir-helper-multi-kparam     | 42 ++++++++++++++++++++++++++
 shared-bootdir-helper-multi-kparam.cfg | 14 +++++++++
 shared-bootdir-helper.install          | 14 +++++++++
 6 files changed, 123 insertions(+), 10 deletions(-)
 create mode 100644 PKGBUILD
 create mode 100755 shared-bootdir-helper-multi-kparam
 create mode 100644 shared-bootdir-helper-multi-kparam.cfg
 create mode 100644 shared-bootdir-helper.install

diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 0000000..2c25a55
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,28 @@
+# Maintainer: Recolic Keghart <root@recolic.net>
+# Original repo: https://git.recolic.net/root/shared-bootdir-helper
+
+pkgname=shared-bootdir-helper
+pkgver=1.0
+pkgrel=1
+pkgdesc="Allow multiple linux installations to share the same /boot directory. Useful for deniable encryption. "
+url="https://github.com/recolic/$pkgname"
+license=("GPL3")
+arch=("any")
+depends=("bash" "sed" "grep" "mkinitcpio")
+install="$pkgname.install"
+source=(
+    "$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz"
+    "$pkgname-$pkgver.tar.gz.sig::$url/releases/download/v$pkgver/v$pkgver.tar.gz.sig"
+)
+validpgpkeys=("6861D89984E7887F0FFE6E08C344D5EAE3933636")
+sha256sums=(
+    "SKIP"
+    "SKIP"
+)
+
+package() {
+    mkdir -p "$pkgdir/opt" "$pkgdir/usr/bin" &&
+    cp -r "$pkgname-$pkgver" "$pkgdir/opt/vivado-wrapper" &&
+    ln -s "/opt/vivado-wrapper/vivado-wrapper" "$pkgdir/usr/bin/vivadow"
+}
+
diff --git a/README.md b/README.md
index f7dc77e..a619d74 100644
--- a/README.md
+++ b/README.md
@@ -2,34 +2,48 @@
 
 Background: <https://recolic.net/blog/post/deniable-encryption-and-shared-boot-partition>
 
-## Problem to solve
-
 You may have multiple linux installations, and they want to share the same `/boot` directory. 
 However, each of them want different kernel paramters. 
 
 This scenario usually appears while you want to deniable-encrypt all your computers, without 
 bringing tons of USB sticks with you. 
 
-## What this package do
+## Problem1 - multiple installations may share the same vmlinuz filename
+
+You just need to install this package. And it can automatically add hooks to help you rename them. 
+
+- What does this package do for you
 
 1. Add a pre-transaction hook to make sure you have inserted your USB stick before upgrading kernel. 
 2. Add a post-transaction hook to rename your kernel file basing on hostname, to avoid conflicting with other installations. And learn from `/usr/share/libalpm/scripts/mkinitcpio-install`, to find and modify the `pkgbase` file to add a hostname.
 3. Add a new mkinitcpio preset basing on hostname.  
-4. Modify `/etc/default/grub` to allow external script to manage kernel parameters. 
-5. Add a post-transaction hook after `grub-mkconfig`, to automatically set kernel parameters for every boot entry. 
 
-> I don't think it's a good idea for a package to modify others configuration file. I'm reviewing the design to see if there's any better solution. 
+## Problem2 - every kernel wants its own kernel parameter set
 
-## Support status
+GRUB is managing kernel parameters. 
 
-### Bootloader
+- What does this package do for you
+
+1. Provide a tool to modify the generated `/boot/grub/grub.cfg`. 
+2. Add a post-transaction hook after `grub-mkconfig`, to automatically run that tool for you. 
+
+This package will do NOTHING if you skipped the configuration.
 
-only supports grub
+- What should you do
+
+1. Modify `/etc/default/grub`, to set `GRUB_CMDLINE_LINUX_DEFAULT="__KERNEL_PARAMETER_MANAGED_BY_HELPER"`. 
+2. Modify file `/etc/shared-bootdir-helper-multi-kparam.cfg`, to set kernel parameters for each hostname. 
+
+## Support status
 
 ### Distributions
 
 only supports arch-based distributions. Tested on Arch Linux and Manjaro Linux. 
 
+### Bootloader
+
+only supports grub. This only matters if you're using `shared-bootdir-helper-multi-kparam`. 
+
 ## notes
 
 depends on: sed, bash, 
diff --git a/hook-kernel-rename.sh b/hook-kernel-rename.sh
index 3543b4d..4e31f6c 100755
--- a/hook-kernel-rename.sh
+++ b/hook-kernel-rename.sh
@@ -35,9 +35,10 @@ while read -r line; do
         continue
     fi
 
-    # Generates a filename for the kernel, and limit the length
+    # Generates a filename for the kernel, and limit the length, convert to lowercase
     new_pkgbase="${pkgbase}-$(hostname)"
     new_pkgbase="${new_pkgbase:0:63}"
+    new_pkgbase="${new_pkgbase,,}" # since bash 4.0
 
     # Generate mkinitcpio presets
     generate_mkinitcpio_preset "${new_pkgbase}" && 
diff --git a/shared-bootdir-helper-multi-kparam b/shared-bootdir-helper-multi-kparam
new file mode 100755
index 0000000..1f3f8f6
--- /dev/null
+++ b/shared-bootdir-helper-multi-kparam
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+# For shared boot partition between multiple installations, 
+#   each kernel image may need different boot parameter, and 
+#   it's not a good idea to manage them manually in grub.d. 
+# So we set GRUB_CMDLINE_LINUX_DEFAULT to 
+#    __KERNEL_PARAMETER_MANAGED_BY_HELPER, 
+# and this script is intended to run after `grub-mkconfig`, 
+#   which alters all `__KERNEL_PARAMETER_MANAGED_BY_HELPER`
+#   to correct kernel parameters. 
+#
+# Usage: ./this.sh /boot/grub/grub.cfg
+
+source "/etc/shared-bootdir-helper-multi-kparam.cfg" || exit 1
+
+########### implementation begin ##############
+tmpfile="$(mktemp)"
+inputfile="$1"
+[[ "$inputfile" = "" ]] && echo "Usage: $0 /boot/grub/grub.cfg" && exit 1
+
+while IFS= read -r line; do
+    matched=0
+    if [[ "$line" == *"$placeholder"* ]]; then
+        for hostname in "${!map_hostname_to_kparam[@]}"; do
+            # Assuming that, the kimg filename contains "vmlinuz-xxx-$hostname ", in lowercase. That's important! 
+            [[ "$line" == *"-$hostname "* ]] &&
+                echo "$line" | sed "s|$placeholder|${map_kimage_to_kparam[$hostname]}|g" >> "$tmpfile" &&
+                matched=1 && 
+                break
+        done
+    fi
+    [[ $matched == 0 ]] && echo "$line" >> "$tmpfile"
+done < "$inputfile" || exit $?
+
+mv "$tmpfile" "$inputfile" || exit $?
+
+grep "$placeholder" "$inputfile" &&
+    echo "Warning: placeholder '$placeholder' still exists in processed grub.cfg. Have you correctly set the 'map_kimage_to_kparam' of $0? Please double-check! " &&
+    exit 2
+
+exit 0
+
diff --git a/shared-bootdir-helper-multi-kparam.cfg b/shared-bootdir-helper-multi-kparam.cfg
new file mode 100644
index 0000000..569fc1d
--- /dev/null
+++ b/shared-bootdir-helper-multi-kparam.cfg
@@ -0,0 +1,14 @@
+
+# You use this placeholder in GRUB_CMDLINE_LINUX_DEFAULT in /etc/default/grub
+placeholder="__KERNEL_PARAMETER_MANAGED_BY_HELPER"
+
+# mapping between hostname and kernel parameters. 
+declare -A map_hostname_to_kparam=(
+    # Parameters can not contain `|` character, which will crash this naive script. 
+    # hostname MUST be in lowercase, because `hook-kernel-rename.sh` converts hostname to lowercase. 
+    # This is some examples: 
+    ["recolicpc"]="quiet amdgpu.ppfeaturemask=0xffffffff cryptdevice=/dev/disk/by-id/nvme-SAMSUNG_MZVLW256HEHP-xxxxxxxxxxxx:cryptlvm:allow-discards cryptkey=/dev/disk/by-partlabel/xxxxxxxx:0:64 crypto=:aes-xts-plain64:512:0:"
+    ["recolicmpc"]="quiet cryptdevice=/dev/disk/by-id/ata-SAMSUNG_MZNTY128HDHP-000xxxxxxxxxx:cryptlvm:allow-discards cryptkey=/dev/disk/by-partlabel/xxxxxxx:0:64 crypto=:aes-xts-plain64:512:0: resume=/dev/RecolicmpcVolGroup/swap"
+    ["recolicmsmpc"]="quiet cryptdevice=/dev/disk/by-id/xxxxxxxxxxxxxxxxxx:cryptlvm cryptkey=/dev/disk/by-partlabel/xxxxxxxx:0:64 crypto=xxxxxxxxxxxxxxxxxxxxxx"
+)
+
diff --git a/shared-bootdir-helper.install b/shared-bootdir-helper.install
new file mode 100644
index 0000000..8a1c380
--- /dev/null
+++ b/shared-bootdir-helper.install
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+post_install() {
+    echo "***********************************shared-bootdir-helper**************************************"
+    echo "If you want to boot each kernel with different kernel parameters, "
+    echo "  you need to use the tool 'shared-bootdir-helper-multi-kparam'. "
+    echo "  PLEASE read README.md to learn what should you do. "
+    echo ""
+    echo "If you're ok to boot each kernel with the same kernel parameters (in /etc/default/grub), "
+    echo "  you need to do nothing. "
+    echo "**********************************************************************************************"
+}
+
+
-- 
GitLab