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

added implementation for the getCompression for LTO and IBM.

As soon as mhvtl does not support LogPages 32h and 38h it is not tested.
parent 19d06ead
......@@ -39,6 +39,8 @@ namespace Tape {
*/
class compressionStats{
public:
compressionStats():
fromHost(0),fromTape(0),toHost(0),toTape(0) {}
uint64_t fromHost;
uint64_t fromTape;
uint64_t toHost;
......@@ -328,9 +330,9 @@ class DriveT10000 : public Drive<sysWrapperClass> {
driveCompressionStats.toHost = SCSI::Structures::toU64(reinterpret_cast<unsigned char(&)[8]>(logPageParam.parameterValue));
break;
}
logParameter += logPageParam.header.parameterLength + sizeof(logPageParam.header);
}
logParameter += logPageParam.header.parameterLength + sizeof(logPageParam.header);
}
return driveCompressionStats;
}
};
......@@ -339,13 +341,144 @@ template <class sysWrapperClass>
class DriveLTO : public Drive<sysWrapperClass> {
public:
DriveLTO(SCSI::DeviceInfo di, sysWrapperClass & sw): Drive<sysWrapperClass>(di, sw) {}
virtual compressionStats getCompression() throw (Exception) { throw Exception("Not implemented"); }
virtual compressionStats getCompression() throw (Exception) {
SCSI::Structures::logSenseCDB_t cdb;
compressionStats driveCompressionStats;
unsigned char dataBuff[1024];
unsigned char senseBuff[255];
memset (dataBuff, 0, sizeof (dataBuff));
memset (senseBuff, 0, sizeof (senseBuff));
cdb.pageCode = SCSI::logSensePages::dataCompression32h;
cdb.PC = 0x01; // Current Comulative Values
cdb.allocationLength[0] = (sizeof(dataBuff) & 0xFF00) >> 8;
cdb.allocationLength[1] = sizeof(dataBuff) & 0x00FF;
SCSI::Structures::LinuxSGIO_t sgh;
sgh.setCDB(&cdb);
sgh.setDataBuffer(&dataBuff);
sgh.setSenseBuffer(&senseBuff);
sgh.dxfer_direction = SG_DXFER_FROM_DEV;
/* Manage both system error and SCSI errors. */
if (-1 == this->m_sysWrapper.ioctl(this->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 getCompression: ") +
SCSI::statusToString(sgh.status));
SCSI::Structures::logSenseLogPageHeader_t & logPageHeader =
*(SCSI::Structures::logSenseLogPageHeader_t *) dataBuff;
unsigned char *endPage = dataBuff +
SCSI::Structures::toU16(logPageHeader.pageLength)+sizeof(logPageHeader);
unsigned char *logParameter = dataBuff+sizeof(logPageHeader);
const uint64_t mb = 1000000; // Mega bytes as power of 10
while ( logParameter < endPage ) { /* values in MB and Bytes */
SCSI::Structures::logSenseParameter_t & logPageParam =
*(SCSI::Structures::logSenseParameter_t *) logParameter;
std::cout << SCSI::Structures::toU16(logPageParam.header.parameterCode) <<std::endl;
switch (SCSI::Structures::toU16(logPageParam.header.parameterCode)) {
// fromHost
case SCSI::dataCompression32h::mbTransferredFromServer :
driveCompressionStats.fromHost = SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue)) * mb;
break;
case SCSI::dataCompression32h::bytesTransferredFromServer :
driveCompressionStats.fromHost += SCSI::Structures::toS32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue));
break;
// toTape
case SCSI::dataCompression32h::mbWrittenToTape :
driveCompressionStats.toTape = SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue)) * mb;
break;
case SCSI::dataCompression32h::bytesWrittenToTape :
driveCompressionStats.toTape += SCSI::Structures::toS32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue));
break;
// fromTape
case SCSI::dataCompression32h::mbReadFromTape :
driveCompressionStats.fromTape = SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue)) * mb;
break;
case SCSI::dataCompression32h::bytesReadFromTape :
driveCompressionStats.fromTape += SCSI::Structures::toS32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue));
break;
// toHost
case SCSI::dataCompression32h::mbTransferredToServer :
driveCompressionStats.toHost = SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue)) * mb;
break;
case SCSI::dataCompression32h::bytesTransferredToServer :
driveCompressionStats.toHost += SCSI::Structures::toS32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue));
break;
}
logParameter += logPageParam.header.parameterLength + sizeof(logPageParam.header);
}
return driveCompressionStats;
}
};
template <class sysWrapperClass>
class DriveIBM3592 : public Drive<sysWrapperClass> {
public:
DriveIBM3592(SCSI::DeviceInfo di, sysWrapperClass & sw): Drive<sysWrapperClass>(di, sw) {}
virtual compressionStats getCompression() throw (Exception) { throw Exception("Not implemented"); }
virtual compressionStats getCompression() throw (Exception) {
SCSI::Structures::logSenseCDB_t cdb;
compressionStats driveCompressionStats;
unsigned char dataBuff[1024];
unsigned char senseBuff[255];
memset (dataBuff, 0, sizeof (dataBuff));
memset (senseBuff, 0, sizeof (senseBuff));
cdb.pageCode = SCSI::logSensePages::blockBytesTransferred;
cdb.PC = 0x01; // Current Comulative Values
cdb.allocationLength[0] = (sizeof(dataBuff) & 0xFF00) >> 8;
cdb.allocationLength[1] = sizeof(dataBuff) & 0x00FF;
SCSI::Structures::LinuxSGIO_t sgh;
sgh.setCDB(&cdb);
sgh.setDataBuffer(&dataBuff);
sgh.setSenseBuffer(&senseBuff);
sgh.dxfer_direction = SG_DXFER_FROM_DEV;
/* Manage both system error and SCSI errors. */
if (-1 == this->m_sysWrapper.ioctl(this->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 getCompression: ") +
SCSI::statusToString(sgh.status));
SCSI::Structures::logSenseLogPageHeader_t & logPageHeader =
*(SCSI::Structures::logSenseLogPageHeader_t *) dataBuff;
unsigned char *endPage = dataBuff +
SCSI::Structures::toU16(logPageHeader.pageLength)+sizeof(logPageHeader);
unsigned char *logParameter = dataBuff+sizeof(logPageHeader);
while ( logParameter < endPage ) { /* values in KiBs and we use shift <<10 to get bytes */
SCSI::Structures::logSenseParameter_t & logPageParam =
*(SCSI::Structures::logSenseParameter_t *) logParameter;
switch (SCSI::Structures::toU16(logPageParam.header.parameterCode)) {
case SCSI::blockBytesTransferred::hostWriteKiBProcessed :
driveCompressionStats.fromHost = (uint64_t)SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue))<<10;
break;
case SCSI::blockBytesTransferred::deviceWriteKiBProcessed :
driveCompressionStats.toTape = (uint64_t)SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue))<<10;
break;
case SCSI::blockBytesTransferred::deviceReadKiBProcessed :
driveCompressionStats.fromTape = (uint64_t)SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue))<<10;
break;
case SCSI::blockBytesTransferred::hostReadKiBProcessed :
driveCompressionStats.toHost = (uint64_t)SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]>(logPageParam.parameterValue))<<10;
break;
}
logParameter += logPageParam.header.parameterLength + sizeof(logPageParam.header);
}
return driveCompressionStats;
}
};
}
......@@ -228,8 +228,10 @@ namespace SCSI {
class logSensePages {
public:
enum {
tapeAlert = 0x2e,
sequentialAccessDevicePage = 0x0C
sequentialAccessDevicePage = 0x0C,
tapeAlert = 0x2e,
dataCompression32h = 0x32, // for LTO, SDLT. We have Data Compression 1Bh for LTO5,6 and DataComppression 0Fh in SSC-3
blockBytesTransferred = 0x38 // parameters in this page are reset when a cartridge is loaded
};
};
/**
......@@ -246,4 +248,49 @@ namespace SCSI {
leftOnTape = 0x8000 // number of 4k bytes left on tape from the current position
};
};
/**
* IBM System Storage Tape Drive 3592 SCSI Reference
*/
class blockBytesTransferred {
public:
enum {
hostWriteBlocksProcessed = 0x0000,
hostWriteKiBProcessed = 0x0001,
hostReadBlocksProcessed = 0x0002,
hostReadKiBProcessed = 0x0003,
deviceWriteDatasetsProcessed = 0x0004,
deviceWriteKiBProcessed = 0x0005,
deviceReadDatasetsProcessed = 0x0006,
deviceReadKiBProcessed = 0x0007,
deviceWriteDatasetsTransferred = 0x0008,
deviceWriteKiBTransferred = 0x0009,
deviceReadDatasetsTransferred = 0x000A,
deviceReadKiBTransferred = 0x000B,
nominalCapacityOfPartition = 0x000C, // in KiB
fractionOfPartitionTraversed = 0x000D,
nominalCapacityOfVolume = 0x000E, // in KiB
fractionOfVolumeTravesed = 0x000F,
remainingCapacityOfVolume = 0x0010, // in KiB
remainingCapacityOfPartition = 0x0011
};
};
/**
* IBM TotalStorage LTO Ultrium Tape Drive SCSI Reference
*/
class dataCompression32h {
public:
enum {
readCompressionRatio = 0x0000, // x100
writeCompressionRation = 0x0001, // x100
mbTransferredToServer = 0x0002, // rounded to the nearest megabyte 10^6
bytesTransferredToServer = 0x0003, // a signed number and may be negative
mbReadFromTape = 0x0004, // rounded to the nearest megabyte 10^6
bytesReadFromTape = 0x0005, // a signed number and may be negative
mbTransferredFromServer = 0x0006, // rounded to the nearest megabyte 10^6
bytesTransferredFromServer = 0x0007, // a signed number and may be negative
mbWrittenToTape = 0x0008, // rounded to the nearest megabyte 10^6
bytesWrittenToTape = 0x0009 // a signed number and may be negative
};
};
}; // namespace SCSI
......@@ -106,6 +106,18 @@ namespace SCSI {
return ntohl (*((uint32_t *) t));
}
/**
* Helper function to deal with endianness.
* for signed values
* @param t byte array in SCSI order representing a 32 bits number
* @return
*/
inline int32_t toS32(const unsigned char(& t)[4])
{
/* Like network, SCSI is BigEndian */
return (int32_t)(ntohl (*((uint32_t *) t)));
}
/**
* Helper function to deal with endianness.
* @param t byte array in SCSI order representing a 16 bits number
......
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