From c3d1d3659c23a8fb2a2ce043561c43af15414087 Mon Sep 17 00:00:00 2001
From: Daniele Kruse <dkruse@cern.ch>
Date: Fri, 23 Oct 2015 16:16:55 +0200
Subject: [PATCH] Trying to archive files for the first time: fixing bugs and
 adding missing information

---
 scheduler/ArchiveMount.cpp                        |  7 +++++++
 scheduler/ArchiveMount.hpp                        |  7 +++++++
 scheduler/OStoreDB/OStoreDB.cpp                   |  4 ++--
 scheduler/OStoreDB/OStoreDB.hpp                   |  1 -
 scheduler/RetrieveMount.cpp                       |  7 +++++++
 scheduler/RetrieveMount.hpp                       |  7 +++++++
 scheduler/SchedulerDatabase.hpp                   |  2 ++
 scheduler/TapeMount.hpp                           |  9 ++++++++-
 .../castor/messages/ArchiveJobFromCTA.proto       |  1 +
 tapeserver/castor/messages/TapeserverProxy.hpp    |  2 +-
 .../castor/messages/TapeserverProxyDummy.cpp      |  2 +-
 .../castor/messages/TapeserverProxyDummy.hpp      |  2 +-
 tapeserver/castor/messages/TapeserverProxyZmq.cpp |  7 ++++---
 tapeserver/castor/messages/TapeserverProxyZmq.hpp |  4 ++--
 .../tapeserver/daemon/DataTransferSession.cpp     |  6 ++++--
 .../tape/tapeserver/daemon/TapeMessageHandler.cpp | 15 +++------------
 .../tape/tapeserver/daemon/TapeServerReporter.cpp |  2 +-
 .../castor/tape/tapeserver/daemon/VolumeInfo.hpp  |  2 ++
 18 files changed, 60 insertions(+), 27 deletions(-)

diff --git a/scheduler/ArchiveMount.cpp b/scheduler/ArchiveMount.cpp
index 3288c31a40..bfe1bffdde 100644
--- a/scheduler/ArchiveMount.cpp
+++ b/scheduler/ArchiveMount.cpp
@@ -59,6 +59,13 @@ std::string cta::ArchiveMount::getPoolName() const {
   return m_dbMount->mountInfo.tapePool;
 }
 
+//------------------------------------------------------------------------------
+// getNbFiles
+//------------------------------------------------------------------------------
+uint32_t cta::ArchiveMount::getNbFiles() const {
+  return m_dbMount->nbFilesCurrentlyOnTape;
+}
+
 //------------------------------------------------------------------------------
 // getMountTransactionId
 //------------------------------------------------------------------------------
diff --git a/scheduler/ArchiveMount.hpp b/scheduler/ArchiveMount.hpp
index 478866cdec..dc4003b2b2 100644
--- a/scheduler/ArchiveMount.hpp
+++ b/scheduler/ArchiveMount.hpp
@@ -101,6 +101,13 @@ namespace cta {
      */
     virtual std::string getPoolName() const;
     
+    /**
+     * Returns the mount transaction id.
+     *
+     * @return The mount transaction id.
+     */
+    virtual uint32_t getNbFiles() const;
+    
     /**
      * Destructor.
      */
diff --git a/scheduler/OStoreDB/OStoreDB.cpp b/scheduler/OStoreDB/OStoreDB.cpp
index 31114f7985..aeb586b705 100644
--- a/scheduler/OStoreDB/OStoreDB.cpp
+++ b/scheduler/OStoreDB/OStoreDB.cpp
@@ -1203,7 +1203,7 @@ std::unique_ptr<SchedulerDatabase::ArchiveMount>
       m_agent.addToOwnership(t.getAddressIfSet());
       m_agent.commit();
     }
-    am.m_nextFseq = t.getLastFseq() + 1;
+    am.nbFilesCurrentlyOnTape = t.getLastFseq();
     am.mountInfo.vid = t.getVid();
     t.setBusy(driveName, objectstore::Tape::MountType::Archive, hostName, startTime, 
       m_agent.getAddressIfSet());
@@ -1416,7 +1416,7 @@ auto OStoreDB::ArchiveMount::getNextJob() -> std::unique_ptr<SchedulerDatabase::
     tp.commit();
     privateRet->archiveFile = privateRet->m_atfr.getArchiveFile();
     privateRet->remoteFile = privateRet->m_atfr.getRemoteFile();
-    privateRet->nameServerTapeFile.tapeFileLocation.fSeq = m_nextFseq++;
+    privateRet->nameServerTapeFile.tapeFileLocation.fSeq = ++nbFilesCurrentlyOnTape;
     privateRet->nameServerTapeFile.tapeFileLocation.copyNb = privateRet->m_copyNb;
     privateRet->nameServerTapeFile.tapeFileLocation.vid = mountInfo.vid;
     privateRet->nameServerTapeFile.tapeFileLocation.blockId =
diff --git a/scheduler/OStoreDB/OStoreDB.hpp b/scheduler/OStoreDB/OStoreDB.hpp
index 7350a8d0f2..d10f5be239 100644
--- a/scheduler/OStoreDB/OStoreDB.hpp
+++ b/scheduler/OStoreDB/OStoreDB.hpp
@@ -80,7 +80,6 @@ public:
     ArchiveMount(objectstore::Backend &, objectstore::Agent &);
     objectstore::Backend & m_objectStore;
     objectstore::Agent & m_agent;
-    uint64_t m_nextFseq;
   public:
     virtual const MountInfo & getMountInfo();
     virtual std::unique_ptr<ArchiveJob> getNextJob();
diff --git a/scheduler/RetrieveMount.cpp b/scheduler/RetrieveMount.cpp
index ee5de6392b..524a9d94da 100644
--- a/scheduler/RetrieveMount.cpp
+++ b/scheduler/RetrieveMount.cpp
@@ -40,6 +40,13 @@ cta::MountType::Enum cta::RetrieveMount::getMountType() const{
   return MountType::RETRIEVE;
 }
 
+//------------------------------------------------------------------------------
+// getNbFiles
+//------------------------------------------------------------------------------
+uint32_t cta::RetrieveMount::getNbFiles() const {
+  return m_dbMount->nbFilesCurrentlyOnTape;
+}
+
 //------------------------------------------------------------------------------
 // getVid
 //------------------------------------------------------------------------------
