Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
dCache
cta
Commits
41b4704e
Commit
41b4704e
authored
Dec 03, 2014
by
Eric Cano
Browse files
Added tape alert error counts to the tape log input.
Migrations now abort in the presence of tape alerts.
parent
a6af1306
Changes
12
Hide whitespace changes
Inline
Side-by-side
castor/tape/tapeserver/SCSI/Constants.cpp
View file @
41b4704e
...
...
@@ -163,6 +163,133 @@ std::string castor::tape::SCSI::tapeAlertToString(uint16_t parameterCode)
}
}
std
::
string
castor
::
tape
::
SCSI
::
tapeAlertToCompactString
(
uint16_t
parameterCode
)
{
std
::
stringstream
ret
;
ret
<<
std
::
hex
<<
std
::
nouppercase
<<
std
::
showbase
;
ret
<<
"tapeAlert"
;
if
(
parameterCode
<
1
||
parameterCode
>
64
)
{
ret
<<
"Unexpected"
<<
parameterCode
;
return
ret
.
str
();
}
else
if
(
parameterCode
>=
0x28
&&
parameterCode
<=
0x2e
)
{
ret
<<
"Obsolete"
<<
parameterCode
;
return
ret
.
str
();
}
switch
(
parameterCode
)
{
/* This list is hand compacted from the one in castor::tape::SCSI::tapeAlertToString
*/
case
0x01
:
return
"tapeAlertReadWarning"
;
case
0x02
:
return
"tapeAlertWriteWarning"
;
case
0x03
:
return
"tapeAlertHardError"
;
case
0x04
:
return
"tapeAlertMedium"
;
case
0x05
:
return
"tapeAlertReadFailure"
;
case
0x06
:
return
"tapeAlertWriteFailure"
;
case
0x07
:
return
"tapeAlertMediumLife"
;
case
0x08
:
return
"tapeAlertNotDataGrade"
;
case
0x09
:
return
"tapeAlertWriteProtect"
;
case
0x0A
:
return
"tapeAlertVolumePemovalPrevented"
;
case
0x0B
:
return
"tapeAlertCleaningVolume"
;
case
0x0C
:
return
"tapeAlertUnsupportedFormat"
;
case
0x0D
:
return
"tapeAlertRecoverableMechanicalCartridgeFailure"
;
case
0x0E
:
return
"tapeAlertUnrecoverableMechanicalCartridgeFailure"
;
case
0x0F
:
return
"tapeAlertMemoryChipInCartridgeFailure"
;
case
0x10
:
return
"tapeAlertForcedEject"
;
case
0x11
:
return
"tapeAlertReadOnlyFormat"
;
case
0x12
:
return
"tapeAlertTapeDirectoryCorruptedOnLoad"
;
case
0x13
:
return
"tapeAlertNearingMediumLife"
;
case
0x14
:
return
"tapeAlertCleaningRequired"
;
case
0x15
:
return
"tapeAlertCleaningRequested"
;
case
0x16
:
return
"tapeAlertExpiredCleaningVolume"
;
case
0x17
:
return
"tapeAlertInvalidCleaningVolume"
;
case
0x18
:
return
"tapeAlertRetensionRequested"
;
case
0x19
:
return
"tapeAlertMultiPortInterfaceErrorOnAPrimaryPort"
;
case
0x1A
:
return
"tapeAlertCoolingFanFailure"
;
case
0x1B
:
return
"tapeAlertPowerSupplyFailure"
;
case
0x1C
:
return
"tapeAlertPowerConsumption"
;
case
0x1D
:
return
"tapeAlertDrivePreventiveMaintenanceRequired"
;
case
0x1E
:
return
"tapeAlertHardwareA"
;
case
0x1F
:
return
"tapeAlertHardwareB"
;
case
0x20
:
return
"tapeAlertPrimaryInterface"
;
case
0x21
:
return
"tapeAlertEjectVolume"
;
case
0x22
:
return
"tapeAlertMicrocodeUpdateFail"
;
case
0x23
:
return
"tapeAlertDriveHumidity"
;
case
0x24
:
return
"tapeAlertDriveTemperature"
;
case
0x25
:
return
"tapeAlertDriveVoltage"
;
case
0x26
:
return
"tapeAlertPredictiveFailure"
;
case
0x27
:
return
"tapeAlertDiagnosticsRequired"
;
case
0x2F
:
return
"tapeAlertExternalDataEncryptionControlCommunicationFailure"
;
case
0x30
:
return
"tapeAlertExternalDataEncryptionControlKeyManagerReturnedAnError"
;
case
0x31
:
return
"tapeAlertDiminishedNativeCapacity"
;
case
0x32
:
return
"tapeAlertLostStatistics"
;
case
0x33
:
return
"tapeAlertTapeDirectoryInvalidAtUnload"
;
case
0x34
:
return
"tapeAlertTapeSystemAreaWriteFailure"
;
case
0x35
:
return
"tapeAlertTapeSystemAreaReadFailure"
;
case
0x36
:
return
"tapeAlertNoStartOfData"
;
case
0x37
:
return
"tapeAlertLoadingOrThreadingFailure"
;
case
0x38
:
return
"tapeAlertUnrecoverableUnloadFailure"
;
case
0x39
:
return
"tapeAlertAutomationInterfaceFailure"
;
case
0x3A
:
return
"tapeAlertMicrocodeFailure"
;
case
0x3B
:
return
"tapeAlertWORMVolumeIntegrityCheckFailed"
;
case
0x3C
:
return
"tapeAlertWORMVolumeOverwriteAttempted"
;
default:
ret
<<
"ReservedCode"
<<
parameterCode
;
return
ret
.
str
();
}
}
/**
* Turn a SCSI status code into a string
* @param status
...
...
castor/tape/tapeserver/SCSI/Constants.hpp
View file @
41b4704e
...
...
@@ -211,6 +211,11 @@ namespace SCSI {
*/
std
::
string
tapeAlertToString
(
uint16_t
parameterCode
);
/**
* Helper function turning tape alerts to mixed case compact strings.
*/
std
::
string
tapeAlertToCompactString
(
uint16_t
parameterCode
);
class
Status
{
public:
enum
{
...
...
castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp
View file @
41b4704e
...
...
@@ -84,6 +84,8 @@ public:
virtual
void
push
(
TapeReadTask
*
t
){
m_tasks
.
push
(
t
);
}
virtual
void
countTapeLogError
(
const
std
::
string
&
error
)
{};
};
TEST
(
castor_tape_tapeserver_daemon
,
RecallTaskInjectorNominal
)
{
...
...
castor/tape/tapeserver/daemon/TapeReadSingleThread.hpp
View file @
41b4704e
...
...
@@ -125,6 +125,11 @@ private:
/// Reference to the watchdog, used in run()
RecallWatchDog
&
m_watchdog
;
/// Helper virtual function to access the watchdog from parent class
virtual
void
countTapeLogError
(
const
std
::
string
&
error
)
{
m_watchdog
.
addToErrorCount
(
error
);
}
};
// class TapeReadSingleThread
...
...
castor/tape/tapeserver/daemon/TapeSingleThreadInterface.hpp
View file @
41b4704e
...
...
@@ -180,11 +180,13 @@ protected:
/**
* After waiting for the drive, we will dump the tape alert log content, if
* not empty
* @return true if any alert was detected
*/
void
logTapeAlerts
()
{
bool
logTapeAlerts
()
{
std
::
vector
<
std
::
string
>
tapeAlerts
=
m_drive
.
getTapeAlerts
();
if
(
tapeAlerts
.
empty
())
return
;
if
(
tapeAlerts
.
empty
())
return
false
;
size_t
alertNumber
=
0
;
// Log tape alerts in the logs.
for
(
std
::
vector
<
std
::
string
>::
iterator
ta
=
tapeAlerts
.
begin
();
ta
!=
tapeAlerts
.
end
();
ta
++
)
{
...
...
@@ -194,7 +196,23 @@ protected:
.
add
(
"tapeAlertCount"
,
tapeAlerts
.
size
());
m_logContext
.
log
(
LOG_WARNING
,
"Tape alert detected"
);
}
// Add tape alerts in the tape log parameters
std
::
vector
<
std
::
string
>
tapeAlertsCompact
=
m_drive
.
getTapeAlertsCompact
();
for
(
std
::
vector
<
std
::
string
>::
iterator
tac
=
tapeAlertsCompact
.
begin
();
tac
!=
tapeAlertsCompact
.
end
();
tac
++
)
{
countTapeLogError
(
std
::
string
(
"Error_"
)
+*
tac
);
}
return
true
;
}
/**
* Helper virtual function allowing the access to the m_watchdog member
* in the inherited classes (TapeReadSingleThread and TapeWriteSingleThread)
* @param error
*/
virtual
void
countTapeLogError
(
const
std
::
string
&
error
)
=
0
;
public:
Session
::
EndOfSessionAction
getHardwareStatus
()
const
{
...
...
castor/tape/tapeserver/daemon/TapeWriteSingleThread.cpp
View file @
41b4704e
...
...
@@ -162,7 +162,9 @@ void castor::tape::tapeserver::daemon::TapeWriteSingleThread::run() {
currentErrorToCount
=
"Error_tapeLoad"
;
waitForDrive
();
currentErrorToCount
=
"Error_checkingTapeAlert"
;
logTapeAlerts
();
if
(
logTapeAlerts
())
{
throw
castor
::
exception
::
Exception
(
"Aborting migration session in presence of tape alerts"
);
}
currentErrorToCount
=
"Error_tapeNotWriteable"
;
isTapeWritable
();
...
...
castor/tape/tapeserver/daemon/TapeWriteSingleThread.hpp
View file @
41b4704e
...
...
@@ -222,6 +222,15 @@ private:
*/
MigrationWatchDog
&
m_watchdog
;
protected:
/***
* Helper virtual function to access the watchdog from parent class
*/
virtual
void
countTapeLogError
(
const
std
::
string
&
error
)
{
m_watchdog
.
addToErrorCount
(
error
);
}
private:
/**
* Pointer to the task injector allowing termination signaling
*/
...
...
castor/tape/tapeserver/drive/DriveGeneric.cpp
View file @
41b4704e
...
...
@@ -241,12 +241,12 @@ drive::positionInfo drive::DriveGeneric::getPositionInfo()
/**
* Get tape alert information from the drive. There is a quite long list of possible tape alerts.
* They are described in SSC-4, section 4.2.20: TapeAlert application client interface.
* Section is 4.2.17 in SSC-3.
* @return list of tape alerts des
criptions. They are simply used for logging
.
* Section is 4.2.17 in SSC-3.
This version gives a list of numerical codes.
* @return list of tape alerts
co
des.
*/
std
::
vector
<
std
::
string
>
drive
::
DriveGeneric
::
getTapeAlerts
()
{
std
::
vector
<
uint16_t
>
drive
::
DriveGeneric
::
getTapeAlert
Code
s
(){
/* return vector */
std
::
vector
<
std
::
string
>
ret
;
std
::
vector
<
uint16_t
>
ret
;
/* We don't know how many elements we'll get. Prepare a 100 parameters array */
SCSI
::
Structures
::
tapeAlertLogPage_t
<
100
>
tal
;
/* Prepare a sense buffer of 255 bytes */
...
...
@@ -272,9 +272,43 @@ std::vector<std::string> drive::DriveGeneric::getTapeAlerts() {
* return strings. */
for
(
size_t
i
=
0
;
i
<
tal
.
parameterNumber
();
i
++
)
{
if
(
tal
.
parameters
[
i
].
flag
)
ret
.
push_back
(
SCSI
::
tapeAlertToString
(
SCSI
::
Structures
::
toU16
(
tal
.
parameters
[
i
].
parameterCode
)
));
ret
.
push_back
(
SCSI
::
Structures
::
toU16
(
tal
.
parameters
[
i
].
parameterCode
));
}
return
ret
;
}
/**
* Get tape alert information from the drive. There is a quite long list of possible tape alerts.
* They are described in SSC-4, section 4.2.20: TapeAlert application client interface.
* Section is 4.2.17 in SSC-3. This version gives the standard strings from SSC-4.
* @return list of tape alerts descriptions. They are simply used for logging.
*/
std
::
vector
<
std
::
string
>
drive
::
DriveGeneric
::
getTapeAlerts
(){
/* return vector */
std
::
vector
<
std
::
string
>
ret
;
/* The tape alerts */
std
::
vector
<
uint16_t
>
tacs
=
getTapeAlertCodes
();
/* convert tape alert codes to strings */
for
(
std
::
vector
<
uint16_t
>::
iterator
code
=
tacs
.
begin
();
code
!=
tacs
.
end
();
code
++
)
{
ret
.
push_back
(
SCSI
::
tapeAlertToString
(
*
code
));
}
return
ret
;
}
/**
* Get tape alert information from the drive. There is a quite long list of possible tape alerts.
* They are described in SSC-4, section 4.2.20: TapeAlert application client interface.
* Section is 4.2.17 in SSC-3. This version gives the standard strings from SSC-4.
* @return list of tape alerts descriptions, shortened in single words with mixed case.
*/
std
::
vector
<
std
::
string
>
drive
::
DriveGeneric
::
getTapeAlertsCompact
(){
/* return vector */
std
::
vector
<
std
::
string
>
ret
;
/* The tape alerts */
std
::
vector
<
uint16_t
>
tacs
=
getTapeAlertCodes
();
/* convert tape alert codes to strings */
for
(
std
::
vector
<
uint16_t
>::
iterator
code
=
tacs
.
begin
();
code
!=
tacs
.
end
();
code
++
)
{
ret
.
push_back
(
SCSI
::
tapeAlertToCompactString
(
*
code
));
}
return
ret
;
}
...
...
castor/tape/tapeserver/drive/DriveGeneric.hpp
View file @
41b4704e
...
...
@@ -88,13 +88,26 @@ namespace drive {
* on the dirty data still in the write buffer.
*/
virtual
positionInfo
getPositionInfo
()
;
private:
/**
* Utility getting the tape alert codes in a vector.
* @return vector of the tape alert codes.
*/
std
::
vector
<
uint16_t
>
getTapeAlertCodes
();
public:
/**
* Get tape alert information from the drive. There is a quite long list of possible tape alerts.
* They are described in SSC-4, section 4.2.20: TapeAlert application client interface
* @return list of tape alerts descriptions. They are simply used for logging.
*/
virtual
std
::
vector
<
std
::
string
>
getTapeAlerts
()
;
virtual
std
::
vector
<
std
::
string
>
getTapeAlerts
();
/**
* Get tape alert information from the drive. This is the same as getTapeAlerts,
* but providing the alert strings in compact form (mixed case single word).
*/
virtual
std
::
vector
<
std
::
string
>
getTapeAlertsCompact
();
/**
* Set the tape density and compression.
...
...
castor/tape/tapeserver/drive/DriveInterface.hpp
View file @
41b4704e
...
...
@@ -156,6 +156,7 @@ namespace drive {
virtual
void
positionToLogicalObject
(
uint32_t
blockId
)
=
0
;
virtual
positionInfo
getPositionInfo
()
=
0
;
virtual
std
::
vector
<
std
::
string
>
getTapeAlerts
()
=
0
;
virtual
std
::
vector
<
std
::
string
>
getTapeAlertsCompact
()
=
0
;
virtual
void
setDensityAndCompression
(
bool
compression
=
true
,
unsigned
char
densityCode
=
0
)
=
0
;
virtual
driveStatus
getDriveStatus
()
=
0
;
...
...
castor/tape/tapeserver/drive/FakeDrive.cpp
View file @
41b4704e
...
...
@@ -82,6 +82,11 @@ std::vector<std::string> castor::tape::tapeserver::drive::FakeDrive::getTapeAler
std
::
vector
<
std
::
string
>
empty
;
return
empty
;
}
std
::
vector
<
std
::
string
>
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
getTapeAlertsCompact
()
{
std
::
vector
<
std
::
string
>
empty
;
return
empty
;
}
void
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
setDensityAndCompression
(
bool
compression
,
unsigned
char
densityCode
)
{
throw
castor
::
exception
::
Exception
(
"FakeDrive::setDensityAndCompression Not implemented"
);
}
...
...
castor/tape/tapeserver/drive/FakeDrive.hpp
View file @
41b4704e
...
...
@@ -64,6 +64,7 @@ namespace drive {
virtual
void
positionToLogicalObject
(
uint32_t
blockId
)
;
virtual
positionInfo
getPositionInfo
()
;
virtual
std
::
vector
<
std
::
string
>
getTapeAlerts
()
;
virtual
std
::
vector
<
std
::
string
>
getTapeAlertsCompact
()
;
virtual
void
setDensityAndCompression
(
bool
compression
=
true
,
unsigned
char
densityCode
=
0
)
;
virtual
driveStatus
getDriveStatus
()
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment