#!/bin/sh # The initramfs images as the mesh builds them (module kernel, novox/hq issue 1977). Run by # mesh-kernel-initramfs.service: # # initramfs apply [ [ [ []]]] # # `apply` builds every image again (mkinitcpio -P) when the drop-in differs from the one the images were last built # with, kept in the state as `initramfs-built`, and records the drop-in only after mkinitcpio succeeded. Later # kernel upgrades build the images through the distribution's own hook, with the drop-in in place. # # A preset that names the default configuration (ALL_config="/etc/mkinitcpio.conf") makes mkinitcpio pass -c and skip # mkinitcpio.conf.d, so the drop-in is never read: before building, that line is taken out of the preset, a copy of # the preset kept in the state's taken-over directory (novox/hq ADR 0508 ยง10's way with a file the mesh did not # write); any other ALL_config is left and named. After building, every image must hold microcode in its first # 64 KiB (the early uncompressed archive), else the unit fails and records nothing. The arguments are only for the # module's tests. set -eu dropin=/etc/mkinitcpio.conf.d/mesh-microcode.conf state='${dir:state}' [ $# -ge 2 ] && dropin=$2 [ $# -ge 3 ] && state=$3 presets=/etc/mkinitcpio.d boot=/boot [ $# -ge 4 ] && presets=$4 [ $# -ge 5 ] && boot=$5 [ $# -ge 1 ] && [ "$1" = apply ] || { echo "usage: initramfs apply [ []]" >&2 exit 2 } [ -f "$dropin" ] || { echo "initramfs: $dropin is not there, so the images cannot be built with the microcode hook" >&2 exit 1 } if [ -f "$state/initramfs-built" ] && cmp -s "$dropin" "$state/initramfs-built"; then echo "initramfs: the images were built with this drop-in, as it was" exit 0 fi for preset in "$presets"/*.preset; do [ -f "$preset" ] || continue if grep -qx 'ALL_config="/etc/mkinitcpio.conf"' "$preset"; then mkdir -p "$state/taken-over" cp "$preset" "$state/taken-over/$(basename "$preset")" grep -vx 'ALL_config="/etc/mkinitcpio.conf"' "$preset" >"$preset.new" || true cat "$preset.new" >"$preset" rm -f "$preset.new" echo "initramfs: $preset named the default configuration, which skips mkinitcpio.conf.d; that line is taken out, a copy is in $state/taken-over" elif grep -q '^ALL_config=' "$preset"; then echo "initramfs: $preset sets $(grep '^ALL_config=' "$preset" | head -n 1), so the microcode drop-in may not be read; left as it is" fi done if ! mkinitcpio -P; then echo "initramfs: mkinitcpio failed; nothing recorded, the next start tries again" >&2 exit 1 fi missing= for img in "$boot"/initramfs-*.img; do [ -e "$img" ] || continue if ! head -c 65536 "$img" >"$state/image-head.tmp" || ! grep -aq 'kernel/x86/microcode/' "$state/image-head.tmp"; then missing="$missing $(basename "$img")" fi done rm -f "$state/image-head.tmp" if [ -n "$missing" ]; then echo "initramfs: mkinitcpio ran, but no microcode is in the early archive of:$missing; nothing recorded" >&2 exit 1 fi cp "$dropin" "$state/initramfs-built.new" mv "$state/initramfs-built.new" "$state/initramfs-built" echo "initramfs: the images are built with the microcode drop-in"