use super::{RaidController, RaidError}; use std::fs::{File, OpenOptions}; use std::io::{Read, Seek, SeekFrom, Write}; use std::path::PathBuf; pub struct RaidExporter { controller: RaidController, } impl RaidExporter { pub fn new(controller: RaidController) -> Self { RaidExporter { controller } } pub fn export_to_vdisk( &self, array_id: &str, output_path: &PathBuf, block_size: u64, ) -> Result { let array = self .controller .get_array(array_id) .ok_or("RAID array not found")?; let total_size = array.total_size; if total_size == 0 { return Err("RAID array has zero size".into()); } let mut output_file = OpenOptions::new() .write(true) .create(true) .truncate(true) .open(output_path)?; output_file.set_len(total_size)?; let mut exported_bytes = 0u64; let mut current_offset = 0u64; while current_offset < total_size { let chunk_size = std::cmp::min(block_size, total_size - current_offset); let data = match self.controller.read(array_id, current_offset, chunk_size) { Ok(d) => d, Err(_) => { let zeros = vec![0u8; chunk_size as usize]; zeros } }; output_file.seek(SeekFrom::Start(current_offset))?; output_file.write_all(&data)?; exported_bytes += chunk_size; current_offset += chunk_size; } output_file.sync_all()?; Ok(exported_bytes) } pub fn import_from_vdisk( &self, array_id: &str, input_path: &PathBuf, block_size: u64, ) -> Result { let array = self .controller .get_array(array_id) .ok_or("RAID array not found")?; let total_size = array.total_size; let mut input_file = File::open(input_path)?; let mut imported_bytes = 0u64; let mut current_offset = 0u64; while current_offset < total_size { let chunk_size = std::cmp::min(block_size, total_size - current_offset); input_file.seek(SeekFrom::Start(current_offset))?; let mut buffer = vec![0u8; chunk_size as usize]; input_file.read_exact(&mut buffer)?; self.controller.write(array_id, current_offset, &buffer)?; imported_bytes += chunk_size; current_offset += chunk_size; } Ok(imported_bytes) } } #[cfg(test)] mod tests { use super::*; use std::path::PathBuf; #[test] fn test_exporter_creation() { let controller = RaidController::new(); let exporter = RaidExporter::new(controller); assert!(true); } }