public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pbs-devel] [PATCH proxmox] add fsync parameter to replace_file and atomic_open_or_create
@ 2021-10-20 13:00 Dietmar Maurer
  2021-10-20 13:00 ` [pbs-devel] [PATCH proxmox-opendid] add fsync parameter to replace_file Dietmar Maurer
  2021-10-20 13:00 ` [pbs-devel] [PATCH proxmox-backup] use new fsync parameter to replace_file and atomic_open_or_create Dietmar Maurer
  0 siblings, 2 replies; 3+ messages in thread
From: Dietmar Maurer @ 2021-10-20 13:00 UTC (permalink / raw)
  To: pbs-devel

The fsync is required for consistency after power failure, so it should
be set when writing config files or otherwise important data.
---
 proxmox/src/tools/fs.rs | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/proxmox/src/tools/fs.rs b/proxmox/src/tools/fs.rs
index 19e549d..29233dd 100644
--- a/proxmox/src/tools/fs.rs
+++ b/proxmox/src/tools/fs.rs
@@ -163,10 +163,15 @@ pub fn make_tmp_file<P: AsRef<Path>>(
 /// Atomically replace a file.
 ///
 /// This first creates a temporary file and then rotates it in place.
+///
+/// `fsync`: use `fsync(2)` sycall to synchronize a file's in-core
+/// state with storage device. This makes sure the is consistent even
+/// aftert a power loss.
 pub fn replace_file<P: AsRef<Path>>(
     path: P,
     data: &[u8],
     options: CreateOptions,
+    fsync: bool,
 ) -> Result<(), Error> {
     let (fd, tmp_path) = make_tmp_file(&path, options)?;
 
@@ -177,6 +182,11 @@ pub fn replace_file<P: AsRef<Path>>(
         bail!("write failed: {}", err);
     }
 
+    if fsync {
+        // make sure data is on disk
+        nix::unistd::fsync(file.as_raw_fd())?;
+    }
+
     if let Err(err) = std::fs::rename(&tmp_path, &path) {
         let _ = unistd::unlink(&tmp_path);
         bail!(
@@ -194,11 +204,16 @@ pub fn replace_file<P: AsRef<Path>>(
 /// Since we need to initialize the file, we also need a solid slow
 /// path where we create the file. In order to avoid races, we create
 /// it in a temporary location and rotate it in place.
+///
+/// `fsync`: use `fsync(2)` sycall to synchronize the `initial_data`
+/// to the storage device. This options has no effect it the `initial_data`
+/// is empty or the file already exists.
 pub fn atomic_open_or_create_file<P: AsRef<Path>>(
     path: P,
     mut oflag: OFlag,
     initial_data: &[u8],
     options: CreateOptions,
+    fsync: bool,
 ) -> Result<File, Error> {
     let path = path.as_ref();
 
@@ -244,6 +259,10 @@ pub fn atomic_open_or_create_file<P: AsRef<Path>>(
                 err,
             )
         })?;
+        if fsync {
+            // make sure the initial_data is on disk
+            nix::unistd::fsync(file.as_raw_fd())?;
+        }
     }
 
     // rotate the file into place, but use `RENAME_NOREPLACE`, so in case 2 processes race against
@@ -623,6 +642,7 @@ pub fn open_file_locked<P: AsRef<Path>>(
         OFlag::O_RDWR | OFlag::O_CLOEXEC | OFlag::O_APPEND,
         &[],
         options,
+        false,
     )?;
 
     match lock_file(&mut file, exclusive, Some(timeout)) {
-- 
2.30.2





^ permalink raw reply	[flat|nested] 3+ messages in thread

* [pbs-devel] [PATCH proxmox-opendid] add fsync parameter to replace_file
  2021-10-20 13:00 [pbs-devel] [PATCH proxmox] add fsync parameter to replace_file and atomic_open_or_create Dietmar Maurer
@ 2021-10-20 13:00 ` Dietmar Maurer
  2021-10-20 13:00 ` [pbs-devel] [PATCH proxmox-backup] use new fsync parameter to replace_file and atomic_open_or_create Dietmar Maurer
  1 sibling, 0 replies; 3+ messages in thread
From: Dietmar Maurer @ 2021-10-20 13:00 UTC (permalink / raw)
  To: pbs-devel

---
 src/auth_state.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/auth_state.rs b/src/auth_state.rs
index dcf564d..f7c7cd0 100644
--- a/src/auth_state.rs
+++ b/src/auth_state.rs
@@ -62,7 +62,7 @@ fn replace_auth_state(
     let options = CreateOptions::new().perm(mode);
     let raw = serde_json::to_string_pretty(data)?;
 
-    replace_file(path, raw.as_bytes(), options)?;
+    replace_file(path, raw.as_bytes(), options, false)?;
 
     Ok(())
 }
-- 
2.30.2





^ permalink raw reply	[flat|nested] 3+ messages in thread

* [pbs-devel] [PATCH proxmox-backup] use new fsync parameter to replace_file and atomic_open_or_create
  2021-10-20 13:00 [pbs-devel] [PATCH proxmox] add fsync parameter to replace_file and atomic_open_or_create Dietmar Maurer
  2021-10-20 13:00 ` [pbs-devel] [PATCH proxmox-opendid] add fsync parameter to replace_file Dietmar Maurer
@ 2021-10-20 13:00 ` Dietmar Maurer
  1 sibling, 0 replies; 3+ messages in thread
From: Dietmar Maurer @ 2021-10-20 13:00 UTC (permalink / raw)
  To: pbs-devel

---
 pbs-client/src/http_client.rs          | 6 +++---
 pbs-client/src/tools/key_source.rs     | 4 ++--
 pbs-config/src/key_config.rs           | 2 +-
 pbs-config/src/lib.rs                  | 4 ++--
 pbs-config/src/memcom.rs               | 5 ++++-
 pbs-config/src/network/mod.rs          | 2 +-
 pbs-config/src/token_shadow.rs         | 2 +-
 pbs-datastore/src/chunk_store.rs       | 2 +-
 pbs-datastore/src/datastore.rs         | 4 ++--
 proxmox-backup-client/src/key.rs       | 6 +++---
 proxmox-backup-client/src/main.rs      | 4 ++--
 proxmox-rest-server/src/file_logger.rs | 2 +-
 proxmox-rest-server/src/lib.rs         | 2 +-
 proxmox-rest-server/src/worker_task.rs | 2 ++
 proxmox-rrd/src/cache/journal.rs       | 2 ++
 src/acme/client.rs                     | 1 +
 src/api2/admin/datastore.rs            | 4 ++--
 src/api2/backup/environment.rs         | 2 +-
 src/api2/node/apt.rs                   | 2 +-
 src/api2/node/dns.rs                   | 2 +-
 src/api2/node/time.rs                  | 2 +-
 src/api2/tape/restore.rs               | 2 +-
 src/auth.rs                            | 4 ++--
 src/auth_helpers.rs                    | 8 +++++++-
 src/config/tfa.rs                      | 2 +-
 src/server/jobstate.rs                 | 2 +-
 src/tape/changer/mod.rs                | 2 +-
 src/tape/drive/mod.rs                  | 3 ++-
 src/tape/drive/virtual_tape.rs         | 4 ++--
 src/tape/inventory.rs                  | 2 +-
 src/tape/media_catalog_cache.rs        | 1 +
 src/tools/apt.rs                       | 2 +-
 src/tools/subscription.rs              | 4 ++--
 src/tools/systemd/config.rs            | 2 +-
 34 files changed, 58 insertions(+), 42 deletions(-)

diff --git a/pbs-client/src/http_client.rs b/pbs-client/src/http_client.rs
index d135bc4f..73c83f7a 100644
--- a/pbs-client/src/http_client.rs
+++ b/pbs-client/src/http_client.rs
@@ -153,7 +153,7 @@ pub fn delete_ticket_info(prefix: &str, server: &str, username: &Userid) -> Resu
         map.remove(username.as_str());
     }
 
-    replace_file(path, data.to_string().as_bytes(), CreateOptions::new().perm(mode))?;
+    replace_file(path, data.to_string().as_bytes(), CreateOptions::new().perm(mode), false)?;
 
     Ok(())
 }
@@ -195,7 +195,7 @@ fn store_fingerprint(prefix: &str, server: &str, fingerprint: &str) -> Result<()
     result.push_str(fingerprint);
     result.push('\n');
 
-    replace_file(path, result.as_bytes(), CreateOptions::new())?;
+    replace_file(path, result.as_bytes(), CreateOptions::new(), false)?;
 
     Ok(())
 }
@@ -250,7 +250,7 @@ fn store_ticket_info(prefix: &str, server: &str, username: &str, ticket: &str, t
         }
     }
 
