* [pbs-devel] [PATCH proxmox-backup v3] tape: fix LTO locate_file for HP drives
@ 2021-06-29 6:35 Dietmar Maurer
2021-06-30 7:13 ` [pbs-devel] applied: " Dietmar Maurer
0 siblings, 1 reply; 2+ messages in thread
From: Dietmar Maurer @ 2021-06-29 6:35 UTC (permalink / raw)
To: pbs-devel
Add test code to the first locate_file command, compute locate_offset.
Subsequent locate_file commands use that offset.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
This is based on Dominiks patches:
[PATCH proxmox-backup v2 1/2] tape/drive: add 'set_locate_offset' to TapeDriver Trait
[PATCH proxmox-backup v2 2/2] api2/tape/restore: use file offset to compensate for some tape drives
Canges in v3:
- Do not mofify the TapeDriver Trait. Instzead, do everything inside sg_tage.rs
- Add special case for locate_file(1)
src/tape/drive/lto/sg_tape.rs | 69 +++++++++++++++++++++++++++++++----
1 file changed, 61 insertions(+), 8 deletions(-)
diff --git a/src/tape/drive/lto/sg_tape.rs b/src/tape/drive/lto/sg_tape.rs
index 25c239a2..4508f6f3 100644
--- a/src/tape/drive/lto/sg_tape.rs
+++ b/src/tape/drive/lto/sg_tape.rs
@@ -3,6 +3,7 @@ use std::fs::{File, OpenOptions};
use std::os::unix::fs::OpenOptionsExt;
use std::os::unix::io::AsRawFd;
use std::path::Path;
+use std::convert::TryFrom;
use anyhow::{bail, format_err, Error};
use endian_trait::Endian;
@@ -122,6 +123,7 @@ pub struct LtoTapeStatus {
pub struct SgTape {
file: File,
+ locate_offset: Option<i64>,
info: InquiryInfo,
encryption_key_loaded: bool,
}
@@ -145,6 +147,7 @@ impl SgTape {
file,
info,
encryption_key_loaded: false,
+ locate_offset: None,
})
}
@@ -300,26 +303,76 @@ impl SgTape {
return self.rewind();
}
- let position = position -1;
+ const SPACE_ONE_FILEMARK: &[u8] = &[0x11, 0x01, 0, 0, 1, 0];
+
+ // Special case for position 1, because LOCATE 0 does not work
+ if position == 1 {
+ self.rewind()?;
+ let mut sg_raw = SgRaw::new(&mut self.file, 16)?;
+ sg_raw.set_timeout(Self::SCSI_TAPE_DEFAULT_TIMEOUT);
+ sg_raw.do_command(SPACE_ONE_FILEMARK)
+ .map_err(|err| format_err!("locate file {} (space) failed - {}", position, err))?;
+ return Ok(());
+ }
let mut sg_raw = SgRaw::new(&mut self.file, 16)?;
sg_raw.set_timeout(Self::SCSI_TAPE_DEFAULT_TIMEOUT);
- let mut cmd = Vec::new();
+
// Note: LOCATE(16) works for LTO4 or newer
+ //
+ // It seems the LOCATE command behaves slightly different across vendors
+ // e.g. for IBM drives, LOCATE 1 moves to File #2, but
+ // for HP drives, LOCATE 1 move to File #1
+
+ let fixed_position = if let Some(locate_offset) = self.locate_offset {
+ if locate_offset < 0 {
+ position.saturating_sub((-locate_offset) as u64)
+ } else {
+ position.saturating_add(locate_offset as u64)
+ }
+ } else {
+ position
+ };
+ // always sub(1), so that it works for IBM drives without locate_offset
+ let fixed_position = fixed_position.saturating_sub(1);
+
+ let mut cmd = Vec::new();
cmd.extend(&[0x92, 0b000_01_000, 0, 0]); // LOCATE(16) filemarks
- cmd.extend(&position.to_be_bytes());
+ cmd.extend(&fixed_position.to_be_bytes());
cmd.extend(&[0, 0, 0, 0]);
sg_raw.do_command(&cmd)
.map_err(|err| format_err!("locate file {} failed - {}", position, err))?;
- // move to other side of filemark
- cmd.truncate(0);
- cmd.extend(&[0x11, 0x01, 0, 0, 1, 0]); // SPACE(6) one filemarks
-
- sg_raw.do_command(&cmd)
+ // LOCATE always position at the BOT side of the filemark, so
+ // we need to move to other side of filemark
+ sg_raw.do_command(SPACE_ONE_FILEMARK)
.map_err(|err| format_err!("locate file {} (space) failed - {}", position, err))?;
+ if self.locate_offset.is_none() {
+ // check if we landed at correct position
+ let current_file = self.current_file_number()?;
+ if current_file != position {
+ let offset: i64 =
+ i64::try_from((position as i128) - (current_file as i128)).map_err(|err| {
+ format_err!(
+ "locate_file: offset between {} and {} invalid: {}",
+ position,
+ current_file,
+ err
+ )
+ })?;
+ self.locate_offset = Some(offset);
+ self.locate_file(position)?;
+ let current_file = self.current_file_number()?;
+ if current_file != position {
+ bail!("locate_file: compensating offset did not work, aborting...");
+ }
+ } else {
+ self.locate_offset = Some(0);
+ }
+ }
+
Ok(())
}
--
2.30.2
^ permalink raw reply [flat|nested] 2+ messages in thread
* [pbs-devel] applied: [PATCH proxmox-backup v3] tape: fix LTO locate_file for HP drives
2021-06-29 6:35 [pbs-devel] [PATCH proxmox-backup v3] tape: fix LTO locate_file for HP drives Dietmar Maurer
@ 2021-06-30 7:13 ` Dietmar Maurer
0 siblings, 0 replies; 2+ messages in thread
From: Dietmar Maurer @ 2021-06-30 7:13 UTC (permalink / raw)
To: pbs-devel
applied
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-06-30 7:13 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-29 6:35 [pbs-devel] [PATCH proxmox-backup v3] tape: fix LTO locate_file for HP drives Dietmar Maurer
2021-06-30 7:13 ` [pbs-devel] applied: " Dietmar Maurer
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal