use new atomic_open_or_create_file

Factor out open_backup_lockfile() method to acquire locks owned by
user backup with permission 0660.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Dietmar Maurer
2021-07-20 13:51:54 +02:00
committed by Thomas Lamprecht
parent a00888e93f
commit 7526d86419
29 changed files with 161 additions and 270 deletions

View File

@ -5,12 +5,11 @@ use std::sync::{Arc, Mutex};
use std::convert::TryFrom;
use std::str::FromStr;
use std::time::Duration;
use std::fs::File;
use anyhow::{bail, format_err, Error};
use lazy_static::lazy_static;
use proxmox::tools::fs::{replace_file, file_read_optional_string, CreateOptions, open_file_locked};
use proxmox::tools::fs::{replace_file, file_read_optional_string, CreateOptions};
use pbs_api_types::upid::UPID;
use pbs_api_types::{Authid, GarbageCollectionStatus};
@ -32,6 +31,8 @@ use pbs_tools::fs::{lock_dir_noblock, DirLockGuard};
use crate::config::datastore::{self, DataStoreConfig};
use crate::tools;
use crate::backup::{open_backup_lockfile, BackupLockGuard};
lazy_static! {
static ref DATASTORE_MAP: Mutex<HashMap<String, Arc<DataStore>>> = Mutex::new(HashMap::new());
@ -797,12 +798,12 @@ impl DataStore {
fn lock_manifest(
&self,
backup_dir: &BackupDir,
) -> Result<File, Error> {
) -> Result<BackupLockGuard, Error> {
let path = self.manifest_lock_path(backup_dir)?;
// update_manifest should never take a long time, so if someone else has
// the lock we can simply block a bit and should get it soon
open_file_locked(&path, Duration::from_secs(5), true)
open_backup_lockfile(&path, Some(Duration::from_secs(5)), true)
.map_err(|err| {
format_err!(
"unable to acquire manifest lock {:?} - {}", &path, err

View File

@ -87,3 +87,29 @@ pub use verify::*;
mod cached_chunk_reader;
pub use cached_chunk_reader::*;
pub struct BackupLockGuard(std::fs::File);
/// Open or create a lock file owned by user "backup" and lock it.
///
/// Owner/Group of the file is set to backup/backup.
/// File mode is 0660.
/// Default timeout is 10 seconds.
///
/// Note: This method needs to be called by user "root" or "backup".
pub fn open_backup_lockfile<P: AsRef<std::path::Path>>(
path: P,
timeout: Option<std::time::Duration>,
exclusive: bool,
) -> Result<BackupLockGuard, Error> {
let user = backup_user()?;
let options = proxmox::tools::fs::CreateOptions::new()
.perm(nix::sys::stat::Mode::from_bits_truncate(0o660))
.owner(user.uid)
.group(user.gid);
let timeout = timeout.unwrap_or(std::time::Duration::new(10, 0));
let file = proxmox::tools::fs::open_file_locked(&path, timeout, exclusive, options)?;
Ok(BackupLockGuard(file))
}