diff options
| -rw-r--r--[-rwxr-xr-x] | src/main.rs | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/main.rs b/src/main.rs index 6f9239a..847e4a4 100755..100644 --- a/src/main.rs +++ b/src/main.rs @@ -571,7 +571,7 @@ fn parse_hdr_chksum_octal(field: &[u8]) -> Option<u32> { } fn is_valid_tar_header(h: &[u8; 512]) -> bool { - if is_zero_block(h) { return true; } + if is_zero_block(h) { return false; } match parse_hdr_chksum_octal(&h[148..156]) { Some(want) => tar_checksum(h) == want, None => false, @@ -1122,11 +1122,13 @@ fn cmd_backup(ctx:&mut Ctx)->Result<()>{ out }; + // Ensure tar.snapshot is always saved – also when tar did not run (no_changes). + // In the no_changes case we materialize the file from meta, which was already + // done by ensure_tar_snapshot_materialized() at the top, so it's up-to-date. + let staging = ctx.temp_path("meta.staging"); extract_all_meta_to(ctx, &staging)?; - // neues Manifest hinein save_manifest_to_dir(&staging, next_idx, &manifest_now)?; - // aktualisierte tar.snapshot hinein (falls vorhanden) if ctx.tar_snapshot.exists() { let dst = staging.join("tar.snapshot"); if dst.exists() { let _ = fs::remove_file(&dst); } @@ -1134,6 +1136,8 @@ fn cmd_backup(ctx:&mut Ctx)->Result<()>{ } rebuild_meta_from_staging(ctx, &staging)?; let _ = fs::remove_dir_all(&staging); + // Clean up tar.snapshot in work_dir after it was saved to meta + let _ = fs::remove_file(&ctx.tar_snapshot); if tar_warn { eprintln!("[warn] Snapshot {:04} created, but tar reported non-zero exit. Some files may be missing or changed during read.", next_idx); @@ -1707,12 +1711,12 @@ fn merge_first_two(ctx:&mut Ctx)->Result<()>{ fs::create_dir_all(&upper)?; fs::create_dir_all(&work)?; fs::create_dir_all(&view)?; - let loweropt = format!("{}:{}", abspath(&m1).display(), abspath(&m2).display()); + let loweropt = format!("{}:{}", abspath(&m2).display(), abspath(&m1).display()); mount_overlay(&loweropt, &upper, &work, &view)?; - let present = load_manifest(ctx, idx2).unwrap_or_default(); - let past = load_manifest(ctx, idx1).unwrap_or_default(); - let deletes: Vec<String> = past.difference(&present).cloned().collect(); + let older = load_manifest(ctx, idx1).unwrap_or_default(); + let newer = load_manifest(ctx, idx2).unwrap_or_default(); + let deletes: Vec<String> = older.difference(&newer).cloned().collect(); if !deletes.is_empty() { apply_whiteouts_via_unlink(&abspath(&view), &deletes)?; } @@ -1729,6 +1733,15 @@ fn merge_first_two(ctx:&mut Ctx)->Result<()>{ let _ = umount(&view); let _ = umount(&m2); let _ = umount(&m1); + // Close LUKS mappers for the merged snapshots + close_mount_mapper_best_effort(s1); + close_mount_mapper_best_effort(s2); + // Clean up merge temporary directories + let _ = fs::remove_dir_all(&upper); + let _ = fs::remove_dir_all(&work); + let _ = fs::remove_dir_all(&view); + let _ = fs::remove_dir_all(&m1); + let _ = fs::remove_dir_all(&m2); let is_luks = s1.extension().and_then(|e| e.to_str()).unwrap_or("") == "luks"; let out_path = ctx.snapshot_path(idx1, is_luks); @@ -1753,11 +1766,11 @@ fn merge_first_two(ctx:&mut Ctx)->Result<()>{ let staging = ctx.temp_path("meta.staging"); extract_all_meta_to(ctx, &staging)?; - let m1p = staging.join(Ctx::manifest_name(1)); - let m2p = staging.join(Ctx::manifest_name(2)); - if m1p.exists(){ let _ = fs::remove_file(&m1p); } - if m2p.exists(){ fs::rename(&m2p, &m1p).ok(); } - let mut k = 3usize; + let m_older = staging.join(Ctx::manifest_name(idx1)); + let m_newer = staging.join(Ctx::manifest_name(idx2)); + if m_older.exists(){ let _ = fs::remove_file(&m_older); } + if m_newer.exists(){ fs::rename(&m_newer, &m_older).ok(); } + let mut k = idx2 + 1; loop { let from = staging.join(Ctx::manifest_name(k)); if !from.exists() { break; } @@ -1772,4 +1785,3 @@ fn merge_first_two(ctx:&mut Ctx)->Result<()>{ println!("Merged snapshots {:04} + {:04} → {:04}.", idx1, idx2, idx1); Ok(()) } - |
