Commit cad4ea91 authored by Cedric Caffy's avatar Cedric Caffy
Browse files

[lto_rao] Implemented ioctl call for READ END OF WRAPS SCSI command for LTO drive

parent b667c7a4
......@@ -1224,6 +1224,10 @@ namespace SCSI {
unsigned char reserved[2]; // Reserved
unsigned char logicalObjectIdentifier[6]; // The logical object identifier of the object at the end of the above wrap
} wrapDescriptor[maxLTOTapeWraps]; // Array of wrap descriptiors
uint16_t getNbWrapsReturned(){
return (SCSI::Structures::toU16(responseDataLength) / sizeof(wrapDescriptor));
}
};
/**
......
......@@ -118,6 +118,44 @@ void drive::DriveLTO::clearCompressionStats() {
SCSI::ExceptionLauncher(sgh, "SCSI error in clearCompressionStats:");
}
std::vector<castor::tape::tapeserver::drive::endOfWrapPosition> drive::DriveLTO::getEndOfWrapPositions() {
std::vector<castor::tape::tapeserver::drive::endOfWrapPosition> ret;
SCSI::Structures::readEndOfWrapPositionCDB_t cdb;
//WrapNumbeValid = 0, ReportAll = 1 and WrapNumber = 0 as we want all the end of wraps positions
cdb.WNV = 0;
cdb.RA = 1;
cdb.wrapNumber = 0;
//Each wrap descriptor is 12 bytes
SCSI::Structures::setU32(cdb.allocationLength,12 * castor::tape::SCSI::maxLTOTapeWraps);
SCSI::Structures::readEndOfWrapPositionDataLongForm_t data;
SCSI::Structures::LinuxSGIO_t sgh;
sgh.setCDB(&cdb);
sgh.setDataBuffer(&data);
sgh.dxfer_direction = SG_DXFER_FROM_DEV;
/* Manage both system error and SCSI errors. */
cta::exception::Errnum::throwOnMinusOne(
m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh),
"Failed SG_IO ioctl in DriveLTO::getEndOfWrapPositions");
SCSI::ExceptionLauncher(sgh, "SCSI error in getEndOfWrapPositions:");
int nbWrapReturned = data.getNbWrapsReturned();
//Loop over the list of wraps of the tape returned by the drive
for(int i = 0; i < nbWrapReturned; ++i){
castor::tape::tapeserver::drive::endOfWrapPosition position;
auto wrapDescriptor = data.wrapDescriptor[i];
position.wrapNumber = SCSI::Structures::toU16(wrapDescriptor.wrapNumber);
position.partition = SCSI::Structures::toU16(wrapDescriptor.partition);
//blockId returned is 6*8 = 48 bytes, so we need to store it into a uint64_t
position.blockId = SCSI::Structures::toU64(wrapDescriptor.logicalObjectIdentifier);
ret.push_back(position);
}
return ret;
}
/**
* Information about the drive. The vendor id is used in the user labels of the files.
* @return The deviceInfo structure with the information about the drive.
......@@ -367,6 +405,15 @@ drive::physicalPositionInfo drive::DriveGeneric::getPhysicalPositionInfo()
return posInfo;
}
/**
* Returns all the end of wrap positions of the mounted tape
*
* @return a vector of endOfWrapsPositions.
*/
std::vector<drive::endOfWrapPosition> drive::DriveGeneric::getEndOfWrapPositions() {
return std::vector<drive::endOfWrapPosition>();
}
/**
* Get tape alert information from the drive. There is a quite long list of possible tape alerts.
* They are described in SSC-4, section 4.2.20: TapeAlert application client interface.
......
......@@ -139,6 +139,14 @@ namespace drive {
* @return physicalPositionInfo class. This contains the wrap and linear position (LPOS).
*/
virtual physicalPositionInfo getPhysicalPositionInfo();
/**
* Returns all the end of wrap positions of the mounted tape
*
* @return a vector of endOfWrapsPositions.
*/
virtual std::vector<endOfWrapPosition> getEndOfWrapPositions();
/**
* Get tape alert information from the drive. There is a quite long list of possible tape alerts.
......@@ -583,6 +591,7 @@ namespace drive {
virtual compressionStats getCompression();
virtual void clearCompressionStats();
virtual std::vector<castor::tape::tapeserver::drive::endOfWrapPosition> getEndOfWrapPositions();
};
class DriveIBM3592 : public DriveGeneric {
......
......@@ -120,6 +120,18 @@ namespace drive {
}
};
/**
* End of wraps position infos
*
* It is used by the getEndOfWrapPositions() method
*/
class endOfWrapPosition{
public:
uint16_t wrapNumber;
uint64_t blockId;
uint16_t partition;
};
/**
* Logical block protection nformation, returned by getLBPInfo()
*/
......@@ -213,6 +225,7 @@ namespace drive {
virtual void positionToLogicalObject(uint32_t blockId) = 0;
virtual positionInfo getPositionInfo() = 0;
virtual physicalPositionInfo getPhysicalPositionInfo() = 0;
virtual std::vector<endOfWrapPosition> getEndOfWrapPositions() = 0;
virtual std::vector<uint16_t> getTapeAlertCodes() = 0;
virtual std::vector<std::string> getTapeAlerts(const std::vector<uint16_t>&) = 0;
virtual std::vector<std::string> getTapeAlertsCompact (const std::vector<uint16_t>&) = 0;
......
......@@ -98,6 +98,10 @@ castor::tape::tapeserver::drive::physicalPositionInfo castor::tape::tapeserver::
return pos;
}
std::vector<castor::tape::tapeserver::drive::endOfWrapPosition> castor::tape::tapeserver::drive::FakeDrive::getEndOfWrapPositions() {
return std::vector<castor::tape::tapeserver::drive::endOfWrapPosition>();
}
std::vector<uint16_t> castor::tape::tapeserver::drive::FakeDrive::getTapeAlertCodes() {
std::vector<uint16_t> empty;
return empty;
......
......@@ -72,6 +72,7 @@ namespace drive {
virtual void positionToLogicalObject(uint32_t blockId) ;
virtual positionInfo getPositionInfo() ;
virtual physicalPositionInfo getPhysicalPositionInfo();
virtual std::vector<endOfWrapPosition> getEndOfWrapPositions();
virtual std::vector<uint16_t> getTapeAlertCodes();
virtual std::vector<std::string> getTapeAlerts(const std::vector<uint16_t>&) ;
virtual std::vector<std::string> getTapeAlertsCompact(const std::vector<uint16_t>&) ;
......
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