Commit 6c9e0d14 authored by Eric Cano's avatar Eric Cano
Browse files

Refactored some dumping functionnality onto helper functions.

Changed Tape::Drive's behavior to open nst instead or st and adpated test environment.
Changed Exception::what() as it returned pointer to a destroyed stack-based objet. Introduced a setWhat function and made m_what private to adapt.
parent ffc4bad9
......@@ -47,15 +47,15 @@ namespace Tape {
/* We open the tape device file non-blocking as blocking open on rewind tapes (at least)
* will fail after a long timeout when no tape is present (at least with mhvtl)
*/
m_tapeFD = m_sysWrapper.open(m_SCSIInfo.st_dev.c_str(), O_RDWR | O_NONBLOCK);
m_tapeFD = m_sysWrapper.open(m_SCSIInfo.nst_dev.c_str(), O_RDWR | O_NONBLOCK);
if (-1 == m_tapeFD)
throw Tape::Exceptions::Errnum(std::string("Could not open device file: "+ m_SCSIInfo.st_dev));
throw Tape::Exceptions::Errnum(std::string("Could not open device file: "+ m_SCSIInfo.nst_dev));
m_genericFD = m_sysWrapper.open(m_SCSIInfo.sg_dev.c_str(), O_RDWR);
if (-1 == m_genericFD)
throw Tape::Exceptions::Errnum(std::string("Could not open device file: "+ m_SCSIInfo.sg_dev));
/* Read drive status */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, MTIOCGET, &m_mtInfo))
throw Tape::Exceptions::Errnum(std::string("Could not read drive status: "+ m_SCSIInfo.st_dev));
throw Tape::Exceptions::Errnum(std::string("Could not read drive status: "+ m_SCSIInfo.nst_dev));
/* Read Generic SCSI information (INQUIRY) */
}
virtual ~Drive() {
......@@ -68,7 +68,8 @@ namespace Tape {
std::cout << "Doing a SCSI inquiry via generic device:" << std::endl;
SCSI_inquiry(m_genericFD);
std::cout << "Re-doing a SCSI inquiry via st device:" << std::endl;
SCSI_inquiry(m_tapeFD); }
SCSI_inquiry(m_tapeFD);
}
private:
SCSI::DeviceInfo m_SCSIInfo;
int m_tapeFD;
......@@ -84,10 +85,11 @@ namespace Tape {
struct mtget m_mtInfo;
private:
void SCSI_inquiry(int fd) {
unsigned char dataBuff[512];
unsigned char dataBuff[130];
unsigned char senseBuff[256];
unsigned char cdb[6];
memset(&cdb, 0, sizeof (cdb));
memset(&dataBuff, 0, sizeof (dataBuff));
/* Build command */
cdb[0] = SCSI::Commands::INQUIRY;
......@@ -100,7 +102,7 @@ namespace Tape {
sgh.mx_sb_len = 255;
sgh.dxfer_direction = SG_DXFER_FROM_DEV;
sgh.dxferp = dataBuff;
sgh.dxfer_len = 512;
sgh.dxfer_len = sizeof(dataBuff);
sgh.timeout = 30000;
if (-1 == m_sysWrapper.ioctl(fd, SG_IO, &sgh))
throw Tape::Exceptions::Errnum("Failed SG_IO ioctl");
......@@ -110,55 +112,8 @@ namespace Tape {
<< " sgh.status=" << ((int) sgh.status)
<< " sgh.info=" << ((int) sgh.info)
<< std::endl;
std::stringstream hex;
hex << std::hex << std::setfill('0');
int pos = 0;
while (pos < 128) {
hex << std::setw(4) << pos << " | ";
for (int i=0; i<8; i++)
hex << std::setw(2) << ((int) dataBuff[pos + i]) << " ";
hex << "| ";
for (int i=0; i<8; i++)
hex << std::setw(0) << dataBuff[pos + i];
hex << std::endl;
pos += 8;
}
std::cout << hex.str();
SCSI::Structures::inquiryData_t & inq = *((SCSI::Structures::inquiryData_t *) dataBuff);
std::stringstream inqDump;
inqDump << std::hex << std::showbase << std::nouppercase
<< "inq.perifDevType=" << (int) inq.perifDevType << std::endl
<< "inq.perifQualifyer=" << (int) inq.perifQualifyer << std::endl
<< "inq.RMB=" << (int) inq.RMB << std::endl
<< "inq.version=" << (int) inq.version << std::endl
<< "inq.respDataFmt=" << (int) inq.respDataFmt << std::endl
<< "inq.HiSup=" << (int) inq.HiSup << std::endl
<< "inq.normACA=" << (int) inq.normACA << std::endl
<< "inq.addLength=" << (int) inq.addLength << std::endl
<< "inq.protect=" << (int) inq.protect << std::endl
<< "inq.threePC=" << (int) inq.threePC << std::endl
<< "inq.TPGS=" << (int) inq.TPGS << std::endl
<< "inq.ACC=" << (int) inq.ACC << std::endl
<< "inq.SCCS=" << (int) inq.SCCS << std::endl
<< "inq.addr16=" << (int) inq.addr16 << std::endl
<< "inq.multiP=" << (int) inq.multiP << std::endl
<< "inq.VS1=" << (int) inq.VS1 << std::endl
<< "inq.encServ=" << (int) inq.encServ << std::endl
<< "inq.VS2=" << (int) inq.VS2 << std::endl
<< "inq.cmdQue=" << (int) inq.cmdQue << std::endl
<< "inq.sync=" << (int) inq.sync << std::endl
<< "inq.wbus16=" << (int) inq.wbus16 << std::endl
<< "inq.T10Vendor=" << SCSI::Structures::toString(inq.T10Vendor) << std::endl
<< "inq.prodId=" << SCSI::Structures::toString(inq.prodId) << std::endl
<< "inq.prodRevLv=" << SCSI::Structures::toString(inq.prodRevLvl) << std::endl
<< "inq.vendorSpecific1="<< SCSI::Structures::toString(inq.vendorSpecific1)<< std::endl
<< "inq.IUS=" << (int) inq.IUS << std::endl
<< "inq.QAS=" << (int) inq.QAS << std::endl
<< "inq.clocking=" << (int) inq.clocking << std::endl;
for (int i=0; i < 8; i++)
inqDump << "inq.versionDescriptor[" << i << "]=" << SCSI::Structures::toU16(inq.versionDescriptor[i]) << std::endl;
std::cout << inqDump.str();
std::cout << SCSI::Structures::hexDump(dataBuff)
<< SCSI::Structures::toString(*((SCSI::Structures::inquiryData_t *) dataBuff));
}
};
}
......@@ -32,13 +32,21 @@
#include <execinfo.h>
#include <cxxabi.h>
/* TODO remove me: it should be temporary */
#include <iostream>
const char * Tape::Exception::what() const throw () {
return m_what.c_str();
}
void Tape::Exception::setWhat(const std::string& what) {
std::stringstream w;
w << m_what << std::endl << std::string(backtrace);
return w.str().c_str();
w << what << std::endl << std::string(backtrace);
m_what = w.str();
}
Tape::Exceptions::Errnum::Errnum(std::string what):Exception(what) {
Tape::Exceptions::Errnum::Errnum(std::string what):Exception("") {
m_errnum = errno;
char s[1000];
/* _XOPEN_SOURCE seems not to work. */
......@@ -50,13 +58,13 @@ Tape::Exceptions::Errnum::Errnum(std::string what):Exception(what) {
<< new_errno << ")";
m_strerror = w.str();
} else {
m_strerror = std::string(errorStr);
m_strerror = errorStr;
}
std::stringstream w2;
if (what.size())
w2 << what << " ";
w2 << "Errno=" << m_errnum << ": " << m_strerror;
if (m_what.size())
m_what += " ";
m_what += w2.str();
setWhat(w2.str());
}
Tape::Exceptions::Backtrace::Backtrace() {
......
......@@ -44,6 +44,8 @@ namespace Tape {
virtual const char * what() const throw();
Tape::Exceptions::Backtrace backtrace;
protected:
void setWhat(const std::string &w);
private:
std::string m_what;
};
......
......@@ -60,4 +60,15 @@ namespace UnitTests {
ASSERT_NE(std::string::npos, bt.find("Tape::Exceptions::Backtrace::Backtrace"));
}
}
TEST(Exceptions, errnum_throwing) {
/* Mickey Mouse test as we had trouble which throwing Errnum (with errno=ENOENT)*/
errno = ENOENT;
try {
throw Tape::Exceptions::Errnum("Test ENOENT");
} catch (std::exception & e) {
std::string temp = e.what();
temp += " ";
}
}
}
......@@ -21,3 +21,43 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#include "Structures.hh"
#include <sstream>
std::string SCSI::Structures::toString(const inquiryData_t& inq) {
std::stringstream inqDump;
inqDump << std::hex << std::showbase << std::nouppercase
<< "inq.perifDevType=" << (int) inq.perifDevType << std::endl
<< "inq.perifQualifyer=" << (int) inq.perifQualifyer << std::endl
<< "inq.RMB=" << (int) inq.RMB << std::endl
<< "inq.version=" << (int) inq.version << std::endl
<< "inq.respDataFmt=" << (int) inq.respDataFmt << std::endl
<< "inq.HiSup=" << (int) inq.HiSup << std::endl
<< "inq.normACA=" << (int) inq.normACA << std::endl
<< "inq.addLength=" << (int) inq.addLength << std::endl
<< "inq.protect=" << (int) inq.protect << std::endl
<< "inq.threePC=" << (int) inq.threePC << std::endl
<< "inq.TPGS=" << (int) inq.TPGS << std::endl
<< "inq.ACC=" << (int) inq.ACC << std::endl
<< "inq.SCCS=" << (int) inq.SCCS << std::endl
<< "inq.addr16=" << (int) inq.addr16 << std::endl
<< "inq.multiP=" << (int) inq.multiP << std::endl
<< "inq.VS1=" << (int) inq.VS1 << std::endl
<< "inq.encServ=" << (int) inq.encServ << std::endl
<< "inq.VS2=" << (int) inq.VS2 << std::endl
<< "inq.cmdQue=" << (int) inq.cmdQue << std::endl
<< "inq.sync=" << (int) inq.sync << std::endl
<< "inq.wbus16=" << (int) inq.wbus16 << std::endl
<< "inq.T10Vendor=" << SCSI::Structures::toString(inq.T10Vendor) << std::endl
<< "inq.prodId=" << SCSI::Structures::toString(inq.prodId) << std::endl
<< "inq.prodRevLv=" << SCSI::Structures::toString(inq.prodRevLvl) << std::endl
<< "inq.vendorSpecific1="<< SCSI::Structures::toString(inq.vendorSpecific1)<< std::endl
<< "inq.IUS=" << (int) inq.IUS << std::endl
<< "inq.QAS=" << (int) inq.QAS << std::endl
<< "inq.clocking=" << (int) inq.clocking << std::endl;
for (int i=0; i < 8; i++)
inqDump << "inq.versionDescriptor[" << i << "]=" << SCSI::Structures::toU16(inq.versionDescriptor[i]) << std::endl;
return inqDump.str();
}
......@@ -24,6 +24,7 @@
#pragma once
#include <sstream>
#include <iomanip>
#include <arpa/inet.h>
namespace SCSI {
......@@ -93,6 +94,37 @@ namespace SCSI {
r.write(t, std::find(t, t + n, '\0') - t);
return r.str();
}
std::string toString(const inquiryData_t &);
template <size_t n>
std::string hexDump(const unsigned char(& d)[n]) {
std::stringstream hex;
hex << std::hex << std::setfill('0');
int pos = 0;
while (pos < (8* (n / 8))) {
hex << std::setw(4) << pos << " | ";
for (int i=0; i<8; i++)
hex << std::setw(2) << ((int) d[pos + i]) << " ";
hex << "| ";
for (int i=0; i<8; i++)
hex << std::setw(0) << d[pos + i];
hex << std::endl;
pos += 8;
}
if (n % 8) {
hex << std::setw(4) << pos << " | ";
for (int i=0; i<(n % 8); i++)
hex << std::setw(2) << ((int) d[pos + i]) << " ";
for (int i=(n % 8); i<8; i++)
hex << " ";
hex << "| ";
for (int i=0; i<(n % 8); i++)
hex << std::setw(0) << d[pos + i];
hex << std::endl;
}
return hex.str();
}
inline uint32_t toU32(const char(& t)[4])
{
......
......@@ -315,8 +315,8 @@ void Tape::System::fakeWrapper::setupSLC5() {
m_stats["/dev/st1"].st_mode = S_IFCHR;
m_stats["/dev/nst1"].st_rdev = makedev(9, 129);
m_stats["/dev/nst1"].st_mode = S_IFCHR;
m_stFiles["/dev/st0"];
m_stFiles["/dev/st1"];
m_stFiles["/dev/nst0"];
m_stFiles["/dev/nst1"];
m_genericFiles["/dev/sg0"];
m_genericFiles["/dev/sg1"];
m_genericFiles["/dev/sg2"];
......
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