-    replace_file(path, new_data.to_string().as_bytes(), CreateOptions::new().perm(mode))?;
+    replace_file(path, new_data.to_string().as_bytes(), CreateOptions::new().perm(mode), false)?;
 
     Ok(())
 }
diff --git a/pbs-client/src/tools/key_source.rs b/pbs-client/src/tools/key_source.rs
index 32e2b264..8fb24bd1 100644
--- a/pbs-client/src/tools/key_source.rs
+++ b/pbs-client/src/tools/key_source.rs
@@ -440,8 +440,8 @@ fn test_crypto_parameters_handling() -> Result<(), Error> {
         mode: CryptMode::SignOnly,
     };
 
-    replace_file(&keypath, &some_key, CreateOptions::default())?;
-    replace_file(&master_keypath, &some_master_key, CreateOptions::default())?;
+    replace_file(&keypath, &some_key, CreateOptions::default(), false)?;
+    replace_file(&master_keypath, &some_master_key, CreateOptions::default(), false)?;
 
     // no params, no default key == no key
     let res = crypto_parameters(&json!({}));
diff --git a/pbs-config/src/key_config.rs b/pbs-config/src/key_config.rs
index 9c4b3b57..178b3b52 100644
--- a/pbs-config/src/key_config.rs
+++ b/pbs-config/src/key_config.rs
@@ -281,7 +281,7 @@ impl KeyConfig  {
         try_block!({
             if replace {
                 let mode = nix::sys::stat::Mode::S_IRUSR | nix::sys::stat::Mode::S_IWUSR;
-                replace_file(path, data.as_bytes(), CreateOptions::new().perm(mode))?;
+                replace_file(path, data.as_bytes(), CreateOptions::new().perm(mode), true)?;
             } else {
                 use std::os::unix::fs::OpenOptionsExt;
 
diff --git a/pbs-config/src/lib.rs b/pbs-config/src/lib.rs
index 478e0961..8ce84fec 100644
--- a/pbs-config/src/lib.rs
+++ b/pbs-config/src/lib.rs
@@ -80,7 +80,7 @@ pub fn replace_backup_config<P: AsRef<std::path::Path>>(
         .owner(nix::unistd::ROOT)
         .group(backup_user.gid);
 
-    proxmox::tools::fs::replace_file(path, data, options)?;
+    proxmox::tools::fs::replace_file(path, data, options, true)?;
 
     Ok(())
 }
@@ -100,7 +100,7 @@ pub fn replace_secret_config<P: AsRef<std::path::Path>>(
         .owner(nix::unistd::ROOT)
         .group(nix::unistd::Gid::from_raw(0));
 
-    proxmox::tools::fs::replace_file(path, data, options)?;
+    proxmox::tools::fs::replace_file(path, data, options, true)?;
 
     Ok(())
 }
diff --git a/pbs-config/src/memcom.rs b/pbs-config/src/memcom.rs
index 96b577b5..4ab07ec9 100644
--- a/pbs-config/src/memcom.rs
+++ b/pbs-config/src/memcom.rs
@@ -47,7 +47,10 @@ impl Memcom {
         let file = proxmox::tools::fs::atomic_open_or_create_file(
             MEMCOM_FILE_PATH,
             OFlag::O_RDWR | OFlag::O_CLOEXEC,
-            &EMPTY_PAGE, options)?;
+            &EMPTY_PAGE,
+            options,
+            true,
+        )?;
 
         let mmap = unsafe {
             Mmap::<u8>::map_fd(
diff --git a/pbs-config/src/network/mod.rs b/pbs-config/src/network/mod.rs
index fe2f4700..1c10ab31 100644
--- a/pbs-config/src/network/mod.rs
+++ b/pbs-config/src/network/mod.rs
@@ -448,7 +448,7 @@ pub fn save_config(config: &NetworkConfig) -> Result<(), Error> {
         .owner(nix::unistd::ROOT)
         .group(nix::unistd::Gid::from_raw(0));
 
-    replace_file(NETWORK_INTERFACES_NEW_FILENAME, &raw, options)?;
+    replace_file(NETWORK_INTERFACES_NEW_FILENAME, &raw, options, true)?;
 
     Ok(())
 }
diff --git a/pbs-config/src/token_shadow.rs b/pbs-config/src/token_shadow.rs
index 6e466ce5..f813b430 100644
--- a/pbs-config/src/token_shadow.rs
+++ b/pbs-config/src/token_shadow.rs
@@ -45,7 +45,7 @@ fn write_file(data: HashMap<Authid, String>) -> Result<(), Error> {
         .group(backup_user.gid);
 
     let json = serde_json::to_vec(&data)?;
-    proxmox::tools::fs::replace_file(CONF_FILE, &json, options)
+    proxmox::tools::fs::replace_file(CONF_FILE, &json, options, true)
 }
 
 
diff --git a/pbs-datastore/src/chunk_store.rs b/pbs-datastore/src/chunk_store.rs
index 963997f8..4c445019 100644
--- a/pbs-datastore/src/chunk_store.rs
+++ b/pbs-datastore/src/chunk_store.rs
@@ -95,7 +95,7 @@ impl ChunkStore {
 
         // create lock file with correct owner/group
         let lockfile_path = Self::lockfile_path(&base);
-        proxmox::tools::fs::replace_file(lockfile_path, b"", options.clone())?;
+        proxmox::tools::fs::replace_file(lockfile_path, b"", options.clone(), false)?;
 
         // create 64*1024 subdirs
         let mut last_percentage = 0;
diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs
index 79a2d9e8..7159e578 100644
--- a/pbs-datastore/src/datastore.rs
+++ b/pbs-datastore/src/datastore.rs
@@ -705,7 +705,7 @@ impl DataStore {
                     .group(backup_user.gid);
 
                 // ignore errors
-                let _ = replace_file(path, serialized.as_bytes(), options);
+                let _ = replace_file(path, serialized.as_bytes(), options, false);
             }
 
             *self.last_gc_status.lock().unwrap() = gc_status;
@@ -840,7 +840,7 @@ impl DataStore {
         path.push(MANIFEST_BLOB_NAME);
 
         // atomic replace invalidates flock - no other writes past this point!
-        replace_file(&path, raw_data, CreateOptions::new())?;
+        replace_file(&path, raw_data, CreateOptions::new(), false)?;
 
         Ok(())
     }
diff --git a/proxmox-backup-client/src/key.rs b/proxmox-backup-client/src/key.rs
index 2984c581..0b99a888 100644
--- a/proxmox-backup-client/src/key.rs
+++ b/proxmox-backup-client/src/key.rs
@@ -315,7 +315,7 @@ fn import_master_pubkey(path: String) -> Result<(), Error> {
 
     let target_path = place_default_master_pubkey()?;
 
-    replace_file(&target_path, &pem_data, CreateOptions::new())?;
+    replace_file(&target_path, &pem_data, CreateOptions::new(), true)?;
 
     println!("Imported public master key to {:?}", target_path);
 
@@ -348,7 +348,7 @@ fn create_master_key() -> Result<(), Error> {
     let pub_key: Vec<u8> = pkey.public_key_to_pem()?;
     let filename_pub = "master-public.pem";
     println!("Writing public master key to {}", filename_pub);
-    replace_file(filename_pub, pub_key.as_slice(), CreateOptions::new())?;
+    replace_file(filename_pub, pub_key.as_slice(), CreateOptions::new(), true)?;
 
     let cipher = openssl::symm::Cipher::aes_256_cbc();
     let priv_key: Vec<u8> =
@@ -356,7 +356,7 @@ fn create_master_key() -> Result<(), Error> {
 
     let filename_priv = "master-private.pem";
     println!("Writing private master key to {}", filename_priv);
-    replace_file(filename_priv, priv_key.as_slice(), CreateOptions::new())?;
+    replace_file(filename_priv, priv_key.as_slice(), CreateOptions::new(), true)?;
 
     Ok(())
 }
diff --git a/proxmox-backup-client/src/main.rs b/proxmox-backup-client/src/main.rs
index 0ad16b42..cb083006 100644
--- a/proxmox-backup-client/src/main.rs
+++ b/proxmox-backup-client/src/main.rs
@@ -126,7 +126,7 @@ fn record_repository(repo: &BackupRepository) {
 
     let new_data = json!(map);
 
-    let _ = replace_file(path, new_data.to_string().as_bytes(), CreateOptions::new());
+    let _ = replace_file(path, new_data.to_string().as_bytes(), CreateOptions::new(), false);
 }
 
 async fn api_datastore_list_snapshots(
@@ -1132,7 +1132,7 @@ async fn restore(param: Value) -> Result<Value, Error> {
 
     if archive_name == MANIFEST_BLOB_NAME {
         if let Some(target) = target {
-            replace_file(target, &backup_index_data, CreateOptions::new())?;
+            replace_file(target, &backup_index_data, CreateOptions::new(), false)?;
         } else {
             let stdout = std::io::stdout();
             let mut writer = stdout.lock();
diff --git a/proxmox-rest-server/src/file_logger.rs b/proxmox-rest-server/src/file_logger.rs
index 79972d32..c7496874 100644
--- a/proxmox-rest-server/src/file_logger.rs
+++ b/proxmox-rest-server/src/file_logger.rs
@@ -95,7 +95,7 @@ impl FileLogger {
             flags |=  OFlag::O_EXCL;
         }
 
-        let file = atomic_open_or_create_file(&file_name, flags, &[], options.file_opts.clone())?;
+        let file = atomic_open_or_create_file(&file_name, flags, &[], options.file_opts.clone(), false)?;
 
         Ok(file)
     }
diff --git a/proxmox-rest-server/src/lib.rs b/proxmox-rest-server/src/lib.rs
index 6e7c94f2..1a6d827d 100644
--- a/proxmox-rest-server/src/lib.rs
+++ b/proxmox-rest-server/src/lib.rs
@@ -117,7 +117,7 @@ pub(crate) fn pstart() -> u64 {
 /// Helper to write the PID into a file
 pub fn write_pid(pid_fn: &str) -> Result<(), Error> {
     let pid_str = format!("{}\n", *PID);
-    proxmox::tools::fs::replace_file(pid_fn, pid_str.as_bytes(), CreateOptions::new())
+    proxmox::tools::fs::replace_file(pid_fn, pid_str.as_bytes(), CreateOptions::new(), false)
 }
 
 /// Helper to read the PID from a file
diff --git a/proxmox-rest-server/src/worker_task.rs b/proxmox-rest-server/src/worker_task.rs
index fb0dea9b..242d2de2 100644
--- a/proxmox-rest-server/src/worker_task.rs
+++ b/proxmox-rest-server/src/worker_task.rs
@@ -146,6 +146,7 @@ impl WorkerTaskSetup {
             &self.active_tasks_fn,
             active_raw.as_bytes(),
             options,
+            false,
         )?;
 
         finish_list.sort_unstable_by(|a, b| {
@@ -166,6 +167,7 @@ impl WorkerTaskSetup {
                 OFlag::O_APPEND | OFlag::O_RDWR,
                 &[],
                 options,
+                false,
             )?;
             for info in &finish_list {
                 writer.write_all(render_task_line(&info).as_bytes())?;
diff --git a/proxmox-rrd/src/cache/journal.rs b/proxmox-rrd/src/cache/journal.rs
index 85e3906a..a85154a4 100644
--- a/proxmox-rrd/src/cache/journal.rs
+++ b/proxmox-rrd/src/cache/journal.rs
@@ -113,6 +113,7 @@ impl JournalState {
             flags,
             &[],
             self.config.file_options.clone(),
+            false,
         )?;
         Ok(BufReader::new(journal))
     }
@@ -127,6 +128,7 @@ impl JournalState {
             flags,
             &[],
             config.file_options.clone(),
+            false,
         )?;
         Ok(journal)
     }
diff --git a/src/acme/client.rs b/src/acme/client.rs
index 48ae6112..ee04edad 100644
--- a/src/acme/client.rs
+++ b/src/acme/client.rs
@@ -171,6 +171,7 @@ impl AcmeClient {
                 .perm(Mode::from_bits_truncate(0o600))
                 .owner(nix::unistd::ROOT)
                 .group(nix::unistd::Gid::from_raw(0)),
+            true,
         )
     }
 
diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs
index fb5647ce..3bf8e104 100644
--- a/src/api2/admin/datastore.rs
+++ b/src/api2/admin/datastore.rs
@@ -1328,7 +1328,7 @@ pub fn upload_backup_log(
         // always verify blob/CRC at server side
         let blob = DataBlob::load_from_reader(&mut &data[..])?;
 
-        replace_file(&path, blob.raw_data(), CreateOptions::new())?;
+        replace_file(&path, blob.raw_data(), CreateOptions::new(), false)?;
 
         // fixme: use correct formatter
         Ok(formatter::JSON_FORMATTER.format_data(Value::Null, &*rpcenv))
@@ -1644,7 +1644,7 @@ pub fn set_group_notes(
     check_priv_or_backup_owner(&datastore, &backup_group, &auth_id, PRIV_DATASTORE_MODIFY)?;
 
     let note_path = get_group_note_path(&datastore, &backup_group);
-    replace_file(note_path, notes.as_bytes(), CreateOptions::new())?;
+    replace_file(note_path, notes.as_bytes(), CreateOptions::new(), false)?;
 
     Ok(())
 }
diff --git a/src/api2/backup/environment.rs b/src/api2/backup/environment.rs
index 5906cb57..9cfc5534 100644
--- a/src/api2/backup/environment.rs
+++ b/src/api2/backup/environment.rs
@@ -453,7 +453,7 @@ impl BackupEnvironment {
         let blob = DataBlob::load_from_reader(&mut &data[..])?;
 
         let raw_data = blob.raw_data();
-        replace_file(&path, raw_data, CreateOptions::new())?;
+        replace_file(&path, raw_data, CreateOptions::new(), false)?;
 
         self.log(format!("add blob {:?} ({} bytes, comp: {})", path, orig_len, blob_len));
 
diff --git a/src/api2/node/apt.rs b/src/api2/node/apt.rs
index 46d015b9..a31e73a1 100644
--- a/src/api2/node/apt.rs
+++ b/src/api2/node/apt.rs
@@ -68,7 +68,7 @@ pub fn update_apt_proxy_config(proxy_config: Option<&ProxyConfig>) -> Result<(),
     if let Some(proxy_config) = proxy_config {
         let proxy = proxy_config.to_proxy_string()?;
         let data = format!("Acquire::http::Proxy \"{}\";\n", proxy);
-        replace_file(PROXY_CFG_FN, data.as_bytes(), CreateOptions::new())
+        replace_file(PROXY_CFG_FN, data.as_bytes(), CreateOptions::new(), false)
     } else {
         match std::fs::remove_file(PROXY_CFG_FN) {
             Ok(()) => Ok(()),
diff --git a/src/api2/node/dns.rs b/src/api2/node/dns.rs
index 34a42a65..ff04a5e3 100644
--- a/src/api2/node/dns.rs
+++ b/src/api2/node/dns.rs
@@ -171,7 +171,7 @@ pub fn update_dns(
         data.push_str(options);
     }
 
-    replace_file(RESOLV_CONF_FN, data.as_bytes(), CreateOptions::new())?;
+    replace_file(RESOLV_CONF_FN, data.as_bytes(), CreateOptions::new(), true)?;
 
     Ok(Value::Null)
 }
diff --git a/src/api2/node/time.rs b/src/api2/node/time.rs
index d17c7f72..b58f1dd2 100644
--- a/src/api2/node/time.rs
+++ b/src/api2/node/time.rs
@@ -97,7 +97,7 @@ fn set_timezone(
         bail!("No such timezone.");
     }
 
-    replace_file("/etc/timezone", timezone.as_bytes(), CreateOptions::new())?;
+    replace_file("/etc/timezone", timezone.as_bytes(), CreateOptions::new(), true)?;
 
     let _ = std::fs::remove_file("/etc/localtime");
 
diff --git a/src/api2/tape/restore.rs b/src/api2/tape/restore.rs
index 30e99343..40a2414f 100644
--- a/src/api2/tape/restore.rs
+++ b/src/api2/tape/restore.rs
@@ -1362,7 +1362,7 @@ fn try_restore_snapshot_archive<R: pxar::decoder::SeqRead>(
             let blob = DataBlob::encode(old_manifest.as_bytes(), None, true)?;
 
             let options = CreateOptions::new();
-            replace_file(&tmp_path, blob.raw_data(), options)?;
+            replace_file(&tmp_path, blob.raw_data(), options, false)?;
 
             manifest = Some(BackupManifest::try_from(blob)?);
         } else {
diff --git a/src/auth.rs b/src/auth.rs
index 215cd9aa..1560d565 100644
--- a/src/auth.rs
+++ b/src/auth.rs
@@ -95,7 +95,7 @@ impl ProxmoxAuthenticator for PBS {
             .group(nix::unistd::Gid::from_raw(0));
 
         let data = serde_json::to_vec_pretty(&data)?;
-        proxmox::tools::fs::replace_file(SHADOW_CONFIG_FILENAME, &data, options)?;
+        proxmox::tools::fs::replace_file(SHADOW_CONFIG_FILENAME, &data, options, true)?;
 
         Ok(())
     }
@@ -113,7 +113,7 @@ impl ProxmoxAuthenticator for PBS {
             .group(nix::unistd::Gid::from_raw(0));
 
         let data = serde_json::to_vec_pretty(&data)?;
-        proxmox::tools::fs::replace_file(SHADOW_CONFIG_FILENAME, &data, options)?;
+        proxmox::tools::fs::replace_file(SHADOW_CONFIG_FILENAME, &data, options, true)?;
 
         Ok(())
     }
diff --git a/src/auth_helpers.rs b/src/auth_helpers.rs
index a4ac956e..f15c0eab 100644
--- a/src/auth_helpers.rs
+++ b/src/auth_helpers.rs
@@ -104,6 +104,7 @@ pub fn generate_csrf_key() -> Result<(), Error> {
             .perm(Mode::from_bits_truncate(0o0640))
             .owner(nix::unistd::ROOT)
             .group(backup_user.gid),
+        true,
     )?;
 
     Ok(())
@@ -125,7 +126,11 @@ pub fn generate_auth_key() -> Result<(), Error> {
     use nix::sys::stat::Mode;
 
     replace_file(
-        &priv_path, &priv_pem, CreateOptions::new().perm(Mode::from_bits_truncate(0o0600)))?;
+        &priv_path,
+        &priv_pem,
+        CreateOptions::new().perm(Mode::from_bits_truncate(0o0600)),
+        true,
+    )?;
 
     let public_pem = rsa.public_key_to_pem()?;
 
@@ -138,6 +143,7 @@ pub fn generate_auth_key() -> Result<(), Error> {
             .perm(Mode::from_bits_truncate(0o0640))
             .owner(nix::unistd::ROOT)
             .group(backup_user.gid),
+        true,
     )?;
 
     Ok(())
diff --git a/src/config/tfa.rs b/src/config/tfa.rs
index 2a41cbdf..dae0f31c 100644
--- a/src/config/tfa.rs
+++ b/src/config/tfa.rs
@@ -76,7 +76,7 @@ pub fn write(data: &TfaConfig) -> Result<(), Error> {
     let options = CreateOptions::new().perm(Mode::from_bits_truncate(0o0600));
 
     let json = serde_json::to_vec(data)?;
-    proxmox::tools::fs::replace_file(CONF_FILE, &json, options)
+    proxmox::tools::fs::replace_file(CONF_FILE, &json, options, true)
 }
 
 #[derive(Deserialize, Serialize)]
diff --git a/src/server/jobstate.rs b/src/server/jobstate.rs
index 1377470d..8df245d6 100644
--- a/src/server/jobstate.rs
+++ b/src/server/jobstate.rs
@@ -301,7 +301,7 @@ impl Job {
             .owner(backup_user.uid)
             .group(backup_user.gid);
 
-        replace_file(path, serialized.as_bytes(), options)
+        replace_file(path, serialized.as_bytes(), options, false)
     }
 }
 
diff --git a/src/tape/changer/mod.rs b/src/tape/changer/mod.rs
index cc9ee734..63c54b41 100644
--- a/src/tape/changer/mod.rs
+++ b/src/tape/changer/mod.rs
@@ -345,7 +345,7 @@ fn save_changer_state_cache(
         .owner(backup_user.uid)
         .group(backup_user.gid);
 
-    replace_file(path, state.as_bytes(), options)
+    replace_file(path, state.as_bytes(), options, false)
 }
 
 fn delete_changer_state_cache(changer: &str) {
diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs
index 16845973..df990ccf 100644
--- a/src/tape/drive/mod.rs
+++ b/src/tape/drive/mod.rs
@@ -555,7 +555,7 @@ pub fn set_tape_device_state(
         .owner(backup_user.uid)
         .group(backup_user.gid);
 
-    replace_file(path, state.as_bytes(), options)
+    replace_file(path, state.as_bytes(), options, false)
 }
 
 /// Get the device state
@@ -618,6 +618,7 @@ fn open_device_lock(device_path: &str) -> Result<std::fs::File, Error> {
         OFlag::O_RDWR | OFlag::O_CLOEXEC | OFlag::O_APPEND,
         &[],
         options,
+        false,
     )
 }
 
diff --git a/src/tape/drive/virtual_tape.rs b/src/tape/drive/virtual_tape.rs
index 0cc8ae70..4f1fe4d8 100644
--- a/src/tape/drive/virtual_tape.rs
+++ b/src/tape/drive/virtual_tape.rs
@@ -117,7 +117,7 @@ impl VirtualTapeHandle {
         let raw = serde_json::to_string_pretty(&serde_json::to_value(index)?)?;
 
         let options = CreateOptions::new();
-        replace_file(&path, raw.as_bytes(), options)?;
+        replace_file(&path, raw.as_bytes(), options, false)?;
         Ok(())
     }
 
@@ -157,7 +157,7 @@ impl VirtualTapeHandle {
         let raw = serde_json::to_string_pretty(&serde_json::to_value(status)?)?;
 
         let options = CreateOptions::new();
-        replace_file(&path, raw.as_bytes(), options)?;
+        replace_file(&path, raw.as_bytes(), options, false)?;
         Ok(())
     }
 
diff --git a/src/tape/inventory.rs b/src/tape/inventory.rs
index 593985ed..86588617 100644
--- a/src/tape/inventory.rs
+++ b/src/tape/inventory.rs
@@ -183,7 +183,7 @@ impl Inventory {
                 .group(backup_user.gid)
         };
 
-        replace_file(&self.inventory_path, raw.as_bytes(), options)?;
+        replace_file(&self.inventory_path, raw.as_bytes(), options, true)?;
 
         Ok(())
     }
diff --git a/src/tape/media_catalog_cache.rs b/src/tape/media_catalog_cache.rs
index 6593833d..bcfdd700 100644
--- a/src/tape/media_catalog_cache.rs
+++ b/src/tape/media_catalog_cache.rs
@@ -102,6 +102,7 @@ fn write_snapshot_cache(
         cache_path,
         data.as_bytes(),
         options,
+        false,
     )?;
 
     Ok(list)
diff --git a/src/tools/apt.rs b/src/tools/apt.rs
index 209274a8..1ffaaa6a 100644
--- a/src/tools/apt.rs
+++ b/src/tools/apt.rs
@@ -24,7 +24,7 @@ pub struct PkgState {
 pub fn write_pkg_cache(state: &PkgState) -> Result<(), Error> {
     let serialized_state = serde_json::to_string(state)?;
 
-    replace_file(APT_PKG_STATE_FN, &serialized_state.as_bytes(), CreateOptions::new())
+    replace_file(APT_PKG_STATE_FN, &serialized_state.as_bytes(), CreateOptions::new(), false)
         .map_err(|err| format_err!("Error writing package cache - {}", err))?;
     Ok(())
 }
diff --git a/src/tools/subscription.rs b/src/tools/subscription.rs
index 1a9ada66..5b1e6b63 100644
--- a/src/tools/subscription.rs
+++ b/src/tools/subscription.rs
@@ -312,7 +312,7 @@ pub fn write_subscription(info: SubscriptionInfo) -> Result<(), Error> {
         .group(backup_user.gid);
 
     let subscription_file = std::path::Path::new(SUBSCRIPTION_FN);
-    replace_file(subscription_file, raw.as_bytes(), file_opts)?;
+    replace_file(subscription_file, raw.as_bytes(), file_opts, true)?;
 
     update_apt_auth(key, server_id)?;
 
@@ -343,7 +343,7 @@ pub fn update_apt_auth(key: Option<String>, password: Option<String>) -> Result<
                 .owner(nix::unistd::ROOT);
 
             // we use a namespaced .conf file, so just overwrite..
-            replace_file(auth_conf, conf.as_bytes(), file_opts)
+            replace_file(auth_conf, conf.as_bytes(), file_opts, true)
                 .map_err(|e| format_err!("Error saving apt auth config - {}", e))?;
         }
         _ => match nix::unistd::unlink(auth_conf) {
diff --git a/src/tools/systemd/config.rs b/src/tools/systemd/config.rs
index ed95bcff..baf94e88 100644
--- a/src/tools/systemd/config.rs
+++ b/src/tools/systemd/config.rs
@@ -133,7 +133,7 @@ fn save_systemd_config(config: &SectionConfig, filename: &str, data: &SectionCon
         .perm(mode)
         .owner(nix::unistd::ROOT);
 
-    replace_file(filename, raw.as_bytes(), options)?;
+    replace_file(filename, raw.as_bytes(), options, true)?;
 
     Ok(())
 }
-- 
2.30.2





^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-10-20 13:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-20 13:00 [pbs-devel] [PATCH proxmox] add fsync parameter to replace_file and atomic_open_or_create Dietmar Maurer
2021-10-20 13:00 ` [pbs-devel] [PATCH proxmox-opendid] add fsync parameter to replace_file Dietmar Maurer
2021-10-20 13:00 ` [pbs-devel] [PATCH proxmox-backup] use new fsync parameter to replace_file and atomic_open_or_create Dietmar Maurer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal