#!/usr/bin/env bash # Check Rustbelt's ext2 writes with the host's own tools (e2fsprogs). # # 1. e2fsck the pristine images build.rs made (sanity check of the build). # 2. Copy them to target/fsck/ and boot Rustbelt on the *writable* copies # (no snapshot=on), so whatever it writes really lands in the files: # - the shell self-test (cp B: -> C:, mkdir, echo > file) # - the tests/ext2.rs kernel (create/write/truncate/unlink/rmdir on # all three images: 1 KiB blocks, 4 KiB blocks, revision 0) # 3. `e2fsck -fn` every copy: -f = check even if marked clean, -n = open # read-only and answer "no" to every question (report, don't fix). # Any complaint means the driver wrote something inconsistent. # 4. Show the root directory with debugfs, to see the new files. # # Usage: ./scripts/ext2-check.sh (after `cargo build` and # `cargo test --test ext2`, which build the images and the kernels) set -euo pipefail cd "$(dirname "$0")/.." T="${CARGO_TARGET_DIR:-target}" # stage 21: the build output (cargo's target dir) export PATH="$HOME/.cargo/bin:$PATH:/usr/sbin:/sbin" for tool in e2fsck debugfs qemu-system-x86_64; do command -v $tool >/dev/null || { echo "need $tool (apt install e2fsprogs qemu-system-x86)"; exit 1; } done fsck() { # fsck echo "== e2fsck -fn $1 ($2)" e2fsck -fn "$1" || { echo "!! e2fsck found problems in $1"; status=1; } } status=0 for img in $T/ext2.img $T/ext2-4k.img $T/ext2-rev0.img; do fsck $img "pristine, as built" done mkdir -p $T/fsck cp $T/ext2.img $T/fsck/selftest.img for img in ext2 ext2-4k ext2-rev0; do cp $T/$img.img $T/fsck/tests-$img.img; done echo "== boot the shell self-test on $T/fsck/selftest.img" EXT2_IMG=$T/fsck/selftest.img ./scripts/run-headless.sh >/dev/null && echo "self-test OK" echo "== run the tests/ext2.rs kernel on $T/fsck/tests-*.img" KERNEL=$(ls -t $T/x86_64-rust_kernel/debug/build/rustbelt/*/out/bootimage-ext2-*.bin 2>/dev/null | head -1 || true) [ -n "$KERNEL" ] || { echo "no test kernel: run 'cargo test --test ext2' first"; exit 1; } set +e timeout 120 qemu-system-x86_64 -smp 4 -drive format=raw,file="$KERNEL" -no-reboot \ -drive file=$T/disk.img,format=raw,if=virtio,snapshot=on \ -drive file=$T/fsck/tests-ext2.img,format=raw,if=virtio \ -drive file=$T/exfat.img,format=raw,if=virtio,snapshot=on \ -drive file=$T/btrfs.img,format=raw,if=virtio,snapshot=on \ -drive file=$T/fsck/tests-ext2-4k.img,format=raw,if=virtio \ -drive file=$T/fsck/tests-ext2-rev0.img,format=raw,if=virtio \ -drive file=$T/exfat-512.img,format=raw,if=virtio,snapshot=on \ -device isa-debug-exit,iobase=0xf4,iosize=0x04 \ -serial stdio -display none > $T/fsck/tests.log code=$? set -e grep -c "\[ok\]" $T/fsck/tests.log | sed 's/$/ ext2 tests ok/' [ $code = 33 ] || { echo "!! test kernel failed (exit $code), see $T/fsck/tests.log"; exit 1; } for img in $T/fsck/selftest.img $T/fsck/tests-ext2*.img; do fsck "$img" "after Rustbelt wrote to it" done echo "== debugfs: ls -l / on the self-test copy" debugfs -R "ls -l /" $T/fsck/selftest.img 2>/dev/null echo "== debugfs: cat /made-here/note.txt" debugfs -R "cat /made-here/note.txt" $T/fsck/selftest.img 2>/dev/null [ $status = 0 ] && echo "== all images are clean" || echo "== e2fsck found problems" exit $status