//! Explicit degraded read-only GPT backup selection from physical media. use super::*; use os_partitions_gpt::{Error as PartitionError, RecoveryState, RecoveryStatus, StreamError}; pub fn run(boot: &BootData, allocator: &mut memory::FrameAllocator) -> Result<(), &'static str> { let before = allocator.remaining_pages(); let mut primary = [0u8; 512]; let mut backup = [0u8; 512]; let mut disk = virtio_ro_turkfs::RoDisk::open( boot, allocator, "TURKOS/OS/K1540-GET")?; if disk.capacity() != 2048 { return Err("k1540-disk-capacity"); } disk.read(1, &mut primary)?; disk.read(2047, &mut backup)?; disk.close(allocator)?; if allocator.remaining_pages() != before { return Err("k1540-header-DMA-leak"); } let mut mounts = RecoveryState::new(); let mut active: Option = None; let mut batch = 0usize; let mut reads = 0usize; let result = mounts.mount_stream(&primary, &backup, 2048, |lba, destination| { if batch == 4 { active.take().ok_or("k1540-reader-missing")?.close(allocator)?; batch = 0; } if active.is_none() { active = Some(virtio_ro_turkfs::RoDisk::open( boot, allocator, "TURKOS/OS/K1540-GET")?); } active.as_mut().ok_or("k1540-reader-open")?.read(lba, destination)?; batch += 1; reads += 1; Ok::<(), &'static str>(()) }); if let Some(disk) = active.take() { disk.close(allocator)?; } let degraded = result.map_err(|_| "k1540-backup-validation")?; if reads != 32 || degraded.table.count != 2 || degraded.table.entries[0].map(|p| (p.first_lba, p.last_lba)) != Some((34, 100)) || degraded.table.entries[1].map(|p| (p.first_lba, p.last_lba)) != Some((101, 2014)) || degraded.status != (RecoveryStatus::DegradedBackup { primary_error: PartitionError::BadHeaderCrc }) || allocator.remaining_pages() != before { return Err("k1540-degraded-mount-state"); } let healthy = mounts; let mut mismatch = primary; mismatch[16..20].fill(0); let crc = os_partitions_gpt::crc32(&mismatch[..92]); mismatch[16..20].copy_from_slice(&crc.to_le_bytes()); let mut forbidden_reads = 0usize; let refusal = mounts.mount_stream(&mismatch, &backup, 2048, |_lba, _sector| { forbidden_reads += 1; Ok::<(), ()>(()) }); if refusal != Err(StreamError::Parse(PartitionError::InconsistentCopies)) || forbidden_reads != 0 || mounts != healthy { return Err("k1540-mismatched-pair-mounted"); } let mut empty = RecoveryState::new(); let refusal = empty.mount_stream(&mismatch, &backup, 2048, |_lba, _sector| { forbidden_reads += 1; Ok::<(), ()>(()) }); if refusal != Err(StreamError::Parse(PartitionError::InconsistentCopies)) || forbidden_reads != 0 || empty.result.is_some() || empty.generation != 0 { return Err("k1540-mismatched-fresh-mount"); } write_line("TURKOS/OS/K1540-RECOVERY: PHYSICAL=READ BACKUP=32 STATUS=DEGRADED PRIMARY=BAD-CRC MISMATCH=REJECTED MOUNT=UNCHANGED FRAMES=RETURNED"); Ok(()) }