Commit ecf6d814 authored by Victor Kotlyar's avatar Victor Kotlyar
Browse files

added implementation for the positionToLogicalObject.

We use LOCATE(10) CDB as CASTOR does.
Here we need castor.conf LOCATE_TIMEOUT environment (*to be implemented*)

Tested with mhvtl.
parent 354eee2d
......@@ -146,7 +146,7 @@ namespace Tape {
if (-1 == m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh))
throw Tape::Exceptions::Errnum("Failed SG_IO ioctl");
if (SCSI::Status::GOOD != sgh.status)
throw Tape::Exception(std::string("SCSI error in getTapeAlerts: ") +
throw Tape::Exception(std::string("SCSI error in clearCompressionStats: ") +
SCSI::statusToString(sgh.status));
}
......@@ -155,12 +155,38 @@ namespace Tape {
* @return
*/
virtual deviceInfo getDeviceInfo() throw (Exception) { throw Exception("Not implemented"); }
/**
* Position to logical object address (i.e. block). This function is non-blocking:
* the immediate bit is not set.
* Position to logical object identifier (i.e. block address).
* This function is blocking: the immediate bit is not set.
* The device server will not return status until the locate operation
* has completed.
* @param blockId The blockId, represented in local endianness.
*/
virtual void positionToLogicalObject (uint32_t blockId) throw (Exception) { throw Exception("Not implemented"); }
virtual void positionToLogicalObject (uint32_t blockId) throw (Exception) {
SCSI::Structures::locate10CDB_t cdb;
uint32_t blkId = ntohl(blockId);
memcpy (cdb.logicalObjectID, &blkId, sizeof(cdb.logicalObjectID));
SCSI::Structures::senseData_t<255> senseBuff;
SCSI::Structures::LinuxSGIO_t sgh;
sgh.setCDB(&cdb);
sgh.setSenseBuffer(&senseBuff);
sgh.dxfer_direction = SG_DXFER_NONE;
sgh.timeout = 180000; // TODO castor.conf LOCATE_TIMEOUT or default
/* Manage both system error and SCSI errors. */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh))
throw Tape::Exceptions::Errnum("Failed SG_IO ioctl");
if (SCSI::Status::GOOD != sgh.status)
throw Tape::Exception(std::string("SCSI error in positionToLogicalObject: ") +
SCSI::statusToString(sgh.status));
}
/**
* Return logical position of the drive. This is the address of the next object
* to read or write.
......
......@@ -93,6 +93,7 @@ namespace SCSI {
WRITE_10 = 0x2a,
SEEK_10 = 0x2b,
POSITION_TO_ELEMENT = 0x2b,
LOCATE_10 = 0x2b,
WRITE_VERIFY = 0x2e,
VERIFY = 0x2f,
SEARCH_HIGH = 0x30,
......
......@@ -207,6 +207,40 @@ namespace SCSI {
unsigned char vendorSpecific2[1];
};
/*
* LOCATE(10) CDB as described in SSC-3.
*/
class locate10CDB_t {
public:
locate10CDB_t() {
zeroStruct(this);
opCode = SCSI::Commands::LOCATE_10;
}
// byte 0
unsigned char opCode; // OPERATION CODE (2Bh)
// byte 1
unsigned char IMMED : 1; // Immediate
unsigned char CP : 1; // Change Partition
unsigned char BT : 1; // Block address Type
unsigned char : 5; // Reserved
// byte 2
unsigned char : 8; // Reserved
// bytes 3-6
unsigned char logicalObjectID[4] ; // Logical object identifier or block address
// byte 7
unsigned char :8; // Reserved
// byte 8
unsigned char partition; // Partition
// byte 9
unsigned char control; // Control byte
};
/*
* LOG SELECT CDB as described in SPC-4.
*/
......
......@@ -217,6 +217,47 @@ namespace UnitTests {
ASSERT_EQ(0xBC, logSenseCDB.control);
}
TEST(SCSI_Structures, locate10CDB_t) {
SCSI::Structures::locate10CDB_t locate10CDB;
unsigned char *buff = (unsigned char *)&locate10CDB;
/*
* Make sure this struct is a POD (plain old data without virtual table)
* (and has the right size).
*/
ASSERT_EQ(10, sizeof(locate10CDB)); // that is why it called locate 10
/* Check proper initialization an location of struct members match
the bit/byte locations defined in SPC-4 */
ASSERT_EQ(SCSI::Commands::LOCATE_10, locate10CDB.opCode);
buff[0] = 0xAB;
ASSERT_EQ(0xAB, locate10CDB.opCode);
ASSERT_EQ(0, locate10CDB.IMMED);
buff[1] |= (0x1 & 0x7) << 0;
ASSERT_EQ(1, locate10CDB.IMMED);
ASSERT_EQ(0, locate10CDB.CP);
buff[1] |= (0x1 & 0xF) << 1;
ASSERT_EQ(1, locate10CDB.CP);
ASSERT_EQ(0, locate10CDB.BT);
buff[1] |= (0x1 & 0xF) << 2;
ASSERT_EQ(1, locate10CDB.BT);
ASSERT_EQ(0, SCSI::Structures::toU32(locate10CDB.logicalObjectID));
buff[3] |= 0x0A;buff[4] |= 0xBC;buff[5] |= 0xDE;buff[6] |= 0xF0;
ASSERT_EQ(0x0ABCDEF0, SCSI::Structures::toU32(locate10CDB.logicalObjectID));
ASSERT_EQ(0, locate10CDB.partition);
buff[8] = 0xAB;
ASSERT_EQ(0xAB, locate10CDB.partition);
ASSERT_EQ(0, locate10CDB.control);
buff[9] |= 0xBC;
ASSERT_EQ(0xBC, locate10CDB.control);
}
TEST(SCSI_Structures, tapeAlertLogPage_t_and_parameters) {
SCSI::Structures::tapeAlertLogPage_t<12> tal;
unsigned char * buff = (unsigned char *) & tal;
......@@ -313,6 +354,11 @@ namespace UnitTests {
ASSERT_EQ( 0x1020304, SCSI::Structures::toU32(num));
}
TEST(SCSI_Structures, toS32) {
unsigned char num[4] = { 0xE6, 0x29, 0x66, 0x5B };
ASSERT_EQ( -433494437, SCSI::Structures::toS32(num));
}
TEST(SCSI_Structures, toU64) {
unsigned char num[8] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xFA, 0xDE };
ASSERT_EQ ( 0xDEADBEEFCAFEFADEULL, SCSI::Structures::toU64(num));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment