diff options
Diffstat (limited to 'debian/tests/utils/mkinitramfs')
-rwxr-xr-x | debian/tests/utils/mkinitramfs | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/debian/tests/utils/mkinitramfs b/debian/tests/utils/mkinitramfs new file mode 100755 index 0000000..6bc70f4 --- /dev/null +++ b/debian/tests/utils/mkinitramfs @@ -0,0 +1,159 @@ +#!/bin/sh + +# Generate an initramfs image, much like mkinitramfs(8) but simpler +# +# Copyright © 2021-2022 Guilhem Moulin <guilhem@debian.org> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +set -eu +PATH="/usr/sbin:/usr/bin:/sbin:/bin" +export PATH + +unset DEBUG +EXTRACT_DIR="$1" +KERNEL_VERSION="$2" +INITRD="$3" + +UTILS="$(dirname -- "$0")" +DESTDIR="$(mktemp --directory -- "$INITRD.XXXXXXXXXX")" +trap "rm -r${DEBUG:+v}f -- \"$DESTDIR\"" EXIT INT TERM + +# from /usr/sbin/mkinitramfs: create usr-merged filesystem layout, to +# avoid duplicates if the host filesystem is usr-merged +for d in /bin /lib* /sbin; do + [ -d "$d" ] || continue + mkdir -p "$DESTDIR/usr$d" + ln -sT "usr$d" "$DESTDIR$d" +done + +install -m0755 "$UTILS/init" "$DESTDIR/init" +install -m0755 "$UTILS/debootstrap" "$DESTDIR/debootstrap" +cat >"$DESTDIR/init.conf" <<- EOF + HOSTNAME="$TESTNAME" + export HOSTNAME + PACKAGES="$PACKAGES" + BOOT="$BOOT" + CONSOLE="$CONSOLE" + ARCH="$ARCH" + MERGED_USR="$MERGED_USR" +EOF + +for p in setup preinst postinst bottom; do + # setup: sourced after creating the BIOS or EFI boot partition + # preinst: run in chroot after debootstrap, but before installing extra packages + # postinst: optionally run in chroot after installing extra packages + # bottom: last thing to run before shutdown + if [ -f "$TESTDIR/$TESTNAME.d/$p" ]; then + install -m0755 "$TESTDIR/$TESTNAME.d/$p" "$DESTDIR/init.$p" + fi +done + +MODULES="dm_crypt ext4 btrfs raid0 raid1" +if [ "$BOOT" = "efi" ]; then + MODULES="$MODULES efivarfs nls_ascii nls_cp437 vfat" +fi + +depmod -ab "$EXTRACT_DIR" "$KERNEL_VERSION" +for kmod in virtio_console virtio_blk virtio_pci virtio_rng \ + "$EXTRACT_DIR/lib/modules/$KERNEL_VERSION"/kernel/arch/*/crypto/*.ko* \ + "$EXTRACT_DIR/lib/modules/$KERNEL_VERSION"/kernel/crypto/*.ko* \ + $MODULES; do + kmod="${kmod##*/}" + modprobe -aid "$EXTRACT_DIR" -S "$KERNEL_VERSION" --show-depends "${kmod%%.*}" +done | while read -r insmod kmod _; do + [ "$insmod" = "insmod" ] || continue + kmod_rel="${kmod#"$EXTRACT_DIR/lib/modules/$KERNEL_VERSION/"}" + if [ ! -f "$kmod" ] || [ "${kmod_rel#kernel/}" = "$kmod_rel" ]; then + echo "Error: Unexpected modprobe output: $insmod $kmod" >&2 + exit 1 + fi + mkdir -p "$DESTDIR/lib/modules/$KERNEL_VERSION/${kmod_rel%/*}" + ln -f${DEBUG:+v}T -- "$kmod" "$DESTDIR/lib/modules/$KERNEL_VERSION/$kmod_rel" +done + +ln -t "$DESTDIR/lib/modules/$KERNEL_VERSION" -- \ + "$EXTRACT_DIR/lib/modules/$KERNEL_VERSION/modules.order" \ + "$EXTRACT_DIR/lib/modules/$KERNEL_VERSION/modules.builtin" +depmod -wab "$DESTDIR" "$KERNEL_VERSION" + +verbose="${DEBUG-}" +. /usr/share/initramfs-tools/hook-functions # for copy_exec() +if [ -f "$TESTDIR/$TESTNAME.d/mkinitramfs" ]; then + . "$TESTDIR/$TESTNAME.d/mkinitramfs" +fi + +copy_exec /bin/cp +copy_exec /bin/rm +copy_exec /bin/chmod + +copy_exec /sbin/modprobe +copy_exec /sbin/blkid +copy_exec /sbin/sfdisk +copy_exec /sbin/mkswap +copy_exec /sbin/swapon +copy_exec /sbin/swapoff +copy_exec /sbin/cryptsetup +copy_exec /sbin/dmsetup +copy_exec /usr/bin/dpkg-deb +copy_exec /bin/tar + +# assume ossl-modules/legacy.so and libgcc_s.so are relative to the linked libcryptsetup.so +libdir="$(env --unset=LD_PRELOAD ldd /sbin/cryptsetup | sed -nr '/.*=>\s*(\S+)\/libcryptsetup\.so\..*/ {s//\1/p;q}')" +copy_exec "$libdir/ossl-modules/legacy.so" || true +copy_libgcc "$libdir" + +for p in /sbin/cryptsetup /sbin/lvm /sbin/mdadm /sbin/mke2fs /sbin/mkfs.btrfs /bin/btrfs; do + if [ -x "$p" ]; then + copy_exec "$p" + fi +done + +if [ "$BOOT" = "efi" ]; then + if [ ! -x "/sbin/mkfs.vfat" ]; then + echo "Couldn't find mkfs.vfat, is the 'dosfstools' package installed?" >&2 + exit 1 + fi + copy_exec /sbin/mkfs.vfat +fi + +cp -pLt "$DESTDIR/lib" /lib/klibc-*.so +for cmd in cat chroot ln ls mkdir mount mv sh umount uname; do + exe="/usr/lib/klibc/bin/$cmd" + if [ ! -f "$exe" ] || [ ! -x "$exe" ]; then + echo "No such executable: $exe" >&2 + exit 1 + fi + copy_exec "$exe" /bin +done + +# copy udevd and (some of) its rules +copy_exec /lib/systemd/systemd-udevd +copy_exec /bin/udevadm + +mkdir -p -- "$DESTDIR/etc/udev" "$DESTDIR/lib/udev/rules.d" +cat >"$DESTDIR/etc/udev/udev.conf" <<-EOF + udev_log=info + resolve_names=never +EOF +for rules in 50-udev-default.rules 55-dm.rules 60-block.rules \ + 60-persistent-storage.rules 60-persistent-storage-dm.rules \ + 63-md-raid-arrays.rules 95-dm-notify.rules; do + if [ -e "/lib/udev/rules.d/$rules" ]; then + cp -T "/lib/udev/rules.d/$rules" "$DESTDIR/lib/udev/rules.d/$rules" + fi +done + +cd "$DESTDIR" +find . -print0 | cpio -o0 -R 0:0 -H newc --quiet ${DEBUG:+--verbose} >"$INITRD" |