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 4794C1FF09B for ; Mon, 28 Sep 2026 15:14:11 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id BC704216D2; Mon, 28 Sep 2026 15:14:10 +0200 (CEST) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup] tape: labeling: improve error message for tapes with existing data Date: Mon, 28 Sep 2026 15:13:56 +0200 Message-ID: <20260928131405.3659144-1-d.csapak@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.425 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) 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 Message-ID-Hash: BZ3WEOGV44NXY2NRXBN3XXL5XFRUV733 X-Message-ID-Hash: BZ3WEOGV44NXY2NRXBN3XXL5XFRUV733 X-MailFrom: d.csapak@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 Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: A tape used by e.g. tar, has a different block length structure than what we expect. When labeling such tape, reading the existing tape errors out with 'read failed - unexpected block len' which does not give the user any hint what might be wrong if they're not familiar with inner workings of our tape code. Instead, introduce a new error variant in our BlockReadError which we can use to return an improved error message, namely the same one when the user tries to label an already labeled tape with the hint that it has to be formatted first. Leave the error handling the same on all other paths, by either converting into an `io::Error` or an `anyhow::Error`. Signed-off-by: Dominik Csapak --- pbs-tape/src/blocked_reader.rs | 2 ++ pbs-tape/src/sg_tape.rs | 6 +----- pbs-tape/src/tape_read.rs | 2 ++ src/api2/tape/drive.rs | 4 +++- src/api2/tape/restore.rs | 2 ++ src/bin/proxmox-tape.rs | 1 + src/tape/drive/mod.rs | 2 ++ 7 files changed, 13 insertions(+), 6 deletions(-) diff --git a/pbs-tape/src/blocked_reader.rs b/pbs-tape/src/blocked_reader.rs index 22803371c..fd07b8056 100644 --- a/pbs-tape/src/blocked_reader.rs +++ b/pbs-tape/src/blocked_reader.rs @@ -119,6 +119,7 @@ impl BlockedReader { proxmox_lang::io_bail!("got unexpected end of tape"); } Err(BlockReadError::Error(err)) => Err(err), + Err(err) => proxmox_lang::io_bail!("{err}"), } } @@ -139,6 +140,7 @@ impl BlockedReader { Err(BlockReadError::Error(err)) => { return Err(err); } + Err(err) => proxmox_lang::io_bail!("{err}"), } let (size, found_end_marker) = Self::check_buffer(&self.buffer, self.seq_nr)?; diff --git a/pbs-tape/src/sg_tape.rs b/pbs-tape/src/sg_tape.rs index 3fc6873a8..a98e8960a 100644 --- a/pbs-tape/src/sg_tape.rs +++ b/pbs-tape/src/sg_tape.rs @@ -840,11 +840,7 @@ impl SgTape { }; if data.len() != transfer_len { - return Err(BlockReadError::Error(proxmox_lang::io_format_err!( - "read failed - unexpected block len ({} != {})", - data.len(), - buffer.len() - ))); + return Err(BlockReadError::InvalidBlockSize(data.len(), buffer.len())); } Ok(transfer_len) diff --git a/pbs-tape/src/tape_read.rs b/pbs-tape/src/tape_read.rs index 8142081c2..2cef58e96 100644 --- a/pbs-tape/src/tape_read.rs +++ b/pbs-tape/src/tape_read.rs @@ -29,6 +29,8 @@ pub enum BlockReadError { EndOfFile, #[error("end of data stream")] EndOfStream, + #[error("read failed - unexpected block len ({0} != {1})")] + InvalidBlockSize(usize, usize), } /// Read streams of blocks diff --git a/src/api2/tape/drive.rs b/src/api2/tape/drive.rs index 7381c1b2e..79b3b269c 100644 --- a/src/api2/tape/drive.rs +++ b/src/api2/tape/drive.rs @@ -505,7 +505,9 @@ pub fn label_media( drive.rewind()?; match drive.read_next_file() { - Ok(_reader) => bail!("media is not empty (format it first)"), + Ok(_) | Err(BlockReadError::InvalidBlockSize(_, _)) => { + bail!("media is not empty (format it first)") + } Err(BlockReadError::EndOfFile) => { /* EOF mark at BOT, assume tape is empty */ } Err(BlockReadError::EndOfStream) => { /* tape is empty */ } Err(err) => { diff --git a/src/api2/tape/restore.rs b/src/api2/tape/restore.rs index 64c4251bc..6544aa726 100644 --- a/src/api2/tape/restore.rs +++ b/src/api2/tape/restore.rs @@ -1310,6 +1310,7 @@ pub fn restore_media( Err(BlockReadError::Error(err)) => { return Err(err.into()); } + Err(err) => return Err(err.into()), Ok(reader) => reader, }; @@ -1813,6 +1814,7 @@ pub fn fast_catalog_restore( Err(BlockReadError::Error(err)) => { return Err(err.into()); } + Err(err) => return Err(err.into()), Ok(reader) => reader, }; diff --git a/src/bin/proxmox-tape.rs b/src/bin/proxmox-tape.rs index 0cb98d45d..dcbf2d0fb 100644 --- a/src/bin/proxmox-tape.rs +++ b/src/bin/proxmox-tape.rs @@ -600,6 +600,7 @@ fn debug_scan(mut param: Value) -> Result<(), Error> { Err(BlockReadError::Error(err)) => { return Err(err.into()); } + Err(err) => return Err(err.into()), Ok(mut reader) => { println!("got file number {file_number}"); diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs index 051977240..fa84fd54a 100644 --- a/src/tape/drive/mod.rs +++ b/src/tape/drive/mod.rs @@ -124,6 +124,7 @@ pub trait TapeDriver { Err(BlockReadError::Error(err)) => { return Err(err.into()); } + Err(err) => return Err(err.into()), Ok(reader) => reader, }; @@ -158,6 +159,7 @@ pub trait TapeDriver { Err(BlockReadError::Error(err)) => { return Err(err.into()); } + Err(err) => return Err(err.into()), Ok(reader) => reader, }; -- 2.47.3