//! Fixed journal checkpoint, resumed from disk in a new QEMU process. use super::*; use os_turkfs_journal_checkpoint::{Block, Checkpoint, Error, Mount, HOMES}; pub fn run(boot: &BootData, allocator: &mut memory::FrameAllocator) -> Result<(), &'static str> { let before = allocator.remaining_pages(); let mut expected_log = [0u8; 512]; expected_log[..128].copy_from_slice(include_bytes!("k1665-journal.bin")); let mut expected_commit = [0u8; 512]; expected_commit[..8].copy_from_slice(b"TKCOMMIT"); expected_commit[8..16].copy_from_slice(&7u64.to_le_bytes()); expected_commit[16..20].copy_from_slice(&expected_log[28..32]); expected_commit[32..64].copy_from_slice(&turkos_kernel::turkfs::file_sha256(&[0x44; 512])); let mut job = Checkpoint::new(&expected_log, &expected_commit).map_err(|_| "k1680-format")?; let mut disk = k1680_virtio_checkpoint::Disk::open(boot, allocator).map_err(|_| "k1680-open")?; let result = (|| { let mut blocks: [Block; 7] = [[0; 512]; 7]; for (i, lba) in [111, 112, 113, 114, HOMES[0], HOMES[1], HOMES[2]].iter().enumerate() { disk.read(*lba, &mut blocks[i]).map_err(|_| "k1680-read")?; } if &blocks[0][..16] != b"K1680DISPOSABLE!" { return Err("k1680-control"); } let homes = [blocks[4], blocks[5], blocks[6]]; let mounted = job.mount(&blocks[1], &blocks[2], &blocks[3], &homes).map_err(|_| "k1680-mount")?; if job.recycle(&mut disk) != Err(Error::Order) { return Err("k1680-early-recycle"); } write_line("TURKOS/OS/K1680-CHECKPOINT: EARLY-RECYCLE=REJECTED"); if mounted == Mount::Clean { write_line("TURKOS/OS/K1680-CHECKPOINT: MOUNT=CLEAN NO-WRITES"); return Ok(()); } let homes_already_applied = &homes == job.homes(); job.apply(&mut disk).map_err(|_| "k1680-apply")?; if job.recycle(&mut disk) != Err(Error::Order) { return Err("k1680-uncheckpointed-recycle"); } write_line("TURKOS/OS/K1680-CHECKPOINT: HOMES=3 FLUSHED COMMIT=RETAINED"); if homes_already_applied { job.persist(&mut disk).map_err(|_| "k1680-checkpoint")?; write_line("TURKOS/OS/K1680-CHECKPOINT: CHECKPOINT=FLUSHED"); job.recycle(&mut disk).map_err(|_| "k1680-recycle")?; write_line("TURKOS/OS/K1680-CHECKPOINT: JOURNAL=RECYCLED"); } else { write_line("TURKOS/OS/K1680-CHECKPOINT: RESTART-BOUNDARY=BEFORE-CHECKPOINT"); } Ok(()) })(); let closed = disk.close(allocator).map_err(|_| "k1680-reset"); result?; closed?; if allocator.remaining_pages() != before { return Err("k1680-frames"); } write_line("TURKOS/OS/K1680-CHECKPOINT: FRAMES=UNCHANGED"); Ok(()) }