From 98eb435d901bd4d31da2ce5174389e4d1caf79ae Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Mon, 18 Oct 2021 13:45:30 +0200 Subject: [PATCH] proxmox-rrd: use syncfs after writing rrd files Signed-off-by: Dietmar Maurer --- proxmox-rrd/Cargo.toml | 1 + proxmox-rrd/src/cache.rs | 6 ++++++ proxmox-rrd/src/cache/journal.rs | 11 +++++++++++ proxmox-rrd/src/rrd.rs | 1 - src/bin/proxmox-backup-proxy.rs | 6 +++++- src/rrd_cache.rs | 8 ++++++++ 6 files changed, 31 insertions(+), 2 deletions(-) diff --git a/proxmox-rrd/Cargo.toml b/proxmox-rrd/Cargo.toml index 900b8fef..67095689 100644 --- a/proxmox-rrd/Cargo.toml +++ b/proxmox-rrd/Cargo.toml @@ -12,6 +12,7 @@ proxmox-router = "1.1" anyhow = "1.0" bitflags = "1.2.1" crossbeam-channel = "0.5" +libc = "0.2" log = "0.4" nix = "0.19.1" serde = { version = "1.0", features = ["derive"] } diff --git a/proxmox-rrd/src/cache.rs b/proxmox-rrd/src/cache.rs index faeae89f..547f6603 100644 --- a/proxmox-rrd/src/cache.rs +++ b/proxmox-rrd/src/cache.rs @@ -147,6 +147,10 @@ impl RRDCache { Ok(JournalEntry { time, value, dst, rel_path }) } + pub fn sync_journal(&self) -> Result<(), Error> { + self.state.read().unwrap().sync_journal() + } + /// Apply and commit the journal. Should be used at server startup. pub fn apply_journal(&self) -> Result { let state = Arc::clone(&self.state); @@ -387,6 +391,8 @@ fn commit_journal_impl( } } + state.read().unwrap().syncfs()?; + if errors != 0 { bail!("errors during rrd flush - unable to commit rrd journal"); } diff --git a/proxmox-rrd/src/cache/journal.rs b/proxmox-rrd/src/cache/journal.rs index 592e18ec..3514e9e7 100644 --- a/proxmox-rrd/src/cache/journal.rs +++ b/proxmox-rrd/src/cache/journal.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; use std::sync::Arc; use std::io::{Write, BufReader}; use std::ffi::OsStr; +use std::os::unix::io::AsRawFd; use anyhow::Error; use nix::fcntl::OFlag; @@ -50,6 +51,16 @@ impl JournalState { }) } + pub fn sync_journal(&self) -> Result<(), Error> { + nix::unistd::fdatasync(self.journal.as_raw_fd())?; + Ok(()) + } + + pub fn syncfs(&self) -> Result<(), nix::Error> { + let res = unsafe { libc::syncfs(self.journal.as_raw_fd()) }; + nix::errno::Errno::result(res).map(drop) + } + pub fn append_journal_entry( &mut self, time: f64, diff --git a/proxmox-rrd/src/rrd.rs b/proxmox-rrd/src/rrd.rs index 3550e30a..15d73856 100644 --- a/proxmox-rrd/src/rrd.rs +++ b/proxmox-rrd/src/rrd.rs @@ -14,7 +14,6 @@ use std::path::Path; use anyhow::{bail, format_err, Error}; - use serde::{Serialize, Deserialize}; use proxmox::tools::fs::{replace_file, CreateOptions}; diff --git a/src/bin/proxmox-backup-proxy.rs b/src/bin/proxmox-backup-proxy.rs index 3774199e..1589a57d 100644 --- a/src/bin/proxmox-backup-proxy.rs +++ b/src/bin/proxmox-backup-proxy.rs @@ -30,7 +30,9 @@ use proxmox_rest_server::{ ServerAdapter, WorkerTask, cleanup_old_tasks, }; -use proxmox_backup::rrd_cache::{ rrd_update_gauge, rrd_update_derive, initialize_rrd_cache}; +use proxmox_backup::rrd_cache::{ + initialize_rrd_cache, rrd_update_gauge, rrd_update_derive, rrd_sync_journal, +}; use proxmox_backup::{ server::{ auth::check_pbs_auth, @@ -896,6 +898,8 @@ async fn run_stat_generator() { generate_host_stats().await; + rrd_sync_journal(); + tokio::time::sleep_until(tokio::time::Instant::from_std(delay_target)).await; } diff --git a/src/rrd_cache.rs b/src/rrd_cache.rs index a2129523..25dc8ca4 100644 --- a/src/rrd_cache.rs +++ b/src/rrd_cache.rs @@ -94,6 +94,14 @@ pub fn extract_rrd_data( rrd_cache.extract_cached_data(basedir, name, cf, resolution, Some(start), Some(end)) } +/// Sync/Flush the RRD journal +pub fn rrd_sync_journal() { + if let Ok(rrd_cache) = get_rrd_cache() { + if let Err(err) = rrd_cache.sync_journal() { + log::error!("rrd_sync_journal failed - {}", err); + } + } +} /// Update RRD Gauge values pub fn rrd_update_gauge(name: &str, value: f64) { if let Ok(rrd_cache) = get_rrd_cache() {