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
d4374ac4
Commit
d4374ac4
authored
Feb 24, 2016
by
Julien Leduc
Browse files
0011-Add-unittest-for-SCSI-commands-for-working-with-Logi.patch
parent
fee555fd
Changes
11
Hide whitespace changes
Inline
Side-by-side
tapeserver/castor/tape/tapeserver/SCSI/Constants.cpp
View file @
d4374ac4
...
...
@@ -1103,8 +1103,20 @@ const char * const castor::tape::SCSI::senseKeys::senseKeysText[] = {
do not agree */
};
/* names for the logical block protection methods */
const
char
*
const
castor
::
tape
::
SCSI
::
LBPMethods
::
LBPMethodsName
[]
=
{
"Reed-Solomon"
,
"CRC32C"
};
//------------------------------------------------------------------------------
// LBPMethodToString
//------------------------------------------------------------------------------
std
::
string
castor
::
tape
::
SCSI
::
LBPMethodToString
(
const
unsigned
char
LBPMethod
)
{
switch
(
LBPMethod
)
{
case
LBPMethods
::
Disabled
:
return
"Disabled"
;
case
LBPMethods
::
ReedSolomon
:
return
"Reed-Solomon"
;
case
LBPMethods
::
CRC32C
:
return
"CRC32C"
;
default:
return
"Unknown"
;
}
}
\ No newline at end of file
tapeserver/castor/tape/tapeserver/SCSI/Constants.hpp
View file @
d4374ac4
...
...
@@ -391,15 +391,27 @@ namespace SCSI {
class
LBPMethods
{
public:
enum
{
Disabled
=
0x00
,
// do not use logical block protection
ReedSolomon
=
0x01
,
// Reed-Solomon CRC as specified in ECMA-319
CRC32C
=
0x02
// CRC32C polynomial as specified for iSCSI
};
enum
{
ReedSolomonLeg
h
t
=
4
,
// Reed-Solomon CRC length in bytes
CRC32CLeng
h
t
=
4
// CRC32C length in bytes
ReedSolomonLegt
h
=
4
,
// Reed-Solomon CRC length in bytes
CRC32CLengt
h
=
4
// CRC32C length in bytes
};
static
const
char
*
const
LBPMethodsName
[];
};
};
/**
* Turn a LBP method code into a string
* @param LBPmethod The integer presentation of Logical Block Protection method
* @return The string presentation for LBP method or Unknown if method
* unknown.
*/
std
::
string
LBPMethodToString
(
const
unsigned
char
LBPMethod
);
/**
* Addition for the mode page Length for the Control Data Protection Mode Page
*/
const
unsigned
char
controlDataProtectionModePageLengthAddition
=
4
;
}
// namespace SCSI
}
// namespace tape
}
// namespace castor
tapeserver/castor/tape/tapeserver/SCSI/StructuresTest.cpp
View file @
d4374ac4
...
...
@@ -474,7 +474,38 @@ namespace unitTests {
buff
[
26
]
|=
0xEF
;
ASSERT_EQ
(
0xEFU
,
devConfig
.
modePage
.
selectDataComprAlgorithm
);
}
TEST
(
castor_tape_SCSI_Structures
,
modeSenseControlDataProtection_t
)
{
castor
::
tape
::
SCSI
::
Structures
::
modeSenseControlDataProtection_t
dataProt
;
unsigned
char
*
buff
=
(
unsigned
char
*
)
&
dataProt
;
/*
* Make sure this struct is a POD (plain old data without virtual table)
* (and has the right size).
*/
ASSERT_EQ
(
44U
,
sizeof
(
dataProt
));
ASSERT_EQ
(
4U
,
sizeof
(
dataProt
.
header
));
ASSERT_EQ
(
8U
,
sizeof
(
dataProt
.
blockDescriptor
));
ASSERT_EQ
(
32U
,
sizeof
(
dataProt
.
modePage
));
/* We will only check used by us parameters */
ASSERT_EQ
(
0U
,
dataProt
.
header
.
modeDataLength
);
buff
[
0
]
|=
0xAC
;
ASSERT_EQ
(
0xACU
,
dataProt
.
header
.
modeDataLength
);
for
(
int
i
=
1
;
i
<=
15
;
i
++
)
buff
[
i
]
=
0xFF
;
// fill the space
ASSERT_EQ
(
0U
,
dataProt
.
modePage
.
LBPMethod
);
buff
[
16
]
|=
0xEF
;
ASSERT_EQ
(
0xEFU
,
dataProt
.
modePage
.
LBPMethod
);
ASSERT_EQ
(
0U
,
dataProt
.
modePage
.
LBPInformationLength
);
buff
[
17
]
|=
0xDF
;
ASSERT_EQ
(
0x1FU
,
dataProt
.
modePage
.
LBPInformationLength
);
ASSERT_EQ
(
0U
,
dataProt
.
modePage
.
LBP_W
);
buff
[
18
]
|=
0x8F
;
ASSERT_EQ
(
0x1U
,
dataProt
.
modePage
.
LBP_W
);
ASSERT_EQ
(
0U
,
dataProt
.
modePage
.
LBP_R
);
buff
[
18
]
|=
0x4F
;
ASSERT_EQ
(
0x1U
,
dataProt
.
modePage
.
LBP_R
);
}
TEST
(
castor_tape_SCSI_Structures
,
tapeAlertLogPage_t_and_parameters
)
{
castor
::
tape
::
SCSI
::
Structures
::
tapeAlertLogPage_t
<
12
>
tal
;
unsigned
char
*
buff
=
(
unsigned
char
*
)
&
tal
;
...
...
tapeserver/castor/tape/tapeserver/drive/DriveGeneric.cpp
View file @
d4374ac4
...
...
@@ -116,7 +116,7 @@ drive::deviceInfo drive::DriveGeneric::getDeviceInfo() {
devInfo
.
productRevisionLevel
=
SCSI
::
Structures
::
toString
(
inquiryData
.
prodRevLvl
);
devInfo
.
vendor
=
SCSI
::
Structures
::
toString
(
inquiryData
.
T10Vendor
);
devInfo
.
serialNumber
=
getSerialNumber
();
devInfo
.
isPIsupported
=
inquiryData
.
protect
;
return
devInfo
;
}
...
...
@@ -389,22 +389,23 @@ void drive::DriveGeneric::setLogicalBlockProtection(
SCSI
::
Structures
::
senseData_t
<
255
>
senseBuff
;
SCSI
::
Structures
::
LinuxSGIO_t
sgh
;
cdb
.
PF
=
0
;
// required for IBM, LTO, not supported for T10000
cdb
.
paramListLength
=
sizeof
(
controlDataProtection
);
cdb
.
PF
=
1
;
// means nothing for IBM, LTO, T10000
cdb
.
paramListLength
=
sizeof
(
controlDataProtection
.
header
)
+
sizeof
(
controlDataProtection
.
blockDescriptor
)
+
SCSI
::
controlDataProtectionModePageLengthAddition
+
SCSI
::
Structures
::
toU16
(
controlDataProtection
.
modePage
.
pageLength
);
if
(
cdb
.
paramListLength
>
sizeof
(
controlDataProtection
))
{
// should never happen
throw
castor
::
exception
::
Exception
(
std
::
string
(
"cdb.paramListLength greater then size "
"of controlDataProtection in setLogicalBlockProtection"
));
}
controlDataProtection
.
header
.
modeDataLength
=
0
;
// must be 0 for IBM, LTO
// ignored by T10000
controlDataProtection
.
modePage
.
LBPMethod
=
method
;
controlDataProtection
.
modePage
.
LBPInformationLength
=
methodLength
;
if
(
enableLBPforWrite
)
{
controlDataProtection
.
modePage
.
LBP_W
=
1
;
}
else
{
controlDataProtection
.
modePage
.
LBP_W
=
0
;
}
if
(
enableLBPforRead
)
{
controlDataProtection
.
modePage
.
LBP_R
=
1
;
}
else
{
controlDataProtection
.
modePage
.
LBP_R
=
0
;
}
controlDataProtection
.
modePage
.
LBP_W
=
enableLBPforWrite
;
controlDataProtection
.
modePage
.
LBP_R
=
enableLBPforRead
;
sgh
.
setCDB
(
&
cdb
);
sgh
.
setDataBuffer
(
&
controlDataProtection
);
...
...
@@ -426,7 +427,7 @@ void drive::DriveGeneric::setLogicalBlockProtection(
//------------------------------------------------------------------------------
void
drive
::
DriveGeneric
::
enableCRC32CLogicalBlockProtectionReadOnly
()
{
setLogicalBlockProtection
(
SCSI
::
LBPMethods
::
CRC32C
,
SCSI
::
LBPMethods
::
CRC32CLeng
h
t
,
true
,
false
);
SCSI
::
LBPMethods
::
CRC32CLengt
h
,
true
,
false
);
}
//------------------------------------------------------------------------------
...
...
@@ -434,7 +435,23 @@ void drive::DriveGeneric::enableCRC32CLogicalBlockProtectionReadOnly() {
//------------------------------------------------------------------------------
void
drive
::
DriveGeneric
::
enableCRC32CLogicalBlockProtectionReadWrite
()
{
setLogicalBlockProtection
(
SCSI
::
LBPMethods
::
CRC32C
,
SCSI
::
LBPMethods
::
CRC32CLenght
,
true
,
true
);
SCSI
::
LBPMethods
::
CRC32CLength
,
true
,
true
);
}
//------------------------------------------------------------------------------
// enableReedSolomonLogicalBlockProtectionReadOnly
//------------------------------------------------------------------------------
void
drive
::
DriveGeneric
::
enableReedSolomonLogicalBlockProtectionReadOnly
()
{
setLogicalBlockProtection
(
SCSI
::
LBPMethods
::
ReedSolomon
,
SCSI
::
LBPMethods
::
ReedSolomonLegth
,
true
,
false
);
}
//------------------------------------------------------------------------------
// enableReedSolomonLogicalBlockProtectionReadWrite
//------------------------------------------------------------------------------
void
drive
::
DriveGeneric
::
enableReedSolomonLogicalBlockProtectionReadWrite
()
{
setLogicalBlockProtection
(
SCSI
::
LBPMethods
::
ReedSolomon
,
SCSI
::
LBPMethods
::
ReedSolomonLegth
,
true
,
true
);
}
//------------------------------------------------------------------------------
...
...
@@ -443,7 +460,44 @@ void drive::DriveGeneric::enableCRC32CLogicalBlockProtectionReadWrite() {
void
drive
::
DriveGeneric
::
disableLogicalBlockProtection
()
{
setLogicalBlockProtection
(
0
,
0
,
false
,
false
);
}
//------------------------------------------------------------------------------
// getLBPInfo
//------------------------------------------------------------------------------
drive
::
LBPInfo
drive
::
DriveGeneric
::
getLBPInfo
()
{
SCSI
::
Structures
::
modeSenseControlDataProtection_t
controlDataProtection
;
drive
::
LBPInfo
LBPdata
;
/* fetch Control Data Protection */
SCSI
::
Structures
::
modeSense6CDB_t
cdb
;
SCSI
::
Structures
::
senseData_t
<
255
>
senseBuff
;
SCSI
::
Structures
::
LinuxSGIO_t
sgh
;
cdb
.
pageCode
=
SCSI
::
modeSensePages
::
controlDataProtection
;
cdb
.
subPageCode
=
SCSI
::
modePageControlDataProtection
::
subpageCode
;
cdb
.
allocationLength
=
sizeof
(
controlDataProtection
);
sgh
.
setCDB
(
&
cdb
);
sgh
.
setDataBuffer
(
&
controlDataProtection
);
sgh
.
setSenseBuffer
(
&
senseBuff
);
sgh
.
dxfer_direction
=
SG_DXFER_FROM_DEV
;
/* Manage both system error and SCSI errors. */
castor
::
exception
::
Errnum
::
throwOnMinusOne
(
m_sysWrapper
.
ioctl
(
m_tapeFD
,
SG_IO
,
&
sgh
),
"Failed SG_IO ioctl"
);
SCSI
::
ExceptionLauncher
(
sgh
,
std
::
string
(
"SCSI error fetching data in getLBPInfo: "
)
+
SCSI
::
statusToString
(
sgh
.
status
));
LBPdata
.
method
=
controlDataProtection
.
modePage
.
LBPMethod
;
LBPdata
.
methodLength
=
controlDataProtection
.
modePage
.
LBPInformationLength
;
LBPdata
.
enableLBPforRead
=
(
1
==
controlDataProtection
.
modePage
.
LBP_R
);
LBPdata
.
enableLBPforWrite
=
(
1
==
controlDataProtection
.
modePage
.
LBP_W
);
return
LBPdata
;
}
/**
* Function that checks if a tape is blank (contains no records)
* @return true if tape is blank, false otherwise
...
...
tapeserver/castor/tape/tapeserver/drive/DriveGeneric.hpp
View file @
d4374ac4
...
...
@@ -352,20 +352,45 @@ namespace drive {
void
SCSI_inquiry
();
/**
* TOFILL
* Enable Logical Block Protection on the drive for reading only.
* Set method CRC32C to be used.
*/
virtual
void
enableCRC32CLogicalBlockProtectionReadOnly
();
/**
* TOFILL
* Enable Logical Block Protection on the drive for reading and writing.
* Set method CRC32C to be used.
*/
virtual
void
enableCRC32CLogicalBlockProtectionReadWrite
();
/**
* Enable Logical Block Protection on the drive for reading only.
* Set method Reed-Solomon to be used.
*/
virtual
void
enableReedSolomonLogicalBlockProtectionReadOnly
();
/**
* TOFILL
* Enable Logical Block Protection on the drive for reading and writing.
* Set method Reed-Solomon to be used.
*/
virtual
void
enableReedSolomonLogicalBlockProtectionReadWrite
();
/**
* Disable Logical Block Protection on the drive.
*/
virtual
void
disableLogicalBlockProtection
();
/**
* Return Logical Block Protection Information of the drive.
*
* We use MODE SENSE Control Data Protection (0Ah) mode page as
* described in SSC-5.
*
* @return LBPInfo class. This contains the LBP method to be used for
* Logical Block Protection, the method length, the status if LBP enabled
* for reading and the status if LBP enabled for writing.
*/
virtual
LBPInfo
getLBPInfo
();
protected:
SCSI
::
DeviceInfo
m_SCSIInfo
;
int
m_tapeFD
;
...
...
@@ -384,7 +409,15 @@ namespace drive {
void
waitTestUnitReady
(
const
uint32_t
timeoutSecond
);
/**
* TOFILL
* Set the tape Logical Block Protection.
* We use MODE SENSE/SELECT Control Data Protection (0Ah) mode page as
* described in SSC-5.
*
* @param method The LBP method to be set.
* @param methodLength The method length in bytes.
* @param enableLPBforRead Should be LBP set for reading.
* @param enableLBBforWrite Should be LBP set for writing.
*
*/
virtual
void
setLogicalBlockProtection
(
const
unsigned
char
method
,
unsigned
char
methodLength
,
const
bool
enableLPBforRead
,
...
...
tapeserver/castor/tape/tapeserver/drive/DriveInterface.hpp
View file @
d4374ac4
...
...
@@ -75,6 +75,7 @@ namespace drive {
std
::
string
product
;
std
::
string
productRevisionLevel
;
std
::
string
serialNumber
;
bool
isPIsupported
;
};
/**
...
...
@@ -90,6 +91,17 @@ namespace drive {
uint32_t
dirtyBytesCount
;
};
/**
* Logical block protection nformation, returned by getLBPInfo()
*/
class
LBPInfo
{
public:
unsigned
char
method
;
unsigned
char
methodLength
;
bool
enableLBPforRead
;
bool
enableLBPforWrite
;
};
/**
*
*/
...
...
@@ -160,6 +172,15 @@ namespace drive {
virtual
std
::
vector
<
std
::
string
>
getTapeAlertsCompact
(
const
std
::
vector
<
uint16_t
>&
)
=
0
;
virtual
void
setDensityAndCompression
(
bool
compression
=
true
,
unsigned
char
densityCode
=
0
)
=
0
;
virtual
void
enableCRC32CLogicalBlockProtectionReadOnly
()
=
0
;
virtual
void
enableCRC32CLogicalBlockProtectionReadWrite
()
=
0
;
virtual
void
enableReedSolomonLogicalBlockProtectionReadOnly
()
=
0
;
virtual
void
enableReedSolomonLogicalBlockProtectionReadWrite
()
=
0
;
virtual
void
disableLogicalBlockProtection
()
=
0
;
virtual
drive
::
LBPInfo
getLBPInfo
()
=
0
;
virtual
void
setLogicalBlockProtection
(
const
unsigned
char
method
,
unsigned
char
methodLength
,
const
bool
enableLPBforRead
,
const
bool
enableLBBforWrite
)
=
0
;
virtual
driveStatus
getDriveStatus
()
=
0
;
virtual
tapeError
getTapeError
()
=
0
;
virtual
void
setSTBufferWrite
(
bool
bufWrite
)
=
0
;
...
...
tapeserver/castor/tape/tapeserver/drive/DriveTest.cpp
View file @
d4374ac4
...
...
@@ -235,13 +235,15 @@ TEST(castor_tape_drive_Drive, getDeviceInfo) {
castor
::
tape
::
tapeserver
::
drive
::
createDrive
(
*
i
,
sysWrapper
));
castor
::
tape
::
tapeserver
::
drive
::
deviceInfo
devInfo
;
EXPECT_CALL
(
sysWrapper
,
ioctl
(
_
,
_
,
An
<
sg_io_hdr_t
*>
())).
Times
(
2
);
devInfo
.
isPIsupported
=
false
;
EXPECT_CALL
(
sysWrapper
,
ioctl
(
_
,
_
,
An
<
sg_io_hdr_t
*>
())).
Times
(
2
);
devInfo
=
drive
->
getDeviceInfo
();
ASSERT_EQ
(
"STK "
,
devInfo
.
vendor
);
ASSERT_EQ
(
"T10000B "
,
devInfo
.
product
);
ASSERT_EQ
(
"0104"
,
devInfo
.
productRevisionLevel
);
ASSERT_EQ
(
"XYZZY_A2 "
,
devInfo
.
serialNumber
);
ASSERT_TRUE
(
devInfo
.
isPIsupported
);
}
}
}
...
...
@@ -343,6 +345,45 @@ TEST(castor_tape_drive_Drive, getCompressionAndClearCompressionStats) {
}
}
TEST
(
castor_tape_drive_Drive
,
getLBPInfo
)
{
/* Prepare the test harness */
castor
::
tape
::
System
::
mockWrapper
sysWrapper
;
sysWrapper
.
fake
.
setupSLC5
();
sysWrapper
.
delegateToFake
();
/* We expect the following calls: */
EXPECT_CALL
(
sysWrapper
,
opendir
(
_
)).
Times
(
AtLeast
(
3
));
EXPECT_CALL
(
sysWrapper
,
readdir
(
_
)).
Times
(
AtLeast
(
30
));
EXPECT_CALL
(
sysWrapper
,
closedir
(
_
)).
Times
(
AtLeast
(
3
));
EXPECT_CALL
(
sysWrapper
,
realpath
(
_
,
_
)).
Times
(
3
);
EXPECT_CALL
(
sysWrapper
,
open
(
_
,
_
)).
Times
(
21
);
EXPECT_CALL
(
sysWrapper
,
read
(
_
,
_
,
_
)).
Times
(
38
);
EXPECT_CALL
(
sysWrapper
,
write
(
_
,
_
,
_
)).
Times
(
0
);
EXPECT_CALL
(
sysWrapper
,
ioctl
(
_
,
_
,
An
<
mtget
*>
())).
Times
(
0
);
EXPECT_CALL
(
sysWrapper
,
close
(
_
)).
Times
(
21
);
EXPECT_CALL
(
sysWrapper
,
readlink
(
_
,
_
,
_
)).
Times
(
3
);
EXPECT_CALL
(
sysWrapper
,
stat
(
_
,
_
)).
Times
(
7
);
/* Test: detect devices, then open the device files */
castor
::
tape
::
SCSI
::
DeviceVector
dl
(
sysWrapper
);
for
(
std
::
vector
<
castor
::
tape
::
SCSI
::
DeviceInfo
>::
iterator
i
=
dl
.
begin
();
i
!=
dl
.
end
();
i
++
)
{
if
(
castor
::
tape
::
SCSI
::
Types
::
tape
==
i
->
type
)
{
std
::
unique_ptr
<
castor
::
tape
::
tapeserver
::
drive
::
DriveInterface
>
drive
(
castor
::
tape
::
tapeserver
::
drive
::
createDrive
(
*
i
,
sysWrapper
));
castor
::
tape
::
tapeserver
::
drive
::
LBPInfo
LBPdata
;
EXPECT_CALL
(
sysWrapper
,
ioctl
(
_
,
_
,
An
<
sg_io_hdr_t
*>
())).
Times
(
1
);
LBPdata
=
drive
->
getLBPInfo
();
ASSERT_EQ
(
castor
::
tape
::
SCSI
::
LBPMethods
::
CRC32C
,
LBPdata
.
method
);
ASSERT_EQ
(
castor
::
tape
::
SCSI
::
LBPMethods
::
CRC32CLength
,
LBPdata
.
methodLength
);
ASSERT_TRUE
(
LBPdata
.
enableLBPforRead
);
ASSERT_TRUE
(
LBPdata
.
enableLBPforWrite
);
}
}
}
TEST
(
castor_tape_drive_Drive
,
getTapeAlerts
)
{
/**
...
...
tapeserver/castor/tape/tapeserver/drive/FakeDrive.cpp
View file @
d4374ac4
...
...
@@ -63,6 +63,7 @@ castor::tape::tapeserver::drive::deviceInfo castor::tape::tapeserver::drive::Fak
devInfo
.
productRevisionLevel
=
"0.1"
;
devInfo
.
vendor
=
"ACME Ind"
;
devInfo
.
serialNumber
=
"123456"
;
devInfo
.
isPIsupported
=
true
;
return
devInfo
;
}
std
::
string
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
getSerialNumber
()
{
...
...
@@ -105,6 +106,29 @@ void castor::tape::tapeserver::drive::FakeDrive::setDensityAndCompression(bool c
castor
::
tape
::
tapeserver
::
drive
::
driveStatus
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
getDriveStatus
()
{
throw
castor
::
exception
::
Exception
(
"FakeDrive::getDriveStatus Not implemented"
);
}
void
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
enableCRC32CLogicalBlockProtectionReadOnly
()
{
throw
castor
::
exception
::
Exception
(
"FakeDrive::enableCRC32CLogicalBlockProtectionReadOnly Not implemented"
);
}
void
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
enableCRC32CLogicalBlockProtectionReadWrite
()
{
throw
castor
::
exception
::
Exception
(
"FakeDrive::enableCRC32CLogicalBlockProtectionReadWrite Not implemented"
);
}
void
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
enableReedSolomonLogicalBlockProtectionReadOnly
()
{
throw
castor
::
exception
::
Exception
(
"FakeDrive::enableReedSolomonLogicalBlockProtectionReadOnly Not implemented"
);
}
void
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
enableReedSolomonLogicalBlockProtectionReadWrite
()
{
throw
castor
::
exception
::
Exception
(
"FakeDrive::enableCReedSolomonLogicalBlockProtectionReadWrite Not implemented"
);
}
void
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
disableLogicalBlockProtection
()
{
throw
castor
::
exception
::
Exception
(
"FakeDrive::disableLogicalBlockProtection Not implemented"
);
}
castor
::
tape
::
tapeserver
::
drive
::
LBPInfo
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
getLBPInfo
()
{
throw
castor
::
exception
::
Exception
(
"FakeDrive::dgetLBPInfo Not implemented"
);
}
void
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
setLogicalBlockProtection
(
const
unsigned
char
method
,
unsigned
char
methodLength
,
const
bool
enableLPBforRead
,
const
bool
enableLBBforWrite
)
{
throw
castor
::
exception
::
Exception
(
"FakeDrive::setLogicalBlockProtection Not implemented"
);
}
castor
::
tape
::
tapeserver
::
drive
::
tapeError
castor
::
tape
::
tapeserver
::
drive
::
FakeDrive
::
getTapeError
()
{
throw
castor
::
exception
::
Exception
(
"FakeDrive::getTapeError Not implemented"
);
}
...
...
tapeserver/castor/tape/tapeserver/drive/FakeDrive.hpp
View file @
d4374ac4
...
...
@@ -68,6 +68,15 @@ namespace drive {
virtual
std
::
vector
<
std
::
string
>
getTapeAlertsCompact
(
const
std
::
vector
<
uint16_t
>&
)
;
virtual
void
setDensityAndCompression
(
bool
compression
=
true
,
unsigned
char
densityCode
=
0
)
;
virtual
void
enableCRC32CLogicalBlockProtectionReadOnly
()
;
virtual
void
enableCRC32CLogicalBlockProtectionReadWrite
()
;
virtual
void
enableReedSolomonLogicalBlockProtectionReadOnly
()
;
virtual
void
enableReedSolomonLogicalBlockProtectionReadWrite
()
;
virtual
void
disableLogicalBlockProtection
()
;
virtual
drive
::
LBPInfo
getLBPInfo
();
virtual
void
setLogicalBlockProtection
(
const
unsigned
char
method
,
unsigned
char
methodLength
,
const
bool
enableLPBforRead
,
const
bool
enableLBBforWrite
);
virtual
driveStatus
getDriveStatus
()
;
virtual
tapeError
getTapeError
()
;
virtual
void
setSTBufferWrite
(
bool
bufWrite
)
;
...
...
tapeserver/castor/tape/tapeserver/system/FileWrappers.cpp
View file @
d4374ac4
...
...
@@ -105,6 +105,10 @@ System::stDeviceFile::stDeviceFile()
blockID
=
0xFFFFFFFF
;
// Logical Object ID - position on tape
clearCompressionStats
=
false
;
m_LBPInfoMethod
=
SCSI
::
LBPMethods
::
CRC32C
;
m_LBPInfoLength
=
SCSI
::
LBPMethods
::
CRC32CLength
;
m_LBPInfo_R
=
1
;
m_LBPInfo_W
=
1
;
}
int
System
::
stDeviceFile
::
ioctl
(
unsigned
long
int
request
,
struct
mtop
*
mt_cmd
)
...
...
@@ -417,6 +421,20 @@ int System::stDeviceFile::ioctlModSense6(sg_io_hdr_t * sgio_h) {
errno
=
EINVAL
;
return
-
1
;
}
SCSI
::
Structures
::
modeSense6CDB_t
&
cdb
=
*
(
SCSI
::
Structures
::
modeSense6CDB_t
*
)
sgio_h
->
cmdp
;
switch
(
cdb
.
pageCode
)
{
case
SCSI
::
modeSensePages
::
deviceConfiguration
:
return
modeSenseDeviceConfiguration
(
sgio_h
);
case
SCSI
::
modeSensePages
::
controlDataProtection
:
return
modeSenseControlDataProtection
(
sgio_h
);
}
errno
=
EINVAL
;
return
-
1
;
}
int
System
::
stDeviceFile
::
modeSenseDeviceConfiguration
(
sg_io_hdr_t
*
sgio_h
)
{
SCSI
::
Structures
::
modeSense6CDB_t
&
cdb
=
*
(
SCSI
::
Structures
::
modeSense6CDB_t
*
)
sgio_h
->
cmdp
;
if
(
SCSI
::
modeSensePages
::
deviceConfiguration
!=
cdb
.
pageCode
)
{
...
...
@@ -436,6 +454,38 @@ int System::stDeviceFile::ioctlModSense6(sg_io_hdr_t * sgio_h) {
return
0
;
}
int
System
::
stDeviceFile
::
modeSenseControlDataProtection
(
sg_io_hdr_t
*
sgio_h
)
{
SCSI
::
Structures
::
modeSense6CDB_t
&
cdb
=
*
(
SCSI
::
Structures
::
modeSense6CDB_t
*
)
sgio_h
->
cmdp
;
if
(
SCSI
::
modeSensePages
::
controlDataProtection
!=
cdb
.
pageCode
)
{
errno
=
EINVAL
;
return
-
1
;
}
if
(
cdb
.
subPageCode
!=
SCSI
::
modePageControlDataProtection
::
subpageCode
)
{
errno
=
EINVAL
;
return
-
1
;
}
SCSI
::
Structures
::
modeSenseControlDataProtection_t
&
controlDataProtection
=
*
(
SCSI
::
Structures
::
modeSenseControlDataProtection_t
*
)
sgio_h
->
dxferp
;
if
(
sizeof
(
controlDataProtection
)
>
sgio_h
->
dxfer_len
)
{
errno
=
EINVAL
;
return
-
1
;
}
/* fill the replay with random data */
srandom
(
SCSI
::
Commands
::
MODE_SENSE_6
);
memset
(
sgio_h
->
dxferp
,
random
(),
sizeof
(
controlDataProtection
));
controlDataProtection
.
modePage
.
LBPMethod
=
m_LBPInfoMethod
;
controlDataProtection
.
modePage
.
LBPInformationLength
=
m_LBPInfoLength
;
controlDataProtection
.
modePage
.
LBP_R
=
m_LBPInfo_R
;
controlDataProtection
.
modePage
.
LBP_W
=
m_LBPInfo_W
;
return
0
;
}
int
System
::
stDeviceFile
::
ioctlModSelect6
(
sg_io_hdr_t
*
sgio_h
)
{
if
(
SG_DXFER_TO_DEV
!=
sgio_h
->
dxfer_direction
)
{
errno
=
EINVAL
;
...
...
@@ -494,6 +544,7 @@ int System::stDeviceFile::ioctlInquiry(sg_io_hdr_t * sgio_h) {
memcpy
(
inqData
.
prodRevLvl
,
prodRevLvl
,
sizeof
(
inqData
.
prodRevLvl
));
const
char
*
T10Vendor
=
"STK "
;
memcpy
(
inqData
.
T10Vendor
,
T10Vendor
,
sizeof
(
inqData
.
T10Vendor
));
inqData
.
protect
=
1
;
}
else
if
(
1
==
cdb
.
EVPD
&&
SCSI
::
inquiryVPDPages
::
unitSerialNumber
==
cdb
.
pageCode
)
{
/* the unit serial number VPD page is returned*/
SCSI
::
Structures
::
inquiryUnitSerialNumberData_t
&
inqSerialData
=
...
...
tapeserver/castor/tape/tapeserver/system/FileWrappers.hpp
View file @
d4374ac4
...
...
@@ -78,6 +78,10 @@ namespace System {
struct
mtop
m_mtCmd
;
uint32_t
blockID
;
bool
clearCompressionStats
;
unsigned
char
m_LBPInfoMethod
;
unsigned
char
m_LBPInfoLength
;
unsigned
char
m_LBPInfo_R
;
unsigned
char
m_LBPInfo_W
;
/**
* This function handles READ_POSITION CDB and prepares the replay.
*
...
...
@@ -199,6 +203,33 @@ namespace System {
* -1 with appropriate errno if an error occurred.
*/
int
logSenseTapeAlerts
(
sg_io_hdr_t
*
sgio_h
);
/**
* This function only checks the corectness of the parameters in sg_io_hdr_t
* sturcture and returns random data.
*
* @param sgio_h The pointer to the sg_io_hdr_t structure with
* ioctl call data
* @return Returns 0 in success and
* -1 with appropriate errno if an error occurred.
*/
int
modeSenseDeviceConfiguration
(
sg_io_hdr_t
*
sgio_h
);
/**
* This function checks the corectness of the parameters in sg_io_hdr_t and
* returns filled filds:
* controlDataProtection.modePage.LBPMethod
* controlDataProtection.modePage.LBPInformationLength
* controlDataProtection.modePage.LBP_R
* controlDataProtection.modePage.LBP_W
* All other filds in SCSI replay are random.
*
* @param sgio_h The pointer to the sg_io_hdr_t structure with
* ioctl call data
* @return Returns 0 in success and
* -1 with appropriate errno if an error occurred.
*/
int
modeSenseControlDataProtection
(
sg_io_hdr_t
*
sgio_h
);
};
}
// namespace System
}
// namespace tape
...
...
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