From: Dietmar Maurer <dietmar@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH 07/11] tape: make sure there is a filemark at the end of the tape
Date: Wed, 7 Apr 2021 12:23:04 +0200 [thread overview]
Message-ID: <20210407102308.9750-8-dietmar@proxmox.com> (raw)
In-Reply-To: <20210407102308.9750-1-dietmar@proxmox.com>
---
src/bin/pmt.rs | 2 +-
src/bin/proxmox-tape.rs | 2 +-
src/tape/drive/lto/mod.rs | 8 ++--
src/tape/drive/lto/sg_tape.rs | 71 +++++++++++++++++++++++++++++-----
src/tape/drive/mod.rs | 6 ++-
src/tape/drive/virtual_tape.rs | 4 +-
src/tape/pool_writer/mod.rs | 2 +-
7 files changed, 75 insertions(+), 20 deletions(-)
diff --git a/src/bin/pmt.rs b/src/bin/pmt.rs
index da0d4fd9..854364c7 100644
--- a/src/bin/pmt.rs
+++ b/src/bin/pmt.rs
@@ -383,7 +383,7 @@ fn eject(param: Value) -> Result<(), Error> {
fn eod(param: Value) -> Result<(), Error> {
let mut handle = get_tape_handle(¶m)?;
- handle.move_to_eom()?;
+ handle.move_to_eom(false)?;
Ok(())
}
diff --git a/src/bin/proxmox-tape.rs b/src/bin/proxmox-tape.rs
index 2a784632..f1de6236 100644
--- a/src/bin/proxmox-tape.rs
+++ b/src/bin/proxmox-tape.rs
@@ -551,7 +551,7 @@ fn move_to_eom(mut param: Value) -> Result<(), Error> {
let mut drive = open_drive(&config, &drive)?;
- drive.move_to_eom()?;
+ drive.move_to_eom(false)?;
Ok(())
}
diff --git a/src/tape/drive/lto/mod.rs b/src/tape/drive/lto/mod.rs
index 25df897f..7fcef8a0 100644
--- a/src/tape/drive/lto/mod.rs
+++ b/src/tape/drive/lto/mod.rs
@@ -215,13 +215,15 @@ impl TapeDriver for LtoTapeHandle {
}
/// Go to the end of the recorded media (for appending files).
- fn move_to_eom(&mut self) -> Result<(), Error> {
- self.sg_tape.move_to_eom()
+ fn move_to_eom(&mut self, write_missing_eof: bool) -> Result<(), Error> {
+ self.sg_tape.move_to_eom(write_missing_eof)
}
fn move_to_last_file(&mut self) -> Result<(), Error> {
- self.move_to_eom()?;
+ self.move_to_eom(false)?;
+
+ self.sg_tape.check_filemark()?;
let pos = self.current_file_number()?;
diff --git a/src/tape/drive/lto/sg_tape.rs b/src/tape/drive/lto/sg_tape.rs
index fd1a067a..9af0eae3 100644
--- a/src/tape/drive/lto/sg_tape.rs
+++ b/src/tape/drive/lto/sg_tape.rs
@@ -190,8 +190,6 @@ impl SgTape {
bail!("detecthed partitioned tape - not supported");
}
- println!("DATA: {:?}", page);
-
Ok(page)
}
@@ -222,7 +220,35 @@ impl SgTape {
Ok(())
}
- pub fn move_to_eom(&mut self) -> Result<(), Error> {
+ /// Check if we are positioned after a filemark (or BOT)
+ pub fn check_filemark(&mut self) -> Result<bool, Error> {
+
+ let pos = self.position()?;
+ if pos.logical_object_number == 0 {
+ // at BOT, Ok (no filemark required)
+ return Ok(true);
+ }
+
+ // Note: SPACE blocks returns Err at filemark
+ match self.space(-1, true) {
+ Ok(_) => {
+ self.space(1, true) // move back to end
+ .map_err(|err| format_err!("check_filemark failed (space forward) - {}", err))?;
+ Ok(false)
+ }
+ Err(ScsiError::Sense(SenseInfo { sense_key: 0, asc: 0, ascq: 1 })) => {
+ // Filemark detected - good
+ self.space(1, true) // move back to end
+ .map_err(|err| format_err!("check_filemark failed (space forward) - {}", err))?;
+ Ok(true)
+ }
+ Err(err) => {
+ bail!("check_filemark failed - {:?}", err);
+ }
+ }
+ }
+
+ pub fn move_to_eom(&mut self, write_missing_eof: bool) -> 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();
@@ -231,35 +257,60 @@ impl SgTape {
sg_raw.do_command(&cmd)
.map_err(|err| format_err!("move to EOD failed - {}", err))?;
+ if write_missing_eof {
+ if !self.check_filemark()? {
+ self.write_filemarks(1, false)?;
+ }
+ }
+
Ok(())
}
- pub fn space_filemarks(&mut self, count: isize) -> Result<(), Error> {
+ fn space(&mut self, count: isize, blocks: bool) -> Result<(), ScsiError> {
let mut sg_raw = SgRaw::new(&mut self.file, 16)?;
sg_raw.set_timeout(Self::SCSI_TAPE_DEFAULT_TIMEOUT);
let mut cmd = Vec::new();
// Use short command if possible (supported by all drives)
if (count <= 0x7fffff) && (count > -0x7fffff) {
- cmd.extend(&[0x11, 0x01]); // SPACE(6) with filemarks
+ cmd.push(0x11); // SPACE(6)
+ if blocks {
+ cmd.push(0); // blocks
+ } else {
+ cmd.push(1); // filemarks
+ }
cmd.push(((count >> 16) & 0xff) as u8);
cmd.push(((count >> 8) & 0xff) as u8);
cmd.push((count & 0xff) as u8);
cmd.push(0); //control byte
} else {
-
- cmd.extend(&[0x91, 0x01, 0, 0]); // SPACE(16) with filemarks
+ cmd.push(0x91); // SPACE(16)
+ if blocks {
+ cmd.push(0); // blocks
+ } else {
+ cmd.push(1); // filemarks
+ }
+ cmd.extend(&[0, 0]); // reserved
let count: i64 = count as i64;
cmd.extend(&count.to_be_bytes());
- cmd.extend(&[0, 0, 0, 0]);
+ cmd.extend(&[0, 0, 0, 0]); // reserved
}
- sg_raw.do_command(&cmd)
- .map_err(|err| format_err!("space filemarks failed - {}", err))?;
+ sg_raw.do_command(&cmd)?;
Ok(())
}
+ pub fn space_filemarks(&mut self, count: isize) -> Result<(), Error> {
+ self.space(count, false)
+ .map_err(|err| format_err!("space filemarks failed - {}", err))
+ }
+
+ pub fn space_blocks(&mut self, count: isize) -> Result<(), Error> {
+ self.space(count, true)
+ .map_err(|err| format_err!("space blocks failed - {}", err))
+ }
+
pub fn eject(&mut self) -> Result<(), Error> {
let mut sg_raw = SgRaw::new(&mut self.file, 16)?;
sg_raw.set_timeout(Self::SCSI_TAPE_DEFAULT_TIMEOUT);
diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs
index 28ff0a3a..cd02e16d 100644
--- a/src/tape/drive/mod.rs
+++ b/src/tape/drive/mod.rs
@@ -84,8 +84,10 @@ pub trait TapeDriver {
/// Move to end of recorded data
///
- /// We assume this flushes the tape write buffer.
- fn move_to_eom(&mut self) -> Result<(), Error>;
+ /// We assume this flushes the tape write buffer. if
+ /// write_missing_eof is true, we verify that there is a filemark
+ /// at the end. If not, we write one.
+ fn move_to_eom(&mut self, write_missing_eof: bool) -> Result<(), Error>;
/// Move to last file
fn move_to_last_file(&mut self) -> Result<(), Error>;
diff --git a/src/tape/drive/virtual_tape.rs b/src/tape/drive/virtual_tape.rs
index bb4b4e3c..a852056a 100644
--- a/src/tape/drive/virtual_tape.rs
+++ b/src/tape/drive/virtual_tape.rs
@@ -249,7 +249,7 @@ impl TapeDriver for VirtualTapeHandle {
/// Move to last file
fn move_to_last_file(&mut self) -> Result<(), Error> {
- self.move_to_eom()?;
+ self.move_to_eom(false)?;
if self.current_file_number()? == 0 {
bail!("move_to_last_file failed - media contains no data");
@@ -347,7 +347,7 @@ impl TapeDriver for VirtualTapeHandle {
}
}
- fn move_to_eom(&mut self) -> Result<(), Error> {
+ fn move_to_eom(&mut self, _write_missing_eof: bool) -> Result<(), Error> {
let mut status = self.load_status()?;
match status.current_tape {
Some(VirtualTapeStatus { ref name, ref mut pos }) => {
diff --git a/src/tape/pool_writer/mod.rs b/src/tape/pool_writer/mod.rs
index 05aa52a4..99fdb48c 100644
--- a/src/tape/pool_writer/mod.rs
+++ b/src/tape/pool_writer/mod.rs
@@ -297,7 +297,7 @@ impl PoolWriter {
if !status.at_eom {
worker.log(String::from("moving to end of media"));
- status.drive.move_to_eom()?;
+ status.drive.move_to_eom(true)?;
status.at_eom = true;
}
--
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 ` [pbs-devel] [PATCH 05/11] tape: fix LEOM handling Dietmar Maurer
2021-04-07 10:23 ` [pbs-devel] [PATCH 06/11] tape: make fsf/bsf driver specific Dietmar Maurer
2021-04-07 10:23 ` Dietmar Maurer [this message]
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-8-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox