mod deserialization;
pub(super) mod preserialization;
mod serialization;
mod serialized;
use crate::filesystem::SerializableFileSystem;
use crate::passthrough::{MigrationMode, PassthroughFs};
use preserialization::proc_paths::{self, ConfirmPaths, ImplicitPathCheck};
use preserialization::{file_handles, find_paths};
use std::convert::{TryFrom, TryInto};
use std::fs::File;
use std::io::{self, Read, Write};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
impl SerializableFileSystem for PassthroughFs {
fn prepare_serialization(&self, cancel: Arc<AtomicBool>) {
self.inodes.clear_migration_info();
self.track_migration_info.store(true, Ordering::Relaxed);
match self.cfg.migration_mode {
MigrationMode::FindPaths => {
if proc_paths::Constructor::new(self, Arc::clone(&cancel)).execute() {
warn!("Falling back to iterating through the shared directory to reconstruct paths for migration");
find_paths::Constructor::new(self, Arc::clone(&cancel)).execute();
}
}
MigrationMode::FileHandles => {
file_handles::Constructor::new(self, Arc::clone(&cancel)).execute();
}
}
let checker = ImplicitPathCheck::new(self, cancel);
checker.check_paths();
}
fn serialize(&self, mut state_pipe: File) -> io::Result<()> {
self.track_migration_info.store(false, Ordering::Relaxed);
if self.cfg.migration_confirm_paths {
let checker = ConfirmPaths::new(self);
if let Err(err) = checker.confirm_paths() {
self.inodes.clear_migration_info();
return Err(err);
}
}
let state = serialized::PassthroughFs::V2(self.into());
self.inodes.clear_migration_info();
let serialized: Vec<u8> = state.try_into()?;
state_pipe.write_all(&serialized)?;
Ok(())
}
fn deserialize_and_apply(&self, mut state_pipe: File) -> io::Result<()> {
let mut serialized: Vec<u8> = Vec::new();
state_pipe.read_to_end(&mut serialized)?;
match serialized::PassthroughFs::try_from(serialized)? {
serialized::PassthroughFs::V1(state) => state.apply(self)?,
serialized::PassthroughFs::V2(state) => state.apply(self)?,
};
Ok(())
}
}