From ba10f2b0d4fd8320f2e2ad7b363303161f5ffb57 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Sat, 16 Mar 2019 14:22:14 +0100 Subject: [PATCH] src/bin/dynamic-files.rs: test case for file shrink during backup --- src/bin/dynamic-files.rs | 62 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/bin/dynamic-files.rs diff --git a/src/bin/dynamic-files.rs b/src/bin/dynamic-files.rs new file mode 100644 index 00000000..1db16e8f --- /dev/null +++ b/src/bin/dynamic-files.rs @@ -0,0 +1,62 @@ +use failure::*; + +use std::thread; +use std::path::PathBuf; +use std::io::Write; + +// tar handle files that shrink during backup, by simply padding with zeros. +// +// this binary run multiple thread which writes some large files, then truncates +// them in a loop. + +// # tar cf test.tar ./dyntest1/ +// tar: dyntest1/testfile0.dat: File shrank by 2768972800 bytes; padding with zeros +// tar: dyntest1/testfile17.dat: File shrank by 2899853312 bytes; padding with zeros +// tar: dyntest1/testfile2.dat: File shrank by 3093422080 bytes; padding with zeros +// tar: dyntest1/testfile7.dat: File shrank by 2833252864 bytes; padding with zeros + +// # pxar create test.pxar ./dyntest1/ +// Error: detected shrinked file "./dyntest1/testfile0.dat" (22020096 < 12679380992) + +fn create_large_file(path: PathBuf) { + + println!("TEST {:?}", path); + + let mut file = std::fs::OpenOptions::new() + .write(true) + .create_new(true) + .open(&path).unwrap(); + + let buffer = vec![0u8; 64*1024]; + + loop { + for _ in 0..64 { + file.write_all(&buffer).unwrap(); + } + file.sync_all().unwrap(); + //println!("TRUNCATE {:?}", path); + file.set_len(0).unwrap(); + } +} + +fn main() -> Result<(), Error> { + + let base = PathBuf::from("dyntest1"); + let _ = std::fs::create_dir(&base); + + let mut handles = vec![]; + for i in 0..20 { + let base = base.clone(); + handles.push(thread::spawn(move || { + create_large_file(base.join(format!("testfile{}.dat", i))); + })); + } + + for h in handles { + if let Err(_) = h.join() { + bail!("join failed"); + } + } + + Ok(()) +}