#!/bin/sh # prepare-linux-initramfs.sh # # Checks (default) or adds (--apply) the storage and network drivers a Linux guest # needs in its initramfs to boot on the target hypervisor, BEFORE the conversion. # hyperv : hv_vmbus hv_storvsc hv_netvsc # virtio : virtio_pci virtio_blk virtio_scsi virtio_net (Nutanix AHV, Proxmox VE, KVM) # # Supports dracut (RHEL, Rocky, Alma, SUSE, Fedora) and initramfs-tools (Debian, Ubuntu). # Drivers built into the kernel (=y) need nothing and are reported as such. # # Usage: sudo sh prepare-linux-initramfs.sh hyperv # check only # sudo sh prepare-linux-initramfs.sh virtio --apply # add missing drivers, rebuild # # Take a snapshot or a backup first. Rebuilding the initramfs of the running kernel is a # boot-critical change: keep the previous kernel entry available in the boot menu. # Source: ANYSYS ICT, https://www.anysys.be/articles/ set -eu TARGET="${1:-}" MODE="${2:-check}" KVER="${KVER:-$(uname -r)}" case "$TARGET" in hyperv) MODULES="hv_vmbus hv_storvsc hv_netvsc" ;; virtio) MODULES="virtio_pci virtio_blk virtio_scsi virtio_net" ;; *) echo "usage: $0 hyperv|virtio [--apply]" >&2; exit 2 ;; esac if command -v dracut >/dev/null 2>&1 && [ ! -d /etc/initramfs-tools ]; then TOOL=dracut elif [ -d /etc/initramfs-tools ]; then TOOL=initramfs-tools else echo "Neither dracut nor initramfs-tools found: prepare this guest manually." >&2 exit 3 fi BUILTIN="/lib/modules/$KVER/modules.builtin" # RHEL family names the image initramfs-.img, Debian family initrd.img-. if [ -f "/boot/initramfs-$KVER.img" ]; then IMG="/boot/initramfs-$KVER.img" else IMG="/boot/initrd.img-$KVER" fi list_initramfs() { if [ "$TOOL" = dracut ]; then lsinitrd "$IMG" 2>/dev/null else lsinitramfs "$IMG" 2>/dev/null fi } CONTENT="$(list_initramfs || true)" MISSING="" for m in $MODULES; do if [ -f "$BUILTIN" ] && grep -q "/$m.ko" "$BUILTIN"; then echo "builtin $m" elif printf '%s\n' "$CONTENT" | grep -q "/$m.ko"; then echo "present $m" else echo "MISSING $m" MISSING="$MISSING $m" fi done echo "kernel=$KVER tool=$TOOL image=$IMG target=$TARGET" if [ -z "$MISSING" ]; then echo "Nothing to do." exit 0 fi if [ "$MODE" != "--apply" ]; then echo "Run again with --apply to add:$MISSING" exit 1 fi if [ "$TOOL" = dracut ]; then CONF="/etc/dracut.conf.d/90-migration-$TARGET.conf" echo "add_drivers+=\"$MISSING \"" > "$CONF" echo "wrote $CONF" dracut -f "$IMG" "$KVER" else for m in $MISSING; do grep -qx "$m" /etc/initramfs-tools/modules || echo "$m" >> /etc/initramfs-tools/modules done echo "updated /etc/initramfs-tools/modules" update-initramfs -u -k "$KVER" fi echo "Rebuilt. Verify with: $0 $TARGET"