tape: use LP 12h TapeAlert Response to query tape alert flags
This commit is contained in:
parent
165b641c1d
commit
5c012b392a
@ -17,56 +17,61 @@ bitflags::bitflags!{
|
|||||||
///
|
///
|
||||||
/// See LTO SCSI Reference LOG_SENSE - LP 2Eh: TapeAlerts
|
/// See LTO SCSI Reference LOG_SENSE - LP 2Eh: TapeAlerts
|
||||||
pub struct TapeAlertFlags: u64 {
|
pub struct TapeAlertFlags: u64 {
|
||||||
const READ_WARNING = 0x0001;
|
const READ_WARNING = 1 << 0x0001;
|
||||||
const WRITE_WARNING = 0002;
|
const WRITE_WARNING = 1 << 0002;
|
||||||
const HARD_ERROR = 0x0003;
|
const HARD_ERROR = 1 << 0x0003;
|
||||||
const MEDIA = 0x0004;
|
const MEDIA = 1 << 0x0004;
|
||||||
const READ_FAILURE = 0x0005;
|
const READ_FAILURE = 1 << 0x0005;
|
||||||
const WRITE_FAILURE = 0x0006;
|
const WRITE_FAILURE = 1 << 0x0006;
|
||||||
const MEDIA_LIFE = 0x0007;
|
const MEDIA_LIFE = 1 << 0x0007;
|
||||||
const NOT_DATA_GRADE = 0x0008;
|
const NOT_DATA_GRADE = 1 << 0x0008;
|
||||||
const WRITE_PROTECT = 0x0009;
|
const WRITE_PROTECT = 1 << 0x0009;
|
||||||
const NO_REMOVAL = 0x000A;
|
const NO_REMOVAL = 1 << 0x000A;
|
||||||
const CLEANING_MEDIA = 0x000B;
|
const CLEANING_MEDIA = 1 << 0x000B;
|
||||||
const UNSUPPORTED_FORMAT = 0x000C;
|
const UNSUPPORTED_FORMAT = 1 << 0x000C;
|
||||||
const UNRECOVERABLE_SNAPPED_TAPE = 0x000E;
|
const RECOVERABLE_MECHANICAL_CARTRIDGE_FAILURE = 1 << 0x000D; // LTO5
|
||||||
const MEMORY_CHIP_IN_CARTRIDGE_FAILURE = 0x000F;
|
const UNRECOVERABLE_SNAPPED_TAPE = 1 << 0x000E;
|
||||||
const FORCED_EJECT = 0x0010;
|
const MEMORY_CHIP_IN_CARTRIDGE_FAILURE = 1 << 0x000F;
|
||||||
const READ_ONLY_FORMAT = 0x0011;
|
const FORCED_EJECT = 1 << 0x0010;
|
||||||
const TAPE_DIRECTORY_CORRUPTED = 0x0012;
|
const READ_ONLY_FORMAT = 1 << 0x0011;
|
||||||
const NEARING_MEDIA_LIFE = 0x0013;
|
const TAPE_DIRECTORY_CORRUPTED = 1 << 0x0012;
|
||||||
const CLEAN_NOW = 0x0014;
|
const NEARING_MEDIA_LIFE = 1 << 0x0013;
|
||||||
const CLEAN_PERIODIC = 0x0015;
|
const CLEAN_NOW = 1 << 0x0014;
|
||||||
const EXPIRED_CLEANING_MEDIA = 0x0016;
|
const CLEAN_PERIODIC = 1 << 0x0015;
|
||||||
const INVALID_CLEANING_TAPE = 0x0017;
|
const EXPIRED_CLEANING_MEDIA = 1 << 0x0016;
|
||||||
const HOST_CHANNEL_FAILURE = 0x0019;
|
const INVALID_CLEANING_TAPE = 1 << 0x0017;
|
||||||
const COOLING_FAN_FAILURE = 0x001A;
|
const RETENSION_REQUEST = 1 << 0x0018; // LTO5
|
||||||
const POWER_SUPPLY_FAILURE = 0x001B;
|
const HOST_CHANNEL_FAILURE = 1 << 0x0019;
|
||||||
const HARDWARE_A = 0x001E;
|
const COOLING_FAN_FAILURE = 1 << 0x001A;
|
||||||
const HARDWARE_B = 0x001F;
|
const POWER_SUPPLY_FAILURE = 1 << 0x001B;
|
||||||
const INTERFACE = 0x0020;
|
const POWER_CONSUMPTION = 1 << 0x001C; // LTO5
|
||||||
const EJECT_MEDIA = 0x0021;
|
const DRIVE_MANTAINANCE = 1 << 0x001D; // LTO5
|
||||||
const DOWNLOAD_FAULT = 0x0022;
|
const HARDWARE_A = 1 << 0x001E;
|
||||||
const DRIVE_TEMPERATURE = 0x0024;
|
const HARDWARE_B = 1 << 0x001F;
|
||||||
const DRIVE_VOLTAGE = 0x0025;
|
const INTERFACE = 1 << 0x0020;
|
||||||
const PREDICTIVE_FAILURE = 0x0026;
|
const EJECT_MEDIA = 1 << 0x0021;
|
||||||
const DIAGNOSTICS_REQUIRED = 0x0027;
|
const DOWNLOAD_FAULT = 1 << 0x0022;
|
||||||
const LOADER_STRAY_TAPE = 0x0029;
|
const DRIVE_HUMIDITY = 1 << 0x0023; // LTO5
|
||||||
const LOADER_HARDWARE = 0x002A;
|
const DRIVE_TEMPERATURE = 1 << 0x0024;
|
||||||
const LOADER_MAGAZINE = 0x002D;
|
const DRIVE_VOLTAGE = 1 << 0x0025;
|
||||||
const DIMINISHED_NATIVE_CAPACITY = 0x0031;
|
const PREDICTIVE_FAILURE = 1 << 0x0026;
|
||||||
const LOST_STATISTICS = 0x0032;
|
const DIAGNOSTICS_REQUIRED = 1 << 0x0027;
|
||||||
const TAPE_DIRECTORY_INVALID_AT_UNLOAD = 0x0033;
|
const LOADER_STRAY_TAPE = 1 << 0x0029;
|
||||||
const TAPE_SYSTEM_AREA_WRITE_FAILURE = 0x0034;
|
const LOADER_HARDWARE = 1 << 0x002A;
|
||||||
const TAPE_SYSTEM_AREA_READ_FAILURE = 0x0035;
|
const LOADER_MAGAZINE = 1 << 0x002D;
|
||||||
const NO_START_OF_DATA = 0x0036;
|
const DIMINISHED_NATIVE_CAPACITY = 1 << 0x0031;
|
||||||
const LOADING_FAILURE = 0x0037;
|
const LOST_STATISTICS = 1 << 0x0032;
|
||||||
const UNRECOVERABLE_UNLOAD_FAILURE = 0x0038;
|
const TAPE_DIRECTORY_INVALID_AT_UNLOAD = 1 << 0x0033;
|
||||||
const AUTOMATION_INTERFACE_FAILURE = 0x0039;
|
const TAPE_SYSTEM_AREA_WRITE_FAILURE = 1 << 0x0034;
|
||||||
const FIRMWARE_FAILURE = 0x003A;
|
const TAPE_SYSTEM_AREA_READ_FAILURE = 1 << 0x0035;
|
||||||
const WORM_INTEGRITY_CHECK_FAILED = 0x003B;
|
const NO_START_OF_DATA = 1 << 0x0036;
|
||||||
const WORM_OVERWRITE_ATTEMPTED = 0x003C;
|
const LOADING_FAILURE = 1 << 0x0037;
|
||||||
const ENCRYPTION_POLICY_VIOLATION = 0x003D;
|
const UNRECOVERABLE_UNLOAD_FAILURE = 1 << 0x0038;
|
||||||
|
const AUTOMATION_INTERFACE_FAILURE = 1 << 0x0039;
|
||||||
|
const FIRMWARE_FAILURE = 1 << 0x003A;
|
||||||
|
const WORM_INTEGRITY_CHECK_FAILED = 1 << 0x003B;
|
||||||
|
const WORM_OVERWRITE_ATTEMPTED = 1 << 0x003C;
|
||||||
|
const ENCRYPTION_POLICY_VIOLATION = 1 << 0x003D;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,14 +83,18 @@ pub fn read_tape_alert_flags<F: AsRawFd>(file: &mut F) -> Result<TapeAlertFlags
|
|||||||
decode_tape_alert_flags(&data)
|
decode_tape_alert_flags(&data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn sg_read_tape_alert_flags<F: AsRawFd>(file: &mut F) -> Result<Vec<u8>, Error> {
|
fn sg_read_tape_alert_flags<F: AsRawFd>(file: &mut F) -> Result<Vec<u8>, Error> {
|
||||||
|
|
||||||
let mut sg_raw = SgRaw::new(file, 512)?;
|
let mut sg_raw = SgRaw::new(file, 512)?;
|
||||||
|
|
||||||
|
// Note: We cannjot use LP 2Eh TapeAlerts, because that clears flags on read.
|
||||||
|
// Instead, we use LP 12h TapeAlert Response. which does not clear the flags.
|
||||||
|
|
||||||
let mut cmd = Vec::new();
|
let mut cmd = Vec::new();
|
||||||
cmd.push(0x4D); // LOG SENSE
|
cmd.push(0x4D); // LOG SENSE
|
||||||
cmd.push(0);
|
cmd.push(0);
|
||||||
cmd.push(0x2e); // Tape Alert Flag page
|
cmd.push((1<<6) | 0x12); // Tape Alert Response log page
|
||||||
cmd.push(0);
|
cmd.push(0);
|
||||||
cmd.push(0);
|
cmd.push(0);
|
||||||
cmd.push(0);
|
cmd.push(0);
|
||||||
@ -101,36 +110,30 @@ fn sg_read_tape_alert_flags<F: AsRawFd>(file: &mut F) -> Result<Vec<u8>, Error>
|
|||||||
fn decode_tape_alert_flags(data: &[u8]) -> Result<TapeAlertFlags, Error> {
|
fn decode_tape_alert_flags(data: &[u8]) -> Result<TapeAlertFlags, Error> {
|
||||||
|
|
||||||
proxmox::try_block!({
|
proxmox::try_block!({
|
||||||
if !(data[0] == 0x2e && data[1] == 0) {
|
if !((data[0] & 0x7f) == 0x12 && data[1] == 0) {
|
||||||
bail!("invalid response");
|
bail!("invalid response");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut reader = &data[2..];
|
let mut reader = &data[2..];
|
||||||
|
|
||||||
let page_len: u16 = unsafe { reader.read_be_value()? };
|
let page_len: u16 = unsafe { reader.read_be_value()? };
|
||||||
if page_len != 0x140 {
|
if page_len != 0x0c {
|
||||||
bail!("invalid page length");
|
bail!("invalid page length");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut value: u64 = 0;
|
let parameter_code: u16 = unsafe { reader.read_be_value()? };
|
||||||
|
if parameter_code != 0 {
|
||||||
for _ in 1..65 {
|
bail!("invalid parameter code");
|
||||||
let id: u16 = unsafe { reader.read_be_value()? };
|
|
||||||
if id < 1 || id > 64 {
|
|
||||||
bail!("invalid parameter id '{}'", id);
|
|
||||||
}
|
}
|
||||||
let bit: u64 = 1 << (id as usize - 1);
|
|
||||||
let mut data = [0u8;3];
|
let mut control_buf = [0u8; 2];
|
||||||
reader.read_exact(&mut data)?;
|
reader.read_exact(&mut control_buf)?;
|
||||||
if data[1] != 1 {
|
|
||||||
|
if control_buf[1] != 8 {
|
||||||
bail!("invalid parameter length");
|
bail!("invalid parameter length");
|
||||||
}
|
}
|
||||||
match data[2] {
|
|
||||||
0 => {},
|
let value: u64 = unsafe { reader.read_le_value()? };
|
||||||
1 => { value |= bit; }
|
|
||||||
_ => bail!("invalid flag value"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(TapeAlertFlags::from_bits_truncate(value))
|
Ok(TapeAlertFlags::from_bits_truncate(value))
|
||||||
}).map_err(|err| format_err!("decode tape alert flags failed - {}", err))
|
}).map_err(|err| format_err!("decode tape alert flags failed - {}", err))
|
||||||
|
Loading…
Reference in New Issue
Block a user