From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id C2087691A7 for ; Tue, 4 Aug 2020 12:42:58 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id B8504BE12 for ; Tue, 4 Aug 2020 12:42:28 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 78839BD9F for ; Tue, 4 Aug 2020 12:42:24 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 3F38B43456 for ; Tue, 4 Aug 2020 12:42:24 +0200 (CEST) From: Stefan Reiter To: pbs-devel@lists.proxmox.com Date: Tue, 4 Aug 2020 12:42:05 +0200 Message-Id: <20200804104205.29540-8-s.reiter@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200804104205.29540-1-s.reiter@proxmox.com> References: <20200804104205.29540-1-s.reiter@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.054 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [environment.rs, backup.rs] Subject: [pbs-devel] [PATCH proxmox-backup 7/7] backup: lock base snapshot and ensure existance on finish X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Aug 2020 10:42:58 -0000 To prevent forgetting the base snapshot of a running backup, and catch the case when it still happens (e.g. via manual rm) to at least error out instead of storing a potentially invalid backup. Signed-off-by: Stefan Reiter --- src/api2/backup.rs | 10 ++++++++-- src/api2/backup/environment.rs | 10 ++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/api2/backup.rs b/src/api2/backup.rs index 4b751e3e..2973864a 100644 --- a/src/api2/backup.rs +++ b/src/api2/backup.rs @@ -100,11 +100,16 @@ async move { let last_backup = BackupInfo::last_backup(&datastore.base_path(), &backup_group, true).unwrap_or(None); let backup_dir = BackupDir::new_with_group(backup_group.clone(), backup_time); - if let Some(last) = &last_backup { + let _last_guard = if let Some(last) = &last_backup { if backup_dir.backup_time() <= last.backup_dir.backup_time() { bail!("backup timestamp is older than last backup."); } - } + + // lock last snapshot to prevent forgetting/pruning it during backup + Some(last.lock()) + } else { + None + }; let (path, is_new, _snap_guard) = datastore.create_locked_backup_dir(&backup_dir)?; if !is_new { bail!("backup directory already exists."); } @@ -147,6 +152,7 @@ async move { // keep flock until task ends let _group_guard = _group_guard; let _snap_guard = _snap_guard; + let _last_guard = _last_guard; let res = select!{ req = req_fut => req, diff --git a/src/api2/backup/environment.rs b/src/api2/backup/environment.rs index aa039cd9..dffca562 100644 --- a/src/api2/backup/environment.rs +++ b/src/api2/backup/environment.rs @@ -479,6 +479,16 @@ impl BackupEnvironment { self.datastore.store_manifest(&self.backup_dir, manifest) .map_err(|err| format_err!("unable to store manifest blob - {}", err))?; + if let Some(base) = &self.last_backup { + let path = self.datastore.snapshot_path(&base.backup_dir); + if !path.exists() { + bail!( + "base snapshot {} was removed during backup, cannot finish as chunks might be missing", + base.backup_dir + ); + } + } + // marks the backup as successful state.finished = true; -- 2.20.1