From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id B41831FF135 for ; Thu, 02 Jul 2026 11:23:19 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 2542821407; Thu, 02 Jul 2026 11:23:19 +0200 (CEST) From: Lukas Wagner To: pdm-devel@lists.proxmox.com Subject: [PATCH proxmox 01/15] sys: fs: don't replace file extension make_tmp_file Date: Thu, 2 Jul 2026 11:22:44 +0200 Message-ID: <20260702092258.174740-2-l.wagner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260702092258.174740-1-l.wagner@proxmox.com> References: <20260702092258.174740-1-l.wagner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1782984189330 X-SPAM-LEVEL: Spam detection results: 0 DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: OBGFMTTMQ3UQUZOK2NKCWR4RVVHF7UAH X-Message-ID-Hash: OBGFMTTMQ3UQUZOK2NKCWR4RVVHF7UAH X-MailFrom: l.wagner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Datacenter Manager development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Rather than creating the template path used by mkostemp by replacing the existing file extension, use `add_extension` to append to any existing one. We often provide the path of some original file that is later to be replaced by the temporary one, and therefore having the full original filename intact is a benefit for debugability in case there are leftover temporary files. For instance, the task archive in PDM uses the following file name schema: `archive.{timestamp}[.zst]`. Archive files are atomically replaced by using make_tmp_file and rename, however due to using `set_extension` before, the `{timestamp}[.zst]` part would be lost. Signed-off-by: Lukas Wagner --- proxmox-sys/src/fs/file.rs | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/proxmox-sys/src/fs/file.rs b/proxmox-sys/src/fs/file.rs index f0939381..3336156b 100644 --- a/proxmox-sys/src/fs/file.rs +++ b/proxmox-sys/src/fs/file.rs @@ -149,7 +149,7 @@ pub fn make_tmp_file>( // use mkstemp here, because it works with different processes, threads, even tokio tasks let mut template = path.to_owned(); - template.set_extension("tmp_XXXXXX"); + template.add_extension("tmp_XXXXXX"); let (mut file, tmp_path) = match mkostemp(&template, OFlag::O_CLOEXEC) { Ok((fd, path)) => (unsafe { File::from_raw_fd(fd) }, path), Err(err) => bail!("mkstemp {:?} failed: {}", template, err), @@ -466,3 +466,35 @@ pub fn file_get_non_comment_lines>( Err(err) => Some(Err(err)), })) } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn make_tmp_file_does_not_replace_extension() { + let (_, path) = make_tmp_file("/tmp/proxmox-sys-test.json", CreateOptions::new()).unwrap(); + + assert!( + &path + .file_name() + .unwrap() + .to_string_lossy() + .contains("proxmox-sys-test.json") + ); + + let (_, path) = make_tmp_file( + "/tmp/proxmox-sys-test.archive.1000.zst", + CreateOptions::new(), + ) + .unwrap(); + + assert!( + &path + .file_name() + .unwrap() + .to_string_lossy() + .contains("archive.1000.zst") + ); + } +} -- 2.47.3