From 6397a7f8adea987aea3930d494b6a7d9a4130f17 Mon Sep 17 00:00:00 2001 From: Dennis Schwerdel Date: Fri, 26 Oct 2018 14:05:28 +0200 Subject: [PATCH] Fixed errors & warnings --- Cargo.lock | 132 ++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/backups/backup.rs | 11 ++- src/backups/integrity.rs | 149 +++++++++++++++++++++++++++++++++- src/backups/mod.rs | 106 +++++------------------- src/backups/tarfile.rs | 2 +- src/backups/vacuum.rs | 5 +- src/cli/args.rs | 1 + src/cli/mod.rs | 62 +++++++++++--- src/main.rs | 1 + src/prelude.rs | 2 +- src/repository/bundledb/db.rs | 2 +- src/repository/integrity.rs | 46 +---------- src/repository/mod.rs | 11 ++- src/util/mod.rs | 1 - src/util/mode_test.rs | 117 -------------------------- 16 files changed, 375 insertions(+), 274 deletions(-) delete mode 100644 src/util/mode_test.rs diff --git a/Cargo.lock b/Cargo.lock index 4472a5d..a3f68d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,15 @@ dependencies = [ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "argon2rs" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "arrayvec" version = "0.4.7" @@ -40,6 +49,27 @@ dependencies = [ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "backtrace" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bindgen" version = "0.28.0" @@ -234,6 +264,16 @@ name = "crossbeam-utils" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "dirs" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dtoa" version = "0.4.3" @@ -260,6 +300,26 @@ dependencies = [ "termcolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "failure" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure_derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.14 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "filetime" version = "0.2.1" @@ -538,6 +598,14 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro2" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "quasi" version = "0.32.0" @@ -571,6 +639,14 @@ dependencies = [ "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quote" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.4.2" @@ -611,6 +687,17 @@ dependencies = [ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "redox_users" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "regex" version = "0.2.11" @@ -683,11 +770,21 @@ name = "runtime-fmt" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-demangle" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-serialize" version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "scopeguard" version = "0.3.3" @@ -764,6 +861,27 @@ name = "strsim" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "syn" +version = "0.15.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synstructure" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.14 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syntex" version = "0.58.1" @@ -1011,6 +1129,7 @@ dependencies = [ "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "fuse 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1040,9 +1159,12 @@ dependencies = [ [metadata] "checksum aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c6d463cbe7ed28720b5b489e7c083eeb8f90d08be2a0d6bb9e1ffea9ce1afa" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" +"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" +"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" "checksum bindgen 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16a8070d69d86935d11b0778dbdbc83a0a799d982e521baa62d0812b727734be" "checksum bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1b25ab82877ea8fe6ce1ce1f8ac54361f0218bad900af9eb11803994bf67c221" "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" @@ -1064,9 +1186,12 @@ dependencies = [ "checksum crossbeam-deque 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7792c4a9b5a4222f654e3728a3dd945aacc24d2c3a1a096ed265d80e4929cb9a" "checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9" "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" +"checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a" "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "f4d7e69c283751083d53d01eac767407343b8b69c4bd70058e08adc2637cb257" +"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7" +"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596" "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" @@ -1103,15 +1228,18 @@ dependencies = [ "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum pkg-config 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "104630aa1c83213cbc76db0703630fcb0421dac3585063be4ce9a8a2feeaa745" "checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4" +"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" "checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3" "checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" +"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "214a97e49be64fd2c86f568dd0cb2c757d2cc53de95b273b6ad0a1c908482f26" "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" "checksum regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbbea44c5490a1e84357ff28b7d518b4619a159fed5d25f6c1de2d19cc42814" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" @@ -1120,7 +1248,9 @@ dependencies = [ "checksum rmp 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a3d45d7afc9b132b34a2479648863aa95c5c88e98b32285326a6ebadc80ec5c9" "checksum rmp-serde 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "011e1d58446e9fa3af7cdc1fb91295b10621d3ac4cb3a85cc86385ee9ca50cd3" "checksum runtime-fmt 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "647a821d66049faccc993fc3c379d1181b81a484097495cda79ffdb17b55b87f" +"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum serde 1.0.71 (registry+https://github.com/rust-lang/crates.io-index)" = "6dfad05c8854584e5f72fb859385ecdfa03af69c3fd0572f0da2d4c95f060bdb" "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3" @@ -1131,6 +1261,8 @@ dependencies = [ "checksum squash-sys 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76f31a010ae66493a57b16f02d7df88d966d78ce7f09d54d922a082954cfc7ee" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" +"checksum syn 0.15.14 (registry+https://github.com/rust-lang/crates.io-index)" = "baaba45c6bf60fe29aaf241fa33306c0b75c801edea8378263a8f043b09a5634" +"checksum synstructure 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec37f4fab4bafaf6b5621c1d54e6aa5d4d059a8f84929e87abfdd7f9f04c6db2" "checksum syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f5e3aaa79319573d19938ea38d068056b826db9883a5d47f86c1cecc688f0e" "checksum syntex_errors 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "867cc5c2d7140ae7eaad2ae9e8bf39cb18a67ca651b7834f88d46ca98faadb9c" "checksum syntex_pos 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13ad4762fe52abc9f4008e85c4fb1b1fe3aa91ccb99ff4826a439c7c598e1047" diff --git a/Cargo.toml b/Cargo.toml index 627199d..583d931 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ libc = "~0.2" runtime-fmt = "~0.3" locale_config = "~0.2.2" mmap = "~0.1" +dirs = "^1.0" [features] default = [] diff --git a/src/backups/backup.rs b/src/backups/backup.rs index ea81472..4fb1093 100644 --- a/src/backups/backup.rs +++ b/src/backups/backup.rs @@ -59,7 +59,7 @@ pub trait RepositoryBackupIO { fn create_backup>(&mut self, path: P, name: &str, reference: Option<&BackupFile>, options: &BackupOptions, lock: &BackupMode ) -> Result; - fn remove_backup_path>(&mut self, backup: &mut BackupFile, path: P, + fn remove_backup_path>(&mut self, backup: &mut BackupFile, name: &str, path: P, lock: &BackupMode) -> Result<(), RepositoryError>; fn get_backup_path>(&mut self, backup: &BackupFile, path: P, lock: &OnlineMode ) -> Result, RepositoryError>; @@ -99,7 +99,7 @@ impl RepositoryBackupIO for Repository { Ok(try!(BackupFile::read_from(&self.get_crypto(), self.get_layout().backup_path(name)))) } - fn save_backup(&mut self, backup: &BackupFile, name: &str, lock: &BackupMode) -> Result<(), RepositoryError> { + fn save_backup(&mut self, backup: &BackupFile, name: &str, _lock: &BackupMode) -> Result<(), RepositoryError> { let path = self.get_layout().backup_path(name); try!(fs::create_dir_all(path.parent().unwrap())); try!(backup.save_to( @@ -110,7 +110,7 @@ impl RepositoryBackupIO for Repository { Ok(()) } - fn delete_backup(&mut self, name: &str, lock: &BackupMode) -> Result<(), RepositoryError> { + fn delete_backup(&mut self, name: &str, _lock: &BackupMode) -> Result<(), RepositoryError> { let mut path = self.get_layout().backup_path(name); try!(fs::remove_file(&path)); loop { @@ -381,7 +381,7 @@ impl RepositoryBackupIO for Repository { } } - fn remove_backup_path>(&mut self, backup: &mut BackupFile, path: P, + fn remove_backup_path>(&mut self, backup: &mut BackupFile, name: &str, path: P, lock: &BackupMode ) -> Result<(), RepositoryError> { let mut inodes = try!(self.get_backup_path(backup, path, lock.as_online())); @@ -405,8 +405,7 @@ impl RepositoryBackupIO for Repository { } backup.root = last_inode_chunks; backup.modified = true; - //TODO: save - Ok(()) + self.save_backup(backup, name, lock) } fn get_backup_path>(&mut self, backup: &BackupFile, path: P, lock: &OnlineMode diff --git a/src/backups/integrity.rs b/src/backups/integrity.rs index 72d5f6c..176b26a 100644 --- a/src/backups/integrity.rs +++ b/src/backups/integrity.rs @@ -29,6 +29,83 @@ quick_error!{ } +pub struct CheckOptions { + all_backups: bool, + single_backup: Option<(String, BackupFile)>, + subpath: Option<(PathBuf, Inode)>, + index: bool, + bundles: bool, + bundle_data: bool, + repair: bool +} + +impl CheckOptions { + pub fn new() -> CheckOptions { + CheckOptions { + all_backups: false, + single_backup: None, + subpath: None, + index: false, + bundles: false, + bundle_data: false, + repair: false + } + } + + pub fn all_backups(&mut self) -> &mut Self { + self.all_backups = true; + self.single_backup = None; + self.subpath = None; + self + } + + pub fn single_backup(&mut self, name: &str, backup: BackupFile) -> &mut Self { + self.all_backups = false; + self.single_backup = Some((name.to_string(), backup)); + self + } + + pub fn subpath(&mut self, subpath: &Path, inode: Inode) -> &mut Self { + self.subpath = Some((subpath.to_path_buf(), inode)); + self + } + + pub fn index(&mut self, index: bool) -> &mut Self { + self.index = index; + self + } + + pub fn bundles(&mut self, bundles: bool) -> &mut Self { + self.bundles = bundles; + self.bundle_data &= bundles; + self + } + + pub fn bundle_data(&mut self, bundle_data: bool) -> &mut Self { + self.bundle_data = bundle_data; + self.bundles |= bundle_data; + self + } + + pub fn repair(&mut self, repair: bool) -> &mut Self { + self.repair = repair; + self + } + + pub fn get_repair(&self) -> bool { + self.repair + } +} + + +pub struct IntegrityReport { + pub bundle_map: Option>, + pub index: Option>, + pub bundles: Option>, + pub backups: Option> +} + + pub trait RepositoryIntegrityIO { fn check_inode_contents(&mut self, inode: &Inode, checked: &mut Bitmap, lock: &OnlineMode ) -> Result<(), RepositoryError>; @@ -40,7 +117,7 @@ pub trait RepositoryIntegrityIO { fn check_backup_inode(&mut self, inode: &Inode, path: &Path, lock: &OnlineMode ) -> ModuleIntegrityReport; - fn check_backup(&mut self, name: &str, backup: &mut BackupFile, lock: &OnlineMode + fn check_backup(&mut self, name: &str, backup: &BackupFile, lock: &OnlineMode ) -> ModuleIntegrityReport; fn check_backups(&mut self, lock: &OnlineMode) -> ModuleIntegrityReport; @@ -60,6 +137,11 @@ pub trait RepositoryIntegrityIO { fn check_and_repair_backups(&mut self, lock: &BackupMode ) -> Result, RepositoryError>; + + fn check(&mut self, options: CheckOptions, lock: &OnlineMode) -> IntegrityReport; + + fn check_and_repair(&mut self, options: CheckOptions, lock: &VacuumMode + ) -> Result; } @@ -87,7 +169,6 @@ impl RepositoryIntegrityIO for Repository { fn check_subtree(&mut self, path: PathBuf, chunks: &[Chunk], checked: &mut Bitmap, errors: &mut Vec, lock: &OnlineMode ) { - let mut modified = false; match self.mark_chunks(checked, chunks, false) { Ok(false) => return, Ok(true) => (), @@ -133,7 +214,7 @@ impl RepositoryIntegrityIO for Repository { } #[inline] - fn check_backup(&mut self, name: &str, backup: &mut BackupFile, lock: &OnlineMode, + fn check_backup(&mut self, _name: &str, backup: &BackupFile, lock: &OnlineMode, ) -> ModuleIntegrityReport { tr_info!("Checking backup..."); let mut checked = self.get_chunk_marker(); @@ -216,7 +297,7 @@ impl RepositoryIntegrityIO for Repository { } - fn evacuate_broken_backup(&self, name: &str, lock: &BackupMode) -> Result<(), RepositoryError> { + fn evacuate_broken_backup(&self, name: &str, _lock: &BackupMode) -> Result<(), RepositoryError> { tr_warn!( "The backup {} was corrupted and needed to be modified.", name @@ -353,4 +434,64 @@ impl RepositoryIntegrityIO for Repository { } Ok(ModuleIntegrityReport{errors_unfixed: vec![], errors_fixed: errors}) } + + fn check(&mut self, options: CheckOptions, lock: &OnlineMode) -> IntegrityReport { + let mut report = IntegrityReport { + bundle_map: None, + index: None, + bundles: None, + backups: None + }; + report.bundle_map = Some(self.check_bundle_map()); + if options.index { + report.index = Some(self.check_index(lock.as_readonly())); + } + if options.bundles { + report.bundles = Some(self.check_bundles(options.bundle_data, lock)); + } + if let Some((name, backup)) = options.single_backup { + if let Some((subpath, inode)) = options.subpath { + report.backups = Some(self.check_backup_inode(&inode, &subpath, lock)) + } else { + report.backups = Some(self.check_backup(&name, &backup, lock)); + } + } + if options.all_backups { + report.backups = Some(self.check_backups(lock)); + } + report + } + + fn check_and_repair(&mut self, options: CheckOptions, lock: &VacuumMode) -> Result { + let mut report = IntegrityReport { + bundle_map: None, + index: None, + bundles: None, + backups: None + }; + let bundle_map = try!(self.check_and_repair_bundle_map(lock.as_online())); + if !bundle_map.errors_fixed.is_empty() { + try!(self.rebuild_index(lock.as_online())); + } + report.bundle_map = Some(bundle_map); + if options.index { + report.index = Some(try!(self.check_and_repair_index(lock.as_online()))); + } + if options.bundles { + report.bundles = Some(try!(self.check_and_repair_bundles(options.bundle_data, lock))); + } + if let Some((name, mut backup)) = options.single_backup { + if let Some((subpath, _inode)) = options.subpath { + report.backups = Some(try!(self.check_and_repair_backup_inode(&name, &mut backup, &subpath, lock.as_backup()))); + } else { + report.backups = Some(try!(self.check_and_repair_backup(&name, &mut backup, lock.as_backup()))); + } + } + if options.all_backups { + report.backups = Some(try!(self.check_and_repair_backups(lock.as_backup()))); + } + Ok(report) + } + + } \ No newline at end of file diff --git a/src/backups/mod.rs b/src/backups/mod.rs index 616adb6..3e42642 100644 --- a/src/backups/mod.rs +++ b/src/backups/mod.rs @@ -11,7 +11,7 @@ mod layout; pub use self::backup::{BackupOptions, BackupError, DiffType, RepositoryBackupIO}; pub use self::backup_file::{BackupFile, BackupFileError}; pub use self::inode::{Inode, FileData, FileType, InodeError}; -pub use self::integrity::{InodeIntegrityError, RepositoryIntegrityIO}; +pub use self::integrity::{InodeIntegrityError, RepositoryIntegrityIO, CheckOptions, IntegrityReport}; pub use self::layout::BackupRepositoryLayout; pub use self::metadata::RepositoryMetadataIO; pub use self::vacuum::RepositoryVacuumIO; @@ -29,71 +29,6 @@ use std::io::Write; const DEFAULT_EXCLUDES: &[u8] = include_bytes!("../../docs/excludes.default"); -pub struct CheckOptions { - all_backups: bool, - single_backup: Option, - subpath: Option, - index: bool, - bundles: bool, - bundle_data: bool, - repair: bool -} - -impl CheckOptions { - pub fn new() -> CheckOptions { - CheckOptions { - all_backups: false, - single_backup: None, - subpath: None, - index: false, - bundles: false, - bundle_data: false, - repair: false - } - } - - pub fn all_backups(&mut self) -> &mut Self { - self.all_backups = true; - self.single_backup = None; - self.subpath = None; - self - } - - pub fn single_backup(&mut self, backup: &str) -> &mut Self { - self.all_backups = false; - self.single_backup = Some(backup.to_string()); - self - } - - pub fn subpath(&mut self, subpath: &Path) -> &mut Self { - self.subpath = Some(subpath.to_path_buf()); - self - } - - pub fn index(&mut self, index: bool) -> &mut Self { - self.index = index; - self - } - - pub fn bundles(&mut self, bundles: bool) -> &mut Self { - self.bundles = bundles; - self.bundle_data &= bundles; - self - } - - pub fn bundle_data(&mut self, bundle_data: bool) -> &mut Self { - self.bundle_data = bundle_data; - self.bundles |= bundle_data; - self - } - - pub fn repair(&mut self, repair: bool) -> &mut Self { - self.repair = repair; - self - } -} - - pub struct BackupRepository(Repository); impl BackupRepository { @@ -184,16 +119,6 @@ impl BackupRepository { self.0.info() } - #[inline] - pub fn check_repo(&mut self, index: bool, bundles: bool, bundle_data: bool) -> Result { - self.0.online_mode(|r, l| Ok(r.check(index, bundles, bundle_data, l))) - } - - #[inline] - pub fn check_and_repair_repo(&mut self, index: bool, bundles: bool, bundle_data: bool) -> Result { - self.0.vacuum_mode(|r, l| r.check_and_repair(index, bundles, bundle_data, l)) - } - #[inline] pub fn statistics(&self) -> RepositoryStatistics { self.0.statistics() @@ -224,6 +149,11 @@ impl BackupRepository { self.0.backup_mode(|r, l| r.delete_backup(name, l)) } + #[inline] + pub fn save_backup(&mut self, backup: &BackupFile, name: &str) -> Result<(), RepositoryError> { + self.0.backup_mode(|r, l| r.save_backup(backup, name, l)) + } + #[inline] pub fn prune_backups(&mut self, prefix: &str, daily: usize, weekly: usize, monthly: usize, yearly: usize, force: bool) -> Result<(), RepositoryError> @@ -241,7 +171,7 @@ impl BackupRepository { self.0.online_mode(|r, l| r.get_inode_children(inode, l)) } - #[inline] + #[inline] pub fn restore_inode_tree>(&mut self, backup: &BackupFile, inode: Inode, path: P) -> Result<(), RepositoryError> { self.0.online_mode(|r, l| r.restore_inode_tree(backup, inode, path, l)) } @@ -254,12 +184,13 @@ impl BackupRepository { } #[inline] - pub fn remove_backup_path>(&mut self, backup: &mut BackupFile, path: P + pub fn remove_backup_path>(&mut self, backup: &mut BackupFile, name: &str, path: P ) -> Result<(), RepositoryError> { - self.0.backup_mode(|r, l| r.remove_backup_path(backup, path, l)) + self.0.backup_mode(|r, l| r.remove_backup_path(backup, name, path, l)) } #[inline] + #[allow(dead_code)] pub fn get_backup_path>(&mut self, backup: &BackupFile, path: P) -> Result, RepositoryError> { self.0.online_mode(|r, l| r.get_backup_path(backup, path, l)) } @@ -321,13 +252,16 @@ impl BackupRepository { }) } - pub fn check(&mut self, options: &CheckOptions) -> Result<(), RepositoryError> { - self.0.online_mode(|r, l| { - r.check(options.index, options.bundles, options.bundle_data, l); - Ok(()) - }); - unimplemented!() - //TODO: implement + pub fn check(&mut self, options: CheckOptions) -> Result { + if options.get_repair() { + self.0.vacuum_mode(|r, l| { + r.check_and_repair(options, l) + }) + } else { + self.0.online_mode(|r, l| { + Ok(r.check(options, l)) + }) + } } #[inline] diff --git a/src/backups/tarfile.rs b/src/backups/tarfile.rs index 7833819..ae30456 100644 --- a/src/backups/tarfile.rs +++ b/src/backups/tarfile.rs @@ -331,7 +331,7 @@ impl RepositoryTarfileIO for Repository { } fn export_xattrs(&mut self, inode: &Inode, tarfile: &mut tar::Builder, - lock: &OnlineMode + _lock: &OnlineMode ) -> Result<(), RepositoryError> { let mut pax = PaxBuilder::new(); for (key, value) in &inode.xattrs { diff --git a/src/backups/vacuum.rs b/src/backups/vacuum.rs index a3911b0..aa948dc 100644 --- a/src/backups/vacuum.rs +++ b/src/backups/vacuum.rs @@ -17,7 +17,7 @@ pub trait RepositoryVacuumIO { impl RepositoryVacuumIO for Repository { fn mark_used(&self, bundles: &mut HashMap, chunks: &[Chunk], - lock: &OnlineMode + _lock: &OnlineMode ) -> Result { let mut new = false; for &(hash, len) in chunks { @@ -108,6 +108,9 @@ impl RepositoryVacuumIO for Repository { let mut reclaim_space = 0; let mut rewrite_data = 0; for (id, bundle) in &usage { + //TODO: make this + // bundle.get_usage_ratio() < ratio || bundle.get_usage_ratio() == 0.0 + // to avoid rewriting completely full bundles, also if bundle.get_usage_ratio() <= ratio { rewrite_bundles.insert(*id); reclaim_space += bundle.get_unused_size(); diff --git a/src/cli/args.rs b/src/cli/args.rs index cb7a42a..d222b85 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -723,6 +723,7 @@ pub fn parse() -> Result<(log::Level, Arguments), ErrorCode> { yearly: parse_num(args.value_of("yearly").unwrap()).unwrap() as usize } } + //TODO: add new parameter scrub that sets ratio to 101, disallow values outside 0..100 ("vacuum", Some(args)) => { let (repository, _backup, _inode) = parse_repo_path( args.value_of("REPO").unwrap(), diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 6e19aed..9048baa 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -10,9 +10,9 @@ use regex::{self, RegexSet}; use std::collections::HashMap; use std::io::{BufReader, BufRead}; use std::fs::File; -use std::env; use std::str; use std::path::{Path, PathBuf}; +use std::error::Error; use self::args::Arguments; @@ -99,7 +99,7 @@ pub const DEFAULT_VACUUM_RATIO_STR: &str = "0"; pub const DEFAULT_DUPLICATES_MIN_SIZE_STR: &str = "1b"; lazy_static! { pub static ref ZVAULT_FOLDER: PathBuf = { - env::home_dir().unwrap().join(".zvault") + dirs::home_dir().unwrap().join(".zvault") }; } @@ -499,6 +499,38 @@ fn print_duplicates(dups: Vec<(Vec, u64)>) { } } +fn print_integrity_report_module(name: &str, module: &ModuleIntegrityReport) -> usize { + let found = module.errors_fixed.len() + module.errors_unfixed.len(); + let fixed = module.errors_fixed.len(); + tr_println!("{}: {} errors found, {} corrected:", name, found, fixed); + for e in &module.errors_fixed { + println!("{}", e); + } + for e in &module.errors_unfixed { + println!("{}", e); + } + found - fixed +} + +fn print_integrity_report(report: &IntegrityReport) { + let mut unfixed = 0; + if let Some(ref module) = report.bundle_map { + unfixed += print_integrity_report_module("Bundle map", module); + } + if let Some(ref module) = report.index { + unfixed += print_integrity_report_module("Index", module); + } + if let Some(ref module) = report.bundles { + unfixed += print_integrity_report_module("Bundles", module); + } + if let Some(ref module) = report.backups { + unfixed += print_integrity_report_module("Backups", module); + } + if unfixed == 0 { + tr_info!("Integrity verified") + } +} + #[allow(unknown_lints, cyclomatic_complexity)] @@ -714,7 +746,11 @@ pub fn run() -> Result<(), ErrorCode> { return Err(ErrorCode::BackupAlreadyExists); } let backup = try!(get_backup(&repo, &backup_name_src)); - //TODO: implement + checked!( + repo.save_backup(&backup, &backup_name_dst), + "save backup", + ErrorCode::SaveBackup + ); } Arguments::Remove { repo_path, @@ -726,7 +762,7 @@ pub fn run() -> Result<(), ErrorCode> { if let Some(inode) = inode { let mut backup = try!(get_backup(&repo, &backup_name)); checked!( - repo.remove_backup_path(&mut backup, inode), + repo.remove_backup_path(&mut backup, &backup_name, inode), "remove backup subpath", ErrorCode::RemoveRun ); @@ -819,19 +855,25 @@ pub fn run() -> Result<(), ErrorCode> { let mut options = CheckOptions::new(); options.index(index).bundle_data(bundle_data).bundles(bundles).repair(repair); if let Some(backup_name) = backup_name { - options.single_backup(&backup_name); - if let Some(inode) = inode { - options.subpath(Path::new(&inode)); + let backup = try!(get_backup(&repo, &backup_name)); + if let Some(inode_name) = inode { + let inode = checked!( + repo.get_backup_inode(&backup, &inode_name), + "load subpath inode", + ErrorCode::LoadInode + ); + options.subpath(Path::new(&inode_name), inode); } + options.single_backup(&backup_name, backup); } else { options.all_backups(); } - checked!( - repo.check(&options), + let report = checked!( + repo.check(options), "check repository", ErrorCode::CheckRun ); - tr_info!("Integrity verified") + print_integrity_report(&report); } Arguments::List { repo_path, diff --git a/src/main.rs b/src/main.rs index ee0e7ff..2c6d74d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,6 +39,7 @@ extern crate tar; extern crate runtime_fmt; extern crate locale_config; extern crate mmap; +extern crate dirs; #[macro_use] mod translation; pub mod util; diff --git a/src/prelude.rs b/src/prelude.rs index fa3e56d..7c2e341 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -10,7 +10,7 @@ pub use repository::index::{Index, IndexError, IndexStatistics}; pub use backups::mount::FuseFilesystem; pub use backups::{BackupFile, BackupFileError, Inode, FileType, FileData, InodeError, BackupError, BackupOptions, DiffType, InodeIntegrityError, BackupRepositoryLayout, - RepositoryBackupIO, RepositoryMetadataIO, CheckOptions}; + RepositoryBackupIO, RepositoryMetadataIO, CheckOptions, IntegrityReport}; pub use translation::CowStr; pub use backups::BackupRepository; diff --git a/src/repository/bundledb/db.rs b/src/repository/bundledb/db.rs index 985c4f5..46295a5 100644 --- a/src/repository/bundledb/db.rs +++ b/src/repository/bundledb/db.rs @@ -288,7 +288,7 @@ impl BundleDb { hash_method: HashMethod, compression: Option, encryption: Option, - lock: &BackupMode + _lock: &BackupMode ) -> Result { Ok(try!(BundleWriter::new( self.layout.clone(), diff --git a/src/repository/integrity.rs b/src/repository/integrity.rs index 7550f30..297ddbc 100644 --- a/src/repository/integrity.rs +++ b/src/repository/integrity.rs @@ -51,13 +51,9 @@ pub struct ModuleIntegrityReport { pub errors_unfixed: Vec } -pub struct IntegrityReport { - pub bundle_map: Option>, - pub index: Option>, - pub bundles: Option> -} - +//FIXME: use or remove +#[allow(dead_code)] pub struct ChunkMarker<'a> { marked: Bitmap, repo: &'a Repository @@ -183,7 +179,7 @@ impl Repository { } #[inline] - pub fn check_index(&mut self, lock: &ReadonlyMode) -> ModuleIntegrityReport { + pub fn check_index(&mut self, _lock: &ReadonlyMode) -> ModuleIntegrityReport { tr_info!("Checking index integrity..."); let mut errors: Vec = self.index.check().into_iter().map(IntegrityError::Index).collect(); tr_info!("Checking index entries..."); @@ -230,40 +226,4 @@ impl Repository { Ok(report) } - pub fn check(&mut self, index: bool, bundles: bool, bundle_data: bool, lock: &OnlineMode) -> IntegrityReport { - let mut report = IntegrityReport { - bundle_map: None, - index: None, - bundles: None - }; - report.bundle_map = Some(self.check_bundle_map()); - if index { - report.index = Some(self.check_index(lock.as_readonly())); - } - if bundles { - report.bundles = Some(self.check_bundles(bundle_data, lock)); - } - report - } - - pub fn check_and_repair(&mut self, index: bool, bundles: bool, bundle_data: bool, lock: &VacuumMode) -> Result { - let mut report = IntegrityReport { - bundle_map: None, - index: None, - bundles: None - }; - let bundle_map = try!(self.check_and_repair_bundle_map(lock.as_online())); - if !bundle_map.errors_fixed.is_empty() { - try!(self.rebuild_index(lock.as_online())); - } - report.bundle_map = Some(bundle_map); - if index { - report.index = Some(try!(self.check_and_repair_index(lock.as_online()))); - } - if bundles { - report.bundles = Some(try!(self.check_and_repair_bundles(bundle_data, lock))); - } - Ok(report) - } - } diff --git a/src/repository/mod.rs b/src/repository/mod.rs index ea52087..60a0396 100644 --- a/src/repository/mod.rs +++ b/src/repository/mod.rs @@ -24,7 +24,7 @@ pub use self::error::RepositoryError; pub use self::config::Config; pub use self::layout::ChunkRepositoryLayout; use self::bundle_map::BundleMap; -pub use self::integrity::{IntegrityError, ModuleIntegrityReport, IntegrityReport}; +pub use self::integrity::{IntegrityError, ModuleIntegrityReport}; pub use self::info::{BundleAnalysis, RepositoryInfo, RepositoryStatistics}; const REPOSITORY_README: &[u8] = include_bytes!("../../docs/repository_readme.md"); @@ -118,11 +118,12 @@ impl Repository { let remote_locks = LockFolder::new(layout.remote_locks_path()); try!(fs::create_dir_all(layout.local_locks_path())); // Added after v0.1.0 let local_locks = LockFolder::new(layout.local_locks_path()); - let lock = try!(local_locks.lock(false)); + let _lock = try!(local_locks.lock(false)); let mock_lock = Lock; let bundles = try!(BundleDb::open(layout.clone(), crypto.clone(), &mock_lock)); let mut rebuild_index = false; - let mut rebuild_bundle_map = false; + //FIXME: why is this never set? + let /*mut*/ rebuild_bundle_map = false; let index = match unsafe { Index::open(layout.index_path(), &INDEX_MAGIC, INDEX_VERSION) } { Ok(index) => index, Err(err) => { @@ -170,6 +171,8 @@ impl Repository { Ok(repo) } + //FIXME: use or remove + #[allow(dead_code)] pub fn synchronize(&mut self, lock: &OnlineMode) -> Result<(), RepositoryError> { let (new, gone) = try!(self.bundles.synchronize(lock)); let mut save_bundle_map = false; @@ -421,6 +424,8 @@ impl Repository { Ok(()) } + //FIXME: use or remove + #[allow(dead_code)] pub fn readonly_mode Result> (&mut self, f: F) -> Result { let _local_lock = try!(self.local_locks.lock(false)); f(self, &Lock) diff --git a/src/util/mod.rs b/src/util/mod.rs index a90e8c0..1ac1075 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -10,7 +10,6 @@ mod hostname; mod fs; mod lock; mod statistics; -mod mode_test; pub mod msgpack; diff --git a/src/util/mode_test.rs b/src/util/mode_test.rs deleted file mode 100644 index 60de71d..0000000 --- a/src/util/mode_test.rs +++ /dev/null @@ -1,117 +0,0 @@ -/** - -ReadonlyMode -- Local: readonly, shared lock -- Remote: offline - -LocalWriteMode -- Local: writable, exclusive lock, dirty flag -- Remote: offline - -OnlineMode -- Local: writable, exclusive lock, dirty flag -- Remote: readonly, shared lock - -BackupMode -- Local: writable, exclusive lock, dirty flag -- Remote: append-only, shared lock - -VacuumMode -- Local: writable, exclusive lock, dirty flag -- Remote: writable, exclusive lock - -**/ - - -pub struct Repository { - -} - -impl Repository { - pub fn readonly_mode R> (&mut self, f: F) -> R { - f(self, &Lock) - } - - pub fn localwrite_mode R> (&mut self, f: F) -> R { - f(self, &Lock) - } - - pub fn online_mode R> (&mut self, f: F) -> R { - f(self, &Lock) - } - - pub fn backup_mode R> (&mut self, f: F) -> R { - f(self, &Lock) - } - - pub fn vacuum_mode R> (&mut self, f: F) -> R { - f(self, &Lock) - } -} - - -struct Lock; - -pub trait ReadonlyMode {} - -impl ReadonlyMode for Lock {} - - -pub trait LocalWriteMode: ReadonlyMode { - fn as_readonly(&self) -> &ReadonlyMode; -} - -impl LocalWriteMode for Lock { - fn as_readonly(&self) -> &ReadonlyMode { - self - } -} - - -pub trait OnlineMode: LocalWriteMode { - fn as_localwrite(&self) -> &LocalWriteMode; -} - -impl OnlineMode for Lock { - fn as_localwrite(&self) -> &LocalWriteMode { - self - } -} - - -pub trait BackupMode: OnlineMode { - fn as_online(&self) -> &OnlineMode; -} - -impl BackupMode for Lock { - fn as_online(&self) -> &OnlineMode { - self - } -} - - -pub trait VacuumMode: BackupMode { - fn as_backup(&self) -> &BackupMode; -} - -impl VacuumMode for Lock { - fn as_backup(&self) -> &BackupMode { - self - } -} - - -impl Repository { - fn write(&mut self, w: W, lock: &LocalWriteMode) { - - } - - fn test(&mut self) { - self.localwrite_mode(|repo, lock| { - repo.write(&mut Vec::new(), lock) - }); - self.online_mode(|repo, lock| { - repo.write(&mut Vec::new(), lock.as_localwrite()) - }); - } -} \ No newline at end of file