From: Christian Ebner <c.ebner@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [PATCH proxmox-backup v2 06/10] datastore: move file lock helper to centralized place
Date: Wed, 6 May 2026 18:56:47 +0200 [thread overview]
Message-ID: <20260506165651.1322947-7-c.ebner@proxmox.com> (raw)
In-Reply-To: <20260506165651.1322947-1-c.ebner@proxmox.com>
Moves the implementation to a more central location, as it is not
only used by the datastore contents, but also by the chunk store.
No functional changes.
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
pbs-datastore/src/backup_info.rs | 35 ++---------------------------
pbs-datastore/src/chunk_store.rs | 2 +-
pbs-datastore/src/lib.rs | 38 ++++++++++++++++++++++++++++++++
3 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/pbs-datastore/src/backup_info.rs b/pbs-datastore/src/backup_info.rs
index 9919b908a..bae136d3c 100644
--- a/pbs-datastore/src/backup_info.rs
+++ b/pbs-datastore/src/backup_info.rs
@@ -1,5 +1,5 @@
use std::fmt;
-use std::os::unix::io::{AsRawFd, RawFd};
+use std::os::unix::io::RawFd;
use std::os::unix::prelude::OsStrExt;
use std::path::Path;
use std::path::PathBuf;
@@ -24,7 +24,7 @@ use crate::datastore::{GROUP_NOTES_FILE_NAME, GROUP_OWNER_FILE_NAME};
use crate::manifest::{BackupManifest, MANIFEST_LOCK_NAME};
use crate::move_journal;
use crate::s3::S3_CONTENT_PREFIX;
-use crate::{DataBlob, DataStore, DatastoreBackend, DATASTORE_LOCKS_DIR};
+use crate::{lock_helper, DataBlob, DataStore, DatastoreBackend, DATASTORE_LOCKS_DIR};
pub const PROTECTED_MARKER_FILENAME: &str = ".protected";
@@ -1210,34 +1210,3 @@ fn lock_file_path_helper(ns: &BackupNamespace, path: PathBuf) -> PathBuf {
to_return.join(format!("{first_eigthy}...{last_eighty}-{hash}"))
}
-
-/// Helps implement the double stat'ing procedure. It avoids certain race conditions upon lock
-/// deletion.
-///
-/// It also creates the base directory for lock files.
-pub(crate) fn lock_helper<F>(
- store_name: &str,
- path: &std::path::Path,
- lock_fn: F,
-) -> Result<BackupLockGuard, Error>
-where
- F: Fn(&std::path::Path) -> Result<BackupLockGuard, Error>,
-{
- let mut lock_dir = Path::new(DATASTORE_LOCKS_DIR).join(store_name);
-
- if let Some(parent) = path.parent() {
- lock_dir = lock_dir.join(parent);
- };
-
- std::fs::create_dir_all(&lock_dir)?;
-
- let lock = lock_fn(path)?;
-
- let inode = nix::sys::stat::fstat(lock.as_raw_fd())?.st_ino;
-
- if nix::sys::stat::stat(path).map_or(true, |st| inode != st.st_ino) {
- bail!("could not acquire lock, another thread modified the lock file");
- }
-
- Ok(lock)
-}
diff --git a/pbs-datastore/src/chunk_store.rs b/pbs-datastore/src/chunk_store.rs
index f239b4237..e9dadce59 100644
--- a/pbs-datastore/src/chunk_store.rs
+++ b/pbs-datastore/src/chunk_store.rs
@@ -927,7 +927,7 @@ impl ChunkStore {
timeout: Duration,
) -> Result<BackupLockGuard, Error> {
let lock_path = self.chunk_lock_path(digest);
- let guard = crate::backup_info::lock_helper(self.name(), &lock_path, |path| {
+ let guard = crate::lock_helper(self.name(), &lock_path, |path| {
pbs_config::open_backup_lockfile(path, Some(timeout), true)
})?;
Ok(guard)
diff --git a/pbs-datastore/src/lib.rs b/pbs-datastore/src/lib.rs
index 358f418d1..f10a2840d 100644
--- a/pbs-datastore/src/lib.rs
+++ b/pbs-datastore/src/lib.rs
@@ -157,6 +157,13 @@
#![deny(unsafe_op_in_unsafe_fn)]
+use std::os::unix::io::AsRawFd;
+use std::path::Path;
+
+use anyhow::{bail, Error};
+
+use pbs_config::BackupLockGuard;
+
/// Directory path where active operations counters are saved.
pub const ACTIVE_OPERATIONS_DIR: &str = concat!(
pbs_buildcfg::PROXMOX_BACKUP_RUN_DIR_M!(),
@@ -236,3 +243,34 @@ pub use local_chunk_reader::LocalChunkReader;
mod local_datastore_lru_cache;
pub use local_datastore_lru_cache::LocalDatastoreLruCache;
+
+/// Helps implement the double stat'ing procedure. It avoids certain race conditions upon lock
+/// deletion.
+///
+/// It also creates the base directory for lock files.
+pub(crate) fn lock_helper<F>(
+ store_name: &str,
+ path: &Path,
+ lock_fn: F,
+) -> Result<BackupLockGuard, Error>
+where
+ F: Fn(&Path) -> Result<BackupLockGuard, Error>,
+{
+ let mut lock_dir = Path::new(DATASTORE_LOCKS_DIR).join(store_name);
+
+ if let Some(parent) = path.parent() {
+ lock_dir = lock_dir.join(parent);
+ };
+
+ std::fs::create_dir_all(&lock_dir)?;
+
+ let lock = lock_fn(path)?;
+
+ let inode = nix::sys::stat::fstat(lock.as_raw_fd())?.st_ino;
+
+ if nix::sys::stat::stat(path).map_or(true, |st| inode != st.st_ino) {
+ bail!("could not acquire lock, another thread modified the lock file");
+ }
+
+ Ok(lock)
+}
--
2.47.3
next prev parent reply other threads:[~2026-05-06 16:57 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-06 16:56 [PATCH proxmox{,-backup} v2 00/10] keep datastore config unlock during long running operations Christian Ebner
2026-05-06 16:56 ` [PATCH proxmox v2 01/10] pbs-api-types: add datastore create maintenance-mode type Christian Ebner
2026-05-06 16:56 ` [PATCH proxmox-backup v2 02/10] api: config: rearrange independent code block for datastore creation Christian Ebner
2026-05-06 16:56 ` [PATCH proxmox-backup v2 03/10] api/datastore: refactor datastore creation helper logic Christian Ebner
2026-05-06 16:56 ` [PATCH proxmox-backup v2 04/10] datastore: restrict chunk store scope to pbs-datastore crate Christian Ebner
2026-05-06 16:56 ` [PATCH proxmox-backup v2 05/10] datastore: move lock files base path constant to central location Christian Ebner
2026-05-06 16:56 ` Christian Ebner [this message]
2026-05-06 16:56 ` [PATCH proxmox-backup v2 07/10] datastore: create lockdir with correct mode for backup user access Christian Ebner
2026-05-06 16:56 ` [PATCH proxmox-backup v2 08/10] api/datastore: use maintenance-mode lock to protect against changes Christian Ebner
2026-05-06 16:56 ` [PATCH proxmox-backup v2 09/10] api: config: unlocked s3 bucket access check for datastore creation Christian Ebner
2026-05-06 16:56 ` [PATCH proxmox-backup v2 10/10] datastore: protect datastore creation by maintenance-mode 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=20260506165651.1322947-7-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.