From 1a2ea29d24aea9f62f6043d8cdd4b526b41446c5 Mon Sep 17 00:00:00 2001 From: Dennis Schwerdel Date: Wed, 15 Mar 2017 21:53:05 +0100 Subject: [PATCH] Backups --- Comparison.txt | 259 +++++++++++++++++++++++++++++++++++++ src/index.rs | 5 + src/main.rs | 102 +++++++++++---- src/repository/backup.rs | 79 +++++++++++ src/repository/info.rs | 10 +- src/repository/metadata.rs | 39 ++++-- src/repository/mod.rs | 3 + src/util/hash.rs | 4 +- src/util/lru_cache.rs | 4 +- test.sh | 60 +++++++++ 10 files changed, 524 insertions(+), 41 deletions(-) create mode 100644 Comparison.txt create mode 100644 src/repository/backup.rs create mode 100755 test.sh diff --git a/Comparison.txt b/Comparison.txt new file mode 100644 index 0000000..4a70f38 --- /dev/null +++ b/Comparison.txt @@ -0,0 +1,259 @@ +++ mkdir repos +++ target/release/zvault init --compression brotli/3 repos/zvault_brotli3 + +real 0m0.009s +user 0m0.008s +sys 0m0.000s +++ target/release/zvault init --compression brotli/6 repos/zvault_brotli6 + +real 0m0.010s +user 0m0.004s +sys 0m0.004s +++ target/release/zvault init --compression lzma2/2 repos/zvault_lzma2 + +real 0m0.009s +user 0m0.004s +sys 0m0.004s +++ attic init repos/attic +Initializing repository at "repos/attic" +Encryption NOT enabled. +Use the "--encryption=passphrase|keyfile" to enable encryption. +Initializing cache... + +real 0m0.136s +user 0m0.100s +sys 0m0.016s +++ borg init -e none repos/borg + +real 0m0.253s +user 0m0.204s +sys 0m0.012s +++ borg init -e none repos/borg-zlib + +real 0m0.243s +user 0m0.200s +sys 0m0.008s +++ zbackup init --non-encrypted repos/zbackup + +real 0m0.003s +user 0m0.000s +sys 0m0.000s +++ cat +++ target/release/zvault put repos/zvault_brotli3::silesia1 test_data/silesia.tar + +real 0m3.389s +user 0m3.172s +sys 0m0.220s +++ target/release/zvault put repos/zvault_brotli3::silesia2 test_data/silesia.tar + +real 0m0.741s +user 0m0.708s +sys 0m0.032s +++ target/release/zvault put repos/zvault_brotli6::silesia1 test_data/silesia.tar + +real 0m10.166s +user 0m9.880s +sys 0m0.284s +++ target/release/zvault put repos/zvault_brotli6::silesia2 test_data/silesia.tar + +real 0m0.707s +user 0m0.660s +sys 0m0.044s +++ target/release/zvault put repos/zvault_lzma2::silesia1 test_data/silesia.tar + +real 0m26.277s +user 0m25.988s +sys 0m0.288s +++ target/release/zvault put repos/zvault_lzma2::silesia2 test_data/silesia.tar + +real 0m0.710s +user 0m0.656s +sys 0m0.052s +++ attic create repos/attic::silesia1 test_data/silesia.tar + +real 0m9.304s +user 0m8.440s +sys 0m0.328s +++ attic create repos/attic::silesia2 test_data/silesia.tar + +real 0m1.210s +user 0m1.128s +sys 0m0.040s +++ borg create -C none repos/borg::silesia1 test_data/silesia.tar + +real 0m4.805s +user 0m2.240s +sys 0m1.156s +++ borg create -C none repos/borg::silesia2 test_data/silesia.tar + +real 0m1.475s +user 0m1.260s +sys 0m0.164s +++ borg create -C zlib repos/borg-zlib::silesia1 test_data/silesia.tar + +real 0m10.093s +user 0m9.184s +sys 0m0.428s +++ borg create -C zlib repos/borg-zlib::silesia2 test_data/silesia.tar + +real 0m1.534s +user 0m1.280s +sys 0m0.192s +++ zbackup backup --non-encrypted repos/zbackup/backups/silesia1 +Loading index... +Index loaded. +Using up to 4 thread(s) for compression + +real 0m24.362s +user 1m32.292s +sys 0m0.776s +++ zbackup backup --non-encrypted repos/zbackup/backups/silesia2 +Loading index... +Loading index file 90cd1b771e3c068c6617b0089f4fe5fde4f654cb0473b7d7... +Index loaded. +Using up to 4 thread(s) for compression + +real 0m1.281s +user 0m1.248s +sys 0m0.032s +++ du -h test_data/silesia.tar +203M test_data/silesia.tar +++ du -sh repos/zbackup/bundles repos/zvault_brotli3/bundles repos/zvault_brotli6/bundles repos/zvault_lzma2/bundles repos/attic repos/borg repos/borg-zlib repos/zbackup +51M repos/zbackup/bundles +65M repos/zvault_brotli3/bundles +58M repos/zvault_brotli6/bundles +55M repos/zvault_lzma2/bundles +68M repos/attic +203M repos/borg +66M repos/borg-zlib +164K repos/zbackup +++ rm -rf repos +++ mkdir repos +++ target/release/zvault init --compression brotli/3 repos/zvault_brotli3 + +real 0m0.005s +user 0m0.000s +sys 0m0.004s +++ target/release/zvault init --compression brotli/6 repos/zvault_brotli6 + +real 0m0.005s +user 0m0.004s +sys 0m0.000s +++ target/release/zvault init --compression lzma2/2 repos/zvault_lzma2 + +real 0m0.005s +user 0m0.004s +sys 0m0.000s +++ attic init repos/attic +Initializing repository at "repos/attic" +Encryption NOT enabled. +Use the "--encryption=passphrase|keyfile" to enable encryption. +Initializing cache... + +real 0m0.095s +user 0m0.060s +sys 0m0.020s +++ borg init -e none repos/borg + +real 0m0.235s +user 0m0.184s +sys 0m0.016s +++ borg init -e none repos/borg-zlib + +real 0m0.262s +user 0m0.200s +sys 0m0.016s +++ zbackup init --non-encrypted repos/zbackup + +real 0m0.004s +user 0m0.000s +sys 0m0.000s +++ cat +++ target/release/zvault put repos/zvault_brotli3::ubuntu1 test_data/ubuntu.tar + +real 0m3.008s +user 0m2.748s +sys 0m0.260s +++ target/release/zvault put repos/zvault_brotli3::ubuntu2 test_data/ubuntu.tar + +real 0m0.621s +user 0m0.580s +sys 0m0.040s +++ target/release/zvault put repos/zvault_brotli6::ubuntu1 test_data/ubuntu.tar + +real 0m10.916s +user 0m10.680s +sys 0m0.232s +++ target/release/zvault put repos/zvault_brotli6::ubuntu2 test_data/ubuntu.tar + +real 0m0.619s +user 0m0.596s +sys 0m0.020s +++ target/release/zvault put repos/zvault_lzma2::ubuntu1 test_data/ubuntu.tar + +real 0m37.039s +user 0m36.792s +sys 0m0.244s +++ target/release/zvault put repos/zvault_lzma2::ubuntu2 test_data/ubuntu.tar + +real 0m0.640s +user 0m0.624s +sys 0m0.012s +++ attic create repos/attic::ubuntu1 test_data/ubuntu.tar + +real 0m9.309s +user 0m8.316s +sys 0m0.368s +++ attic create repos/attic::ubuntu2 test_data/ubuntu.tar + +real 0m1.093s +user 0m1.008s +sys 0m0.044s +++ borg create -C none repos/borg::ubuntu1 test_data/ubuntu.tar + +real 0m4.317s +user 0m1.988s +sys 0m1.032s +++ borg create -C none repos/borg::ubuntu2 test_data/ubuntu.tar + +real 0m1.402s +user 0m1.160s +sys 0m0.188s +++ borg create -C zlib repos/borg-zlib::ubuntu1 test_data/ubuntu.tar + +real 0m10.049s +user 0m8.788s +sys 0m0.532s +++ borg create -C zlib repos/borg-zlib::ubuntu2 test_data/ubuntu.tar + +real 0m1.291s +user 0m1.088s +sys 0m0.168s +++ zbackup backup --non-encrypted repos/zbackup/backups/ubuntu1 +Loading index... +Index loaded. +Using up to 4 thread(s) for compression + +real 0m17.972s +user 1m7.956s +sys 0m0.644s +++ zbackup backup --non-encrypted repos/zbackup/backups/ubuntu2 +Loading index... +Loading index file 3fea916708827f3f5cdfc18fca024ef9cf00aa92a0c8d676... +Index loaded. +Using up to 4 thread(s) for compression + +real 0m1.158s +user 0m1.132s +sys 0m0.024s +++ du -h test_data/ubuntu.tar +176M test_data/ubuntu.tar +++ du -sh repos/zbackup/bundles repos/zvault_brotli3/bundles repos/zvault_brotli6/bundles repos/zvault_lzma2/bundles repos/attic repos/borg repos/borg-zlib repos/zbackup +64M repos/zbackup/bundles +77M repos/zvault_brotli3/bundles +68M repos/zvault_brotli6/bundles +63M repos/zvault_lzma2/bundles +84M repos/attic +176M repos/borg +83M repos/borg-zlib +148K repos/zbackup diff --git a/src/index.rs b/src/index.rs index 5ae4a51..eae9e76 100644 --- a/src/index.rs +++ b/src/index.rs @@ -483,6 +483,11 @@ impl Index { self.entries } + #[inline] + pub fn size(&self) -> usize { + self.mmap.len() + } + #[inline] pub fn is_empty(&self) -> bool { self.entries == 0 diff --git a/src/main.rs b/src/main.rs index 0e12145..d176af9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,56 +11,70 @@ extern crate docopt; extern crate rustc_serialize; mod errors; -mod util; -mod bundle; -mod index; +pub mod util; +pub mod bundle; +pub mod index; mod chunker; mod repository; mod algotest; -use chunker::ChunkerType; -use repository::{Repository, Config, Mode, Inode}; -use util::{ChecksumType, Compression, HashMethod, to_file_size}; - use std::fs::File; use std::io::Read; use std::time; use docopt::Docopt; +use chunker::ChunkerType; +use repository::{Repository, Config, Mode, Inode, Backup}; +use util::{ChecksumType, Compression, HashMethod, to_file_size}; + static USAGE: &'static str = " Usage: - zvault init - zvault info - zvault bundles + zvault init [--bundle-size SIZE] [--chunker METHOD] [--chunk-size SIZE] [--compression COMPRESSION] + zvault backup [--full] + zvault restore zvault check [--full] + zvault list + zvault info + zvault stats + zvault bundles zvault algotest zvault test zvault stat - zvault put + zvault put Options: - --full Whether to verify the repository by loading all bundles - --bundle-size SIZE The target size of a full bundle in MiB [default: 25] - --chunker METHOD The chunking algorithm to use [default: fastcdc] - --chunk-size SIZE The target average chunk size in KiB [default: 8] - --compression COMPRESSION The compression to use [default: brotli/3] + --full Whether to verify the repository by loading all bundles + --bundle-size SIZE The target size of a full bundle in MiB [default: 25] + --chunker METHOD The chunking algorithm to use [default: fastcdc] + --chunk-size SIZE The target average chunk size in KiB [default: 8] + --compression COMPRESSION The compression to use [default: brotli/3] "; #[derive(RustcDecodable, Debug)] struct Args { cmd_init: bool, + cmd_backup: bool, + cmd_restore: bool, + cmd_check: bool, + + cmd_list: bool, cmd_info: bool, + + cmd_stats: bool, + cmd_bundles: bool, + cmd_algotest: bool, cmd_test: bool, cmd_stat: bool, - cmd_check: bool, - cmd_bundles: bool, cmd_put: bool, + arg_repo: Option, arg_path: Option, + arg_backup: Option, + flag_full: bool, flag_bundle_size: usize, flag_chunker: String, @@ -100,14 +114,23 @@ fn main() { return } - let mut repo = Repository::open(&args.arg_repo.unwrap()).unwrap(); + + let mut repo; + if let Some(path) = args.arg_repo { + repo = Repository::open(path).unwrap(); + } else if let Some(ref backup) = args.arg_backup { + let path = backup.splitn(2, "::").nth(0).unwrap(); + repo = Repository::open(path).unwrap(); + } else { + panic!("Repository is needed"); + } if args.cmd_check { repo.check(args.flag_full).unwrap(); return } - if args.cmd_info { + if args.cmd_stats { let info = repo.info(); println!("Bundles: {}", info.bundle_count); println!("Total size: {}", to_file_size(info.encoded_data_size)); @@ -115,6 +138,15 @@ fn main() { println!("Compression ratio: {:.1}", info.compression_ratio * 100.0); println!("Chunk count: {}", info.chunk_count); println!("Average chunk size: {}", to_file_size(info.avg_chunk_size as u64)); + let index_usage = info.index_entries as f32 / info.index_capacity as f32; + println!("Index: {}, {}% full", to_file_size(info.index_size as u64), index_usage * 100.0); + return + } + + if args.cmd_list { + for backup in repo.list_backups().unwrap() { + println!("{}", backup); + } return } @@ -136,12 +168,6 @@ fn main() { return } - if args.cmd_put { - let chunks = repo.put_inode(&args.arg_path.unwrap()).unwrap(); - println!("done. {} chunks, total size: {}", chunks.len(), to_file_size(chunks.iter().map(|&(_,s)| s).sum::() as u64)); - return - } - if args.cmd_test { print!("Integrity check before..."); repo.check(true).unwrap(); @@ -175,5 +201,29 @@ fn main() { let read_speed = data.len() as f64 / duration; assert_eq!(data.len(), data2.len()); println!(" done. {:.1} MB/s", read_speed / 1_000_000.0); + return + } + + let backup_name = args.arg_backup.unwrap().splitn(2, "::").nth(1).unwrap().to_string(); + + if args.cmd_put { + let chunks = repo.put_inode(&args.arg_path.unwrap()).unwrap(); + repo.save_backup(&Backup{root: chunks, ..Default::default()}, &backup_name).unwrap(); + return + } + + if args.cmd_backup { + unimplemented!() + } + + let backup = repo.get_backup(&backup_name).unwrap(); + + if args.cmd_info { + println!("{:?}", backup.root); + return + } + + if args.cmd_restore { + repo.restore_backup(&backup, &args.arg_path.unwrap()).unwrap(); } } diff --git a/src/repository/backup.rs b/src/repository/backup.rs new file mode 100644 index 0000000..379d680 --- /dev/null +++ b/src/repository/backup.rs @@ -0,0 +1,79 @@ +use super::{Repository, Chunk}; + +use rmp_serde; +use serde::{Deserialize, Serialize}; + +use std::fs::{self, File}; +use std::path::Path; + + +#[derive(Default, Debug)] +pub struct Backup { + pub root: Vec, + pub total_data_size: u64, + pub changed_data_size: u64, + pub new_data_size: u64, + pub encoded_data_size: u64, + pub new_bundle_count: usize, + pub chunk_count: usize, + pub avg_chunk_size: f32, + pub date: i64, + pub duration: f32, + pub file_count: usize, + pub dir_count: usize +} +serde_impl!(Backup(u8) { + root: Vec => 0, + total_data_size: u64 => 1, + changed_data_size: u64 => 2, + new_data_size: u64 => 3, + encoded_data_size: u64 => 4, + new_bundle_count: usize => 5, + chunk_count: usize => 6, + avg_chunk_size: f32 => 7, + date: i64 => 8, + duration: f32 => 9, + file_count: usize => 10, + dir_count: usize => 11 +}); + + +impl Repository { + pub fn list_backups(&self) -> Result, &'static str> { + let mut backups = Vec::new(); + let mut paths = Vec::new(); + let base_path = self.path.join("backups"); + paths.push(base_path.clone()); + while let Some(path) = paths.pop() { + for entry in try!(fs::read_dir(path).map_err(|_| "Failed to list files")) { + let entry = try!(entry.map_err(|_| "Failed to list files")); + let path = entry.path(); + if path.is_dir() { + paths.push(path); + } else { + let relpath = try!(path.strip_prefix(&base_path).map_err(|_| "Failed to obtain relative path")); + backups.push(relpath.to_string_lossy().to_string()); + } + } + } + Ok(backups) + } + + pub fn get_backup(&self, name: &str) -> Result { + let file = try!(File::open(self.path.join("backups").join(name)).map_err(|_| "Failed to load backup")); + let mut reader = rmp_serde::Deserializer::new(file); + Backup::deserialize(&mut reader).map_err(|_| "Failed to read backup data") + } + + pub fn save_backup(&mut self, backup: &Backup, name: &str) -> Result<(), &'static str> { + let mut file = try!(File::create(self.path.join("backups").join(name)).map_err(|_| "Failed to save backup")); + let mut writer = rmp_serde::Serializer::new(&mut file); + backup.serialize(&mut writer).map_err(|_| "Failed to write backup data") + } + + pub fn restore_backup>(&mut self, backup: &Backup, path: P) -> Result<(), &'static str> { + let inode = try!(self.get_inode(&backup.root)); + try!(self.save_inode_at(&inode, path)); + Ok(()) + } +} diff --git a/src/repository/info.rs b/src/repository/info.rs index 423ed7d..fd961a2 100644 --- a/src/repository/info.rs +++ b/src/repository/info.rs @@ -7,7 +7,10 @@ pub struct RepositoryInfo { pub raw_data_size: u64, pub compression_ratio: f32, pub chunk_count: usize, - pub avg_chunk_size: f32 + pub avg_chunk_size: f32, + pub index_size: usize, + pub index_capacity: usize, + pub index_entries: usize } @@ -28,7 +31,10 @@ impl Repository { encoded_data_size: encoded_data_size, raw_data_size: raw_data_size, compression_ratio: encoded_data_size as f32 / raw_data_size as f32, - avg_chunk_size: raw_data_size as f32 / chunk_count as f32 + avg_chunk_size: raw_data_size as f32 / chunk_count as f32, + index_size: self.index.size(), + index_capacity: self.index.capacity(), + index_entries: self.index.len() } } } diff --git a/src/repository/metadata.rs b/src/repository/metadata.rs index d7fe254..118b7ff 100644 --- a/src/repository/metadata.rs +++ b/src/repository/metadata.rs @@ -4,11 +4,11 @@ use rmp_serde; use std::collections::HashMap; use std::path::Path; -use std::fs::{self, Metadata, File}; +use std::fs::{self, Metadata, File, Permissions}; use std::os::linux::fs::MetadataExt; -use std::io::{Cursor, Read}; +use std::os::unix::fs::{PermissionsExt, symlink}; +use std::io::{Cursor, Read, Write}; -use ::util::Hash; use super::{Repository, Mode, Chunk}; @@ -118,25 +118,29 @@ impl Inode { } #[allow(dead_code)] - pub fn create_at>(&self, path: P) -> Result<(), &'static str> { + pub fn create_at>(&self, path: P) -> Result, &'static str> { let full_path = path.as_ref().join(&self.name); + let mut file = None; match self.file_type { FileType::File => { - try!(File::create(&full_path).map_err(|_| "Failed to create file")); + file = Some(try!(File::create(&full_path).map_err(|_| "Failed to create file"))); }, FileType::Directory => { try!(fs::create_dir(&full_path).map_err(|_| "Failed to create directory")); }, FileType::Symlink => { if let Some(ref src) = self.symlink_target { - try!(fs::soft_link(src, &full_path).map_err(|_| "Failed to create symlink")); + + try!(symlink(src, &full_path).map_err(|_| "Failed to create symlink")); } else { return Err("Symlink without destination") } } } - //FIXME: set times and permissions - Ok(()) + try!(fs::set_permissions(&full_path, Permissions::from_mode(self.mode)).map_err(|_| "Failed to set permissions")); + //FIXME: set times and gid/uid + // https://crates.io/crates/filetime + Ok(file) } } @@ -158,7 +162,7 @@ impl Repository { let mut inode_data = Vec::new(); { let mut writer = rmp_serde::Serializer::new(&mut inode_data); - inode.serialize(&mut writer).map_err(|_| "Failed to write inode data"); + try!(inode.serialize(&mut writer).map_err(|_| "Failed to write inode data")); } self.put_data(Mode::Meta, &inode_data) } @@ -169,4 +173,21 @@ impl Repository { let mut reader = rmp_serde::Deserializer::new(data); Inode::deserialize(&mut reader).map_err(|_| "Failed to read inode data") } + + #[inline] + pub fn save_inode_at>(&mut self, inode: &Inode, path: P) -> Result<(), &'static str> { + if let Some(mut file) = try!(inode.create_at(path.as_ref())) { + if let Some(ref contents) = inode.contents { + match *contents { + FileContents::Inline(ref data) => { + try!(file.write_all(&data).map_err(|_| "Failed to write data to file")); + }, + FileContents::Chunked(ref chunks) => { + try!(self.get_stream(chunks, &mut file)); + } + } + } + } + Ok(()) + } } diff --git a/src/repository/mod.rs b/src/repository/mod.rs index 58b6592..7fe4151 100644 --- a/src/repository/mod.rs +++ b/src/repository/mod.rs @@ -4,6 +4,7 @@ mod integrity; mod basic_io; mod info; mod metadata; +mod backup; use std::mem; use std::cmp::max; @@ -17,6 +18,7 @@ use super::chunker::Chunker; pub use self::config::Config; pub use self::metadata::Inode; pub use self::basic_io::Chunk; +pub use self::backup::Backup; use self::bundle_map::BundleMap; @@ -53,6 +55,7 @@ impl Repository { try!(config.save(path.join("config.yaml")).map_err(|_| "Failed to save config")); let bundle_map = BundleMap::create(); try!(bundle_map.save(path.join("bundles.map")).map_err(|_| "Failed to save bundle map")); + try!(fs::create_dir(&path.join("backups")).map_err(|_| "Failed to create backup directory")); Ok(Repository{ path: path, chunker: config.chunker.create(), diff --git a/src/util/hash.rs b/src/util/hash.rs index 7fa8789..cc9a193 100644 --- a/src/util/hash.rs +++ b/src/util/hash.rs @@ -33,14 +33,14 @@ impl Hash { impl fmt::Display for Hash { #[inline] fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(fmt, "{:16x}{:16x}", self.high, self.low) + write!(fmt, "{:016x}{:016x}", self.high, self.low) } } impl fmt::Debug for Hash { #[inline] fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(fmt, "{:16x}{:16x}", self.high, self.low) + write!(fmt, "{:016x}{:016x}", self.high, self.low) } } diff --git a/src/util/lru_cache.rs b/src/util/lru_cache.rs index cd95402..b387f4f 100644 --- a/src/util/lru_cache.rs +++ b/src/util/lru_cache.rs @@ -45,9 +45,9 @@ impl LruCache { fn shrink(&mut self) { let mut tags: Vec = self.items.values().map(|&(_, n)| n).collect(); tags.sort(); - let bar = tags[tags.len()-self.min_size]; + let min = tags[tags.len()-self.min_size]; let mut new = HashMap::with_capacity(self.min_size); - new.extend(self.items.drain().filter(|&(_,(_, n))| n>=bar)); + new.extend(self.items.drain().filter(|&(_,(_, n))| n>=min)); self.items = new; } } diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..924fe43 --- /dev/null +++ b/test.sh @@ -0,0 +1,60 @@ +set -ex + +mkdir repos +time target/release/zvault init --compression brotli/3 repos/zvault_brotli3 +time target/release/zvault init --compression brotli/6 repos/zvault_brotli6 +time target/release/zvault init --compression lzma2/2 repos/zvault_lzma2 +time attic init repos/attic +time borg init -e none repos/borg +time borg init -e none repos/borg-zlib +time zbackup init --non-encrypted repos/zbackup + +cat < test_data/silesia.tar > /dev/null +time target/release/zvault put repos/zvault_brotli3::silesia1 test_data/silesia.tar +time target/release/zvault put repos/zvault_brotli3::silesia2 test_data/silesia.tar +time target/release/zvault put repos/zvault_brotli6::silesia1 test_data/silesia.tar +time target/release/zvault put repos/zvault_brotli6::silesia2 test_data/silesia.tar +time target/release/zvault put repos/zvault_lzma2::silesia1 test_data/silesia.tar +time target/release/zvault put repos/zvault_lzma2::silesia2 test_data/silesia.tar +time attic create repos/attic::silesia1 test_data/silesia.tar +time attic create repos/attic::silesia2 test_data/silesia.tar +time borg create -C none repos/borg::silesia1 test_data/silesia.tar +time borg create -C none repos/borg::silesia2 test_data/silesia.tar +time borg create -C zlib repos/borg-zlib::silesia1 test_data/silesia.tar +time borg create -C zlib repos/borg-zlib::silesia2 test_data/silesia.tar +time zbackup backup --non-encrypted repos/zbackup/backups/silesia1 < test_data/silesia.tar +time zbackup backup --non-encrypted repos/zbackup/backups/silesia2 < test_data/silesia.tar + +du -h test_data/silesia.tar +du -sh repos/zvault*/bundles repos/attic repos/borg repos/borg-zlib repos/zbackup + +rm -rf repos + + +mkdir repos +time target/release/zvault init --compression brotli/3 repos/zvault_brotli3 +time target/release/zvault init --compression brotli/6 repos/zvault_brotli6 +time target/release/zvault init --compression lzma2/2 repos/zvault_lzma2 +time attic init repos/attic +time borg init -e none repos/borg +time borg init -e none repos/borg-zlib +time zbackup init --non-encrypted repos/zbackup + +cat < test_data/ubuntu.tar > /dev/null +time target/release/zvault put repos/zvault_brotli3::ubuntu1 test_data/ubuntu.tar +time target/release/zvault put repos/zvault_brotli3::ubuntu2 test_data/ubuntu.tar +time target/release/zvault put repos/zvault_brotli6::ubuntu1 test_data/ubuntu.tar +time target/release/zvault put repos/zvault_brotli6::ubuntu2 test_data/ubuntu.tar +time target/release/zvault put repos/zvault_lzma2::ubuntu1 test_data/ubuntu.tar +time target/release/zvault put repos/zvault_lzma2::ubuntu2 test_data/ubuntu.tar +time attic create repos/attic::ubuntu1 test_data/ubuntu.tar +time attic create repos/attic::ubuntu2 test_data/ubuntu.tar +time borg create -C none repos/borg::ubuntu1 test_data/ubuntu.tar +time borg create -C none repos/borg::ubuntu2 test_data/ubuntu.tar +time borg create -C zlib repos/borg-zlib::ubuntu1 test_data/ubuntu.tar +time borg create -C zlib repos/borg-zlib::ubuntu2 test_data/ubuntu.tar +time zbackup backup --non-encrypted repos/zbackup/backups/ubuntu1 < test_data/ubuntu.tar +time zbackup backup --non-encrypted repos/zbackup/backups/ubuntu2 < test_data/ubuntu.tar + +du -h test_data/ubuntu.tar +du -sh repos/zvault*/bundles repos/attic repos/borg repos/borg-zlib repos/zbackup