diff --git a/src/backup/datastore.rs b/src/backup/datastore.rs index fa52cd82..fe915285 100644 --- a/src/backup/datastore.rs +++ b/src/backup/datastore.rs @@ -11,7 +11,7 @@ use super::backup_info::{BackupGroup, BackupDir}; use super::chunk_store::ChunkStore; use super::dynamic_index::{DynamicIndexReader, DynamicIndexWriter}; use super::fixed_index::{FixedIndexReader, FixedIndexWriter}; -use super::manifest::{MANIFEST_BLOB_NAME, BackupManifest}; +use super::manifest::{MANIFEST_BLOB_NAME, CLIENT_LOG_BLOB_NAME, BackupManifest}; use super::index::*; use super::{DataBlob, ArchiveType, archive_type}; use crate::config::datastore; @@ -149,6 +149,7 @@ impl DataStore { let mut wanted_files = HashSet::new(); wanted_files.insert(MANIFEST_BLOB_NAME.to_string()); + wanted_files.insert(CLIENT_LOG_BLOB_NAME.to_string()); manifest.files().iter().for_each(|item| { wanted_files.insert(item.filename.clone()); }); for item in tools::fs::read_subdir(libc::AT_FDCWD, &full_path)? { diff --git a/src/client/pull.rs b/src/client/pull.rs index cb2a2537..378f400c 100644 --- a/src/client/pull.rs +++ b/src/client/pull.rs @@ -106,6 +106,34 @@ async fn pull_single_archive( Ok(()) } +// Note: The client.log.blob is uploaded after the backup, so it is +// not mentioned in the manifest. +async fn try_client_log_download( + worker: &WorkerTask, + reader: Arc, + path: &std::path::Path, +) -> Result<(), Error> { + + let mut tmp_path = path.to_owned(); + tmp_path.set_extension("tmp"); + + let tmpfile = std::fs::OpenOptions::new() + .write(true) + .create(true) + .read(true) + .open(&tmp_path)?; + + // Note: be silent if there is no log - only log sucessful download + if let Ok(_) = reader.download(CLIENT_LOG_BLOB_NAME, tmpfile).await { + if let Err(err) = std::fs::rename(&tmp_path, &path) { + bail!("Atomic rename file {:?} failed - {}", path, err); + } + worker.log(format!("got bakup log file {:?}", CLIENT_LOG_BLOB_NAME)); + } + + Ok(()) +} + async fn pull_snapshot( worker: &WorkerTask, reader: Arc, @@ -117,6 +145,10 @@ async fn pull_snapshot( manifest_name.push(snapshot.relative_path()); manifest_name.push(MANIFEST_BLOB_NAME); + let mut client_log_name = tgt_store.base_path(); + client_log_name.push(snapshot.relative_path()); + client_log_name.push(CLIENT_LOG_BLOB_NAME); + let mut tmp_manifest_name = manifest_name.clone(); tmp_manifest_name.set_extension("tmp"); @@ -137,7 +169,10 @@ async fn pull_snapshot( })?; if manifest_blob.raw_data() == tmp_manifest_blob.raw_data() { - worker.log("nothing changed - skip sync"); + if !client_log_name.exists() { + try_client_log_download(worker, reader, &client_log_name).await?; + } + worker.log("no data changes"); return Ok(()); // nothing changed } } @@ -200,6 +235,10 @@ async fn pull_snapshot( bail!("Atomic rename file {:?} failed - {}", manifest_name, err); } + if !client_log_name.exists() { + try_client_log_download(worker, reader, &client_log_name).await?; + } + // cleanup - remove stale files tgt_store.cleanup_backup_dir(snapshot, &manifest)?;