Commit 4bb07abb authored by Steven Murray's avatar Steven Murray
Browse files

Fixed bug where putting down a running drive crashes tapeserverd

Vlado found this bug whilst running tapserverd with real tape hardware.
Mounts last long enough with real hardware for an operator to easily
use "tpconfig down" on a running drive.

The tapserverd process was not handling the WAIT_DOWN state correctly
and was throwing an unexpected exception that in turn caused the process
to crash due to the resulting abort signal.

The tapserverd process was not handling the WAIT_DOWN state correctly
due to some over simplifications I made to the architecture of
tapeserverd.
parent 9ce8dca3
......@@ -133,7 +133,7 @@ const castor::tape::tapeserver::daemon::DriveCatalogueSession &
//------------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogueEntry::checkForSession()
const {
if(DRIVE_STATE_RUNNING != m_state) {
if(DRIVE_STATE_RUNNING != m_state && DRIVE_STATE_WAITDOWN != m_state) {
castor::exception::Exception ex;
ex.getMessage() << "Drive is currently not running a session";
throw ex;
......@@ -204,11 +204,7 @@ castor::tape::tapeserver::daemon::DriveCatalogueCleanerSession &
//------------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogueEntry::
checkForCleanerSession() const {
if(DRIVE_STATE_RUNNING != m_state) {
castor::exception::Exception ex;
ex.getMessage() << "Drive is currently not running a session";
throw ex;
}
checkForSession();
if(SESSION_TYPE_CLEANER != m_sessionType) {
castor::exception::Exception ex;
ex.getMessage() <<
......@@ -280,11 +276,7 @@ castor::tape::tapeserver::daemon::DriveCatalogueLabelSession &
//------------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogueEntry::
checkForLabelSession() const {
if(DRIVE_STATE_RUNNING != m_state) {
castor::exception::Exception ex;
ex.getMessage() << "Drive is currently not running a session";
throw ex;
}
checkForSession();
if(SESSION_TYPE_LABEL != m_sessionType) {
castor::exception::Exception ex;
ex.getMessage() << "Session associated with drive is not a label session"
......@@ -357,11 +349,7 @@ castor::tape::tapeserver::daemon::DriveCatalogueTransferSession &
//------------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogueEntry::
checkForTransferSession() const {
if(DRIVE_STATE_RUNNING != m_state) {
castor::exception::Exception ex;
ex.getMessage() << "Drive is currently not running a session";
throw ex;
}
checkForSession();
if(SESSION_TYPE_DATATRANSFER != m_sessionType) {
castor::exception::Exception ex;
ex.getMessage() <<
......@@ -546,15 +534,20 @@ void castor::tape::tapeserver::daemon::DriveCatalogueEntry::toBeCleaned() {
// Get the vid and assignment time of the crashed tape session
std::string vid;
try {
vid = m_session->getVid();
vid = getSession().getVid();
} catch(...) {
vid = "";
}
const time_t assignmentTime = m_session->getAssignmentTime();
time_t assignmentTime = 0;
try {
getSession().getAssignmentTime();
} catch(...) {
assignmentTime = 0;
}
// Free the catalogue representation of the crashed tape session setting
// the sesison pointer to NULL to prevent the destructor from perfroming
// a doyble delete
// a double delete
delete(m_session);
m_session = NULL;
......@@ -708,11 +701,9 @@ uint32_t castor::tape::tapeserver::daemon::DriveCatalogueEntry::
//------------------------------------------------------------------------------
uint32_t castor::tape::tapeserver::daemon::DriveCatalogueEntry::
getJidForTapeStatDriveEntry() const throw() {
switch(m_state) {
case DRIVE_STATE_RUNNING:
case DRIVE_STATE_WAITDOWN:
try {
return getSession().getPid();
default:
} catch(...) {
return 0;
}
}
......@@ -750,15 +741,9 @@ uint16_t castor::tape::tapeserver::daemon::DriveCatalogueEntry::
//------------------------------------------------------------------------------
uint32_t castor::tape::tapeserver::daemon::DriveCatalogueEntry::
getAsnTimeForTapeStatDriveEntry() const throw() {
switch(m_state) {
case DRIVE_STATE_RUNNING:
case DRIVE_STATE_WAITDOWN:
try {
return m_session->getAssignmentTime();
} catch(...) {
return 0;
}
default:
try {
return getSession().getAssignmentTime();
} catch(...) {
return 0;
}
}
......@@ -768,15 +753,9 @@ uint32_t castor::tape::tapeserver::daemon::DriveCatalogueEntry::
//------------------------------------------------------------------------------
uint16_t castor::tape::tapeserver::daemon::DriveCatalogueEntry::
getModeForTapeStatDriveEntry() const throw() {
switch(m_state) {
case DRIVE_STATE_RUNNING:
case DRIVE_STATE_WAITDOWN:
try {
return m_session->getMode();
} catch(...) {
return WRITE_DISABLE;
}
default:
try {
return getSession().getMode();
} catch(...) {
return WRITE_DISABLE;
}
}
......@@ -794,11 +773,9 @@ std::string castor::tape::tapeserver::daemon::DriveCatalogueEntry::
//------------------------------------------------------------------------------
uint16_t castor::tape::tapeserver::daemon::DriveCatalogueEntry::
getToBeMountedForTapeStatDriveEntry() const throw() {
switch(m_state) {
case DRIVE_STATE_RUNNING:
case DRIVE_STATE_WAITDOWN:
return m_session->tapeIsBeingMounted();
default:
try {
return getSession().tapeIsBeingMounted();
} catch(...) {
return 0;
}
}
......@@ -808,15 +785,9 @@ uint16_t castor::tape::tapeserver::daemon::DriveCatalogueEntry::
//------------------------------------------------------------------------------
std::string castor::tape::tapeserver::daemon::DriveCatalogueEntry::
getVidForTapeStatDriveEntry() const throw() {
switch(m_state) {
case DRIVE_STATE_RUNNING:
case DRIVE_STATE_WAITDOWN:
try {
return m_session->getVid();
} catch(...) {
return "";
}
default:
try {
return getSession().getVid();
} catch(...) {
return "";
}
}
......
......@@ -209,13 +209,7 @@ std::string castor::tape::tapeserver::daemon::DriveCatalogueTransferSession::
case TRANSFERSTATE_RUNNING:
return m_vid;
default:
{
castor::exception::Exception ex;
ex.getMessage() << "Failed to get VID from catalogue transfer-session"
": Catalogue transfer-session is in an incomaptible state: "
" state=" << transferStateToStr(m_state);
throw ex;
}
return "";
}
}
......@@ -233,7 +227,7 @@ int castor::tape::tapeserver::daemon::DriveCatalogueTransferSession::
castor::exception::Exception ex;
ex.getMessage() << "Failed to get access mode from catalogue"
" transfer-session"
": Catalogue transfer-session is in an incomaptible state: "
": Catalogue transfer-session is in an incompatible state: "
" state=" << transferStateToStr(m_state);
throw ex;
}
......
......@@ -113,10 +113,9 @@ public:
/**
* Gets the volume identifier of the tape associated with the tape drive.
*
* This method throws a castor::exception::Exception if the volume identifer
* is not yet known.
*
* @return The volume identifier of the tape associated with the tape drive.
* If the volume indentifier is not known then this method returns the empty
* string.
*/
std::string getVid() const;
......
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