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

changed parsing for the compression statistic log pages to work correctly

with new IBM drives.
parent 53835b4c
......@@ -27,6 +27,7 @@
#include <iomanip>
#include <algorithm>
#include <arpa/inet.h>
#include <endian.h>
#include <string.h>
#include <scsi/sg.h>
#include <climits>
......@@ -458,8 +459,64 @@ namespace SCSI {
// bytes 4-n
unsigned char parameterValue[1]; // parameters have variable length
/**
* Gets the parameter value
*
* @return The value of the log sense parameter as uint64_t.
* If we have a parameter length more than 8 bytes the returning
* value is not determined.
*/
inline uint64_t getU64Value() {
union {
unsigned char tmp[8];
uint64_t val64;
} u;
u.tmp[0]=(header.parameterLength>0)?parameterValue[0]:0;
u.tmp[1]=(header.parameterLength>1)?parameterValue[1]:0;
u.tmp[2]=(header.parameterLength>2)?parameterValue[2]:0;
u.tmp[3]=(header.parameterLength>3)?parameterValue[3]:0;
u.tmp[4]=(header.parameterLength>4)?parameterValue[4]:0;
u.tmp[5]=(header.parameterLength>5)?parameterValue[5]:0;
u.tmp[6]=(header.parameterLength>6)?parameterValue[6]:0;
u.tmp[7]=(header.parameterLength>7)?parameterValue[7]:0;
u.val64 = be64toh(u.val64);
return u.val64>>(64-(header.parameterLength<<3));
}
/**
* Gets the parameter value.
*
* @return The value of the log sense parameter as int64_t.
* If we have a parameter length more than 8 bytes the returning
* value is not determined.
*/
inline int64_t getS64Value() {
union {
unsigned char tmp[8];
uint64_t val64U;
int64_t val64S;
} u;
u.tmp[0]=(header.parameterLength>0)?parameterValue[0]:0;
u.tmp[1]=(header.parameterLength>1)?parameterValue[1]:0;
u.tmp[2]=(header.parameterLength>2)?parameterValue[2]:0;
u.tmp[3]=(header.parameterLength>3)?parameterValue[3]:0;
u.tmp[4]=(header.parameterLength>4)?parameterValue[4]:0;
u.tmp[5]=(header.parameterLength>5)?parameterValue[5]:0;
u.tmp[6]=(header.parameterLength>6)?parameterValue[6]:0;
u.tmp[7]=(header.parameterLength>7)?parameterValue[7]:0;
u.val64U = be64toh(u.val64U);
return (u.val64S < 0?-(-u.val64S>> (64-(header.parameterLength<<3))):
(u.val64S>>(64-(header.parameterLength<<3))));
}
};
/**
* Log sense Log Page Format as described in SPC-4,
*/
......
......@@ -624,4 +624,57 @@ namespace unitTests {
ASSERT_NE(std::string::npos, what.find("In exception validation: "));
}
}
TEST(castor_tape_SCSI_Structures, logSenseParameter_t) {
unsigned char dataBuff[128];
memset(dataBuff, random(), sizeof (dataBuff));
castor::tape::SCSI::Structures::logSenseParameter_t &logParam=
*(castor::tape::SCSI::Structures::logSenseParameter_t *) dataBuff;
ASSERT_EQ(4U, sizeof(logParam.header));
ASSERT_LE(sizeof(castor::tape::SCSI::Structures::logSenseParameterHeader_t), sizeof(logParam));
unsigned char test1[] = {0x00, 0x08, 0x43, 0x04, 0x11, 0x22, 0x33, 0x44, 0x55};
memcpy(dataBuff,test1,sizeof(test1));
ASSERT_EQ(0x08U,castor::tape::SCSI::Structures::toU16(logParam.header.parameterCode));
ASSERT_EQ(0x04U,logParam.header.parameterLength);
ASSERT_EQ(0x11223344ULL,logParam.getU64Value());
ASSERT_EQ(0x11223344LL,logParam.getS64Value());
unsigned char test2[] = {0x00, 0x00, 0x43, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
memcpy(dataBuff,test2,sizeof(test2));
ASSERT_EQ(0x00U,castor::tape::SCSI::Structures::toU16(logParam.header.parameterCode));
ASSERT_EQ(0x06U,logParam.header.parameterLength);
ASSERT_EQ(0x112233445566ULL,logParam.getU64Value());
ASSERT_EQ(0x112233445566LL,logParam.getS64Value());
unsigned char test3[] = {0x0A, 0x0F, 0x43, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99};
memcpy(dataBuff,test3,sizeof(test3));
ASSERT_EQ(0xA0FU,castor::tape::SCSI::Structures::toU16(logParam.header.parameterCode));
ASSERT_EQ(0x08U,logParam.header.parameterLength);
ASSERT_EQ(0x1122334455667788ULL,logParam.getU64Value());
ASSERT_EQ(0x1122334455667788LL,logParam.getS64Value());
unsigned char test4[] = {0x0A, 0x0F, 0x43, 0x09, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99};
memcpy(dataBuff,test4,sizeof(test4));
ASSERT_EQ(0xA0FU,castor::tape::SCSI::Structures::toU16(logParam.header.parameterCode));
ASSERT_EQ(0x09U,logParam.header.parameterLength);
ASSERT_NE(0x1122334455667788ULL,logParam.getU64Value());
ASSERT_NE(0x1122334455667788LL,logParam.getS64Value());
unsigned char test5[] = {0xBB, 0xEE, 0x43, 0x00, 0x11, 0x22};
memcpy(dataBuff,test5,sizeof(test5));
ASSERT_EQ(0xBBEEU,castor::tape::SCSI::Structures::toU16(logParam.header.parameterCode));
ASSERT_EQ(0x00U,logParam.header.parameterLength);
ASSERT_EQ(0ULL,logParam.getU64Value());
ASSERT_EQ(0LL,logParam.getS64Value());
unsigned char test6[] = {0xDD, 0xCC, 0x43, 0x04, 0xFF, 0x22, 0x33, 0x44, 0x55};
memcpy(dataBuff,test6,sizeof(test6));
ASSERT_EQ(0xDDCCU,castor::tape::SCSI::Structures::toU16(logParam.header.parameterCode));
ASSERT_EQ(0x04U,logParam.header.parameterLength);
ASSERT_EQ(4280431428ULL,logParam.getU64Value());
ASSERT_EQ(-14535868LL,logParam.getS64Value());
}
}
......@@ -677,16 +677,16 @@ drives::compressionStats drives::DriveT10000::getCompression() {
*(SCSI::Structures::logSenseParameter_t *) logParameter;
switch (SCSI::Structures::toU16(logPageParam.header.parameterCode)) {
case SCSI::sequentialAccessDevicePage::receivedFromInitiator:
driveCompressionStats.fromHost = SCSI::Structures::toU64(reinterpret_cast<unsigned char(&)[8]> (logPageParam.parameterValue));
driveCompressionStats.fromHost = logPageParam.getU64Value();
break;
case SCSI::sequentialAccessDevicePage::writtenOnTape:
driveCompressionStats.toTape = SCSI::Structures::toU64(reinterpret_cast<unsigned char(&)[8]> (logPageParam.parameterValue));
driveCompressionStats.toTape = logPageParam.getU64Value();
break;
case SCSI::sequentialAccessDevicePage::readFromTape:
driveCompressionStats.fromTape = SCSI::Structures::toU64(reinterpret_cast<unsigned char(&)[8]> (logPageParam.parameterValue));
driveCompressionStats.fromTape = logPageParam.getU64Value();
break;
case SCSI::sequentialAccessDevicePage::readByInitiator:
driveCompressionStats.toHost = SCSI::Structures::toU64(reinterpret_cast<unsigned char(&)[8]> (logPageParam.parameterValue));
driveCompressionStats.toHost = logPageParam.getU64Value();
break;
}
logParameter += logPageParam.header.parameterLength + sizeof (logPageParam.header);
......@@ -736,31 +736,31 @@ drives::compressionStats drives::DriveLTO::getCompression() {
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;
driveCompressionStats.fromHost = logPageParam.getU64Value() * mb;
break;
case SCSI::dataCompression32h::bytesTransferredFromServer:
driveCompressionStats.fromHost += SCSI::Structures::toS32(reinterpret_cast<unsigned char(&)[4]> (logPageParam.parameterValue));
driveCompressionStats.fromHost += logPageParam.getS64Value();
break;
// toTape
case SCSI::dataCompression32h::mbWrittenToTape:
driveCompressionStats.toTape = SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]> (logPageParam.parameterValue)) * mb;
driveCompressionStats.toTape = logPageParam.getU64Value() * mb;
break;
case SCSI::dataCompression32h::bytesWrittenToTape:
driveCompressionStats.toTape += SCSI::Structures::toS32(reinterpret_cast<unsigned char(&)[4]> (logPageParam.parameterValue));
driveCompressionStats.toTape += logPageParam.getS64Value();
break;
// fromTape
case SCSI::dataCompression32h::mbReadFromTape:
driveCompressionStats.fromTape = SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]> (logPageParam.parameterValue)) * mb;
driveCompressionStats.fromTape = logPageParam.getU64Value() * mb;
break;
case SCSI::dataCompression32h::bytesReadFromTape:
driveCompressionStats.fromTape += SCSI::Structures::toS32(reinterpret_cast<unsigned char(&)[4]> (logPageParam.parameterValue));
driveCompressionStats.fromTape += logPageParam.getS64Value();
break;
// toHost
case SCSI::dataCompression32h::mbTransferredToServer:
driveCompressionStats.toHost = SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]> (logPageParam.parameterValue)) * mb;
driveCompressionStats.toHost = logPageParam.getU64Value() * mb;
break;
case SCSI::dataCompression32h::bytesTransferredToServer:
driveCompressionStats.toHost += SCSI::Structures::toS32(reinterpret_cast<unsigned char(&)[4]> (logPageParam.parameterValue));
driveCompressionStats.toHost += logPageParam.getS64Value();
break;
}
logParameter += logPageParam.header.parameterLength + sizeof (logPageParam.header);
......@@ -808,16 +808,16 @@ drives::compressionStats drives::DriveIBM3592::getCompression() {
*(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;
driveCompressionStats.fromHost = logPageParam.getU64Value() << 10;
break;
case SCSI::blockBytesTransferred::deviceWriteKiBProcessed:
driveCompressionStats.toTape = (uint64_t) SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]> (logPageParam.parameterValue)) << 10;
driveCompressionStats.toTape = logPageParam.getU64Value() << 10;
break;
case SCSI::blockBytesTransferred::deviceReadKiBProcessed:
driveCompressionStats.fromTape = (uint64_t) SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]> (logPageParam.parameterValue)) << 10;
driveCompressionStats.fromTape = logPageParam.getU64Value() << 10;
break;
case SCSI::blockBytesTransferred::hostReadKiBProcessed:
driveCompressionStats.toHost = (uint64_t) SCSI::Structures::toU32(reinterpret_cast<unsigned char(&)[4]> (logPageParam.parameterValue)) << 10;
driveCompressionStats.toHost = logPageParam.getU64Value() << 10;
break;
}
logParameter += logPageParam.header.parameterLength + sizeof (logPageParam.header);
......@@ -826,4 +826,5 @@ drives::compressionStats drives::DriveIBM3592::getCompression() {
return driveCompressionStats;
}
}}}
\ No newline at end of file
}}}
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