From: Christian Ebner <c.ebner@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup v5 17/19] chunk store: add helpers marking missing local chunk markers as expected
Date: Tue, 11 Nov 2025 15:30:00 +0100 [thread overview]
Message-ID: <20251111143002.759901-18-c.ebner@proxmox.com> (raw)
In-Reply-To: <20251111143002.759901-1-c.ebner@proxmox.com>
writes or removes a `<digest>.using` marker file in place of an
expected but missing local store cache chunk marker file for s3
backed datastores.
These markers will be used to identify chunks which are still in-use
and not bad, but the local store does not contain the marker file
(e.g. because the cache might be empty due to datastore re-creation
from s3 bucket).
These markers will be set in phase 1 of garbage collection and
replaced with the expected marker file by either a concurrent chunk
insert or if the listing of chunk in phase 2 of garbage collection
detects the chunk to be present on the s3 object store.
Phase 3 will clean up the files after falling out of the cutoff window,
given that the extension is chosen to fit the filename criteria.
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
pbs-datastore/src/chunk_store.rs | 42 ++++++++++++++++++++++++++++++--
1 file changed, 40 insertions(+), 2 deletions(-)
diff --git a/pbs-datastore/src/chunk_store.rs b/pbs-datastore/src/chunk_store.rs
index 20f71efef..f10415d1f 100644
--- a/pbs-datastore/src/chunk_store.rs
+++ b/pbs-datastore/src/chunk_store.rs
@@ -721,18 +721,56 @@ impl ChunkStore {
/// Safety: chunk store mutex must be held!
pub(crate) unsafe fn replace_chunk_with_marker(&self, digest: &[u8; 32]) -> Result<(), Error> {
let (chunk_path, digest_str) = self.chunk_path(digest);
+ Self::create_marker_file(&chunk_path)
+ .map_err(|err| format_err!("clear chunk failed for {digest_str} - {err}"))?;
+ Ok(())
+ }
+
+ /// Helper to generate new empty marker file
+ fn create_marker_file(path: &Path) -> Result<(), Error> {
let mut create_options = CreateOptions::new();
if nix::unistd::Uid::effective().is_root() {
let uid = pbs_config::backup_user()?.uid;
let gid = pbs_config::backup_group()?.gid;
create_options = create_options.owner(uid).group(gid);
}
+ proxmox_sys::fs::replace_file(&path, &[], create_options, false)
+ }
- proxmox_sys::fs::replace_file(&chunk_path, &[], create_options, false)
- .map_err(|err| format_err!("clear chunk failed for {digest_str} - {err}"))?;
+ /// Mark chunk as expected to be present by writing a file the chunk store.
+ ///
+ /// Used to mark chunks which are found in index files during phase 1 of garbage collection
+ /// for s3 datastores, but the marker file is not present and it is seemingly not a bad chunk.
+ /// This might happen if the local store cache is empty after datastore re-creation.
+ pub(crate) fn mark_chunk_as_expected(&self, digest: &[u8; 32]) -> Result<(), Error> {
+ let marker_path = self.chunk_expected_marker_path(digest);
+ Self::create_marker_file(&marker_path)
+ .map_err(|err| format_err!("mark chunk failed for {} - {err}", hex::encode(digest)))?;
Ok(())
}
+ /// Remove chunk as required mark by removing file the chunk store.
+ ///
+ /// Returns true if the file was present and removed, false if the file did not exist.
+ pub(crate) fn clear_chunk_expected_mark(&self, digest: &[u8; 32]) -> Result<bool, Error> {
+ let marker_path = self.chunk_expected_marker_path(digest);
+ if let Err(err) = std::fs::remove_file(marker_path) {
+ if err.kind() != std::io::ErrorKind::NotFound {
+ return Err(err.into());
+ } else {
+ return Ok(false);
+ }
+ }
+ Ok(true)
+ }
+
+ /// Helper to generate marker file path for expected chunks
+ fn chunk_expected_marker_path(&self, digest: &[u8; 32]) -> PathBuf {
+ let (mut path, _digest_str) = self.chunk_path(digest);
+ path.set_extension("using");
+ path
+ }
+
/// Removes a chunk marker file from the `LocalDatastoreLruCache`s chunk store.
///
/// Callers must hold the per-chunk file lock in order to avoid races with renaming of corrupt
--
2.47.3
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
next prev parent reply other threads:[~2025-11-11 14:30 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-11 14:29 [pbs-devel] [PATCH proxmox-backup v5 00/19] fix chunk upload/insert, rename corrupt chunks and GC race conditions for s3 backend Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 01/19] datastore: GC: drop overly verbose info message during s3 chunk sweep Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 02/19] chunk store: implement per-chunk file locking helper for s3 backend Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 03/19] datastore: acquire chunk store mutex lock when renaming corrupt chunk Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 04/19] datastore: get per-chunk file lock for chunk rename on s3 backend Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 05/19] fix #6961: datastore: verify: evict corrupt chunks from in-memory LRU cache Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 06/19] datastore: add locking to protect against races on chunk insert for s3 Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 07/19] GC: fix race with chunk upload/insert on s3 backends Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 08/19] chunk store: reduce exposure of clear_chunk() to crate only Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 09/19] chunk store: make chunk removal a helper method of the chunk store Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 10/19] store: split insert_chunk into wrapper + unsafe locked implementation Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 11/19] store: cache: move Mutex acquire to cache insertion Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 12/19] chunk store: rename cache-specific helpers Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 13/19] GC: cleanup chunk markers from cache in phase 3 on s3 backends Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 14/19] GC: touch bad chunk files independent of backend type Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 15/19] GC: guard missing marker file insertion for s3 backed stores Christian Ebner
2025-11-11 14:29 ` [pbs-devel] [PATCH proxmox-backup v5 16/19] GC: s3: track if a chunk marker file is missing since a bad chunk Christian Ebner
2025-11-11 14:30 ` Christian Ebner [this message]
2025-11-11 14:30 ` [pbs-devel] [PATCH proxmox-backup v5 18/19] GC: assure chunk exists on s3 store when creating missing chunk marker Christian Ebner
2025-11-11 14:30 ` [pbs-devel] [PATCH proxmox-backup v5 19/19] datastore: document s3 backend specific locking restrictions Christian Ebner
2025-11-14 13:21 ` [pbs-devel] superseded: [PATCH proxmox-backup v5 00/19] fix chunk upload/insert, rename corrupt chunks and GC race conditions for s3 backend Christian Ebner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251111143002.759901-18-c.ebner@proxmox.com \
--to=c.ebner@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox