Commit 3e668815 authored by Eric Cano's avatar Eric Cano
Browse files

CASTOR-4800: failed migration mount of tapeserverd is not propagted to disk IO threads

We had a session ending mechanism for the tape and disk tasks in migrations, but it did not cover all the aspects of the tape thread (like in this ticket, mounting). In this case the disk thread was happily reading the data from disk, which the tape thread was putting to the bin.

The signalling mechanism, attached to the task injector has now been passed to tape write thread itself, which signals the error condition when receiving any exception. If this came from a task as before, this is a no-op, but if we had a problem mounting, then the session will and immediately and disk threads will stop reading (also immediately).
parent a05f7d6b
......@@ -301,6 +301,7 @@ castor::tape::tapeserver::daemon::Session::EndOfSessionAction
castor::utils::Timer timer;
if (mti.synchronousInjection()) {
const uint64_t firstFseqFromClient = mti.firstFseqToWrite();
......@@ -103,6 +103,24 @@ public:
* @return
uint64_t firstFseqToWrite() const;
* Public interface allowing to set the error flag. This is used
* by the tasks (disk and tape) and the tape thread to indicate
* that the session cannot continue.
void setErrorFlag() {
* Public interface to the error flag, allowing the disk and tape tasks
* to decide whether they should carry on or just free memory.
* @return value of the error flag
bool hasErrorFlag() {
return m_errorFlag;
* Create all the tape-read and write-disk tasks for set of files to retrieve
......@@ -22,6 +22,7 @@
#include "castor/tape/tapeserver/daemon/TapeWriteSingleThread.hpp"
#include "castor/tape/tapeserver/daemon/MigrationTaskInjector.hpp"
......@@ -206,6 +207,14 @@ void castor::tape::tapeserver::daemon::TapeWriteSingleThread::run() {
//we end there because write session could not be opened
//or because a task failed or because flush failed
// First off, indicate the problem to the task injector so it does not inject
// more work in the pipeline
// If the problem did not originate here, we just re-flag the error, and
// this has no effect, but if we had a problem with a non-file operation
// like mounting the tape, then we have to signal the problem to the disk
// side and the task injector, which will trigger the end of session.
//first empty all the tasks and circulate mem blocks
while(1) {
std::auto_ptr<TapeWriteTask> task(m_tasks.pop());
......@@ -43,6 +43,9 @@ namespace castor {
namespace tape {
namespace tapeserver {
namespace daemon {
// forward definition
class MigrationTaskInjector;
class TapeWriteSingleThread : public TapeSingleThreadInterface<TapeWriteTask> {
......@@ -71,6 +74,19 @@ public:
* @param lastFseq
void setlastFseq(uint64_t lastFseq);
* Sets up the pointer to the task injector. This cannot be done at
* construction time as both task injector and tape write single thread refer to
* each other. This function should be called before starting the threads.
* This is used for signalling problems during mounting. After that, each
* tape write task does the signalling itself, either on tape problem, or
* when receiving an error from the disk tasks via memory blocks.
* @param injector pointer to the task injector
void setTaskInjector(MigrationTaskInjector* injector){
m_injector = injector;
class TapeCleaning{
TapeWriteSingleThread& m_this;
......@@ -187,6 +203,11 @@ private:
* Reference to the watchdog, used in run()
MigrationWatchDog & m_watchdog;
* Pointer to the task injector allowing termination signaling
MigrationTaskInjector* m_injector;
}; // class TapeWriteSingleThread
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