From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pbs-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 1906D1FF170 for <inbox@lore.proxmox.com>; Thu, 29 May 2025 16:33:05 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 2AD2016531; Thu, 29 May 2025 16:33:11 +0200 (CEST) From: Christian Ebner <c.ebner@proxmox.com> To: pbs-devel@lists.proxmox.com Date: Thu, 29 May 2025 16:31:54 +0200 Message-Id: <20250529143207.694497-30-c.ebner@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250529143207.694497-1-c.ebner@proxmox.com> References: <20250529143207.694497-1-c.ebner@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.033 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [RFC v2 proxmox-backup 29/42] datastore: create/delete protected marker file on S3 storage backend X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion <pbs-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pbs-devel>, <mailto:pbs-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pbs-devel/> List-Post: <mailto:pbs-devel@lists.proxmox.com> List-Help: <mailto:pbs-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel>, <mailto:pbs-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox Backup Server development discussion <pbs-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pbs-devel-bounces@lists.proxmox.com Sender: "pbs-devel" <pbs-devel-bounces@lists.proxmox.com> Commit 8292d3d2 ("api2/admin/datastore: add get/set_protection") introduced the protected flag for backup snapshots, considering snapshots as protected based on the presence/absence of the `.protected` marker file in the corresponding snapshot directory. To allow independent recovery of a datastore backed by an S3 bucket, also create/delete the marker file on the object store backend. For actual checks, still rely on the marker as encountered in the local cache store. Signed-off-by: Christian Ebner <c.ebner@proxmox.com> --- pbs-datastore/src/datastore.rs | 45 ++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs index ab5c22501..5c8b49947 100644 --- a/pbs-datastore/src/datastore.rs +++ b/pbs-datastore/src/datastore.rs @@ -1539,12 +1539,47 @@ impl DataStore { let protected_path = backup_dir.protected_file(); if protection { - std::fs::File::create(protected_path) + std::fs::File::create(&protected_path) .map_err(|err| format_err!("could not create protection file: {}", err))?; - } else if let Err(err) = std::fs::remove_file(protected_path) { - // ignore error for non-existing file - if err.kind() != std::io::ErrorKind::NotFound { - bail!("could not remove protection file: {}", err); + if let DatastoreBackend::S3(s3_client) = self.backend()? { + let marker = backup_dir.relative_path().join(".protected"); + let protected_marker = marker + .to_str() + .ok_or_else(|| format_err!("unexpected protected marker path"))?; + let response = proxmox_async::runtime::block_on( + s3_client.put_object(protected_marker.into(), hyper::body::Body::empty()), + )?; + match response { + PutObjectResponse::NeedsRetry => { + let _ = std::fs::remove_file(protected_path); + bail!("failed to mark snapshot as protected, needs retry") + } + PutObjectResponse::PreconditionFailed => { + let _ = std::fs::remove_file(protected_path); + bail!("failed to mark snapshot as protected, precondition failed") + } + PutObjectResponse::Success(_) => (), + } + } + } else { + if let Err(err) = std::fs::remove_file(&protected_path) { + // ignore error for non-existing file + if err.kind() != std::io::ErrorKind::NotFound { + bail!("could not remove protection file: {err}"); + } + } + if let DatastoreBackend::S3(s3_client) = self.backend()? { + let marker = backup_dir.relative_path().join(".protected"); + let protected_marker = marker + .to_str() + .ok_or_else(|| format_err!("unexpected protected marker path"))?; + if let Err(err) = proxmox_async::runtime::block_on( + s3_client.delete_object(protected_marker.into()), + ) { + std::fs::File::create(&protected_path) + .map_err(|err| format_err!("could not re-create protection file: {err}"))?; + return Err(err); + } } } -- 2.39.5 _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel