diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs index 5e6d5720..29e74bd6 100644 --- a/src/api2/admin/datastore.rs +++ b/src/api2/admin/datastore.rs @@ -474,16 +474,24 @@ pub fn verify( let upid_str = WorkerTask::new_thread( "verify", Some(worker_id.clone()), &username, to_stdout, move |worker| { - let success = if let Some(backup_dir) = backup_dir { + let failed_dirs = if let Some(backup_dir) = backup_dir { let mut verified_chunks = HashSet::with_capacity(1024*16); let mut corrupt_chunks = HashSet::with_capacity(64); - verify_backup_dir(&datastore, &backup_dir, &mut verified_chunks, &mut corrupt_chunks, &worker)? + let mut res = Vec::new(); + if !verify_backup_dir(&datastore, &backup_dir, &mut verified_chunks, &mut corrupt_chunks, &worker)? { + res.push(backup_dir.to_string()); + } + res } else if let Some(backup_group) = backup_group { verify_backup_group(&datastore, &backup_group, &worker)? } else { verify_all_backups(&datastore, &worker)? }; - if !success { + if failed_dirs.len() > 0 { + worker.log("Failed to verify following snapshots:"); + for dir in failed_dirs { + worker.log(format!("\t{}", dir)); + } bail!("verfication failed - please check the log for details"); } Ok(()) diff --git a/src/backup/verify.rs b/src/backup/verify.rs index 58b91bc9..cba1297f 100644 --- a/src/backup/verify.rs +++ b/src/backup/verify.rs @@ -198,34 +198,32 @@ pub fn verify_backup_dir( /// Errors are logged to the worker log. /// /// Returns -/// - Ok(true) if verify is successful -/// - Ok(false) if there were verification errors +/// - Ok(failed_dirs) where failed_dirs had verification errors /// - Err(_) if task was aborted -pub fn verify_backup_group(datastore: &DataStore, group: &BackupGroup, worker: &WorkerTask) -> Result { +pub fn verify_backup_group(datastore: &DataStore, group: &BackupGroup, worker: &WorkerTask) -> Result, Error> { + let mut errors = Vec::new(); let mut list = match group.list_backups(&datastore.base_path()) { Ok(list) => list, Err(err) => { worker.log(format!("verify group {}:{} - unable to list backups: {}", datastore.name(), group, err)); - return Ok(false); + return Ok(errors); } }; worker.log(format!("verify group {}:{}", datastore.name(), group)); - let mut error_count = 0; - let mut verified_chunks = HashSet::with_capacity(1024*16); // start with 16384 chunks (up to 65GB) let mut corrupt_chunks = HashSet::with_capacity(64); // start with 64 chunks since we assume there are few corrupt ones BackupInfo::sort_list(&mut list, false); // newest first for info in list { if !verify_backup_dir(datastore, &info.backup_dir, &mut verified_chunks, &mut corrupt_chunks, worker)?{ - error_count += 1; + errors.push(info.backup_dir.to_string()); } } - Ok(error_count == 0) + Ok(errors) } /// Verify all backups inside a datastore @@ -233,27 +231,26 @@ pub fn verify_backup_group(datastore: &DataStore, group: &BackupGroup, worker: & /// Errors are logged to the worker log. /// /// Returns -/// - Ok(true) if verify is successful -/// - Ok(false) if there were verification errors +/// - Ok(failed_dirs) where failed_dirs had verification errors /// - Err(_) if task was aborted -pub fn verify_all_backups(datastore: &DataStore, worker: &WorkerTask) -> Result { +pub fn verify_all_backups(datastore: &DataStore, worker: &WorkerTask) -> Result, Error> { + + let mut errors = Vec::new(); let list = match BackupGroup::list_groups(&datastore.base_path()) { Ok(list) => list, Err(err) => { worker.log(format!("verify datastore {} - unable to list backups: {}", datastore.name(), err)); - return Ok(false); + return Ok(errors); } }; worker.log(format!("verify datastore {}", datastore.name())); - let mut error_count = 0; for group in list { - if !verify_backup_group(datastore, &group, worker)? { - error_count += 1; - } + let mut group_errors = verify_backup_group(datastore, &group, worker)?; + errors.append(&mut group_errors); } - Ok(error_count == 0) + Ok(errors) }