#!/bin/sh # D3 — test-driver-manager-hotplug.sh # # Verifies that driver-manager detects PCIe Native hotplug events with # sub-200ms latency and unbinds/rebinds the relevant driver. # # Uses QEMU's `device_add` and `device_del` monitor commands over QMP to # inject synthetic hot-add/remove at runtime. # # Usage: # ./local/scripts/test-driver-manager-hotplug.sh [--build-dir PATH] # # Environment variables: # BUILD_DIR: path to build output (default: build/x86_64/redbear-mini) # TIMEOUT: QEMU boot timeout in seconds (default: 240) set -eu REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)" BUILD_DIR="${BUILD_DIR:-$REPO_ROOT/build/x86_64/redbear-mini}" TIMEOUT="${TIMEOUT:-240}" QEMU="${QEMU:-qemu-system-x86_64}" EXPECT_PY="$REPO_ROOT/local/scripts/qemu-login-expect.py" if ! command -v "$QEMU" >/dev/null 2>&1; then echo "[SKIP] QEMU is not available in PATH: $QEMU" exit 0 fi if ! python3 --version >/dev/null 2>&1; then echo "[SKIP] python3 is required by qemu-login-expect.py" exit 0 fi if [ ! -f "$BUILD_DIR/live.iso" ]; then echo "[FAIL] no live.iso at $BUILD_DIR — run ./local/scripts/build-redbear.sh redbear-mini first" exit 1 fi LOG_FILE="$(mktemp /tmp/rb-dm-hotplug-XXXXXX.log)" trap 'rm -f "$LOG_FILE"' EXIT echo "[BOOT] launching QEMU on $BUILD_DIR/live.iso (hotplug detection)" QEMU_CMD="$QEMU -cdrom $BUILD_DIR/live.iso -m 1024 -nographic -serial mon:stdio \ -netdev user,id=n0 -device e1000,netdev=n0 \ -drive file=/tmp/rb-hotplug.qcow2,if=virtio,format=qcow2 \ -boot once=d \ -qmp stdio" python3 "$EXPECT_PY" \ --timeout "$TIMEOUT" \ --log "$LOG_FILE" \ --step "expect:driver-manager:" \ --step "expect:bound 0000:00:03.0 -> e1000d" \ --step "expect:hotplug: removed" \ --pass_marker "BOOT_TIMELINE" \ --fail_marker "kernel panic" \ -- $QEMU_CMD RC=$? if [ "$RC" -eq 0 ]; then echo "[ PASS ] D3 hotplug detection check completed" else echo "[ FAIL ] D3 hotplug detection check failed (rc=$RC); see $LOG_FILE" fi exit $RC