diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 0aee4dc1a23e498c938b8cf80973da237f91b20d..d668fe59483eee0e319d05b3fd9d4d9e79b2b52b 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,8 +2,10 @@ ## Summary ### Features +- cta/CTA#1239 - Add support to CTA for multiple tape label formats - cta/CTA#1257 - Refactor CTA/tapeserver/castor/tape/tapeserver/file/File.cpp - cta/CTA#1263 - Abstract ReadSession and FileReader +- cta/CTA#1265 - Create base of the dCache OSM label format ### Bug fixes ### Building and Packaging diff --git a/common/dataStructures/LabelFormat.hpp b/common/dataStructures/LabelFormat.hpp index 4c1400ce84ed9934f578b7f431d9adf465abe228..cf6e7d8b13843443f13b9d12b162d48ee95c9703 100644 --- a/common/dataStructures/LabelFormat.hpp +++ b/common/dataStructures/LabelFormat.hpp @@ -30,7 +30,8 @@ namespace dataStructures { struct Label { enum class Format : std::uint8_t { - CTA = 0x00 + CTA = 0x00, + OSM = 0x01 }; static Format validateFormat(const std::optional<std::uint8_t>& ouiFormat, const std::string& strContext) { @@ -41,6 +42,7 @@ struct Label { Format format = static_cast<Format>(uiFormat); switch (format) { case Format::CTA: + case Format::OSM: return format; default: { diff --git a/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt b/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt index 94b65b8d33d27120abf0726367c524b1bed9aaba..32c00a1819c8882d33b97f3af5f27599840a968c 100644 --- a/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt +++ b/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt @@ -28,6 +28,8 @@ set(TAPESERVER_FILE_LIBRARY_SRCS FileWriter.cpp HeaderChecker.cpp LabelSession.cpp + OsmFileReader.cpp + OsmReadSession.cpp ReadSession.cpp ReadSessionFactory.cpp Structures.cpp diff --git a/tapeserver/castor/tape/tapeserver/file/FileReaderFactory.cpp b/tapeserver/castor/tape/tapeserver/file/FileReaderFactory.cpp index e6bce456fbf45094ed736c8e3efb2f0c1c5a9166..53e54c8db48f2c95cd0573f26da58ec6db7e2f11 100644 --- a/tapeserver/castor/tape/tapeserver/file/FileReaderFactory.cpp +++ b/tapeserver/castor/tape/tapeserver/file/FileReaderFactory.cpp @@ -20,6 +20,7 @@ #include "castor/tape/tapeserver/file/CtaFileReader.hpp" #include "castor/tape/tapeserver/file/FileReaderFactory.hpp" +#include "castor/tape/tapeserver/file/OsmFileReader.hpp" #include "castor/tape/tapeserver/file/ReadSession.hpp" #include "common/dataStructures/LabelFormat.hpp" @@ -37,6 +38,10 @@ std::unique_ptr<FileReader> FileReaderFactory::create(const std::unique_ptr<Read reader = std::make_unique<CtaFileReader>(readSession, fileToRecall); break; } + case LabelFormat::OSM: { + reader = std::make_unique<OsmFileReader>(readSession, fileToRecall); + break; + } default: { std::ostringstream ossLabelFormat; ossLabelFormat << std::showbase << std::internal << std::setfill('0') << std::hex << std::setw(4) diff --git a/tapeserver/castor/tape/tapeserver/file/FileTest.cpp b/tapeserver/castor/tape/tapeserver/file/FileTest.cpp index 11c440fa61eada914b0e7f6d559f9a6117150f3a..3c4efa5cc08179757043ca3728d0ecbc29f94248 100644 --- a/tapeserver/castor/tape/tapeserver/file/FileTest.cpp +++ b/tapeserver/castor/tape/tapeserver/file/FileTest.cpp @@ -248,7 +248,9 @@ TEST_F(castorTapeFileTest, tapeSessionThrowsOnWrongSequence) { } INSTANTIATE_TEST_CASE_P(FormatLabelsParam, castorTapeFileTest, - ::testing::Values(cta::common::dataStructures::Label::Format::CTA)); + ::testing::Values(cta::common::dataStructures::Label::Format::CTA + // , cta::common::dataStructures::Label::Format::OSM +)); // Class creating a temporary file of 1kB and deleting it // automatically diff --git a/tapeserver/castor/tape/tapeserver/file/OsmFileReader.cpp b/tapeserver/castor/tape/tapeserver/file/OsmFileReader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b17997d57bf68c978e3920b80fc5d832279470c --- /dev/null +++ b/tapeserver/castor/tape/tapeserver/file/OsmFileReader.cpp @@ -0,0 +1,52 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright © 2022 CERN + * @license This program is free software, distributed under the terms of the GNU General Public + * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". You can + * redistribute it and/or modify it under the terms of the GPL Version 3, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * In applying this licence, CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization or + * submit itself to any jurisdiction. + */ + +#include <limits> +#include <memory> +#include <sstream> +#include <string> + +#include "castor/tape/tapeserver/drive/DriveInterface.hpp" +#include "castor/tape/tapeserver/file/HeaderChecker.hpp" +#include "castor/tape/tapeserver/file/OsmFileReader.hpp" +#include "castor/tape/tapeserver/file/CtaReadSession.hpp" +#include "castor/tape/tapeserver/file/Structures.hpp" +#include "scheduler/RetrieveJob.hpp" + +namespace castor { +namespace tape { +namespace tapeFile { + +OsmFileReader::OsmFileReader(const std::unique_ptr<ReadSession> &rs, const cta::RetrieveJob &fileToRecall) + : FileReader(rs, fileToRecall) { +} + +void OsmFileReader::positionByFseq(const cta::RetrieveJob &fileToRecall) { + throw NotImplemented("OsmFileReader::positionByFseq() needs to be implemented"); +} + +void OsmFileReader::positionByBlockID(const cta::RetrieveJob &fileToRecall) { + throw NotImplemented("OsmFileReader::positionByBlockID() needs to be implemented"); +} + +size_t OsmFileReader::readNextDataBlock(void *data, const size_t size) { + throw NotImplemented("OsmFileReader::readNextDataBlock() needs to be implemented"); +} + +} // namespace tapeFile +} // namespace tape +} // namespace castor diff --git a/tapeserver/castor/tape/tapeserver/file/OsmFileReader.hpp b/tapeserver/castor/tape/tapeserver/file/OsmFileReader.hpp new file mode 100644 index 0000000000000000000000000000000000000000..aec29a6402b9325ee839acb5ea26b4f37865af17 --- /dev/null +++ b/tapeserver/castor/tape/tapeserver/file/OsmFileReader.hpp @@ -0,0 +1,57 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright © 2022 CERN + * @license This program is free software, distributed under the terms of the GNU General Public + * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". You can + * redistribute it and/or modify it under the terms of the GPL Version 3, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * In applying this licence, CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization or + * submit itself to any jurisdiction. + */ + +#pragma once + +#include <memory> + +#include "castor/tape/tapeserver/file/OsmFileReader.hpp" +#include "castor/tape/tapeserver/file/FileReader.hpp" + +namespace castor { +namespace tape { +namespace tapeFile { + +class UHL1; + +class OsmFileReader : public FileReader { +public: + CTA_GENERATE_EXCEPTION_CLASS(NotImplemented); + /** + * Constructor of the FileReader. It will bind itself to an existing read session + * and position the tape right at the beginning of the file + * @param rs: session to be bound to + * @param fileInfo: information about the file we would like to read + * @param positioningMode: method used when positioning (see the PositioningMode enum) + */ + OsmFileReader(const std::unique_ptr<ReadSession> &rs, const cta::RetrieveJob &fileToRecall); + + /** + * Destructor of the FileReader. It will release the lock on the read session. + */ + ~OsmFileReader() override = default; + + size_t readNextDataBlock(void *data, const size_t size) override; + +private: + void positionByFseq(const cta::RetrieveJob &fileToRecall) override; + void positionByBlockID(const cta::RetrieveJob &fileToRecall) override; +}; + +} // namespace tapeFile +} // namespace tape +} // namespace castor diff --git a/tapeserver/castor/tape/tapeserver/file/OsmReadSession.cpp b/tapeserver/castor/tape/tapeserver/file/OsmReadSession.cpp new file mode 100644 index 0000000000000000000000000000000000000000..52836213bddae318f1d5a49ebe8ce9bae3424462 --- /dev/null +++ b/tapeserver/castor/tape/tapeserver/file/OsmReadSession.cpp @@ -0,0 +1,38 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright © 2022 CERN + * @license This program is free software, distributed under the terms of the GNU General Public + * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". You can + * redistribute it and/or modify it under the terms of the GPL Version 3, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * In applying this licence, CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization or + * submit itself to any jurisdiction. + */ + +#include <memory> +#include <string> + +#include "castor/tape/tapeserver/file/Exceptions.hpp" +#include "castor/tape/tapeserver/file/HeaderChecker.hpp" +#include "castor/tape/tapeserver/file/OsmReadSession.hpp" +#include "castor/tape/tapeserver/file/Structures.hpp" + +namespace castor { +namespace tape { +namespace tapeFile { + +OsmReadSession::OsmReadSession(tapeserver::drive::DriveInterface &drive, + const tapeserver::daemon::VolumeInfo &volInfo, const bool useLbp) + : ReadSession(drive, volInfo, useLbp) { + throw NotImplemented("Constructor not implemented"); +} + +} // namespace tapeFile +} // namespace tape +} // namespace castor diff --git a/tapeserver/castor/tape/tapeserver/file/OsmReadSession.hpp b/tapeserver/castor/tape/tapeserver/file/OsmReadSession.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ee7d591f8526afa4e5c2dbbc2d11ec19adf1bb46 --- /dev/null +++ b/tapeserver/castor/tape/tapeserver/file/OsmReadSession.hpp @@ -0,0 +1,55 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright © 2022 CERN + * @license This program is free software, distributed under the terms of the GNU General Public + * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". You can + * redistribute it and/or modify it under the terms of the GPL Version 3, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * In applying this licence, CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization or + * submit itself to any jurisdiction. + */ + +#pragma once + +#include <memory> +#include <string> + +#include "castor/tape/tapeserver/daemon/VolumeInfo.hpp" +#include "castor/tape/tapeserver/file/ReadSession.hpp" + +namespace castor { +namespace tape { +namespace tapeFile { + +/** + * Class keeping track of a whole tape read session over an AUL formatted + * tape. The session will keep track of the overall coherency of the session + * and check for everything to be coherent. The tape should be mounted in + * the drive before the AULReadSession is started (i.e. constructed). + * Likewise, tape unmount is the business of the user. + */ +class OsmReadSession : public ReadSession { +public: + CTA_GENERATE_EXCEPTION_CLASS(NotImplemented); + /** + * Constructor of the OsmReadSession. It will rewind the tape, and check the + * volId value. Throws an exception in case of mismatch. + * @param drive: drive object to which we bind the session + * @param vid: volume name of the tape we would like to read from + * @param useLbp: castor.conf option to use or not to use LBP in tapeserverd + */ + OsmReadSession(tapeserver::drive::DriveInterface &drive, const tapeserver::daemon::VolumeInfo &volInfo, + const bool useLbp); + + ~OsmReadSession() override = default; +}; + +} // namespace tapeFile +} // namespace tape +} // namespace castor diff --git a/tapeserver/castor/tape/tapeserver/file/ReadSessionFactory.cpp b/tapeserver/castor/tape/tapeserver/file/ReadSessionFactory.cpp index dde98b72010f193e2616ebb2b5a26907c01ea9c8..171e04ed7fe9c94f94ed1ce8c4d2b55e7f37812d 100644 --- a/tapeserver/castor/tape/tapeserver/file/ReadSessionFactory.cpp +++ b/tapeserver/castor/tape/tapeserver/file/ReadSessionFactory.cpp @@ -19,6 +19,7 @@ #include <sstream> #include "castor/tape/tapeserver/file/CtaReadSession.hpp" +#include "castor/tape/tapeserver/file/OsmReadSession.hpp" #include "castor/tape/tapeserver/file/ReadSessionFactory.hpp" #include "common/dataStructures/LabelFormat.hpp" @@ -33,6 +34,8 @@ std::unique_ptr<ReadSession> ReadSessionFactory::create(tapeserver::drive::Drive switch (labelFormat) { case LabelFormat::CTA: return std::make_unique<CtaReadSession>(drive, volInfo, useLbp); + case LabelFormat::OSM: + return std::make_unique<OsmReadSession>(drive, volInfo, useLbp); default: { std::ostringstream ossLabelFormat; ossLabelFormat << std::showbase << std::internal << std::setfill('0') << std::hex << std::setw(4)