Commit 9cc2884f authored by Steven Murray's avatar Steven Murray
Browse files

Implemented Rdbms::reclaimTape()

parent a4489724
......@@ -299,7 +299,21 @@ public:
*/
virtual common::dataStructures::VidToTapeMap getTapesByVid(const std::set<std::string> &vids) const = 0;
/**
* Reclaims the specified tape.
*
* This method will throw an exception if the specified tape does not exist.
*
* This method will throw an exception if the specified tape is not FULL.
*
* This method will throw an exception if there is still at least one tape
* file recorded in the cataligue as being on the specified tape.
*
* @param cliIdentity The user of the command-line tool.
* @param vid The volume identifier of the tape to be reclaimed.
*/
virtual void reclaimTape(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid) = 0;
virtual void modifyTapeLogicalLibraryName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &logicalLibraryName) = 0;
virtual void modifyTapeTapePoolName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &tapePoolName) = 0;
virtual void modifyTapeCapacityInBytes(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const uint64_t capacityInBytes) = 0;
......
This diff is collapsed.
......@@ -21,6 +21,7 @@
#include "common/exception/Exception.hpp"
#include "common/make_unique.hpp"
#include "common/utils/utils.hpp"
#include "rdbms/AutoRollback.hpp"
#include "rdbms/ConnFactoryFactory.hpp"
namespace cta {
......
......@@ -49,7 +49,7 @@ public:
/**
* Destructor.
*/
virtual ~OracleCatalogue() override;
~OracleCatalogue() override;
/**
* Deletes the specified archive file and its associated tape copies from the
......@@ -64,7 +64,7 @@ public:
* @return The metadata of the deleted archive file including the metadata of
* the associated and also deleted tape copies.
*/
virtual common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &diskInstanceName,
common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &diskInstanceName,
const uint64_t archiveFileId) override;
/**
......@@ -79,7 +79,7 @@ public:
* @return A unique archive ID that can be used by a new archive file within
* the catalogue.
*/
virtual uint64_t getNextArchiveFileId(rdbms::Conn &conn) override;
uint64_t getNextArchiveFileId(rdbms::Conn &conn) override;
/**
* Selects the specified tape within the Tape table for update.
......@@ -91,7 +91,7 @@ public:
* @param conn The database connection.
* @param vid The volume identifier of the tape.
*/
virtual common::dataStructures::Tape selectTapeForUpdate(rdbms::Conn &conn, const std::string &vid) override;
common::dataStructures::Tape selectTapeForUpdate(rdbms::Conn &conn, const std::string &vid) override;
}; // class OracleCatalogue
......
......@@ -1496,6 +1496,19 @@ void RdbmsCatalogue::deleteTape(const std::string &vid) {
// getTapes
//------------------------------------------------------------------------------
std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(const TapeSearchCriteria &searchCriteria) const {
try {
auto conn = m_connPool.getConn();
return getTapes(*conn, searchCriteria);
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
//------------------------------------------------------------------------------
// getTapes
//------------------------------------------------------------------------------
std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(rdbms::Conn &conn,
const TapeSearchCriteria &searchCriteria) const {
try {
std::list<common::dataStructures::Tape> tapes;
std::string sql =
......@@ -1578,8 +1591,7 @@ std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(const TapeSearc
sql += " LBP_IS_ON = :LBP_IS_ON";
}
auto conn = m_connPool.getConn();
auto stmt = conn->createStmt(sql, rdbms::Stmt::AutocommitMode::OFF);
auto stmt = conn.createStmt(sql, rdbms::Stmt::AutocommitMode::OFF);
if(searchCriteria.vid) stmt->bindString(":VID", searchCriteria.vid.value());
if(searchCriteria.logicalLibrary) stmt->bindString(":LOGICAL_LIBRARY_NAME", searchCriteria.logicalLibrary.value());
......@@ -1729,6 +1741,63 @@ common::dataStructures::VidToTapeMap RdbmsCatalogue::getTapesByVid(const std::se
}
}
//------------------------------------------------------------------------------
// reclaimTape
//------------------------------------------------------------------------------
void RdbmsCatalogue::reclaimTape(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid) {
try {
const time_t now = time(nullptr);
const char *const sql =
"UPDATE TAPE SET "
"LAST_FSEQ = 0, "
"IS_FULL = 0,"
"LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
"LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
"LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
"WHERE "
"VID = :UPDATE_VID AND "
"IS_FULL != 0 AND "
"NOT EXISTS (SELECT VID FROM TAPE_FILE WHERE VID = :SELECT_VID)";
auto conn = m_connPool.getConn();
auto stmt = conn->createStmt(sql, rdbms::Stmt::AutocommitMode::ON);
stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
stmt->bindUint64(":LAST_UPDATE_TIME", now);
stmt->bindString(":UPDATE_VID", vid);
stmt->bindString(":SELECT_VID", vid);
stmt->executeNonQuery();
// If the update failed due to a user error
if(0 == stmt->getNbAffectedRows()) {
// Try to determine the user error
//
// Please note that this is a best effort diagnosis because there is no
// lock on the database to prevent other concurrent updates from taking
// place on the TAPE and TAPE_FILE tables
TapeSearchCriteria searchCriteria;
searchCriteria.vid = vid;
const auto tapes = getTapes(*conn, searchCriteria);
if(tapes.empty()) {
throw exception::UserError(std::string("Cannot reclaim tape ") + vid + " because it does not exist");
} else {
if(!tapes.front().full) {
throw exception::UserError(std::string("Cannot reclaim tape ") + vid + " because it is not FULL");
} else {
throw exception::UserError(std::string("Cannot reclaim tape ") + vid + " because there is at least one tape"
" file in the catalogue that is on the tape");
}
}
}
conn->commit();
} catch(exception::UserError &) {
throw;
} catch (exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
//------------------------------------------------------------------------------
// getTapeLogFromRset
//------------------------------------------------------------------------------
......@@ -1762,13 +1831,6 @@ optional<common::dataStructures::TapeLog> RdbmsCatalogue::getTapeLogFromRset(con
}
}
//------------------------------------------------------------------------------
// reclaimTape
//------------------------------------------------------------------------------
void RdbmsCatalogue::reclaimTape(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid) {
throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
//------------------------------------------------------------------------------
// modifyTapeLogicalLibraryName
//------------------------------------------------------------------------------
......
This diff is collapsed.
......@@ -44,7 +44,7 @@ public:
/**
* Destructor.
*/
virtual ~SqliteCatalogue() override;
~SqliteCatalogue() override;
/**
* Deletes the specified archive file and its associated tape copies from the
......@@ -59,7 +59,7 @@ public:
* @return The metadata of the deleted archive file including the metadata of
* the associated and also deleted tape copies.
*/
virtual common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &diskInstanceName,
common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &diskInstanceName,
const uint64_t archiveFileId) override;
protected:
......
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