diff --git a/scheduler/RetrieveMount.hpp b/scheduler/RetrieveMount.hpp
index 1bbedfcfc6..e44dc2d52b 100644
--- a/scheduler/RetrieveMount.hpp
+++ b/scheduler/RetrieveMount.hpp
@@ -73,6 +73,13 @@ namespace cta {
      * @return The mount transaction id.
      */
     virtual std::string getMountTransactionId() const;
+    
+    /**
+     * Returns the mount transaction id.
+     *
+     * @return The mount transaction id.
+     */
+    virtual uint32_t getNbFiles() const;
 
     /**
      * Indicates that the mount was completed.
diff --git a/scheduler/SchedulerDatabase.hpp b/scheduler/SchedulerDatabase.hpp
index 069c59362b..a578bed12d 100644
--- a/scheduler/SchedulerDatabase.hpp
+++ b/scheduler/SchedulerDatabase.hpp
@@ -172,6 +172,7 @@ public:
     virtual std::unique_ptr<ArchiveJob> getNextJob() = 0;
     virtual void complete(time_t completionTime) = 0;
     virtual ~ArchiveMount() {}
+    uint32_t nbFilesCurrentlyOnTape;
   };
   
   /**
@@ -250,6 +251,7 @@ public:
     virtual std::unique_ptr<RetrieveJob> getNextJob() = 0;
     virtual void complete(time_t completionTime) = 0;
     virtual ~RetrieveMount() {}
+    uint32_t nbFilesCurrentlyOnTape;
   };
   
   class RetrieveJob {
diff --git a/scheduler/TapeMount.hpp b/scheduler/TapeMount.hpp
index d1c11a832d..ddcc303fe4 100644
--- a/scheduler/TapeMount.hpp
+++ b/scheduler/TapeMount.hpp
@@ -49,7 +49,14 @@ namespace cta {
      *
      * @return The mount transaction id.
      */
-    virtual std::string getMountTransactionId() const = 0;
+    virtual std::string getMountTransactionId() const = 0;    
+    
+    /**
+     * Returns the mount transaction id.
+     *
+     * @return The mount transaction id.
+     */
+    virtual uint32_t getNbFiles() const = 0;
 
     /**
      * Indicates that the mount was completed.
diff --git a/tapeserver/castor/messages/ArchiveJobFromCTA.proto b/tapeserver/castor/messages/ArchiveJobFromCTA.proto
index 46a07569a2..638ec75a49 100644
--- a/tapeserver/castor/messages/ArchiveJobFromCTA.proto
+++ b/tapeserver/castor/messages/ArchiveJobFromCTA.proto
@@ -20,4 +20,5 @@ package castor.messages;
 message ArchiveJobFromCTA {
  required string vid = 1;
  required string unitname = 2;
+ required uint32 nbfiles = 3;
 }
diff --git a/tapeserver/castor/messages/TapeserverProxy.hpp b/tapeserver/castor/messages/TapeserverProxy.hpp
index d815f2cb7d..3484013184 100644
--- a/tapeserver/castor/messages/TapeserverProxy.hpp
+++ b/tapeserver/castor/messages/TapeserverProxy.hpp
@@ -84,7 +84,7 @@ public:
    * @return The number of files currently stored on the tape
    */
   virtual uint32_t gotArchiveJobFromCTA(const std::string &vid,
-    const std::string &unitName) = 0;
+    const std::string &unitName, const uint32_t nbFiles) = 0;
   
   /**
    * Notifies the tapeserverd daemon that the mount-session child-process got
diff --git a/tapeserver/castor/messages/TapeserverProxyDummy.cpp b/tapeserver/castor/messages/TapeserverProxyDummy.cpp
index feea71b47e..c632fa86a7 100644
--- a/tapeserver/castor/messages/TapeserverProxyDummy.cpp
+++ b/tapeserver/castor/messages/TapeserverProxyDummy.cpp
@@ -25,7 +25,7 @@
 // gotArchiveJobFromCTA
 //------------------------------------------------------------------------------
 uint32_t castor::messages::TapeserverProxyDummy::gotArchiveJobFromCTA(
-  const std::string &vid, const std::string &unitName) {
+  const std::string &vid, const std::string &unitName, const uint32_t nbFiles) {
   return 0;
 }
 
diff --git a/tapeserver/castor/messages/TapeserverProxyDummy.hpp b/tapeserver/castor/messages/TapeserverProxyDummy.hpp
index c02aa3e067..d9dfff95aa 100644
--- a/tapeserver/castor/messages/TapeserverProxyDummy.hpp
+++ b/tapeserver/castor/messages/TapeserverProxyDummy.hpp
@@ -41,7 +41,7 @@ public:
    * @return The number of files currently stored on the tape
    */
   virtual uint32_t gotArchiveJobFromCTA(const std::string &vid,
-    const std::string &unitName);
+    const std::string &unitName, const uint32_t nbFiles);
   
   /**
    * Notifies the tapeserverd daemon that the mount-session child-process got
diff --git a/tapeserver/castor/messages/TapeserverProxyZmq.cpp b/tapeserver/castor/messages/TapeserverProxyZmq.cpp
index 4088b8e549..442edea96e 100644
--- a/tapeserver/castor/messages/TapeserverProxyZmq.cpp
+++ b/tapeserver/castor/messages/TapeserverProxyZmq.cpp
@@ -56,11 +56,11 @@ castor::messages::TapeserverProxyZmq::TapeserverProxyZmq(log::Logger &log,
 // gotArchiveJobFromCTA
 //------------------------------------------------------------------------------
 uint32_t castor::messages::TapeserverProxyZmq::gotArchiveJobFromCTA(
-  const std::string &vid, const std::string &unitName) {
+  const std::string &vid, const std::string &unitName, const uint32_t nbFiles) {
   MutexLocker lock(&m_mutex);
 
   try {
-    const Frame rqst = createArchiveJobFromCTAFrame(vid, unitName);
+    const Frame rqst = createArchiveJobFromCTAFrame(vid, unitName, nbFiles);
     sendFrame(m_serverSocket, rqst);
 
     NbFilesOnTape reply;
@@ -303,7 +303,7 @@ castor::messages::Frame castor::messages::TapeserverProxyZmq::
 //------------------------------------------------------------------------------
 castor::messages::Frame castor::messages::TapeserverProxyZmq::
   createArchiveJobFromCTAFrame(const std::string &vid,
-  const std::string &unitName) {
+  const std::string &unitName, const uint32_t nbFiles) {
   try {
     Frame frame;
 
@@ -314,6 +314,7 @@ castor::messages::Frame castor::messages::TapeserverProxyZmq::
     ArchiveJobFromCTA body;
     body.set_vid(vid);
     body.set_unitname(unitName);
+    body.set_nbfiles(nbFiles);
     frame.serializeProtocolBufferIntoBody(body);
 
     return frame;
diff --git a/tapeserver/castor/messages/TapeserverProxyZmq.hpp b/tapeserver/castor/messages/TapeserverProxyZmq.hpp
index 711aea00f2..b681ffff62 100644
--- a/tapeserver/castor/messages/TapeserverProxyZmq.hpp
+++ b/tapeserver/castor/messages/TapeserverProxyZmq.hpp
@@ -57,7 +57,7 @@ public:
    * @return The number of files currently stored on the tape
    */
   virtual uint32_t gotArchiveJobFromCTA(const std::string &vid,
-    const std::string &unitName);
+    const std::string &unitName, const uint32_t nbFiles);
   
   /**
    * Notifies the tapeserverd daemon that the mount-session child-process got
@@ -219,7 +219,7 @@ private:
    * @return The frame.
    */
   Frame createArchiveJobFromCTAFrame(const std::string &vid,
-    const std::string &unitName);
+    const std::string &unitName, const uint32_t nbFiles);
           
   /**
    * Creates a frame containing a RetrieveJobFromCTA message.
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp
index 8a22c5ea6f..503f01127f 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp
@@ -101,6 +101,7 @@ castor::tape::tapeserver::daemon::Session::EndOfSessionAction
     return MARK_DRIVE_AS_UP;
   m_volInfo.vid=tapeMount->getVid();
   m_volInfo.mountType=tapeMount->getMountType();
+  m_volInfo.nbFiles=tapeMount->getNbFiles();
   // 2b) ... and log.
   // Make the DGN and TPVID parameter permanent.
   log::ScopedParamContainer params(lc);
@@ -290,8 +291,9 @@ castor::tape::tapeserver::daemon::Session::EndOfSessionAction
 
       //theses 2 numbers should match. Otherwise, it means the stager went mad 
       if(firstFseqFromClient != nbOfFileOnTape + 1) {
-        lc.log(LOG_ERR, "First file to write's fseq  and number of files on "
-        "the tape according to the VMGR dont match");
+        std::stringstream ss;
+        ss << "First file to write's fseq(" << firstFseqFromClient << ")  and number of files on the tape (" << nbOfFileOnTape << " + 1) dont match";
+        lc.log(LOG_ERR, ss.str());
        //no mount at all, drive to be kept up = return 0
         return MARK_DRIVE_AS_UP;
       }
diff --git a/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp b/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp
index 371a261619..fd343a459e 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp
@@ -337,19 +337,10 @@ castor::messages::Frame castor::tape::tapeserver::daemon::TapeMessageHandler::
     castor::messages::ArchiveJobFromCTA rqstBody;
     rqst.parseBodyIntoProtocolBuffer(rqstBody);
     
-    CatalogueDrive &drive =
-      m_driveCatalogue.findDrive(rqstBody.unitname());
+    CatalogueDrive &drive = m_driveCatalogue.findDrive(rqstBody.unitname());
     drive.getTransferSession().receivedMigrationJob(rqstBody.vid());
-
-    {
-      std::ostringstream msg;
-      msg << __FUNCTION__ << ": Not fully implemented because the number of"
-        " files on tape is not known because there is no vmgr in the CTA"
-        " project";
-      throw castor::exception::Exception(msg.str());
-    }
-    //messages::Frame reply = createNbFilesOnTapeFrame(tapeInfo.nbFiles);
-    //return reply;
+    messages::Frame reply = createNbFilesOnTapeFrame(rqstBody.nbfiles());
+    return reply;
   } catch(castor::exception::Exception &ne) {
     castor::exception::Exception ex;
     ex.getMessage() <<
diff --git a/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.cpp b/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.cpp
index 9795e267c0..769fb9b39e 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.cpp
@@ -96,7 +96,7 @@ TapeServerReporter::TapeServerReporter(
       m_lc.log(LOG_ERR,"TapeServerReporter is running but calling a synchronous operation on it"
       "Could cause a race with the underlying  zmq sockets in the proxy");
     }
-    return m_tapeserverProxy.gotArchiveJobFromCTA(m_volume.vid, m_unitName);
+    return m_tapeserverProxy.gotArchiveJobFromCTA(m_volume.vid, m_unitName, m_volume.nbFiles);
   }
 //------------------------------------------------------------------------------
 //gotReadMountDetailsFromClient
diff --git a/tapeserver/castor/tape/tapeserver/daemon/VolumeInfo.hpp b/tapeserver/castor/tape/tapeserver/daemon/VolumeInfo.hpp
index 82628a84d0..f87e6aeacd 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/VolumeInfo.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/VolumeInfo.hpp
@@ -43,6 +43,8 @@ namespace daemon {
       std::string vid;
       /** The mount type: archive or retrieve */
       cta::MountType::Enum mountType;
+      /** The number of files currently on tape*/
+      uint32_t nbFiles;
     };
 
 } // namespace daemon
-- 
GitLab