Commit 717256c6 authored by Cedric Caffy's avatar Cedric Caffy
Browse files

Added drive --comment and --reason fields in the objectstore

Adapted the cta-admin commands so that we can set the --reason and the
--comment
parent 5b7fe10a
......@@ -321,7 +321,8 @@ const std::map<std::string, OptionString::Key> strOptions = {
{ "--vo", OptionString::VO },
{ "--disksystem", OptionString::DISK_SYSTEM },
{ "--fileregexp", OptionString::FILE_REGEXP },
{ "--freespacequeryurl", OptionString::FREE_SPACE_QUERY_URL }
{ "--freespacequeryurl", OptionString::FREE_SPACE_QUERY_URL },
{ "--reason", OptionString::REASON }
};
......@@ -343,7 +344,7 @@ const std::map<AdminCmd::Cmd, CmdHelp> cmdHelp = {
{ AdminCmd::CMD_ADMIN, { "admin", "ad", { "add", "ch", "rm", "ls" } }},
{ AdminCmd::CMD_ARCHIVEFILE, { "archivefile", "af", { "ls" } }},
{ AdminCmd::CMD_ARCHIVEROUTE, { "archiveroute", "ar", { "add", "ch", "rm", "ls" } }},
{ AdminCmd::CMD_DRIVE, { "drive", "dr", { "up", "down", "ls", "rm" },
{ AdminCmd::CMD_DRIVE, { "drive", "dr", { "up", "down", "ls", "ch", "rm" },
"\n This is a synchronous command that sets and reads back the state of one or\n"
" more drives. The <drive_name> option accepts a regular expression. If the\n"
" --force option is not set, the drives will complete any running mount and\n"
......@@ -479,6 +480,7 @@ const Option opt_free_space_query_url { Option::OPT_STR, "--freespacequeryurl",
const Option opt_refresh_interval { Option::OPT_UINT, "--refreshinterval", "-i", " <refresh_intreval>" };
const Option opt_targeted_free_space { Option::OPT_UINT, "--targetedfreespace", "-f", " <targeted_free_space>" };
const Option opt_sleep_time { Option::OPT_UINT, "--sleeptime", "-s", " <sleep time in s>" };
const Option opt_reason { Option::OPT_STR, "--reason", "-r", " <reason_status_change>" };
/*!
* Map valid options to commands
......@@ -502,10 +504,11 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = {
{{ AdminCmd::CMD_ARCHIVEROUTE, AdminCmd::SUBCMD_RM }, { opt_storageclass, opt_copynb }},
{{ AdminCmd::CMD_ARCHIVEROUTE, AdminCmd::SUBCMD_LS }, { }},
/*----------------------------------------------------------------------------------------------------*/
{{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_UP }, { opt_drivename_cmd }},
{{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_DOWN }, { opt_drivename_cmd, opt_force_flag.optional() }},
{{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_UP }, { opt_drivename_cmd, opt_reason.optional() }},
{{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_DOWN }, { opt_drivename_cmd, opt_reason, opt_force_flag.optional() }},
{{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_LS }, { opt_drivename.optional() }},
{{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_RM }, { opt_drivename_cmd, opt_force_flag.optional() }},
{{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_CH }, { opt_drivename_cmd, opt_comment }},
/*----------------------------------------------------------------------------------------------------*/
{{ AdminCmd::CMD_FAILEDREQUEST, AdminCmd::SUBCMD_LS },
{ opt_justarchive.optional(), opt_justretrieve.optional(), opt_tapepool.optional(),
......
......@@ -18,6 +18,32 @@
#include "DesiredDriveState.hpp"
namespace cta {
namespace common {
namespace dataStructures {
DesiredDriveState::DesiredDriveState(const DesiredDriveState& ds) {
if(this != &ds){
up = ds.up;
forceDown = ds.forceDown;
reason = ds.reason;
comment = ds.comment;
}
}
DesiredDriveState& DesiredDriveState::operator=(const DesiredDriveState& ds) {
if(this != &ds){
up = ds.up;
forceDown = ds.forceDown;
reason = ds.reason;
comment = ds.comment;
}
return *this;
}
}}}
std::ostream &cta::common::dataStructures::operator<<(std::ostream& os, const DesiredDriveState& obj) {
std::string upStr(obj.up?"true":"false"),
forceStr(obj.forceDown?"true":"false");
......
......@@ -19,6 +19,7 @@
#pragma once
#include <ostream>
#include "common/optional.hpp"
namespace cta {
namespace common {
......@@ -30,8 +31,12 @@ namespace dataStructures {
* at startup).
*/
struct DesiredDriveState {
DesiredDriveState(const DesiredDriveState & ds);
DesiredDriveState & operator=(const DesiredDriveState & ds);
bool up; ///< Should the drive be up?
bool forceDown; ///< Should going down preempt an existig mount?
cta::optional<std::string> reason; ///< The reason why operators put the drive down or up
cta::optional<std::string> comment; ///< General informations about the drive given by the operators
bool operator==(const DesiredDriveState &rhs) const {
return up == rhs.up && forceDown == rhs.forceDown;
}
......
......@@ -109,6 +109,12 @@ cta::common::dataStructures::DriveState DriveState::getState() {
ret.currentTapePool = m_payload.currenttapepool();
ret.currentPriority = m_payload.current_priority();
ret.ctaVersion = m_payload.cta_version();
if(m_payload.has_reason()){
ret.desiredDriveState.reason = m_payload.reason();
}
if(m_payload.has_comment()){
ret.desiredDriveState.comment = m_payload.comment();
}
for(auto & driveConfigItem: m_payload.drive_config()){
ret.driveConfigItems.push_back({driveConfigItem.category(),driveConfigItem.key(),driveConfigItem.value(),driveConfigItem.source()});
}
......@@ -158,11 +164,25 @@ void DriveState::setState(cta::common::dataStructures::DriveState& state) {
m_payload.set_shutdowntime(state.shutdownTime);
m_payload.set_mounttype((uint32_t)state.mountType);
m_payload.set_drivestatus((uint32_t)state.driveStatus);
m_payload.set_desiredup(state.desiredDriveState.up);
m_payload.set_desiredforcedown(state.desiredDriveState.forceDown);
common::dataStructures::DesiredDriveState desiredDriveState = state.desiredDriveState;
m_payload.set_desiredup(desiredDriveState.up);
m_payload.set_desiredforcedown(desiredDriveState.forceDown);
m_payload.set_currentvid(state.currentVid);
m_payload.set_currenttapepool(state.currentTapePool);
m_payload.set_current_priority(state.currentPriority);
cta::optional<std::string> reason = desiredDriveState.reason;
cta::optional<std::string> comment = desiredDriveState.comment;
if(reason) {
if(reason.value().empty()){
//The only way to erase a reason is to set the optional value to an empty string
m_payload.clear_reason();
} else {
m_payload.set_reason(reason.value());
}
}
if(comment) {
m_payload.set_comment(comment.value());
}
if (state.currentActivityAndWeight) {
m_payload.set_current_activity(state.currentActivityAndWeight.value().activity);
m_payload.set_current_activity_weight(state.currentActivityAndWeight.value().weight);
......
......@@ -264,6 +264,8 @@ message DriveState {
optional string dev_file_name = 5036;
optional string raw_library_slot = 5037;
repeated DriveConfig drive_config = 5038;
optional string reason = 5039;
optional string comment = 5040;
// TODO: implement or remove required EntryLog creationlog = 5023;
}
......
......@@ -2777,8 +2777,14 @@ void OStoreDB::setDesiredDriveState(const std::string& drive, const common::data
objectstore::DriveState ds(m_objectStore);
ScopedExclusiveLock dsl;
Helpers::getLockedAndFetchedDriveState(ds, dsl, *m_agentReference, drive, lc);
common::dataStructures::DesiredDriveState newDesiredState = desiredState;
auto driveState = ds.getState();
driveState.desiredDriveState = desiredState;
if(desiredState.comment){
//In case we modify the comment, we want to keep the same status and forceDown of the drive
newDesiredState.up = driveState.desiredDriveState.up;
newDesiredState.forceDown = driveState.desiredDriveState.forceDown;
}
driveState.desiredDriveState = newDesiredState;
ds.setState(driveState);
ds.commit();
}
......
......@@ -28,6 +28,7 @@
#include "objectstore/BackendRadosTestSwitch.hpp"
#include "MemQueues.hpp"
#include "catalogue/InMemoryCatalogue.hpp"
#include "objectstore/DriveState.hpp"
namespace unitTests {
......@@ -231,6 +232,116 @@ TEST_P(OStoreDBTest, MemQueuesSharedAddToArchiveQueue) {
ASSERT_EQ(filesToDo, osdbi.getArchiveJobs("tapepool").size());
}
TEST_P(OStoreDBTest, setDesiredState){
using namespace cta::objectstore;
cta::log::StringLogger logger("dummy", "OStoreAbstractTest", cta::log::DEBUG);
cta::log::LogContext lc(logger);
// Get the OStoreBDinterface
OStoreDBWrapperInterface & osdbi = getDb();
AgentReference & agentRef = osdbi.getAgentReference();
//Create the drive first
std::string driveName = "DRIVE";
{
DriveState ds(osdbi.getBackend());
ScopedExclusiveLock dsl;
Helpers::getLockedAndFetchedDriveState(ds, dsl, agentRef, driveName, lc);
}
cta::common::dataStructures::DesiredDriveState desiredState;
desiredState.up = false;
desiredState.forceDown = false;
cta::common::dataStructures::DriveState driveState;
{
//Test the reason and comment fields are empty
osdbi.setDesiredDriveState(driveName,desiredState,lc);
DriveState ds(osdbi.getBackend());
ScopedExclusiveLock dsl;
Helpers::getLockedAndFetchedDriveState(ds, dsl, agentRef, driveName, lc, Helpers::CreateIfNeeded::doNotCreate);
driveState = ds.getState();
ASSERT_EQ(cta::common::dataStructures::DriveStatus::Down, driveState.driveStatus);
ASSERT_EQ(driveName, driveState.driveName);
ASSERT_FALSE(driveState.desiredDriveState.reason);
ASSERT_FALSE(driveState.desiredDriveState.comment);
}
{
//Testing the addition of a comment
desiredState.comment = "comment";
osdbi.setDesiredDriveState(driveName,desiredState,lc);
DriveState ds(osdbi.getBackend());
ScopedExclusiveLock dsl;
Helpers::getLockedAndFetchedDriveState(ds, dsl, agentRef, driveName, lc, Helpers::CreateIfNeeded::doNotCreate);
driveState = ds.getState();
ASSERT_EQ(cta::common::dataStructures::DriveStatus::Down, driveState.driveStatus);
ASSERT_EQ(driveName, driveState.driveName);
ASSERT_FALSE(driveState.desiredDriveState.reason);
ASSERT_EQ(desiredState.comment,driveState.desiredDriveState.comment.value());
}
{
//Testing the changing of a comment
desiredState.comment = "NewComment";
osdbi.setDesiredDriveState(driveName,desiredState,lc);
DriveState ds(osdbi.getBackend());
ScopedExclusiveLock dsl;
Helpers::getLockedAndFetchedDriveState(ds, dsl, agentRef, driveName, lc, Helpers::CreateIfNeeded::doNotCreate);
driveState = ds.getState();
ASSERT_EQ(cta::common::dataStructures::DriveStatus::Down, driveState.driveStatus);
ASSERT_EQ(driveName, driveState.driveName);
ASSERT_FALSE(driveState.desiredDriveState.reason);
ASSERT_EQ(desiredState.comment,driveState.desiredDriveState.comment.value());
}
{
//Testing the addition of a reason
desiredState.reason = "reason";
osdbi.setDesiredDriveState(driveName,desiredState,lc);
DriveState ds(osdbi.getBackend());
ScopedExclusiveLock dsl;
Helpers::getLockedAndFetchedDriveState(ds, dsl, agentRef, driveName, lc, Helpers::CreateIfNeeded::doNotCreate);
driveState = ds.getState();
ASSERT_EQ(cta::common::dataStructures::DriveStatus::Down, driveState.driveStatus);
ASSERT_EQ(driveName, driveState.driveName);
ASSERT_FALSE(!driveState.desiredDriveState.reason);
ASSERT_FALSE(!driveState.desiredDriveState.comment);
ASSERT_EQ(desiredState.reason,driveState.desiredDriveState.reason.value());
}
{
//Testing the modification of a reason
desiredState.reason = "reason2";
osdbi.setDesiredDriveState(driveName,desiredState,lc);
DriveState ds(osdbi.getBackend());
ScopedExclusiveLock dsl;
Helpers::getLockedAndFetchedDriveState(ds, dsl, agentRef, driveName, lc, Helpers::CreateIfNeeded::doNotCreate);
driveState = ds.getState();
ASSERT_EQ(cta::common::dataStructures::DriveStatus::Down, driveState.driveStatus);
ASSERT_EQ(driveName, driveState.driveName);
ASSERT_FALSE(!driveState.desiredDriveState.reason);
ASSERT_EQ(desiredState.reason,driveState.desiredDriveState.reason.value());
}
{
//Testing reason not modified when optional not set
std::string reasonBefore = desiredState.reason.value();
desiredState.reason = cta::optional<std::string>();
osdbi.setDesiredDriveState(driveName,desiredState,lc);
DriveState ds(osdbi.getBackend());
ScopedExclusiveLock dsl;
Helpers::getLockedAndFetchedDriveState(ds, dsl, agentRef, driveName, lc, Helpers::CreateIfNeeded::doNotCreate);
driveState = ds.getState();
ASSERT_EQ(cta::common::dataStructures::DriveStatus::Down, driveState.driveStatus);
ASSERT_EQ(driveName, driveState.driveName);
ASSERT_EQ(reasonBefore,driveState.desiredDriveState.reason);
}
{
//Testing the deletion of a reason
desiredState.reason = "";
osdbi.setDesiredDriveState(driveName,desiredState,lc);
DriveState ds(osdbi.getBackend());
ScopedExclusiveLock dsl;
Helpers::getLockedAndFetchedDriveState(ds, dsl, agentRef, driveName, lc, Helpers::CreateIfNeeded::doNotCreate);
driveState = ds.getState();
ASSERT_EQ(cta::common::dataStructures::DriveStatus::Down, driveState.driveStatus);
ASSERT_EQ(driveName, driveState.driveName);
ASSERT_FALSE(driveState.desiredDriveState.reason);
}
}
static cta::objectstore::BackendVFS osVFS(__LINE__, __FILE__);
#ifdef TEST_RADOS
static cta::OStoreDBFactory<cta::objectstore::BackendRados> OStoreDBFactoryRados("rados://tapetest@tapetest");
......
......@@ -772,17 +772,16 @@ common::dataStructures::DesiredDriveState Scheduler::getDesiredDriveState(const
//------------------------------------------------------------------------------
// setDesiredDriveState
//------------------------------------------------------------------------------
void Scheduler::setDesiredDriveState(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &driveName, const bool up, const bool force, log::LogContext & lc) {
void Scheduler::setDesiredDriveState(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &driveName, const common::dataStructures::DesiredDriveState & desiredState, log::LogContext & lc) {
utils::Timer t;
common::dataStructures::DesiredDriveState desiredDriveState;
desiredDriveState.up = up;
desiredDriveState.forceDown = force;
m_db.setDesiredDriveState(driveName, desiredDriveState, lc);
m_db.setDesiredDriveState(driveName, desiredState, lc);
auto schedulerDbTime = t.secs();
log::ScopedParamContainer spc(lc);
spc.add("drive", driveName)
.add("up", up?"up":"down")
.add("force", force?"yes":"no")
.add("up", desiredState.up ? "up" : "down")
.add("force", desiredState.forceDown ? "yes" : "no")
.add("reason",desiredState.reason ? desiredState.reason.value() : "")
.add("comment", desiredState.comment ? desiredState.comment.value() : "")
.add("schedulerDbTime", schedulerDbTime);
lc.log(log::INFO, "In Scheduler::setDesiredDriveState(): success.");
}
......
......@@ -225,11 +225,10 @@ public:
* on hardware failures.
* @param cliIdentity The identity of the user requesting the drive to put up of down.
* @param driveName The drive name
* @param up indicates whether the drive should be put up or down.
* @param force indicates whether we want to force the drive to be up.
*/ //TODO: replace the 2 bools with a structure.
void setDesiredDriveState(const cta::common::dataStructures::SecurityIdentity &cliIdentity,
const std::string &driveName, const bool up, const bool force, log::LogContext & lc);
* @param desiredState, the structure that contains the desired state informations
*/
void setDesiredDriveState(const cta::common::dataStructures::SecurityIdentity &cliIdentity, const std::string & driveName,
const common::dataStructures::DesiredDriveState & desiredState, log::LogContext & lc);
/**
* Remove drive from the drive register.
......
......@@ -143,7 +143,10 @@ schedule:
if (!emptyDriveProbe.driveIsEmpty()) {
m_scheduler.reportDriveStatus(m_driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, lc);
cta::common::dataStructures::SecurityIdentity securityIdentity;
m_scheduler.setDesiredDriveState(securityIdentity, m_driveConfig.unitName, false, false, lc);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = false;
driveState.forceDown = false;
m_scheduler.setDesiredDriveState(securityIdentity, m_driveConfig.unitName, driveState, lc);
lc.log(cta::log::ERR, "A tape was detected in the drive. Putting the drive back down.");
goto schedule;
} else {
......@@ -164,7 +167,10 @@ schedule:
lc.logBacktrace(cta::log::ERR, e.backtrace());
m_scheduler.reportDriveStatus(m_driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, lc);
cta::common::dataStructures::SecurityIdentity cliId;
m_scheduler.setDesiredDriveState(cliId, m_driveConfig.unitName, false, false, lc);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = false;
driveState.forceDown = false;
m_scheduler.setDesiredDriveState(cliId, m_driveConfig.unitName, driveState, lc);
return MARK_DRIVE_AS_DOWN;
}
// No mount to be done found, that was fast...
......
......@@ -479,7 +479,10 @@ TEST_P(DataTransferSessionTest, DataTransferSessionGooddayRecall) {
driveInfo.host=="host";
// We need to create the drive in the registry before being able to put it up.
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, logContext);
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, true, false, logContext);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = true;
driveState.forceDown = false;
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, driveState, logContext);
// 7) Create the data transfer session
DataTransferConfig castorConf;
......@@ -683,7 +686,10 @@ TEST_P(DataTransferSessionTest, DataTransferSessionWrongRecall) {
driveInfo.host=="host";
// We need to create the drive in the registry before being able to put it up.
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, logContext);
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, true, false, logContext);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = true;
driveState.forceDown = false;
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, driveState, logContext);
// 7) Create the data transfer session
DataTransferConfig castorConf;
......@@ -888,7 +894,10 @@ TEST_P(DataTransferSessionTest, DataTransferSessionRAORecall) {
driveInfo.logicalLibrary=driveConfig.rawLibrarySlot;
// We need to create the drive in the registry before being able to put it up.
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, logContext);
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, true, false, logContext);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = true;
driveState.forceDown = false;
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, driveState, logContext);
// 7) Create the data transfer session
DataTransferConfig castorConf;
......@@ -1065,7 +1074,10 @@ TEST_P(DataTransferSessionTest, DataTransferSessionNoSuchDrive) {
driveInfo.host=="host";
// We need to create the drive in the registry before being able to put it up.
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, logContext);
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, true, false, logContext);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = true;
driveState.forceDown = false;
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, driveState, logContext);
// 8) Create the data transfer session
DataTransferConfig castorConf;
......@@ -1212,7 +1224,10 @@ TEST_P(DataTransferSessionTest, DataTransferSessionFailtoMount) {
driveInfo.host=="host";
// We need to create the drive in the registry before being able to put it up.
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, logContext);
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, true, false, logContext);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = true;
driveState.forceDown = false;
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, driveState, logContext);
// 8) Create the data transfer session
DataTransferConfig castorConf;
......@@ -1342,7 +1357,10 @@ TEST_P(DataTransferSessionTest, DataTransferSessionGooddayMigration) {
driveInfo.host=="host";
// We need to create the drive in the registry before being able to put it up.
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, logContext);
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, true, false, logContext);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = true;
driveState.forceDown = false;
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, driveState, logContext);
// Create the data transfer session
DataTransferConfig castorConf;
......@@ -1490,7 +1508,10 @@ TEST_P(DataTransferSessionTest, DataTransferSessionMissingFilesMigration) {
driveInfo.host=="host";
// We need to create the drive in the registry before being able to put it up.
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, logContext);
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, true, false, logContext);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = true;
driveState.forceDown = false;
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, driveState, logContext);
// Create the data transfer session
DataTransferConfig castorConf;
......@@ -1647,7 +1668,10 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullMigration) {
driveInfo.host=="host";
// We need to create the drive in the registry before being able to put it up.
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, logContext);
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, true, false, logContext);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = true;
driveState.forceDown = false;
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, driveState, logContext);
// Create the data transfer session
DataTransferConfig castorConf;
......@@ -1807,7 +1831,10 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullOnFlushMigration) {
driveInfo.host=="host";
// We need to create the drive in the registry before being able to put it up.
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, logContext);
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, true, false, logContext);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = true;
driveState.forceDown = false;
scheduler.setDesiredDriveState(s_adminOnAdminHost, driveConfig.unitName, driveState, logContext);
// Create the data transfer session
DataTransferConfig castorConf;
......
......@@ -961,7 +961,10 @@ int DriveHandler::runChild() {
driveInfo.host=hostname;
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, lc);
cta::common::dataStructures::SecurityIdentity securityIdentity;
scheduler.setDesiredDriveState(securityIdentity, m_configLine.unitName, false, false, lc);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = false;
driveState.forceDown = false;
scheduler.setDesiredDriveState(securityIdentity, m_configLine.unitName,driveState, lc);
return castor::tape::tapeserver::daemon::Session::MARK_DRIVE_AS_DOWN;
} catch (cta::exception::Exception &ex) {
log::ScopedParamContainer param(lc);
......@@ -987,7 +990,10 @@ int DriveHandler::runChild() {
driveInfo.host=hostname;
scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, lc);
cta::common::dataStructures::SecurityIdentity securityIdentity;
scheduler.setDesiredDriveState(securityIdentity, m_configLine.unitName, false, false, lc);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = false;
driveState.forceDown = false;
scheduler.setDesiredDriveState(securityIdentity, m_configLine.unitName, driveState, lc);
return castor::tape::tapeserver::daemon::Session::MARK_DRIVE_AS_DOWN;
} catch (cta::exception::Exception &ex) {
log::ScopedParamContainer param(lc);
......@@ -1097,7 +1103,10 @@ int DriveHandler::runChild() {
scheduler.reportDriveStatus(driveInfo, common::dataStructures::MountType::NoMount, common::dataStructures::DriveStatus::Down, lc);
cta::common::dataStructures::SecurityIdentity securityIdentity;
scheduler.setDesiredDriveState(securityIdentity, m_configLine.unitName, false /* down */, false /* no force down*/, lc);
cta::common::dataStructures::DesiredDriveState driveState;
driveState.up = false;
driveState.forceDown = false;
scheduler.setDesiredDriveState(securityIdentity, m_configLine.unitName, driveState, lc);
scheduler.reportDriveConfig(m_configLine,m_tapedConfig,lc);
} catch (cta::exception::Exception & ex) {
params.add("Message", ex.getMessageValue())
......
......@@ -124,6 +124,8 @@ int DriveLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) {
dr_item->set_current_activity(dr.currentActivityAndWeight ? dr.currentActivityAndWeight.value().activity : "");
dr_item->set_dev_file_name(dr.devFileName);
dr_item->set_raw_library_slot(dr.rawLibrarySlot);
dr_item->set_comment(dr.desiredDriveState.comment ? dr.desiredDriveState.comment.value() : "");
dr_item->set_reason(dr.desiredDriveState.reason ? dr.desiredDriveState.reason.value() : "");
auto driveConfig = dr_item->mutable_drive_config();
for(auto & driveConfigItem: dr.driveConfigItems){
......
......@@ -113,6 +113,9 @@ void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Respons
case cmd_pair(AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_DOWN):
processDrive_Down(response);
break;
case cmd_pair(AdminCmd::CMD_DRIVE,AdminCmd::SUBCMD_CH):
processDrive_Ch(response);
break;
case cmd_pair(AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_LS):
processDrive_Ls(response, stream);
break;
......@@ -803,8 +806,18 @@ void RequestMessage::processArchiveRoute_Ls(cta::xrd::Response &response, XrdSsi
void RequestMessage::processDrive_Up(cta::xrd::Response &response)
{
using namespace cta::admin;
std::string cmdlineOutput = setDriveState('^' + getRequired(OptionString::DRIVE) + '$', Up);
cta::optional<std::string> reason = getOptional(OptionString::REASON);
cta::common::dataStructures::DesiredDriveState desiredDS;
desiredDS.up = true;
desiredDS.forceDown = false;
desiredDS.reason = reason;
if(!desiredDS.reason){
//If reason not provided while setting the drive up, we delete it, so we set it to an empty string
desiredDS.reason = "";
}
std::string cmdlineOutput = setDriveState('^' + getRequired(OptionString::DRIVE) + '$', desiredDS);
response.set_message_txt(cmdlineOutput);
response.set_type(cta::xrd::Response::RSP_SUCCESS);
......@@ -816,13 +829,37 @@ void RequestMessage::processDrive_Down(cta::xrd::Response &response)
{
using namespace cta::admin;
std::string cmdlineOutput = setDriveState('^' + getRequired(OptionString::DRIVE) + '$', Down);
std::string reason = getRequired(OptionString::REASON);
if(utils::trimString(reason).empty()) {
throw cta::exception::UserError("You must provide a reason in order to set the drive down");
}
cta::common::dataStructures::DesiredDriveState desiredDS;
desiredDS.up = false;
desiredDS.forceDown = has_flag(OptionBoolean::FORCE);
desiredDS.reason = reason;
std::string cmdlineOutput = setDriveState('^' + getRequired(OptionString::DRIVE) + '$', desiredDS);
response.set_message_txt(cmdlineOutput);
response.set_type(cta::xrd::Response::RSP_SUCCESS);
}
void RequestMessage::processDrive_Ch(cta::xrd::Response & response) {
using namespace cta::admin;
std::string comment = getRequired(OptionString::COMMENT);
if(utils::trimString(comment).empty()) {
throw cta::exception::UserError("You must provide a comment to change it.");
}
cta::common::dataStructures::DesiredDriveState desiredDS;
desiredDS.comment = comment;
std::string cmdlineOutput = setDriveState('^' + getRequired(OptionString::DRIVE) + '$', desiredDS);