feat(deploy): USB-bootable batm3 test image (disk-image-batm3-usb)
Add a USB-bootable BATM3 disk-image target plus the batm3 hardware changes that make a dd'd USB stick boot reliably on the Dell 9030 AIO. flake.nix — new `disk-image-batm3-usb` target: - Distinct partition labels (nixos-usb / ESP-USB) so stage-1 by-label resolution can't latch onto an internal SATA drive that already holds a generic nixos/ESP-labelled install. Post-build mlabel relabels the ESP FAT volume to ESP-USB (bootloader files untouched; UEFI still loads /EFI/BOOT/BOOTX64.EFI). - /boot mounted nofail + short device-timeout: the firmware already loaded the bootloader before Linux; without nofail a slow/late ESP-USB enumeration drops to emergency mode with root locked — a dead end. - NO growPartition/autoResize on the USB image: sfdisk rewriting the partition table on first boot is the single most bus-stressing write, and flaky USB bridges drop off the bus mid-rewrite (sfdisk wedges in uninterruptible D-state and ESP-USB vanishes with the device, so /boot times out too). Persistent state is a few MB and the image already ships ~2GB free in root. The internal-SATA disk-image-batm3 keeps growPartition — a real AHCI SSD won't drop the bus. - autoUpgrade off (test image, not a managed fleet member). batm3.nix — USB-boot reliability: - Add usb_storage to initrd.availableKernelModules so stage-1 binds the stick and /dev/disk/by-label/* appears. - Blacklist uas + usbcore.autosuspend=-1: force the slower-but-reliable Bulk-Only Transport path and stop the boot medium being power-suspended mid-I/O — both were causing "device offline error" bus drops. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
da3f3265ab
commit
6edcb8b96d
2 changed files with 94 additions and 0 deletions
77
flake.nix
77
flake.nix
|
|
@ -424,6 +424,83 @@
|
|||
printf 'verify ESP label: '; mlabel -i "$out/nixos.img@@$espStart" -s :: || true
|
||||
'';
|
||||
|
||||
# USB-bootable BATM3 TEST image with DISTINCT partition labels
|
||||
# (nixos-usb / ESP-USB). The plain disk-image-batm3 reuses the generic
|
||||
# nixos/ESP labels, so a USB stick carrying it, booted on a batm3 whose
|
||||
# internal SATA drive ALREADY holds a nixos/ESP-labelled install, makes
|
||||
# stage-1's by-label/nixos resolve to the internal drive (larger fs,
|
||||
# journal recovers) instead of the stick — the stage-2 init path baked
|
||||
# into the USB's boot entry isn't on that root, so stage 1 aborts.
|
||||
# Distinct labels make stage-1 pick the stick unambiguously WITHOUT
|
||||
# touching the internal drive. Unlike disk-image-sintra-usb this keeps
|
||||
# systemd-boot: the batm3 firmware UEFI-USB-boots fine via the ESP's
|
||||
# /EFI/BOOT/BOOTX64.EFI removable fallback, so no GRUB/hybrid-table
|
||||
# change is needed — only the label disambiguation here plus the
|
||||
# usb_storage/uas initrd modules (in batm3.nix). Does NOT grow to fill
|
||||
# the stick (see the growPartition note below — sfdisk on first boot
|
||||
# wedges flaky USB bridges); auto-upgrade off (test image, not a managed
|
||||
# fleet member — also stops scheduled bootloader writes landing on the
|
||||
# internal drive's ESP).
|
||||
disk-image-batm3-usb =
|
||||
let
|
||||
cfg = self.nixosConfigurations.batm3-installed.extendModules {
|
||||
modules = [
|
||||
({ lib, ... }: {
|
||||
fileSystems."/".device = lib.mkForce "/dev/disk/by-label/nixos-usb";
|
||||
fileSystems."/boot".device = lib.mkForce "/dev/disk/by-label/ESP-USB";
|
||||
# /boot must NOT be a hard boot dependency on the USB test
|
||||
# image. The firmware already loaded the bootloader from the
|
||||
# ESP before Linux started; /boot is only remounted so the OS
|
||||
# can *update* the bootloader — which this image never does
|
||||
# (autoUpgrade off, no nixos-rebuild on the stick). Without
|
||||
# nofail, a slow/late ESP-USB enumeration (BOT is slower than
|
||||
# UAS) blows past systemd's 90s device-timeout and drops to
|
||||
# emergency mode — with root locked, an unrecoverable dead end.
|
||||
# nofail + a short timeout lets the (already-mounted) root carry
|
||||
# the boot to completion; /boot mounts if/when the ESP shows up.
|
||||
fileSystems."/boot".options = [ "nofail" "x-systemd.device-timeout=10s" ];
|
||||
# DELIBERATELY NO growPartition/autoResize on the USB image.
|
||||
# growPartition runs sfdisk to rewrite the stick's partition
|
||||
# table on first boot — the single most bus-stressing write of
|
||||
# the boot. Flaky USB bridges drop off the bus mid-rewrite
|
||||
# (sfdisk hangs forever as an uninterruptible D-state task) and,
|
||||
# worse, partition 1 (ESP-USB) vanishes with the device, so
|
||||
# /boot times out too. The kiosk's persistent state (state.db,
|
||||
# .env, wifi.conf, logs) is a few MB and the built image already
|
||||
# carries ~2GB free inside root — growing to fill the stick buys
|
||||
# nothing and costs reliability. The internal-SATA target
|
||||
# (disk-image-batm3) keeps growPartition: a real AHCI SSD won't
|
||||
# drop the bus and there filling the disk is worth it.
|
||||
system.autoUpgrade.enable = lib.mkForce false;
|
||||
})
|
||||
];
|
||||
};
|
||||
baseImage = import (nixpkgs + "/nixos/lib/make-disk-image.nix") {
|
||||
inherit pkgs lib;
|
||||
config = cfg.config;
|
||||
format = "raw";
|
||||
partitionTableType = "efi";
|
||||
diskSize = "auto";
|
||||
label = "nixos-usb"; # ext4 root label (make-disk-image -L)
|
||||
};
|
||||
in
|
||||
pkgs.runCommand "nixos-disk-image-batm3-usb"
|
||||
{ nativeBuildInputs = [ pkgs.parted pkgs.mtools ]; }
|
||||
''
|
||||
mkdir -p $out
|
||||
cp --sparse=always ${baseImage}/nixos.img $out/nixos.img
|
||||
chmod +w $out/nixos.img
|
||||
# make-disk-image hardcodes the ESP FAT label to "ESP"; relabel the
|
||||
# volume to ESP-USB so /boot (by-label/ESP-USB) can't resolve to an
|
||||
# internal drive's ESP. Volume label only — bootloader files are
|
||||
# untouched, and UEFI loads /EFI/BOOT/BOOTX64.EFI regardless.
|
||||
espStart=$(parted -sm "$out/nixos.img" unit B print | awk -F: '$1==1 {gsub("B","",$2); print $2}')
|
||||
echo "ESP partition starts at byte $espStart — relabelling to ESP-USB"
|
||||
export MTOOLS_SKIP_CHECK=1
|
||||
mlabel -i "$out/nixos.img@@$espStart" ::ESP-USB
|
||||
printf 'verify ESP label: '; mlabel -i "$out/nixos.img@@$espStart" -s :: || true
|
||||
'';
|
||||
|
||||
# Backwards compat
|
||||
iso = self.nixosConfigurations.douro.config.system.build.isoImage;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue