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
041ba2aa
Commit
041ba2aa
authored
Sep 15, 2014
by
Victor Kotlyar
Browse files
added support for sense key and sense information for SCSI sense buffer.
parent
4bb07abb
Changes
5
Hide whitespace changes
Inline
Side-by-side
castor/tape/tapeserver/SCSI/Constants.cpp
View file @
041ba2aa
...
@@ -952,3 +952,26 @@ const castor::tape::SCSI::senseConstants::error_range_info castor::tape::SCSI::s
...
@@ -952,3 +952,26 @@ const castor::tape::SCSI::senseConstants::error_range_info castor::tape::SCSI::s
{
0x70
,
0x00
,
0xff
,
"Decompression exception short algorithm id of %02x"
},
{
0x70
,
0x00
,
0xff
,
"Decompression exception short algorithm id of %02x"
},
{
0
,
0
,
0
,
NULL
}
{
0
,
0
,
0
,
NULL
}
};
};
/* description of the sense key values */
const
char
*
const
castor
::
tape
::
SCSI
::
senseKeys
::
senseKeysText
[]
=
{
"No Sense"
,
/* 0: There is no sense information */
"Recovered Error"
,
/* 1: The last command completed successfully
but used error correction */
"Not Ready"
,
/* 2: The addressed target is not ready */
"Medium Error"
,
/* 3: Data error detected on the medium */
"Hardware Error"
,
/* 4: Controller or device failure */
"Illegal Request"
,
/* 5: Error in request */
"Unit Attention"
,
/* 6: Removable medium was changed, or
the target has been reset, or ... */
"Data Protect"
,
/* 7: Access to the data is blocked */
"Blank Check"
,
/* 8: Reached unexpected written or unwritten
region of the medium */
"Vendor Specific(9)"
,
"Copy Aborted"
,
/* A: COPY or COMPARE was aborted */
"Aborted Command"
,
/* B: The target aborted the command */
"Equal"
,
/* C: A SEARCH DATA command found data equal */
"Volume Overflow"
,
/* D: Medium full with still data to be written */
"Miscompare"
/* E: Source data and data on the medium
do not agree */
};
castor/tape/tapeserver/SCSI/Constants.hpp
View file @
041ba2aa
...
@@ -330,8 +330,31 @@ namespace SCSI {
...
@@ -330,8 +330,31 @@ namespace SCSI {
uint8_t
ascq_max
;
uint8_t
ascq_max
;
const
char
*
text
;
const
char
*
text
;
};
};
static
const
struct
error_range_info
ascRangesStrings
[];
static
const
struct
error_range_info
ascRangesStrings
[];
};
};
class
senseKeys
{
public:
enum
{
noSense
=
0x0
,
recoveredError
=
0x1
,
notReady
=
0x2
,
mediumError
=
0x3
,
hardwareError
=
0x4
,
illegalRequest
=
0x5
,
unitAttention
=
0x6
,
dataProtect
=
0x7
,
blankCheck
=
0x8
,
vendorSpecific
=
0x9
,
copyAborted
=
0xA
,
abortedCommand
=
0xB
,
equal
=
0xC
,
volumeOverflow
=
0xD
,
miscompare
=
0xE
,
lastWithText
=
0xE
};
static
const
char
*
const
senseKeysText
[];
};
}
// namespace SCSI
}
// namespace SCSI
}
// namespace tape
}
// namespace tape
}
// namespace castor
}
// namespace castor
castor/tape/tapeserver/SCSI/Exception.hpp
View file @
041ba2aa
...
@@ -43,6 +43,13 @@ namespace SCSI {
...
@@ -43,6 +43,13 @@ namespace SCSI {
<<
"SCSI command failed with status "
<<
"SCSI command failed with status "
<<
SCSI
::
statusToString
(
status
);
<<
SCSI
::
statusToString
(
status
);
if
(
SCSI
::
Status
::
CHECK_CONDITION
==
status
)
{
if
(
SCSI
::
Status
::
CHECK_CONDITION
==
status
)
{
w
<<
": Sense Information"
;
try
{
w
<<
": "
<<
sense
->
getSenseKeyString
();
}
catch
(
Exception
&
ex
)
{
w
<<
": In addition, failed to get Sense Key string: "
<<
ex
.
getMessage
();
}
try
{
try
{
w
<<
": "
<<
sense
->
getACSString
();
w
<<
": "
<<
sense
->
getACSString
();
}
catch
(
Exception
&
ex
)
{
}
catch
(
Exception
&
ex
)
{
...
...
castor/tape/tapeserver/SCSI/Structures.hpp
View file @
041ba2aa
...
@@ -861,7 +861,7 @@ namespace SCSI {
...
@@ -861,7 +861,7 @@ namespace SCSI {
return
responseCode
==
0x70
||
responseCode
==
0x72
;
return
responseCode
==
0x70
||
responseCode
==
0x72
;
}
}
bool
isDef
f
ered
()
{
bool
isDefe
r
red
()
{
return
responseCode
==
0x71
||
responseCode
==
0x73
;
return
responseCode
==
0x71
||
responseCode
==
0x73
;
}
}
...
@@ -890,6 +890,36 @@ namespace SCSI {
...
@@ -890,6 +890,36 @@ namespace SCSI {
throw
castor
::
exception
::
Exception
(
err
.
str
());
throw
castor
::
exception
::
Exception
(
err
.
str
());
}
}
}
}
/**
* Returns the Sense Key value.
*/
unsigned
char
getSenseKey
()
{
if
(
isFixedFormat
())
{
return
fixedFormat
.
senseKey
;
}
else
if
(
isDescriptorFormat
())
{
return
descriptorFormat
.
senseKey
;
}
else
{
std
::
stringstream
err
;
err
<<
"In senseData_t::getSenseKey: no Sense Key with this response "
"code or response code not supported ("
<<
std
::
hex
<<
std
::
showbase
<<
(
int
)
responseCode
<<
")"
;
throw
castor
::
exception
::
Exception
(
err
.
str
());
}
}
/**
* Returns the Sense Key value as string.
*/
std
::
string
getSenseKeyString
()
{
if
(
castor
::
tape
::
SCSI
::
senseKeys
::
lastWithText
>=
getSenseKey
())
{
return
castor
::
tape
::
SCSI
::
senseKeys
::
senseKeysText
[
getSenseKey
()];
}
else
{
std
::
stringstream
err
;
err
<<
"In senseData_t::getSenseKeyString: no Sense Key with this "
"value ("
<<
std
::
hex
<<
std
::
showbase
<<
(
int
)
getSenseKey
()
<<
")"
;
throw
castor
::
exception
::
Exception
(
err
.
str
());
}
}
/**
/**
* Function turning the ACS/ACSQ contents into a string.
* Function turning the ACS/ACSQ contents into a string.
* This function is taken from the Linux kernel sources.
* This function is taken from the Linux kernel sources.
...
@@ -916,7 +946,7 @@ namespace SCSI {
...
@@ -916,7 +946,7 @@ namespace SCSI {
snprintf
(
buff
,
sizeof
(
buff
),
"Unknown ASC/ASCQ:%02x/%02x"
,
asc
,
ascq
);
snprintf
(
buff
,
sizeof
(
buff
),
"Unknown ASC/ASCQ:%02x/%02x"
,
asc
,
ascq
);
return
std
::
string
(
buff
);
return
std
::
string
(
buff
);
}
}
/* TODO: add support for
sense key, and
other bits. See section 4.5.6
/* TODO: add support for other bits. See section 4.5.6
* of SPC-4 for sense key = NO SENSE. */
* of SPC-4 for sense key = NO SENSE. */
};
};
...
@@ -966,7 +996,7 @@ namespace SCSI {
...
@@ -966,7 +996,7 @@ namespace SCSI {
}
}
return
hex
.
str
();
return
hex
.
str
();
}
}
}
}
// namespace Structures
}
// namespace SCSI
}
// namespace SCSI
}
// namespace tape
}
// namespace tape
}
// namespace castor
}
// namespace castor
...
...
castor/tape/tapeserver/SCSI/StructuresTest.cpp
View file @
041ba2aa
...
@@ -518,45 +518,57 @@ namespace unitTests {
...
@@ -518,45 +518,57 @@ namespace unitTests {
ASSERT_EQ
(
255U
-
1U
,
sizeof
(
sense
.
fixedFormat
));
ASSERT_EQ
(
255U
-
1U
,
sizeof
(
sense
.
fixedFormat
));
buff
[
0
]
=
0x70
;
buff
[
0
]
=
0x70
;
buff
[
2
]
=
0xFE
;
buff
[
12
]
=
0x12
;
buff
[
12
]
=
0x12
;
buff
[
13
]
=
0x34
;
buff
[
13
]
=
0x34
;
ASSERT_EQ
(
true
,
sense
.
isCurrent
());
ASSERT_EQ
(
true
,
sense
.
isCurrent
());
ASSERT_EQ
(
false
,
sense
.
isDef
f
ered
());
ASSERT_EQ
(
false
,
sense
.
isDefe
r
red
());
ASSERT_EQ
(
true
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
true
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
false
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
false
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
0x12
,
sense
.
getASC
());
ASSERT_EQ
(
0x12
,
sense
.
getASC
());
ASSERT_EQ
(
0x34
,
sense
.
getASCQ
());
ASSERT_EQ
(
0x34
,
sense
.
getASCQ
());
ASSERT_EQ
(
0xE
,
sense
.
getSenseKey
());
ASSERT_EQ
(
"Miscompare"
,
sense
.
getSenseKeyString
());
buff
[
0
]
=
0x71
;
buff
[
0
]
=
0x71
;
buff
[
2
]
=
0xFA
;
buff
[
12
]
=
0x12
;
buff
[
12
]
=
0x12
;
buff
[
13
]
=
0x34
;
buff
[
13
]
=
0x34
;
ASSERT_EQ
(
false
,
sense
.
isCurrent
());
ASSERT_EQ
(
false
,
sense
.
isCurrent
());
ASSERT_EQ
(
true
,
sense
.
isDef
f
ered
());
ASSERT_EQ
(
true
,
sense
.
isDefe
r
red
());
ASSERT_EQ
(
true
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
true
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
false
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
false
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
0x12
,
sense
.
getASC
());
ASSERT_EQ
(
0x12
,
sense
.
getASC
());
ASSERT_EQ
(
0x34
,
sense
.
getASCQ
());
ASSERT_EQ
(
0x34
,
sense
.
getASCQ
());
ASSERT_EQ
(
0xA
,
sense
.
getSenseKey
());
ASSERT_EQ
(
"Copy Aborted"
,
sense
.
getSenseKeyString
());
buff
[
0
]
=
0x72
;
buff
[
0
]
=
0x72
;
buff
[
1
]
=
0xFB
;
buff
[
2
]
=
0x56
;
buff
[
2
]
=
0x56
;
buff
[
3
]
=
0x78
;
buff
[
3
]
=
0x78
;
ASSERT_EQ
(
true
,
sense
.
isCurrent
());
ASSERT_EQ
(
true
,
sense
.
isCurrent
());
ASSERT_EQ
(
false
,
sense
.
isDef
f
ered
());
ASSERT_EQ
(
false
,
sense
.
isDefe
r
red
());
ASSERT_EQ
(
false
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
false
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
true
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
true
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
0x56
,
sense
.
getASC
());
ASSERT_EQ
(
0x56
,
sense
.
getASC
());
ASSERT_EQ
(
0x78
,
sense
.
getASCQ
());
ASSERT_EQ
(
0x78
,
sense
.
getASCQ
());
ASSERT_EQ
(
0xB
,
sense
.
getSenseKey
());
ASSERT_EQ
(
"Aborted Command"
,
sense
.
getSenseKeyString
());
buff
[
0
]
=
0x73
;
buff
[
0
]
=
0x73
;
buff
[
1
]
=
0xFC
;
buff
[
2
]
=
0x0b
;
buff
[
2
]
=
0x0b
;
buff
[
3
]
=
0x08
;
buff
[
3
]
=
0x08
;
ASSERT_EQ
(
false
,
sense
.
isCurrent
());
ASSERT_EQ
(
false
,
sense
.
isCurrent
());
ASSERT_EQ
(
true
,
sense
.
isDef
f
ered
());
ASSERT_EQ
(
true
,
sense
.
isDefe
r
red
());
ASSERT_EQ
(
false
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
false
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
true
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
true
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
0x0b
,
sense
.
getASC
());
ASSERT_EQ
(
0x0b
,
sense
.
getASC
());
ASSERT_EQ
(
0x08
,
sense
.
getASCQ
());
ASSERT_EQ
(
0x08
,
sense
.
getASCQ
());
ASSERT_EQ
(
0xC
,
sense
.
getSenseKey
());
ASSERT_EQ
(
"Warning - power loss expected"
,
sense
.
getACSString
());
ASSERT_EQ
(
"Warning - power loss expected"
,
sense
.
getACSString
());
ASSERT_EQ
(
"Equal"
,
sense
.
getSenseKeyString
());
buff
[
2
]
=
0x40
;
buff
[
2
]
=
0x40
;
buff
[
3
]
=
0xab
;
buff
[
3
]
=
0xab
;
...
@@ -566,6 +578,9 @@ namespace unitTests {
...
@@ -566,6 +578,9 @@ namespace unitTests {
buff
[
3
]
=
0x1F
;
buff
[
3
]
=
0x1F
;
ASSERT_EQ
(
"Unknown ASC/ASCQ:00/1f"
,
sense
.
getACSString
());
ASSERT_EQ
(
"Unknown ASC/ASCQ:00/1f"
,
sense
.
getACSString
());
buff
[
1
]
=
0xF
;
ASSERT_THROW
(
sense
.
getSenseKeyString
(),
castor
::
exception
::
Exception
);
buff
[
0
]
=
0x74
;
buff
[
0
]
=
0x74
;
ASSERT_THROW
(
sense
.
getASC
(),
castor
::
exception
::
Exception
);
ASSERT_THROW
(
sense
.
getASC
(),
castor
::
exception
::
Exception
);
...
@@ -576,6 +591,20 @@ namespace unitTests {
...
@@ -576,6 +591,20 @@ namespace unitTests {
std
::
string
what
(
ex
.
getMessageValue
());
std
::
string
what
(
ex
.
getMessageValue
());
ASSERT_NE
(
std
::
string
::
npos
,
what
.
find
(
"response code not supported (0x74)"
));
ASSERT_NE
(
std
::
string
::
npos
,
what
.
find
(
"response code not supported (0x74)"
));
}
}
buff
[
1
]
=
0xA
;
ASSERT_THROW
(
sense
.
getSenseKey
(),
castor
::
exception
::
Exception
);
ASSERT_THROW
(
sense
.
getSenseKeyString
(),
castor
::
exception
::
Exception
);
try
{
sense
.
getSenseKey
();
ASSERT_TRUE
(
false
);
}
catch
(
castor
::
exception
::
Exception
&
ex
)
{
std
::
string
what
(
ex
.
getMessageValue
());
ASSERT_NE
(
std
::
string
::
npos
,
what
.
find
(
"response code not supported (0x74)"
));
}
try
{
sense
.
getSenseKeyString
();
ASSERT_TRUE
(
false
);
}
catch
(
castor
::
exception
::
Exception
&
ex
)
{
std
::
string
what
(
ex
.
getMessageValue
());
ASSERT_NE
(
std
::
string
::
npos
,
what
.
find
(
"response code not supported (0x74)"
));
}
}
}
TEST
(
castor_tape_SCSI_Structures
,
toU16
)
{
TEST
(
castor_tape_SCSI_Structures
,
toU16
)
{
...
...
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