//! Commit-gated replay observed on an isolated block device. use super::*; use os_turkfs_recovery_replay::{Block, Outcome, Recovery, HOMES}; fn print_hash(label: &str, homes: &[Block;3]) { let mut bytes = [0;1536]; for (i, block) in homes.iter().enumerate() { bytes[i*512..(i+1)*512].copy_from_slice(block); } let digest = turkos_kernel::program_hash::hex_lower(&turkos_kernel::turkfs::file_sha256(&bytes)); write_str(label); write_line(core::str::from_utf8(&digest).unwrap()); } pub fn run(boot: &BootData, allocator: &mut memory::FrameAllocator) -> Result<(), &'static str> { let before = allocator.remaining_pages(); let mut disk = k1685_virtio_replay::Disk::open(boot, allocator).map_err(|_| "k1685-open")?; let result = (|| { let mut blocks: [Block;6] = [[0;512];6]; for (i,lba) in [111,112,113,HOMES[0],HOMES[1],HOMES[2]].iter().enumerate() { disk.read(*lba,&mut blocks[i]).map_err(|_| "k1685-read")?; } if &blocks[0][..16] != b"K1685DISPOSABLE!" { return Err("k1685-control"); } let mut recovery = Recovery::new(&blocks[1],&blocks[2]).map_err(|_| "k1685-format")?; let old = [blocks[3],blocks[4],blocks[5]]; print_hash("TURKOS/OS/K1685-REPLAY: BEFORE-SHA256=",&old); let outcome = recovery.replay(&mut disk,&old).map_err(|_| "k1685-replay")?; match outcome { Outcome::NoCommit => write_line("TURKOS/OS/K1685-REPLAY: MISSING-COMMIT=UNCHANGED NO-WRITES"), Outcome::AlreadyApplied => write_line("TURKOS/OS/K1685-REPLAY: SECOND=UNCHANGED NO-WRITES"), Outcome::Replayed {writes:3} => write_line("TURKOS/OS/K1685-REPLAY: RECORDS=3 FLUSHED"), _ => return Err("k1685-unexpected-fixture"), } let mut after = [[0;512];3]; for (i,lba) in HOMES.iter().enumerate() { disk.read(*lba,&mut after[i]).map_err(|_| "k1685-readback")?; } let expected = if outcome==Outcome::NoCommit {&old} else {recovery.expected()}; if &after != expected { return Err("k1685-readback-bytes"); } print_hash("TURKOS/OS/K1685-REPLAY: AFTER-SHA256=",&after); Ok(()) })(); let closed = disk.close(allocator).map_err(|_| "k1685-reset"); result?; closed?; if allocator.remaining_pages() != before { return Err("k1685-frames"); } write_line("TURKOS/OS/K1685-REPLAY: FRAMES=UNCHANGED"); Ok(()) }