diff --git a/src/hyperv/layer.rs b/src/hyperv/layer.rs index bf1b697..e630f36 100644 --- a/src/hyperv/layer.rs +++ b/src/hyperv/layer.rs @@ -24,7 +24,7 @@ impl HypervLayer { /// For .bin files, optionally loads CPU state from a companion .vsv file (future). pub fn open(path: &Path) -> Result { let file = fs::File::open(path)?; - let mmap = crate::utils::mmap_file(&file)?; + let mmap = crate::utils::mmap_file(&file, path)?; let size = mmap.len() as u64; // Sanity check: .bin files should be at least a few MB (VM RAM) diff --git a/src/qemu/layer.rs b/src/qemu/layer.rs index 2ed3929..2d2ca07 100644 --- a/src/qemu/layer.rs +++ b/src/qemu/layer.rs @@ -47,7 +47,7 @@ impl QemuElfLayer { /// Open a QEMU ELF core dump file (.elf or any extension). pub fn open(path: &Path) -> Result { let file = fs::File::open(path)?; - let mmap = crate::utils::mmap_file(&file)?; + let mmap = crate::utils::mmap_file(&file, path)?; if mmap.len() < ELF64_EHDR_SIZE { return Err(VmkatzError::InvalidMagic(0)); diff --git a/src/qemu/savevm.rs b/src/qemu/savevm.rs index 6b95257..357a57b 100644 --- a/src/qemu/savevm.rs +++ b/src/qemu/savevm.rs @@ -74,7 +74,7 @@ impl QemuSavevmLayer { /// Supports both regular files and block devices (LVM volumes on Proxmox). pub fn open(path: &Path) -> Result { let file = fs::File::open(path)?; - let mmap = crate::utils::mmap_file(&file)?; + let mmap = crate::utils::mmap_file(&file, path)?; if mmap.len() < 16 { return Err(VmkatzError::InvalidMagic(0)); diff --git a/src/utils.rs b/src/utils.rs index 1d6200c..30928d4 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -204,7 +204,7 @@ pub fn read_file_header(file: &std::fs::File, max_bytes: usize) -> std::io::Resu /// Open a file as MappedFile: tries mmap first, falls back to pread on failure. /// Handles block devices where fstat returns size 0. #[cfg(any(feature = "vmware", feature = "qemu", feature = "hyperv"))] -pub fn mmap_file(file: &std::fs::File) -> std::io::Result { +pub fn mmap_file(file: &std::fs::File, path: &std::path::Path) -> std::io::Result { use std::io::{Seek, SeekFrom}; let mut f = file.try_clone()?; let size = f.seek(SeekFrom::End(0))?; @@ -227,7 +227,8 @@ pub fn mmap_file(file: &std::fs::File) -> std::io::Result { Ok(m) => Ok(MappedFile::Mmap(m)), Err(mmap_err) => { eprintln!( - "[!] mmap failed ({:.1} MB): {} — falling back to file I/O (slower)", + "[!] mmap failed for '{}' ({:.1} MB): {} — falling back to file I/O (slower)", + path.display(), size as f64 / (1024.0 * 1024.0), mmap_err, ); diff --git a/src/vmware/layer.rs b/src/vmware/layer.rs index 35a022f..a2337f3 100644 --- a/src/vmware/layer.rs +++ b/src/vmware/layer.rs @@ -71,7 +71,7 @@ impl VmwareLayer { }; let vmem_file = fs::File::open(&vmem_path)?; - let data = crate::utils::mmap_file(&vmem_file)?; + let data = crate::utils::mmap_file(&vmem_file, &vmem_path)?; log::info!( "VMEM loaded: {} bytes ({} MB)", data.len(), @@ -150,7 +150,7 @@ impl VmwareLayer { /// Parse a .vmsn file and return (regions, tags). fn parse_vmsn_metadata(vmsn_path: &Path) -> Result<(Vec, Vec)> { let vmsn_file = fs::File::open(vmsn_path)?; - let vmsn_mapped = crate::utils::mmap_file(&vmsn_file)?; + let vmsn_mapped = crate::utils::mmap_file(&vmsn_file, vmsn_path)?; // For mmap: use the mapping directly. For pread fallback: read the header // portion (first 8 MB covers all tag structures) for slice-based parsing.