Commit d20995e8 authored by Julien Leduc's avatar Julien Leduc
Browse files

0ccfb5489c9d92521a9bf58e141fe7425422da96

parent 0d58f0be
......@@ -317,6 +317,16 @@ namespace SCSI {
bytesWrittenToTape = 0x0009 // a signed number and may be negative
};
};
/**
* Logic block protection as defined in SSC-5 (latest drafts)
* 8.4.9 Control Data Protection mode page
*/
enum class logicBlockProtectionMethod {
DoNotUse = 0x00,
ReedSolomon = 0x01,
CRC32C = 0x02
};
class senseConstants {
public:
......
......@@ -41,7 +41,7 @@ namespace castor {
LabelSession::LabelSession(tapeserver::drive::DriveInterface & drive, const std::string &vid) {
VOL1 vol1;
vol1.fill(vid);
vol1.fill(vid, SCSI::logicBlockProtectionMethod::DoNotUse);
drive.writeBlock(&vol1, sizeof(vol1));
HDR1PRELABEL prelabel;
prelabel.fill(vid);
......
......@@ -30,11 +30,16 @@ using namespace castor::tape;
#define BASEVERSION "2.1.15"
void tapeFile::VOL1::fill(std::string VSN) {
void tapeFile::VOL1::fill(std::string VSN,
SCSI::logicBlockProtectionMethod LBPMethod) {
setString(m_label, "VOL1");
setString(m_VSN, VSN);
setString(m_lblStandard, "3");
setString(m_ownerID, "CASTOR");
setString(m_ownerID, "CASTOR");
std::stringstream hexLBP;
hexLBP << std::setfill('0') << std::setw(2) << std::hex
<< std::noshowbase << static_cast<int>(LBPMethod);
setString(m_LBPMethod, hexLBP.str());
}
void tapeFile::VOL1::verify() {
......
......@@ -23,7 +23,9 @@
#pragma once
#include "castor/tape/tapeserver/drive/DriveInterface.hpp"
#include "castor/tape/tapeserver/SCSI/Structures.hpp"
#include <string>
#include <stdexcept>
namespace castor {
namespace tape {
......@@ -58,21 +60,29 @@ namespace tape {
VOL1() {
spaceStruct(this);
}
private:
protected:
char m_label[4]; // The characters VOL1.
char m_VSN[6]; // The Volume Serial Number.
char m_accessibility[1]; // A space indicates that the volume is authorized.
char m_reserved1[13]; // Reserved.
char m_implID[13]; // The Implementation Identifier - spaces.
char m_ownerID[14]; // CASTOR or stagesuperuser name padded with spaces.
char m_reserved2[28]; // Reserved
char m_reserved2[26]; // Reserved
char m_LBPMethod[2]; // Logic block protection checksum type.
// This field is a CASTOR variation from the ECMA 013/ISO1001
// standard. It contains 2 spaces or '00'. Otherwise, contains
// the ASCII representation of the hexadecimal value of the
// Logical block protection method, as defined in the SSC-5 (latest drafts)
// In practice we intend to use " " (double space) or "00"
// for no LBP, "02" for CRC32C where possible (enterprise drives)
// and "01" for ECMA-319 Reed-Solomon where not (LTO drives).
char m_lblStandard[1]; // The label standard level - ASCII 3 for the CASTOR
public:
/**
* Fills up all fields of the VOL1 structure with proper values and data provided.
* @param VSN the tape serial number
*/
void fill(std::string VSN);
void fill(std::string VSN, SCSI::logicBlockProtectionMethod LBPMethod);
/**
* @return VSN the tape serial number
......@@ -80,6 +90,37 @@ namespace tape {
inline std::string getVSN() const {
return toString(m_VSN);
}
/**
* @return the logic block protection method as parsed from the header
*/
inline SCSI::logicBlockProtectionMethod getLBPMethod() const {
if (!::strncmp(m_LBPMethod, " ", sizeof(m_LBPMethod)))
return SCSI::logicBlockProtectionMethod::DoNotUse;
// Generate a proper string for the next steps, as otherwise functions
// get confused by the lack of zero-termination.
std::string LBPMethod;
LBPMethod.append(m_LBPMethod, sizeof (m_LBPMethod));
int hexValue;
try {
hexValue = std::stoi(LBPMethod, 0, 16);
} catch (std::invalid_argument &) {
throw exception::InvalidArgument(
std::string("In VOL1::getLBPMethod(): syntax error for numeric value: ") + LBPMethod);
} catch (std::out_of_range &) {
throw exception::InvalidArgument(
std::string("In VOL1::getLBPMethod(): out of range value: ") + LBPMethod);
}
switch (hexValue) {
case SCSI::logicBlockProtectionMethod::DoNotUse:
case SCSI::logicBlockProtectionMethod::CRC32C:
case SCSI::logicBlockProtectionMethod::ReedSolomon:
return static_cast<SCSI::logicBlockProtectionMethod> (hexValue);
default:
throw exception::InvalidArgument(
std::string("In VOL1::getLBPMethod(): unexpected value: ") + LBPMethod);
}
}
/**
* Throws an exception if the structure does not match expectations.
......
......@@ -26,9 +26,17 @@
#include <gmock/gmock-cardinalities.h>
namespace unitTests {
class testVOL1: public castor::tape::tapeFile::VOL1 {
public:
void backdoorSetLBPMethodString(const std::string & LBPString) {
::strncpy(m_LBPMethod, LBPString.c_str(), sizeof(m_LBPMethod));
}
};
TEST(castor_tape_AULFile, VOL1) {
castor::tape::tapeFile::VOL1 vol1Label;
typedef castor::tape::SCSI::logicBlockProtectionMethod LBPM;
testVOL1 vol1Label;
/**
* Make sure this struct is a POD (plain old data without virtual table)
* (and has the right size).
......@@ -38,11 +46,28 @@ namespace unitTests {
EXPECT_ANY_THROW({
vol1Label.verify();
});
vol1Label.fill("test");
vol1Label.fill("test", LBPM::DoNotUse);
ASSERT_NO_THROW({
vol1Label.verify();
});
ASSERT_EQ("test ", vol1Label.getVSN());
/* Validate that parser understands correctly values for LBP */
vol1Label.backdoorSetLBPMethodString(" ");
ASSERT_NO_THROW(vol1Label.getLBPMethod());
ASSERT_EQ((int)LBPM::DoNotUse, (int)vol1Label.getLBPMethod());
vol1Label.backdoorSetLBPMethodString("01");
ASSERT_NO_THROW(vol1Label.getLBPMethod());
ASSERT_EQ((int)LBPM::ReedSolomon, (int)vol1Label.getLBPMethod());
vol1Label.backdoorSetLBPMethodString("00");
ASSERT_NO_THROW(vol1Label.getLBPMethod());
ASSERT_EQ((int)LBPM::DoNotUse, (int)vol1Label.getLBPMethod());
vol1Label.backdoorSetLBPMethodString("02");
ASSERT_NO_THROW(vol1Label.getLBPMethod());
ASSERT_EQ((int)LBPM::CRC32C, (int)vol1Label.getLBPMethod());
vol1Label.backdoorSetLBPMethodString("03");
ASSERT_THROW(vol1Label.getLBPMethod(), castor::exception::Exception);
vol1Label.backdoorSetLBPMethodString("XY");
ASSERT_THROW(vol1Label.getLBPMethod(), castor::exception::Exception);
}
TEST(castor_tape_AULFile, HDR1) {
......
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