[pbs-devel] [PATCH proxmox-backup] tape: changer: sg_pt: always retry until timeout

Dietmar Maurer dietmar at proxmox.com
Tue Jul 13 10:51:57 CEST 2021


---

This replaces the patch from Dominik:

[PATCH proxmox-backup 1/2] tape: changer: sg_pt: do not retry on unknown errors

Opposed to that, we now allways retry (after sleep) and log errors
until we run into the timout.

 src/tape/changer/sg_pt_changer.rs | 63 ++++++++++++-------------------
 1 file changed, 25 insertions(+), 38 deletions(-)

diff --git a/src/tape/changer/sg_pt_changer.rs b/src/tape/changer/sg_pt_changer.rs
index b34219c1..66da140d 100644
--- a/src/tape/changer/sg_pt_changer.rs
+++ b/src/tape/changer/sg_pt_changer.rs
@@ -23,9 +23,6 @@ use crate::{
     },
     tools::sgutils2::{
         SgRaw,
-        SENSE_KEY_NO_SENSE,
-        SENSE_KEY_RECOVERED_ERROR,
-        SENSE_KEY_UNIT_ATTENTION,
         SENSE_KEY_NOT_READY,
         InquiryInfo,
         ScsiError,
@@ -77,11 +74,10 @@ struct AddressAssignmentPage {
 }
 
 /// Execute scsi commands, optionally repeat the command until
-/// successful (sleep 1 second between invovations)
+/// successful or timeout (sleep 1 second between invovations)
 ///
-/// Any Sense key other than NO_SENSE, RECOVERED_ERROR, NOT_READY and
-/// UNIT_ATTENTION aborts the loop and returns an error. If the device
-/// reports "Not Ready - becoming ready", we wait up to 5 minutes.
+/// Timeout is 5 seconds. If the device reports "Not Ready - becoming
+/// ready", we wait up to 5 minutes.
 ///
 /// Skipped errors are printed on stderr.
 fn execute_scsi_command<F: AsRawFd>(
@@ -100,42 +96,33 @@ fn execute_scsi_command<F: AsRawFd>(
     loop {
         match sg_raw.do_command(&cmd) {
             Ok(data) => return Ok(data.to_vec()),
+            Err(err) if !retry => bail!("{} failed: {}", error_prefix, err),
             Err(err) => {
-                if !retry {
-                    bail!("{} failed: {}", error_prefix, err);
+                let msg = err.to_string();
+                if let Some(ref last) = last_msg {
+                    if &msg != last {
+                        eprintln!("{}", err);
+                        last_msg = Some(msg);
+                    }
+                } else {
+                    eprintln!("{}", err);
+                    last_msg = Some(msg);
                 }
-                if let ScsiError::Sense(ref sense) = err {
-
-                    if sense.sense_key == SENSE_KEY_NO_SENSE ||
-                        sense.sense_key == SENSE_KEY_RECOVERED_ERROR ||
-                        sense.sense_key == SENSE_KEY_UNIT_ATTENTION ||
-                        sense.sense_key == SENSE_KEY_NOT_READY
-                    {
-                        let msg = err.to_string();
-                        if let Some(ref last) = last_msg {
-                            if &msg != last {
-                                eprintln!("{}", err);
-                                last_msg = Some(msg);
-                            }
-                        } else {
-                            eprintln!("{}", err);
-                            last_msg = Some(msg);
-                        }
-
-                        // Not Ready - becoming ready
-                        if sense.sense_key == SENSE_KEY_NOT_READY && sense.asc == 0x04 && sense.ascq == 1 {
-                            // wait up to 5 minutes, long enough to finish inventorize
-                            timeout = std::time::Duration::new(5*60, 0);
-                        }
-
-                        if start.elapsed()? > timeout {
-                            bail!("{} failed: {}", error_prefix, err);
-                        }
 
-                        std::thread::sleep(std::time::Duration::new(1, 0));
-                        continue; // try again
+                if let ScsiError::Sense(ref sense) = err {
+                    // Not Ready - becoming ready
+                    if sense.sense_key == SENSE_KEY_NOT_READY && sense.asc == 0x04 && sense.ascq == 1 {
+                        // wait up to 5 minutes, long enough to finish inventorize
+                        timeout = std::time::Duration::new(5*60, 0);
                     }
                 }
+
+                if start.elapsed()? > timeout {
+                    bail!("{} failed: {}", error_prefix, err);
+                }
+
+                std::thread::sleep(std::time::Duration::new(1, 0));
+                continue; // try again
             }
         }
    }
-- 
2.30.2





More information about the pbs-devel mailing list