From: Dietmar Maurer <dietmar@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH 05/11] tape: fix LEOM handling
Date: Wed, 7 Apr 2021 12:23:02 +0200 [thread overview]
Message-ID: <20210407102308.9750-6-dietmar@proxmox.com> (raw)
In-Reply-To: <20210407102308.9750-1-dietmar@proxmox.com>
---
src/tape/drive/lto/sg_tape.rs | 57 +++++++++++++++++++++++++++--------
src/tools/sgutils2.rs | 26 ++++++++--------
2 files changed, 57 insertions(+), 26 deletions(-)
diff --git a/src/tape/drive/lto/sg_tape.rs b/src/tape/drive/lto/sg_tape.rs
index 531acbee..fd1a067a 100644
--- a/src/tape/drive/lto/sg_tape.rs
+++ b/src/tape/drive/lto/sg_tape.rs
@@ -75,6 +75,11 @@ impl SgTape {
Ok(Self { file })
}
+ // fixme: remove - only for testing
+ pub fn file_mut(&mut self) -> &mut File {
+ &mut self.file
+ }
+
pub fn open<P: AsRef<Path>>(path: P) -> Result<SgTape, Error> {
// do not wait for media, use O_NONBLOCK
let file = OpenOptions::new()
@@ -195,9 +200,26 @@ impl SgTape {
Ok(position.logical_file_id)
}
- pub fn locate(&mut self) -> Result<(), Error> {
- // fixme: impl LOCATE
- unimplemented!();
+ // fixme: dont use - needs LTO5
+ pub fn locate_file(&mut self, position: u64) -> Result<(), Error> {
+ let mut sg_raw = SgRaw::new(&mut self.file, 16)?;
+ sg_raw.set_timeout(Self::SCSI_TAPE_DEFAULT_TIMEOUT);
+ let mut cmd = Vec::new();
+ cmd.extend(&[0x92, 0b000_01_000, 0, 0]); // LOCATE(16) filemarks
+ cmd.extend(&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)
+ .map_err(|err| format_err!("locate file {} (space) failed - {}", position, err))?;
+
+ Ok(())
}
pub fn move_to_eom(&mut self) -> Result<(), Error> {
@@ -286,8 +308,15 @@ impl SgTape {
cmd.extend(&[0, 0, count as u8]); // COUNT
cmd.push(0); // control byte
- sg_raw.do_command(&cmd)
- .map_err(|err| proxmox::io_format_err!("write filemark failed - {}", err))?;
+ match sg_raw.do_command(&cmd) {
+ Ok(_) => { /* OK */ }
+ Err(ScsiError::Sense(SenseInfo { sense_key: 0, asc: 0, ascq: 2 })) => {
+ /* LEOM - ignore */
+ }
+ Err(err) => {
+ proxmox::io_bail!("write filemark failed - {}", err);
+ }
+ }
Ok(())
}
@@ -360,7 +389,7 @@ impl SgTape {
let transfer_len = data.len();
- if transfer_len > 0xFFFFFF {
+ if transfer_len > 0x800000 {
proxmox::io_bail!("write failed - data too large");
}
@@ -379,12 +408,15 @@ impl SgTape {
//println!("WRITE {:?}", cmd);
//println!("WRITE {:?}", data);
- sg_raw.do_out_command(&cmd, data)
- .map_err(|err| proxmox::io_format_err!("write failed - {}", err))?;
-
- // fixme: LEOM?
-
- Ok(false)
+ match sg_raw.do_out_command(&cmd, data) {
+ Ok(()) => { return Ok(false) }
+ Err(ScsiError::Sense(SenseInfo { sense_key: 0, asc: 0, ascq: 2 })) => {
+ return Ok(true); // LEOM
+ }
+ Err(err) => {
+ proxmox::io_bail!("write failed - {}", err);
+ }
+ }
}
fn read_block(&mut self, buffer: &mut [u8]) -> Result<BlockReadStatus, std::io::Error> {
@@ -416,7 +448,6 @@ impl SgTape {
return Ok(BlockReadStatus::EndOfStream);
}
Err(err) => {
- println!("READ ERR {:?}", err);
proxmox::io_bail!("read failed - {}", err);
}
};
diff --git a/src/tools/sgutils2.rs b/src/tools/sgutils2.rs
index 987d5738..4edfd9d9 100644
--- a/src/tools/sgutils2.rs
+++ b/src/tools/sgutils2.rs
@@ -203,17 +203,17 @@ struct InquiryPage {
#[repr(C, packed)]
#[derive(Endian, Debug)]
-struct RequestSenseFixed {
- response_code: u8,
+pub struct RequestSenseFixed {
+ pub response_code: u8,
obsolete: u8,
- flags2: u8,
- information: [u8;4],
- additional_sense_len: u8,
- command_specific_information: [u8;4],
- additional_sense_code: u8,
- additional_sense_code_qualifier: u8,
- field_replacable_unit_code: u8,
- sense_key_specific: [u8; 3],
+ pub flags2: u8,
+ pub information: [u8;4],
+ pub additional_sense_len: u8,
+ pub command_specific_information: [u8;4],
+ pub additional_sense_code: u8,
+ pub additional_sense_code_qualifier: u8,
+ pub field_replacable_unit_code: u8,
+ pub sense_key_specific: [u8; 3],
}
#[repr(C, packed)]
@@ -575,15 +575,15 @@ impl <'a, F: AsRawFd> SgRaw<'a, F> {
/// Run dataout command
///
/// Note: use alloc_page_aligned_buffer to alloc data transfer buffer
- pub fn do_out_command(&mut self, cmd: &[u8], data: &[u8]) -> Result<(), Error> {
+ pub fn do_out_command(&mut self, cmd: &[u8], data: &[u8]) -> Result<(), ScsiError> {
if !unsafe { sg_is_scsi_cdb(cmd.as_ptr(), cmd.len() as c_int) } {
- bail!("no valid SCSI command");
+ return Err(format_err!("no valid SCSI command").into());
}
let page_size = unsafe { libc::sysconf(libc::_SC_PAGESIZE) } as usize;
if ((data.as_ptr() as usize) & (page_size -1)) != 0 {
- bail!("wrong transfer buffer alignment");
+ return Err(format_err!("wrong transfer buffer alignment").into());
}
let mut ptvp = self.create_scsi_pt_obj()?;
--
2.20.1
next prev parent reply other threads:[~2021-04-07 10:24 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-07 10:22 [pbs-devel] [PATCH 00/11] Userspace tape driver Dietmar Maurer
2021-04-07 10:22 ` [pbs-devel] [PATCH 01/11] tape: introduce trait BlockRead Dietmar Maurer
2021-04-07 10:22 ` [pbs-devel] [PATCH 02/11] tape: introduce trait BlockWrite Dietmar Maurer
2021-04-07 10:23 ` [pbs-devel] [PATCH 03/11] tape: implement LTO userspace driver Dietmar Maurer
2021-04-07 10:23 ` [pbs-devel] [PATCH 04/11] tape: implement format/erase Dietmar Maurer
2021-04-07 10:23 ` Dietmar Maurer [this message]
2021-04-07 10:23 ` [pbs-devel] [PATCH 06/11] tape: make fsf/bsf driver specific Dietmar Maurer
2021-04-07 10:23 ` [pbs-devel] [PATCH 07/11] tape: make sure there is a filemark at the end of the tape Dietmar Maurer
2021-04-07 10:23 ` [pbs-devel] [PATCH 08/11] sgutils2: add scsi_mode_sense helper Dietmar Maurer
2021-04-07 10:23 ` [pbs-devel] [PATCH 09/11] tape: correctly set/display drive option Dietmar Maurer
2021-04-07 10:23 ` [pbs-devel] [PATCH 10/11] tape: pmt - re-implement fsr/bsr Dietmar Maurer
2021-04-07 10:23 ` [pbs-devel] [PATCH 11/11] tape: pmt - re-implement lock/unlock command Dietmar Maurer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210407102308.9750-6-dietmar@proxmox.com \
--to=dietmar@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.