From 72d17b77231de8c90d6c31b400b08c2c68477de4 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Thu, 4 Mar 2021 16:38:07 +0100 Subject: [PATCH 01/17] Add Storage client --- Online/Dataflow/CMakeLists.txt | 3 +- Online/Dataflow/Dataflow/Receiver.h | 4 +- Online/Dataflow/options/StorageWriter.opts | 9 +- Online/Dataflow/src/Storage/StorageWriter.cpp | 249 ++++++++++++------ Online/Dataflow/src/Storage/StorageWriter.h | 18 +- .../Dataflow/src/components/MBMSelector.cpp | 10 +- .../Dataflow/src/components/MEPSelector.cpp | 10 +- .../src/components/UpgradeMEPReader.cpp | 70 +++-- .../src/components/UpgradeMEPSelector.cpp | 10 +- .../src/framework/DataflowManager.cpp | 5 + Online/Dataflow/src/framework/DiskReader.cpp | 37 +-- Online/Dataflow/src/framework/Receiver.cpp | 44 +++- Online/GaudiOnline/GaudiOnline/EventAccess.h | 12 +- Online/GaudiOnline/GaudiOnline/EventTraits.h | 6 +- Online/GaudiOnline/components/InputAlg.cpp | 6 +- .../GaudiOnline/components/OnlineEventApp.cpp | 91 +++---- Online/GaudiOnline/components/OutputAlg.cpp | 12 +- Online/GaudiOnline/components/Passthrough.cpp | 20 +- Online/GaudiOnline/src/EventAccess.cpp | 19 +- Online/GaudiOnline/src/MBMEventAccess.cpp | 17 +- Online/GaudiOnline/src/MBMEventOutput.cpp | 18 +- Online/OnlineBase/src/MBM/mbm_extract.cpp | 33 ++- Online/PCIE40Data/PCIE40Data/RawBank40.h | 1 + Online/PCIE40Data/PCIE40Data/pcie40.h | 148 +++++++---- Online/PCIE40Data/main/pcie40_decode_file.cpp | 9 + Online/SmiController/options/TestMEPProd.opts | 1 + .../SmiController/scripts/EventProcessor.py | 6 +- Online/SmiController/scripts/TestMEPProd.sh | 3 + .../scripts/TestStorageWriter.sh | 3 +- Online/Storage/src/server/fdb_SQLite.cpp | 16 +- Online/Storage/src/server/fdb_SQLite.h | 4 +- Online/Storage/src/server/fdb_db_server.cpp | 4 +- Online/Tell1Data/Tell1Data/RawFile.h | 2 +- Online/Tell1Data/src/RawFile.cpp | 13 + 34 files changed, 617 insertions(+), 296 deletions(-) create mode 100644 Online/SmiController/scripts/TestMEPProd.sh diff --git a/Online/Dataflow/CMakeLists.txt b/Online/Dataflow/CMakeLists.txt index a7b9474fe..bf780fad6 100755 --- a/Online/Dataflow/CMakeLists.txt +++ b/Online/Dataflow/CMakeLists.txt @@ -23,6 +23,7 @@ gaudi_depends_on_subdirs(Online/dim Online/UPI Online/Storage Online/Tell1Data + Online/PCIE40Data Online/GauchoBase Online/OnlineKernel Online/PCIE40Data) @@ -185,7 +186,7 @@ gaudi_add_library(DataflowStorage src/Storage/*.cpp INCLUDE_DIRS NO_PUBLIC_HEADERS - LINK_LIBRARIES dim Boost OnlineBase Options DataflowLib Tell1Data StorageClient) + LINK_LIBRARIES dim Boost OnlineBase Options DataflowLib Tell1Data PCIE40Data StorageClient) target_include_directories(DataflowStorage BEFORE PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) gaudi_generate_componentslist(DataflowStorage) diff --git a/Online/Dataflow/Dataflow/Receiver.h b/Online/Dataflow/Dataflow/Receiver.h index 26c2dc115..ed80d6a50 100755 --- a/Online/Dataflow/Dataflow/Receiver.h +++ b/Online/Dataflow/Dataflow/Receiver.h @@ -19,12 +19,10 @@ // Framework include files #include "Dataflow/DataflowComponent.h" +#include "MBM/Producer.h" #include "RTL/rtl.h" #include <mutex> -// Forward declarations -namespace MBM { class Producer; } - /// Online namespace declaration namespace Online { diff --git a/Online/Dataflow/options/StorageWriter.opts b/Online/Dataflow/options/StorageWriter.opts index b82311311..b48a52f45 100644 --- a/Online/Dataflow/options/StorageWriter.opts +++ b/Online/Dataflow/options/StorageWriter.opts @@ -1,5 +1,7 @@ #pragma print off #include "$INFO_OPTIONS" +#include "$FARMCONFIGROOT/options/Logging.opts" +#include "$FARMCONFIGROOT/options/Monitoring.opts" // Manager.Services = {"Dataflow_MBMClient/MBM", "Dataflow_MBMSelector/EventProc", @@ -9,8 +11,9 @@ Manager.Algorithms = {"Dataflow_EmptyProcessor/Empty"}; Manager.Runable = "Wrap"; Wrap.Callable = "EventProc"; // -EventProc.REQ1 = "EvType=2;TriggerMask=0xffffffff,0xffffffff,0xffffffff,0xffffffff;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0"; -EventProc.REQ2 = "EvType=3;TriggerMask=0xffffffff,0xffffffff,0xffffffff,0xffffffff;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0"; +EventProc.REQ1 = "EvType=1;TriggerMask=0xffffffff,0xffffffff,0xffffffff,0xffffffff;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0"; +EventProc.REQ2 = "EvType=2;TriggerMask=0xffffffff,0xffffffff,0xffffffff,0xffffffff;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0"; +EventProc.REQ3 = "EvType=3;TriggerMask=0xffffffff,0xffffffff,0xffffffff,0xffffffff;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0"; EventProc.Input = "Events"; // // @@ -34,7 +37,7 @@ Writer.PollTimeout = 100000; // micro-seconds Writer.NumBuffers = 6; Writer.NumThreads = 4; Writer.CancelTimeout = 100; // seconds +Writer.ForceMDF = true; // -Logger.OutputLevel = @OnlineEnv.OutputLevel; Logger.OutputLevel = 0; // diff --git a/Online/Dataflow/src/Storage/StorageWriter.cpp b/Online/Dataflow/src/Storage/StorageWriter.cpp index 337186a2b..33b056d44 100644 --- a/Online/Dataflow/src/Storage/StorageWriter.cpp +++ b/Online/Dataflow/src/Storage/StorageWriter.cpp @@ -20,6 +20,8 @@ #include <Dataflow/Plugins.h> #include <Storage/fdb_client.h> #include <Tell1Data/Tell1Decoder.h> +#include <PCIE40Data/pcie40decoder.h> +#include <PCIE40Data/sodin.h> #include <RTL/rtl.h> /// C/C++ include files @@ -50,6 +52,7 @@ StorageWriter::StorageWriter(const string& nam, Context& ctxt) declareProperty("NumBuffers", m_num_buffers = 2); declareProperty("NumThreads", m_num_threads = 1); declareProperty("MinFileSizeMB", m_minFileSizeMB = 3000); + declareProperty("ForceMDF", m_force_mdf = 0); } /// Default destructor @@ -71,7 +74,7 @@ int StorageWriter::initialize() { m_free.clear(); for(size_t i=0; i<m_num_buffers; ++i) { Buffer b; - b.buffer = (unsigned char*)::malloc(m_bufferSize+1024); + b.buffer = (uint8_t*)::malloc(m_bufferSize+1024); b.pointer = b.buffer; m_free.push_back(b); } @@ -170,57 +173,160 @@ void StorageWriter::flush_buffer(Buffer& buff) { buff = m_shutdown ? Buffer() : get_buffer(); } +/// Manage buffer to ensure the next data block will fit +int StorageWriter::ensure_buffer(Buffer& buff, long length) { + if ( nullptr == buff.buffer ) { + info("Execute: Failed to allocate buffer. Drop MEP buffer. [%s]", + m_shutdown ? "Shutdown requested" : "??????????"); + return DF_CONTINUE; + } + if ( (buff.pointer - buff.buffer) > (maxBufferSize() - length) ) { + /// Do not exceed the max buffer size. Flush data and start with clean buffer + flush_buffer(buff); + m_curr_run = 0; + m_curr_orbit = 0; + m_curr_bunch = 0; + } + if ( nullptr == buff.buffer ) { + info("Execute: Failed to allocate buffer. Drop MEP buffer. [%s]", + m_shutdown ? "Shutdown requested" : "??????????"); + return DF_CONTINUE; + } + if ( (buff.pointer - buff.buffer) > (maxBufferSize() - length) ) { + error("Execute: Failed to allocate buffer [%ld bytes]. " + "BUFFER SIZE TOO SMALL! Change options!", length); + return DF_ERROR; + } + return DF_SUCCESS; +} + +/// Append data to current buffer. If too small allocate a new buffer +int StorageWriter::save_buffer(Buffer& buff, const void* data, long length) { + int sc = ensure_buffer(buff, length); + if ( sc == DF_SUCCESS ) { + ::memcpy(buff.pointer, data, length); + buff.pointer += length; + } + return sc; +} + +/// Convert PCIE40 MEP to MDF and save it. +int StorageWriter::save_pcie40_as_mdf(Buffer& buff, const uint8_t* start, long len) { + auto* mep_start = (pcie40::mep_header_t*)start; + auto* mep_end = pcie40::add_ptr<pcie40::mep_header_t>(start, len); + std::unique_ptr<pcie40::event_collection_t> ev; + pcie40::decoder_t decoder; + long nev = 0; + + for(const pcie40::mep_header_t *m, *mep = mep_start; mep < mep_end; ) { + if ( mep->is_valid() ) { + const pcie40::multi_fragment_t *mfp = mep->multi_fragment(0); + uint16_t packing = mfp->header.packing; + nev += packing; + decoder.decode(ev, mep); + /// Save the events one by one to the buffer + for( auto* e=ev->begin(); e != ev->end(); e=ev->next(e) ) { + size_t length = e->total_length(); + int sc = ensure_buffer(buff, length); + if ( sc == DF_SUCCESS ) { + if ( 0 == m_curr_run ) { + const auto* odin = e->bank_collection(0)->at(0); + if ( odin && odin->data() ) { + const auto* sodin = odin->begin<pcie40::sodin_t>(); + m_curr_run = sodin->run_number(); + m_curr_orbit = sodin->orbit_id(); + m_curr_bunch = sodin->bunch_id(); + } + } + for( size_t i=0, n=e->num_bank_collections(); i<n; ++i) { + buff.pointer = (uint8_t*)e->bank_collection(i)->copy_data(buff.pointer); + } + } + } + /// Move to the next MEP if any + if ( m=mep->next(); m > mep ) { + mep = m; + continue; + } + } + break; + } + return nev > 0 ? DF_SUCCESS : DF_ERROR; +} + +/// Save MDF frame or MDF burst +int StorageWriter::save_mdf_buffer(Buffer& buff, const uint8_t* start, long len) { + + /// Auto detect data type: now check for MDF data type + for( const uint8_t* end = start + len; start < end; ) { + auto* header = (EventHeader*)start; + auto* hdr = header->subHeader().H1; + long length = header->size0(); + long run = hdr->runNumber(); + if ( start+length > end ) { + break; + } + else if ( 0 == m_curr_run ) { + /// First event in this buffer: store the current run number + m_curr_run = run; + m_curr_orbit = hdr->orbitNumber(); + m_curr_bunch = hdr->bunchID(); + } + else if ( run != m_curr_run ) { + /// Run number change. Flush data and start with clean buffer + flush_buffer(buff); + m_curr_run = run; + m_curr_orbit = hdr->orbitNumber(); + m_curr_bunch = hdr->bunchID(); + } + else if ( (buff.pointer - buff.buffer) > (maxBufferSize() - length) ) { + /// Do not exceed the max buffer size. Flush data and start with clean buffer + flush_buffer(buff); + m_curr_run = run; + m_curr_orbit = hdr->orbitNumber(); + m_curr_bunch = hdr->bunchID(); + } + int sc = save_buffer(buff, header, length); + if ( DF_SUCCESS != sc ) { + return DF_SUCCESS; + } + start += length; + } + return DF_SUCCESS; +} + /// Data processing overload: Write the data record to disk int StorageWriter::execute(const Context::EventData& event) { - int sc = DF_SUCCESS; + int status = DF_SUCCESS; try { - size_t len = event.length; - auto* start = (unsigned char*)event.data; - auto& buff = get_buffer(); + size_t len = event.length; + auto* start = (uint8_t*)event.data; + auto& buff = get_buffer(); + /// Check buffer validity if ( nullptr == buff.buffer ) { info("Execute: Failed to allocate buffer. Drop event. [%s]", m_shutdown ? "Shutdown requested" : "??????????"); - return DF_SUCCESS; + return status; } - for( unsigned char* end = start + len; start < end; ) { - auto* header = (EventHeader*)start; - auto* hdr = header->subHeader().H1; - long length = header->size0(); - long run = hdr->runNumber(); - if ( start+length > end ) { - break; - } - else if ( 0 == m_curr_run ) { - /// First event in this buffer: store the current run number - m_curr_run = run; - m_curr_orbit = hdr->orbitNumber(); - m_curr_bunch = hdr->bunchID(); - } - else if ( run != m_curr_run ) { - /// Run number change. Flush data and start with clean buffer - flush_buffer(buff); - m_curr_run = run; - m_curr_orbit = hdr->orbitNumber(); - m_curr_bunch = hdr->bunchID(); - } - else if ( (buff.pointer - buff.buffer) > (maxBufferSize() -length) ) { - /// Do not exceed the max buffer size. Flush data and start with clean buffer - flush_buffer(buff); - m_curr_run = run; - m_curr_orbit = hdr->orbitNumber(); - m_curr_bunch = hdr->bunchID(); - } - if ( nullptr == buff.buffer ) { - info("Execute: Failed to allocate buffer. Drop event. [%s]", - m_shutdown ? "Shutdown requested" : "??????????"); - return DF_SUCCESS; - } - ::memcpy(buff.pointer, header, length); - buff.pointer += length; - start += length; + /// Auto detect data type: first check for PCIE40 MEP format + auto* mep_hdr = (pcie40::mep_header_t*)start; + if( mep_hdr->magic == mep_hdr->MagicPattern ) { + status = m_force_mdf + ? save_pcie40_as_mdf(buff, start, mep_hdr->size*sizeof(uint32_t)) + : save_buffer (buff, start, mep_hdr->size*sizeof(uint32_t)); + return status; + } + /// Auto detect data type: first check for MDF/BURST format + auto* mdf_hdr = (EventHeader*)start; + if ( mdf_hdr->size0() == mdf_hdr->size1() && + mdf_hdr->size0() == mdf_hdr->size2() ) { + status = save_mdf_buffer(buff, start, len); + return status; } - return DF_SUCCESS; + + error("Execute: Cannot determine event type. Drop event buffer."); + return status; } catch(const exception& e) { error(e,"Execute: Error processing event."); @@ -228,7 +334,7 @@ int StorageWriter::execute(const Context::EventData& event) { catch(...) { error("Execute: UNKOWN error processing event."); } - return sc; + return status; } /// Thread invocation routine to save assembled buffers to the disk server @@ -266,6 +372,17 @@ void StorageWriter::process_buffers() { } } +/// Print server's HttpReply structure +void StorageWriter::print_reply(const char* prefix, const http::HttpReply& reply) const { + string line; + stringstream str; + reply.print(str,""); + do { + getline(str, line); + error("writeBuffer-reply<%s>: %s", prefix, line.c_str()); + } while( str.good() && !str.eof() ); +} + /// Construct file name string StorageWriter::makeFileName() const { char fname[1024]; @@ -295,17 +412,12 @@ string StorageWriter::makeFileName() const { /// Write multi event buffer to file. Eventually open a new file.... int StorageWriter::writeBuffer(const Buffer& buff) { -#if 0 - buff.pointer = m_buffer; - m_curr_run = 0; - return DF_SUCCESS; -#else string fname = makeFileName(); - - /// Implement here a retry mechanism starting with registering the DB record int num_retries = m_write_error_retry; size_t len = buff.pointer-buff.buffer; bool process = (m_cancelled == 0) || (::time(0) - m_cancelled < m_cancel_tmo); + + /// Implement here a retry mechanism starting with registering the DB record while ( process ) { try { string url; @@ -314,17 +426,8 @@ int StorageWriter::writeBuffer(const Buffer& buff) { cl.fdbclient = storage::client::create<storage::client::sync>(srv.host, srv.port, 10000); cl.create_client = std::function(storage::client::create<storage::client::sync>); auto reply = cl.save_object_record(fname, url, len); - if ( reply.status != reply.temp_redirect ) { - string line; - stringstream str; - reply.print(str,""); - do { - getline(str, line); - error("writeBuffer: Server reply: %s", line.c_str()); - } while( str.good() && !str.eof() ); - } - else { - /// OK. this was now successful. Send the data. + if ( reply.status == reply.temp_redirect ) { + /// OK. the registration was now successful. Send the data. /// Implement here a retry mechanism sending the data. process = (m_cancelled == 0) || (::time(0) - m_cancelled < m_cancel_tmo); while ( process ) { @@ -339,13 +442,7 @@ int StorageWriter::writeBuffer(const Buffer& buff) { return DF_SUCCESS; } else { - string line; - stringstream str; - reply.print(str,""); - do { - getline(str, line); - error("writeBuffer: Server reply: %s", line.c_str()); - } while( str.good() && !str.eof() ); + print_reply("file-server", reply); } } catch(const std::exception& e) { @@ -354,12 +451,16 @@ int StorageWriter::writeBuffer(const Buffer& buff) { catch(...) { error("writeBuffer: Exception while sending data: UNKNOWN Exception"); } - if ( --num_retries < 0 ) break; ::lib_rtl_sleep(m_write_error_sleep); - process = (m_cancelled == 0) || (::time(0) - m_cancelled < m_cancel_tmo); + process = (m_cancelled == 0); + process |= (::time(0) - m_cancelled < m_cancel_tmo); + process &= (--num_retries < 0); } break; } + else { + print_reply("dbase-server", reply); + } } catch(const std::exception& e) { error("writeBuffer: Exception while connecting: %s",e.what()); @@ -367,11 +468,11 @@ int StorageWriter::writeBuffer(const Buffer& buff) { catch(...) { error("writeBuffer: Exception while connecting: UNKNOWN Exception"); } - if ( --num_retries < 0 ) break; ::lib_rtl_sleep(m_write_error_sleep); - process = (m_cancelled == 0) || (::time(0) - m_cancelled < m_cancel_tmo); + process = (m_cancelled == 0); + process |= (::time(0) - m_cancelled < m_cancel_tmo); + process &= (--num_retries < 0); } return DF_ERROR; -#endif } diff --git a/Online/Dataflow/src/Storage/StorageWriter.h b/Online/Dataflow/src/Storage/StorageWriter.h index b1e8b284f..bffe85a36 100644 --- a/Online/Dataflow/src/Storage/StorageWriter.h +++ b/Online/Dataflow/src/Storage/StorageWriter.h @@ -23,6 +23,7 @@ /// C/C++ include files +#include <cstdint> #include <memory> #include <thread> #include <mutex> @@ -48,9 +49,9 @@ namespace Online { typedef std::unique_ptr<std::thread> thread_t; struct Buffer { /// Pointer to the start of the event buffer - unsigned char* buffer = nullptr; + uint8_t* buffer = nullptr; /// Current pointer inside the event buffer - unsigned char* pointer = nullptr; + uint8_t* pointer = nullptr; /// Default constructor Buffer() = default; }; @@ -75,6 +76,8 @@ namespace Online { int m_poll_tmo {100}; /// Property: Cancel timeout to empty pending buffers int m_cancel_tmo {100}; + /// Property: Force output in MDF format + int m_force_mdf {0}; /// Buffer handling thread std::vector<thread_t> m_threads; @@ -106,10 +109,21 @@ namespace Online { std::string makeFileName() const; /// Get current buffer. If empty check for new one... Buffer& get_buffer(); + /// Manage buffer to ensure the next data block will fit + int ensure_buffer(Buffer& buff, long length); + /// Append data to current buffer. If too small allocate a new buffer + int save_buffer(Buffer& buffer, const void* data, long length); + /// Convert PCIE40 MEP to MDF and save it. + int save_pcie40_as_mdf(Buffer& buffer, const uint8_t* start, long length); + /// Save MDF frame or MDF burst + int save_mdf_buffer(Buffer& buffer, const uint8_t* start, long length); + /// Maximum available buffer size long maxBufferSize() const { return m_bufferSize; } /// Write multi event buffer to file. Eventually open a new file.... int writeBuffer(const Buffer& buffer); + /// Print server's HttpReply structure + void print_reply(const char* prefix, const http::HttpReply& reply) const; public: /// Initializing constructor diff --git a/Online/Dataflow/src/components/MBMSelector.cpp b/Online/Dataflow/src/components/MBMSelector.cpp index f71ec3352..eda6d2e1b 100755 --- a/Online/Dataflow/src/components/MBMSelector.cpp +++ b/Online/Dataflow/src/components/MBMSelector.cpp @@ -205,7 +205,15 @@ int MBMSelector::start() { /// Initialize the event processor int MBMSelector::stop() { - detail::deletePtr(m_consumer); + if ( m_consumer ) { + try { + for( int i=0; i<m_nreqs; ++i ) + m_consumer->delRequest(m_Reqs[i]); + } + catch(...) { } + delete m_consumer; + m_consumer = nullptr; + } m_nreqs = 0; return EventRunable::stop(); } diff --git a/Online/Dataflow/src/components/MEPSelector.cpp b/Online/Dataflow/src/components/MEPSelector.cpp index e2eb57667..89dd32b2a 100755 --- a/Online/Dataflow/src/components/MEPSelector.cpp +++ b/Online/Dataflow/src/components/MEPSelector.cpp @@ -533,7 +533,15 @@ int MEPSelector::start() { /// Initialize the event processor int MEPSelector::stop() { - detail::deletePtr(m_consumer); + if ( m_consumer ) { + try { + for(int i=0; i<m_nreqs; ++i) + m_consumer->delRequest(m_Reqs[i]); + } + catch(...) { } + delete m_consumer; + m_consumer = nullptr; + } if ( m_buffer ) { ::free(m_buffer); m_buffer = 0; diff --git a/Online/Dataflow/src/components/UpgradeMEPReader.cpp b/Online/Dataflow/src/components/UpgradeMEPReader.cpp index 6a3a068d2..e6f1aad77 100644 --- a/Online/Dataflow/src/components/UpgradeMEPReader.cpp +++ b/Online/Dataflow/src/components/UpgradeMEPReader.cpp @@ -38,12 +38,16 @@ namespace Online { */ class UpgradeMEPReader : public DiskReader { public: + /// Header prefix length in MBM file + size_t m_headerPrefixSize = 0; + /// Runable implementation : Run the class implementation virtual int i_run() override; public: /// Standard Constructor - using DiskReader::DiskReader; + UpgradeMEPReader(const std::string& nam, DataflowContext& ctxt); + /// Standard Destructor virtual ~UpgradeMEPReader() = default; }; @@ -80,6 +84,13 @@ DECLARE_DATAFLOW_NAMED_COMPONENT_NS(Online,Dataflow_UpgradeMEPReader,UpgradeMEPR using namespace std; +/// Standard Constructor +UpgradeMEPReader::UpgradeMEPReader(const std::string& nam, DataflowContext& ctxt) + : DiskReader(nam, ctxt) +{ + declareProperty("HeaderPrefixSize", m_headerPrefixSize = 0); +} + /// IRunable implementation : Run the class implementation int Online::UpgradeMEPReader::i_run() { DiskIO io(*this); @@ -90,12 +101,13 @@ int Online::UpgradeMEPReader::i_run() { int partid = context.mbm->partitionID(); bool files_processed = false; MBM::BufferInfo* mbmInfo = m_mbmInfo[m_buffer]; - + size_t file_length = 0; + m_eventsIN = 0; m_goto_paused = true; - m_deleteFiles = false; - m_saveRest = false; - m_mmapFiles = true; + //m_deleteFiles = false; + //m_saveRest = false; + //m_mmapFiles = true; m_receiveEvts = true; status = waitForGo(); @@ -167,40 +179,53 @@ int Online::UpgradeMEPReader::i_run() { const char* ptr = current.name().c_str()+idx; ::sscanf(ptr, "%07d", &runno); updateRunNumber(runno); + file_length = current.data_size(); } } if ( current.isOpen() ) { MBM::EventDesc& dsc = m_producer->event(); MBMAllocator allocator(this); off_t file_position = current.position(); - uint16_t packing = 0; - int data_len = 0, event_type; pcie40::mep_header_t mep_hdr, *pmep_hdr; + int data_len = 0, event_type; + uint16_t packing = 0; + long frame_len = 0; // Check if data are still availible - if ( current.pointer()+sizeof(pcie40::mep_header_t) > current.end() ) { - current.reset(false); + if ( m_mmapFiles && current.pointer()+sizeof(pcie40::mep_header_t) > current.end() ) { + current.reset(!m_mmapFiles); continue; } - - current.read(&mep_hdr, sizeof(mep_hdr)); - data_len = mep_hdr.size; + if ( m_headerPrefixSize > 0 ) { + current.read(&frame_len, sizeof(long)); + } + if ( sizeof(mep_hdr) != current.read(&mep_hdr, sizeof(mep_hdr)) ) { + current.reset(!m_mmapFiles); + continue; + } + data_len = mep_hdr.size*sizeof(uint32_t); event_type = EVENT_TYPE_MEP; if ( data_len <= 0 ) { - current.reset(false); + current.reset(!m_mmapFiles); mep_number = 0; continue; } - else if ( current.pointer()-sizeof(mep_hdr)+data_len > current.end() ) { - current.reset(false); + else if ( data_len < 128 ) { + current.reset(!m_mmapFiles); mep_number = 0; continue; } - else if ( data_len < 128 ) { - current.reset(false); + else if ( m_mmapFiles && current.pointer()-sizeof(mep_hdr)+data_len > current.end() ) { + current.reset(!m_mmapFiles); mep_number = 0; continue; } - unsigned char* data = allocator(data_len); + else if ( file_length - file_position < data_len - sizeof(mep_hdr) ) { + current.reset(!m_mmapFiles); + mep_number = 0; + continue; + } + unsigned char* data = allocator(data_len); + long rd_len = data_len-sizeof(mep_hdr); if ( data == 0 || dsc.len == 0 ) { // MBM Error // Set back the file position to the beginning of the event and continue. // If there was a cancel in between, the file shall be saved. @@ -208,8 +233,13 @@ int Online::UpgradeMEPReader::i_run() { continue; } dsc.len = data_len; - ::memcpy(data,&mep_hdr,sizeof(mep_hdr)); - current.read(data+sizeof(mep_hdr), data_len-sizeof(mep_hdr)); + ::memcpy(data, &mep_hdr, sizeof(mep_hdr)); + if ( rd_len != current.read(data+sizeof(mep_hdr), rd_len) ) { + current.reset(!m_mmapFiles); + continue; + } + //current.position(file_position + frame_len); + pmep_hdr = (pcie40::mep_header_t*)data; packing = pmep_hdr->multi_fragment(0)->header.packing; ++mep_number; diff --git a/Online/Dataflow/src/components/UpgradeMEPSelector.cpp b/Online/Dataflow/src/components/UpgradeMEPSelector.cpp index 196a8b71c..4e19ec474 100644 --- a/Online/Dataflow/src/components/UpgradeMEPSelector.cpp +++ b/Online/Dataflow/src/components/UpgradeMEPSelector.cpp @@ -228,7 +228,15 @@ int UpgradeMEPSelector::start() { /// Initialize the event processor int UpgradeMEPSelector::stop() { - detail::deletePtr(m_consumer); + if ( m_consumer ) { + try { + for( int i=0; i<m_nreqs; ++i ) + m_consumer->delRequest(m_Reqs[i]); + } + catch(...) { } + delete m_consumer; + m_consumer = nullptr; + } if ( m_buffer ) { ::free(m_buffer); m_buffer = 0; diff --git a/Online/Dataflow/src/framework/DataflowManager.cpp b/Online/Dataflow/src/framework/DataflowManager.cpp index 57e7b9748..16b24efdd 100755 --- a/Online/Dataflow/src/framework/DataflowManager.cpp +++ b/Online/Dataflow/src/framework/DataflowManager.cpp @@ -23,6 +23,7 @@ #include "Dataflow/Incidents.h" #include "Dataflow/Plugins.h" #include "Tell1Data/Tell1Decoder.h" +#include "MBM/bmdef.h" // C/C++ include files #include <functional> @@ -442,6 +443,10 @@ int DataflowManager::execute(const DataflowContext::EventData& event) { setRunNumber(mdf->subHeader().H1->runNumber()); m_numBadEvent = 0; } + else if ( event.type == EVENT_TYPE_MEP ) { + setRunNumber(0); + m_numBadEvent = 0; + } else { // We got a MEP event. Should never happen! if ( ++m_numBadEvent <= m_maxBadEvent ) { diff --git a/Online/Dataflow/src/framework/DiskReader.cpp b/Online/Dataflow/src/framework/DiskReader.cpp index 0e28b017e..cd12af3ad 100644 --- a/Online/Dataflow/src/framework/DiskReader.cpp +++ b/Online/Dataflow/src/framework/DiskReader.cpp @@ -61,6 +61,7 @@ unsigned char* DiskReader::MBMAllocator::operator()(size_t length) { catch (const exception& e) { reader->error("Exception while reading input files (spaceRearm): %s BuffSize:%ld. ", e.what(), length); + ::lib_rtl_sleep(1000); } if ( status != MBM_NORMAL ) { return 0; @@ -94,29 +95,29 @@ DiskReader::DiskReader(const string& nam, DataflowContext& ctxt) m_producer(0), m_eventsIN(0), m_evtCountFile(0), m_runSvcID(0), m_currentRun(0), m_goSvcID(0), m_goValue(0), m_disabled(false), m_goto_paused(false), m_mbmInfos(0) { - declareProperty("InputType", m_inputType = AUTO_INPUT_TYPE ); - declareProperty("Buffer", m_buffer = "Mep"); + declareProperty("InputType", m_inputType = AUTO_INPUT_TYPE ); + declareProperty("Buffer", m_buffer = "Mep"); declareProperty("Directories", m_dirList ); - declareProperty("FilePrefix", m_filePrefix = "Run_"); - declareProperty("BrokenHosts", m_brokenHostsFile = ""); - declareProperty("DeleteFiles", m_deleteFiles = true); - declareProperty("SaveRest", m_saveRest = true); - declareProperty("ConsumerWait", m_maxConsWait = 20); - declareProperty("MaxPauseWait", m_maxPauseWait = 1000); + declareProperty("FilePrefix", m_filePrefix = "Run_"); + declareProperty("BrokenHosts", m_brokenHostsFile = ""); + declareProperty("DeleteFiles", m_deleteFiles = true); + declareProperty("SaveRest", m_saveRest = true); + declareProperty("ConsumerWait", m_maxConsWait = 20); + declareProperty("MaxPauseWait", m_maxPauseWait = 1000); declareProperty("AllowedRuns", m_allowedRuns); - declareProperty("InitialSleep", m_initialSleep = 10); - declareProperty("PauseSleep", m_pauseSleep = 5); - declareProperty("Rescan", m_rescan = 1); - declareProperty("GoService", m_goService = ""); - declareProperty("PackingFactor", m_packingFactor = 1); - declareProperty("AllocationSizekB", m_preAllocSize = 2048); + declareProperty("InitialSleep", m_initialSleep = 10); + declareProperty("PauseSleep", m_pauseSleep = 5); + declareProperty("Rescan", m_rescan = 1); + declareProperty("GoService", m_goService = ""); + declareProperty("PackingFactor", m_packingFactor = 1); + declareProperty("AllocationSizekB", m_preAllocSize = 2048); declareProperty("EventsPerFile", m_max_events_per_file = -1); declareProperty("CheckedBuffers", m_mbmNames); - declareProperty("OnOpenFailedDelete", m_openFailDelete = 0); + declareProperty("OnOpenFailedDelete", m_openFailDelete = 0); declareProperty("RequireConsumers", m_requireConsumers = true); - declareProperty("MuDelay", m_muDelay = 0); - declareProperty("MMapFiles", m_mmapFiles = 0); - declareProperty("ReuseFile", m_reuse_file = false); + declareProperty("MuDelay", m_muDelay = 0); + declareProperty("MMapFiles", m_mmapFiles = 0); + declareProperty("ReuseFile", m_reuse_file = false); m_allowedRuns.push_back("*"); ::lib_rtl_create_lock(0, &m_lock); } diff --git a/Online/Dataflow/src/framework/Receiver.cpp b/Online/Dataflow/src/framework/Receiver.cpp index a507faf93..42d0d644f 100755 --- a/Online/Dataflow/src/framework/Receiver.cpp +++ b/Online/Dataflow/src/framework/Receiver.cpp @@ -21,7 +21,6 @@ #include "Dataflow/Incidents.h" #include "Tell1Data/Tell1Decoder.h" #include "DD4hep/Primitives.h" -#include "MBM/Producer.h" #include "RTL/Lock.h" #include "WT/wtdef.h" #include "RTL/rtl.h" @@ -47,11 +46,11 @@ Receiver::Receiver(const string& nam, Context& ctxt) : Component(nam, ctxt) { ::wtc_init(); declareProperty("Buffer", m_buffer); - declareProperty("UseEventRequests", m_useRequests=false); - declareProperty("DeclareAsynchonously",m_declareAsynch=false); - declareProperty("RoutingMask", m_routingMask=0); - declareProperty("VetoMask", m_vetoMask=0); - declareProperty("ErrorDelay", m_errorDelay=100); + declareProperty("UseEventRequests", m_useRequests = false); + declareProperty("DeclareAsynchonously",m_declareAsynch = false); + declareProperty("RoutingMask", m_routingMask = 0); + declareProperty("VetoMask", m_vetoMask = 0); + declareProperty("ErrorDelay", m_errorDelay = 100); } /// Initialize the MBM server @@ -95,13 +94,13 @@ int Receiver::start() { /// Stop the data flow component. Default implementation is empty. int Receiver::stop() { m_recvEvents = false; - if ( m_prod ) m_prod->clear(); return Component::stop(); } /// Finalize the MBM server int Receiver::finalize() { m_recvEvents = false; + if ( m_prod ) m_prod->clear(); unsubscribeIncidents(); ::wtc_flush(WT_FACILITY_DAQ_EVENT); ::wtc_remove(WT_FACILITY_DAQ_EVENT); @@ -261,15 +260,32 @@ int Receiver::declareData(RecvEntry& entry) { int ret = m_recvEvents ? m_prod->getSpace(entry.size) : MBM_REQ_CANCEL; if ( MBM_NORMAL == ret ) { MBM::EventDesc& e = m_prod->event(); - EventHeader* h = (EventHeader*)e.data; - auto m = h->subHeader().H1->triggerMask(); - e.type = EVENT_TYPE_EVENT; - e.len = entry.size; + e.len = entry.size; + e.type = EVENT_TYPE_EVENT; ret = copyEventData(e.data, entry.buffer, entry.size); if ( DF_SUCCESS == ret ) { - e.mask[0] = m[0]; - e.mask[1] = m[1]; - e.mask[2] = m[2]; + EventHeader* h = (EventHeader*)e.data; + e.mask[3] = ~0x0; + if ( h->size0() == h->size1() && entry.size > h->size0() ) { + auto m = h->subHeader().H1->triggerMask(); + e.mask[0] = m[0]; + e.mask[1] = m[1]; + e.mask[2] = m[2]; + e.type = EVENT_TYPE_BURST; + } + else if ( h->size0() == h->size1() && entry.size == h->size0() ) { + auto m = h->subHeader().H1->triggerMask(); + e.mask[0] = m[0]; + e.mask[1] = m[1]; + e.mask[2] = m[2]; + e.type = EVENT_TYPE_EVENT; + } + else if ( *(unsigned short*)e.data == 0xcefa ) { + e.mask[0] = ~0x0; + e.mask[1] = ~0x0; + e.mask[2] = ~0x0; + e.type = EVENT_TYPE_MEP; + } if ( 0 != m_routingMask ) { e.mask[3] &= ~m_vetoMask; e.mask[3] |= m_routingMask; diff --git a/Online/GaudiOnline/GaudiOnline/EventAccess.h b/Online/GaudiOnline/GaudiOnline/EventAccess.h index a69a6fc07..999d8d278 100644 --- a/Online/GaudiOnline/GaudiOnline/EventAccess.h +++ b/Online/GaudiOnline/GaudiOnline/EventAccess.h @@ -79,9 +79,9 @@ namespace Online { /// Default destructor virtual ~guard_t() = default; /// Careful: unprotected information access - bool empty() const { return consumed == length; } - std::size_t size() const { return length; } - long type() const { return typ; } + bool empty() const { return consumed == length; } + std::size_t size() const { return length; } + long type() const { return typ; } virtual record_t at(size_t which) const = 0; }; @@ -199,9 +199,15 @@ namespace Online { /// Dequeue burst if one is present with lock protection shared_guard_t dequeueBurst(); + /// Access thread safe number of queued bursts + size_t numQueuedBurst(); + /// Dequeue burst if present, otherwise wait for producer to emplace one. shared_guard_t waitBurst(); + /// Clear burst queue and update counters + size_t clear(); + /// Dequeue event if one is present with lock protection event_t dequeueEvent(shared_guard_t& context); diff --git a/Online/GaudiOnline/GaudiOnline/EventTraits.h b/Online/GaudiOnline/GaudiOnline/EventTraits.h index b21adbe15..86f5fe93d 100644 --- a/Online/GaudiOnline/GaudiOnline/EventTraits.h +++ b/Online/GaudiOnline/GaudiOnline/EventTraits.h @@ -42,7 +42,8 @@ namespace Online { enum BurstType { NO_DATA_TYPE = 0, TELL1_DATA_TYPE = 1, - TELL40_DATA_TYPE = 2 + TELL40_DATA_TYPE = 2, + TELL1_BURST_TYPE = 3 }; typedef unsigned char data_t; @@ -77,7 +78,8 @@ namespace Online { typedef EventHeader event_type; typedef record_t record_type; typedef RunInfo odin_type; - static constexpr int data_type = TELL1_DATA_TYPE; + static constexpr int data_type = TELL1_DATA_TYPE; + static constexpr int burst_type = TELL1_BURST_TYPE; static event_type& get_event(record_t r) { return *(r.tell1_event); } diff --git a/Online/GaudiOnline/components/InputAlg.cpp b/Online/GaudiOnline/components/InputAlg.cpp index 3c7d5e3a4..04ca7fdeb 100644 --- a/Online/GaudiOnline/components/InputAlg.cpp +++ b/Online/GaudiOnline/components/InputAlg.cpp @@ -25,7 +25,7 @@ DECLARE_COMPONENT( Online::InputAlg ) void Online::InputAlg::halt() const { if ( m_enableHalt ) { m_halt = 1; - m_logger->warning("Algorithm halted by input data handling problem."); + m_logger->warning("+++ Algorithm halted by input data handling problem."); while ( m_halt ) ::lib_rtl_sleep(100); } } @@ -74,9 +74,9 @@ StatusCode Online::InputAlg::process(EventContext const& /* ctxt */) const { return StatusCode::SUCCESS; } else if ( m_io->isCancelled() ) { - m_logger->error("Algorithm failed [Invalid event after CANCEL]."); + m_logger->error("+++ Algorithm failed [Invalid event after CANCEL]."); return StatusCode::FAILURE; } - m_logger->error("Algorithm failed [Invalid data]."); + m_logger->error("+++ Algorithm failed [Invalid data]."); return StatusCode::FAILURE; } diff --git a/Online/GaudiOnline/components/OnlineEventApp.cpp b/Online/GaudiOnline/components/OnlineEventApp.cpp index f6a99dcd5..67f495c91 100644 --- a/Online/GaudiOnline/components/OnlineEventApp.cpp +++ b/Online/GaudiOnline/components/OnlineEventApp.cpp @@ -21,13 +21,10 @@ #include <Gaudi/PluginService.h> #include <Gaudi/Interfaces/IQueueingEventProcessor.h> -#include <GaudiKernel/IMessageSvc.h> -#include <GaudiKernel/IAppMgrUI.h> #include <GaudiKernel/IProperty.h> #include <GaudiKernel/ISvcLocator.h> #include <GaudiKernel/AppReturnCode.h> #include <Gaudi/Property.h> -#include <GaudiKernel/SmartIF.h> #include <CPP/Event.h> #include <RTL/strdef.h> #include <RTL/rtl.h> @@ -35,9 +32,6 @@ // tbb #include "tbb/task_arena.h" -#if defined(USE_OLD_TBB_INTERFACE) -#include "tbb/task_scheduler_init.h" -#endif /// C/C++ include files #include <iostream> @@ -47,6 +41,15 @@ using namespace std; using namespace Online; +namespace { + template <typename T> void stop_thread(T& t) { + if ( t ) { + t->join(); + t.reset(); + } + } +} + /// Easier command line: only supply --application=OnlineEvents class OnlineEvents : public Online::OnlineEventApp { public: @@ -314,28 +317,20 @@ OnlineEventApp::access_t OnlineEventApp::start_file_access() { /// Pause the application (RUNNING -> READY) int OnlineEventApp::pauseProcessing() { - m_logger->debug("Pause the application."); + m_logger->debug("+++ Pause the application."); m_halt = EVENTLOOP_PAUSE; return OnlineApplication::pauseProcessing(); } /// Continue the application (PAUSED -> RUNNING ) int OnlineEventApp::continueProcessing() { - m_logger->debug("Resume application processing."); + m_logger->debug("+++ Resume application processing."); m_halt = EVENTLOOP_EXECUTE; return OnlineApplication::continueProcessing(); } -template <typename T> static void stop_thread(T& t) { - if ( t ) { - t->join(); - t.reset(); - } -} - /// Stop the application (RUNNING -> READY) int OnlineEventApp::stop() { - m_events->queueCancel(true); if ( m_events ) { m_events->cancel(); } @@ -363,12 +358,7 @@ int OnlineEventApp::stop() { void OnlineEventApp::async_queued_event_loop() { size_t num_threads = m_parallel_threads; -#if defined(USE_OLD_TBB_INTERFACE) - tbb::task_scheduler_init tbb_scheduler( num_threads + 1); -#else - //tbb::task_scheduler_init tbb_scheduler_default; std::unique_ptr<tbb::task_arena> tbb_arena = std::make_unique<tbb::task_arena>(num_threads + 1, 1); -#endif bool tbb_inited = true; EventAccess::shared_guard_t loop_context; SmartIF<IQueued> ev_que{app}; @@ -383,22 +373,16 @@ void OnlineEventApp::async_queued_event_loop() { loop_context = m_events->waitBurst(); if ( loop_context ) { m_monitor.burstsOut = m_events->monitor.burstsOut; - size_t num_event = m_ioSvc->push(move(loop_context)); - while ( num_event > 0 ) { + for(size_t nevt=m_ioSvc->push(move(loop_context)); nevt > 0; --nevt) { EventContext ctx(ev_que->createEventContext()); ev_que->push(move(ctx)); - m_monitor.eventsBuffered = m_events->eventsBuffered()+num_event; + m_monitor.eventsBuffered = m_events->eventsBuffered()+nevt; ++m_monitor.eventsSubmitted; - --num_event; } } - else if ( m_events->isCancelled() ) { - m_logger->info("+++ async_loop: Event requests were cancelled."); - break; - } - if ( num_threads == m_parallel_threads && !m_events->isCancelled() ) + else if ( num_threads == m_parallel_threads && !m_events->isCancelled() ) { continue; - //m_logger->info("+++ async_loop: sleep 10"); + } this_thread::sleep_for(chrono::milliseconds(10)); } catch(const exception& e) { @@ -409,7 +393,6 @@ void OnlineEventApp::async_queued_event_loop() { } } else { - //m_logger->info("+++ async_loop: sleep 1000"); this_thread::sleep_for(chrono::milliseconds(1000)); } /// Check if the scenario changed and we have to adapt the number of threads executing @@ -419,42 +402,44 @@ void OnlineEventApp::async_queued_event_loop() { this_thread::sleep_for(chrono::milliseconds(10)); /// Now stop the scheduler if ( tbb_inited ) { -#if defined(USE_OLD_TBB_INTERFACE) - tbb_scheduler.terminate(); // non blocking -#else tbb_arena->terminate(); // non blocking tbb_arena.reset(); -#endif tbb_inited = false; } num_threads = m_parallel_threads; if ( num_threads > 0 ) { m_logger->info("+++ async_loop: Restart event processing with %ld threads.",num_threads); /// Finally restart the scheduler -#if defined(USE_OLD_TBB_INTERFACE) - tbb_scheduler.initialize(num_threads+1); -#else tbb_arena.reset(new tbb::task_arena(num_threads + 1, 1)); -#endif tbb_inited = true; } } - } while ( (m_halt != EVENTLOOP_STOP) || !(ev_que->empty() && m_events->empty()) ); + if ( m_events->eventsBuffered() > 0 ) { + continue; + } + this_thread::sleep_for(chrono::milliseconds(1000)); + // Check if we got some late frame(s) + if ( m_events->eventsBuffered() > 0 ) { + continue; + } + if ( m_events->isCancelled() ) { + m_logger->info("+++ async_loop: Event requests were cancelled."); + break; + } + } while ( !(m_halt == EVENTLOOP_STOP) || + !m_events->empty() || + !ev_que->empty() ); while ( !ev_que->empty() ) // this is our "threads.join()" alternative this_thread::sleep_for( chrono::milliseconds( 100 ) ); -#if defined(USE_OLD_TBB_INTERFACE) - tbb_scheduler.terminate(); // non blocking -#else tbb_arena->terminate(); // non blocking# tbb_arena.reset(); -#endif if ( m_events->isCancelled() ) { loop_context.reset(); - m_logger->info("async_loop: Event loop exiting [CANCELLED]."); + m_logger->info("+++ async_loop: Event loop exiting [CANCELLED]."); } else { - m_logger->info("async_loop: Event loop exiting."); + m_logger->info("+++ async_loop: Event loop exiting."); } autoStop(); } @@ -473,30 +458,28 @@ void OnlineEventApp::sync_queued_event_loop() { loop_context = m_events->waitBurst(); if ( loop_context ) { m_monitor.burstsOut = m_events->monitor.burstsOut; - size_t num_event = m_ioSvc->push(move(loop_context)); - while ( num_event > 0 ) { + for(size_t nevt=m_ioSvc->push(move(loop_context)); nevt > 0; --nevt) { EventContext ctx(ev_que->createEventContext()); ev_que->executeEvent(move(ctx)).ignore(/* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */); - m_monitor.eventsBuffered = m_events->eventsBuffered()+num_event; + m_monitor.eventsBuffered = m_events->eventsBuffered()+nevt; ++m_monitor.eventsSubmitted; - --num_event; } continue; } this_thread::sleep_for(chrono::milliseconds(10)); } catch(const exception& e) { - m_logger->error(e, "Event loop failure with exception."); + m_logger->error(e, "+++ Event loop failure with exception."); } catch(...) { m_logger->error("+++ Event loop failure with UNKNOWN exception"); } this_thread::sleep_for(chrono::milliseconds(100)); } while ( (m_halt != EVENTLOOP_STOP) ); - + // if ( m_events->isCancelled() ) { loop_context.reset(); - m_logger->info("Event loop exiting [CANCELLED]."); + m_logger->info("+++ Event loop exiting [CANCELLED]."); } } diff --git a/Online/GaudiOnline/components/OutputAlg.cpp b/Online/GaudiOnline/components/OutputAlg.cpp index 68fa187ee..120e10fc7 100644 --- a/Online/GaudiOnline/components/OutputAlg.cpp +++ b/Online/GaudiOnline/components/OutputAlg.cpp @@ -119,11 +119,11 @@ OutputAlg::OutputAlg(const string& nam, ISvcLocator* loc) void OutputAlg::handle(const Incident& incident) { if ( incident.type() == "DAQ_END_EVENT" ) { if ( m_output.get() ) { - m_logger->info("Flush all pending data."); + m_logger->info("+++ Flush all pending data."); m_output->commit_all(); return; } - m_logger->error("Failed to commit all transactions."); + m_logger->error("+++ Failed to commit all transactions."); } else if ( incident.type() == "DAQ_STOPPED" ) { stop().ignore(/* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */); @@ -140,13 +140,13 @@ StatusCode OutputAlg::initialize() { EventProcessor::initialize().ignore(/* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */); m_incident = service<IIncidentSvc>("IncidentSvc"); if ( !m_incident ) { - m_logger->error("Failed to access Incident service."); + m_logger->error("+++ Failed to access Incident service."); return StatusCode::FAILURE; } m_incident->addListener(this,"DAQ_END_EVENT"); m_incident->addListener(this,"DAQ_STOPPED"); m_incident->addListener(this,"DAQ_CANCEL"); - m_logger->info("Successfully initialized output algorithm."); + m_logger->info("+++ Successfully initialized output algorithm."); return StatusCode::SUCCESS; } @@ -196,9 +196,11 @@ StatusCode OutputAlg::process(EventContext const& /* ctxt */) const { const LHCb::RawEvent* evt = m_rawEvent.get(); if ( event->second->type() == event_traits::tell1::data_type ) output_mdf<event_traits::tell1>(*evt, m_routingMask.value(), *m_output); + else if ( event->second->type() == event_traits::tell1::burst_type ) + output_mdf<event_traits::tell1>(*evt, m_routingMask.value(), *m_output); else if ( event->second->type() == event_traits::tell40::data_type ) output_mdf<event_traits::tell40>(*evt, m_routingMask.value(), *m_output); else - m_logger->except("Invalid burst data type encountered: %ld",event->second->type()); + m_logger->except("+++ Invalid burst data type encountered: %ld",event->second->type()); return StatusCode::SUCCESS; } diff --git a/Online/GaudiOnline/components/Passthrough.cpp b/Online/GaudiOnline/components/Passthrough.cpp index 8c468e623..32387b86e 100644 --- a/Online/GaudiOnline/components/Passthrough.cpp +++ b/Online/GaudiOnline/components/Passthrough.cpp @@ -135,6 +135,7 @@ StatusCode Passthrough::start() { } StatusCode Passthrough::execute(EventContext const& ctxt) const { + double delay = m_delay*1000+m_muDelay; auto raw = m_rawEvent.get(); if ( !raw ) { MsgStream log(msgSvc(), name()); @@ -143,7 +144,17 @@ StatusCode Passthrough::execute(EventContext const& ctxt) const { return StatusCode::FAILURE; } - double delay = m_delay*1000+m_muDelay; + /// If mothing is specified everything will be downscaled + if ( m_downScale.empty() && m_rate < 1.0 ) { + double frac = double(::rand()) / double(RAND_MAX); + if ( m_rate < frac ) { + execState(ctxt).setFilterPassed(false); + return _halt(delay); + } + execState(ctxt).setFilterPassed(true); + return _halt(delay); + } + const auto odinBanks = raw->banks(LHCb::RawBank::ODIN); if ( odinBanks.empty() ) { execState(ctxt).setFilterPassed(false); @@ -162,13 +173,6 @@ StatusCode Passthrough::execute(EventContext const& ctxt) const { } } } - else if ( m_rate < 1.0 ) { /// If mothing is specified everything will be downscaled - double frac = double(::rand()) / double(RAND_MAX); - if ( m_rate < frac ) { - execState(ctxt).setFilterPassed(false); - return _halt(delay); - } - } // Check trigger type selection (may be ANDed with calibration type selection if( !m_triggerTypesToPass.empty() ) { diff --git a/Online/GaudiOnline/src/EventAccess.cpp b/Online/GaudiOnline/src/EventAccess.cpp index 8cc329182..7ed12c4ef 100644 --- a/Online/GaudiOnline/src/EventAccess.cpp +++ b/Online/GaudiOnline/src/EventAccess.cpp @@ -124,6 +124,23 @@ EventAccess::shared_guard_t EventAccess::dequeueBurst() {{ return shared_guard_t(); } +/// Access thread safe number of queued bursts +size_t EventAccess::numQueuedBurst() { + lock_t lock(m_burstLock); + return m_bursts.size(); +} + +/// Clear burst queue and update counters +size_t EventAccess::clear() { + size_t count = 0; + for(shared_guard_t burst=dequeueBurst(); burst.get(); burst=dequeueBurst()) { + lock_t lock(m_eventLock); + monitor.eventsBuffered -= burst->length; + count += burst->length; + } + return count; +} + /// Dequeue event if present, otherwise wait for producer to emplace one. EventAccess::shared_guard_t EventAccess::waitBurst() { shared_guard_t burst(dequeueBurst()); @@ -234,7 +251,7 @@ EventAccess::convertPCIE40MEP(datapointer_t start, size_t len) const { pcie40::decoder_t decoder; static constexpr size_t max_bank = 20000; static constexpr size_t max_source = 2000; - static constexpr size_t max_packing = 5000; + static constexpr size_t max_packing = 35000; const auto* pmep_hdr = reinterpret_cast<const pcie40::mep_header_t*>(start); if ( 0 == pmep_hdr->size ) { m_logger->error("MEP with invalid size encountered: %d", pmep_hdr->size); diff --git a/Online/GaudiOnline/src/MBMEventAccess.cpp b/Online/GaudiOnline/src/MBMEventAccess.cpp index e021262b6..84ea60b74 100644 --- a/Online/GaudiOnline/src/MBMEventAccess.cpp +++ b/Online/GaudiOnline/src/MBMEventAccess.cpp @@ -22,7 +22,6 @@ using namespace std; using namespace Online; - namespace { template<typename INT> std::string to_hex(INT i) { @@ -90,9 +89,8 @@ string MBMEventAccess::bufferName(const string& nam) const { /// Cancel all pending I/O requests to the buffer manager int MBMEventAccess::cancel() { - int count = 0; + int count = int(m_busyPlugs.size()); m_inhibit = true; - count = int(m_busyPlugs.size()); while( m_busyPlugs.size() > 0 ) { { lock_t lock(m_consumerLock); @@ -103,7 +101,18 @@ int MBMEventAccess::cancel() { lock_t lock(m_consumerLock); if ( m_busyPlugs.empty() ) break; } - ::lib_rtl_sleep(10); + // We try to wait a bit and give the event processing thread some time + // to work down the event queue of possibly pending entries. + // We assume here a maximum time window of 20*100 msec + for( size_t i=0; i<20; ++i ) { + ::lib_rtl_sleep(100); + size_t buffered = eventsBuffered(); + m_logger->info("+++ MBMEventAccess: Current event stack size: %ld events", buffered); + if ( i > 3 && 0 == buffered ) break; + } + if( size_t dropped=clear(); dropped > 0 ) { + m_logger->warning("+++ MBMEventAccess: Dropped %ld events on cancel.", dropped); + } { lock_t lock(m_consumerLock); if ( m_busyPlugs.empty() ) break; diff --git a/Online/GaudiOnline/src/MBMEventOutput.cpp b/Online/GaudiOnline/src/MBMEventOutput.cpp index 0ef67da9c..e50dd2575 100644 --- a/Online/GaudiOnline/src/MBMEventOutput.cpp +++ b/Online/GaudiOnline/src/MBMEventOutput.cpp @@ -122,7 +122,7 @@ bool MBMEventOutput::mbm_transaction_t::sync() { length = 0; events = 0; if ( sc == MBM_REQ_CANCEL ) { - output->m_logger->error("Failed to declare event for MBM buffer %s. " + output->m_logger->error("+++ Failed to declare event for MBM buffer %s. " "Request was cancelled.", mbm_buffer_name(bmid)); return false; @@ -130,7 +130,7 @@ bool MBMEventOutput::mbm_transaction_t::sync() { else if ( sc == MBM_NORMAL ) { sc = ::mbm_send_space(bmid); if ( sc == MBM_REQ_CANCEL ) { - output->m_logger->error("Failed to declare event for MBM buffer %s. " + output->m_logger->error("+++ Failed to declare event for MBM buffer %s. " "Request was cancelled.", mbm_buffer_name(bmid)); return false; @@ -144,7 +144,7 @@ bool MBMEventOutput::mbm_transaction_t::sync() { /// Shutdown the I/O medium bool MBMEventOutput::mbm_transaction_t::close() { if ( bmid != MBM_INV_DESC ) { - output->m_logger->info("Exclude from buffer: %s", mbm_buffer_name(bmid)); + output->m_logger->info("+++ Exclude from buffer: %s", mbm_buffer_name(bmid)); ::mbm_exclude(bmid); bmid = MBM_INV_DESC; return true; @@ -206,7 +206,7 @@ int MBMEventOutput::connect(const string& output, size_t instance) { stringstream nam; string bm_name = bufferName(output); nam << RTL::processName() << '.' << instance; - m_logger->info("MBM: Connecting to MBM Buffer %s.", bm_name.c_str()); + m_logger->info("+++ MBM: Connecting to MBM Buffer %s.", bm_name.c_str()); { lock_t lock(m_transactionLock); BMID bmid = MBM_INV_DESC; @@ -218,7 +218,7 @@ int MBMEventOutput::connect(const string& output, size_t instance) { bmid = ::mbm_connect(tr->bmid, nam.str().c_str(), config.partitionID); } if ( bmid == MBM_INV_DESC ) { - return m_logger->error("MBM: Failed to connect to MBM buffer %s!", + return m_logger->error("+++ MBM: Failed to connect to MBM buffer %s!", bm_name.c_str()); } /// Insert producer into idle plug container @@ -228,7 +228,7 @@ int MBMEventOutput::connect(const string& output, size_t instance) { if ( config.max_consumer_wait ) { m_mbmInfo = make_unique<MBM::BufferInfo>(); m_mbmInfo->attach(bm_name.c_str()); - m_logger->info("Enabled MBM consumer checks. Max Wait time: %d seconds", + m_logger->info("+++ Enabled MBM consumer checks. Max Wait time: %d seconds", config.max_consumer_wait); } return ONLINE_OK; @@ -240,7 +240,7 @@ void MBMEventOutput::checkConsumers(int ev_type, unsigned int pid) { int max_cons_wait = config.max_consumer_wait; while ( --max_cons_wait >= 0 ) { if ( m_mbmInfo->num_consumers_partid_evtype(ev_type, pid) != 0 ) { - m_logger->debug("Waiting for consumers subscribed to event type: %d " + m_logger->debug("+++ Waiting for consumers subscribed to event type: %d " "partition:%08X time left: %d seconds", ev_type, pid, max_cons_wait); ::lib_rtl_sleep(1000); @@ -249,8 +249,8 @@ void MBMEventOutput::checkConsumers(int ev_type, unsigned int pid) { break; } if ( max_cons_wait < 0 ) { - m_logger->except("FAILED: No suitable consumers subscribed to event type: %d partition:%08X", - ev_type, pid, max_cons_wait); + m_logger->except("+++ FAILED: No suitable consumers subscribed to event type:" + " %d partition:%08X", ev_type, pid, max_cons_wait); } } } diff --git a/Online/OnlineBase/src/MBM/mbm_extract.cpp b/Online/OnlineBase/src/MBM/mbm_extract.cpp index 34ad66b46..2007ff943 100644 --- a/Online/OnlineBase/src/MBM/mbm_extract.cpp +++ b/Online/OnlineBase/src/MBM/mbm_extract.cpp @@ -52,8 +52,9 @@ extern "C" int mbm_extract(int argc,char **argv) { ::lib_rtl_output(LIB_RTL_ALWAYS," -t(cp) Use boost::asio TCP connections for communication\n"); ::lib_rtl_output(LIB_RTL_ALWAYS," -ipc Use boost::asio ICP connections for communication\n"); ::lib_rtl_output(LIB_RTL_ALWAYS," -out(put)=<file-name> File name to dump event data \n"); - ::lib_rtl_output(LIB_RTL_ALWAYS," -mep Request event type MEP (default: Event) \n"); - ::lib_rtl_output(LIB_RTL_ALWAYS," -burst Request event type Burst (default: Event) \n"); + ::lib_rtl_output(LIB_RTL_ALWAYS," -event Request event type EVENT \n"); + ::lib_rtl_output(LIB_RTL_ALWAYS," -mep Request event type MEP \n"); + ::lib_rtl_output(LIB_RTL_ALWAYS," -burst Request event type Burst \n"); exit(0); }); std::string name = "consumer", buffer="0", output = "mbm.dat", log; @@ -99,25 +100,35 @@ extern "C" int mbm_extract(int argc,char **argv) { ::exit(errno); } int event_type = EVENT_TYPE_EVENT; - if ( mep ) - event_type = EVENT_TYPE_MEP; - else if ( brst ) - event_type = EVENT_TYPE_BURST; - else if ( evt ) - event_type = EVENT_TYPE_EVENT; if ( one ) { - ::mbm_add_req(bmid,event_type,trmask,vetomask,BM_MASK_ANY,(inc_opt<<8)+BM_REQ_ONE,BM_FREQ_PERC,100.); + if ( mep ) + ::mbm_add_req(bmid,EVENT_TYPE_MEP,trmask,vetomask,BM_MASK_ANY,(inc_opt<<8)+BM_REQ_ONE,BM_FREQ_PERC,100.); + if ( brst ) + ::mbm_add_req(bmid,EVENT_TYPE_BURST,trmask,vetomask,BM_MASK_ANY,(inc_opt<<8)+BM_REQ_ONE,BM_FREQ_PERC,100.); + if ( evt ) + ::mbm_add_req(bmid,EVENT_TYPE_EVENT,trmask,vetomask,BM_MASK_ANY,(inc_opt<<8)+BM_REQ_ONE,BM_FREQ_PERC,100.); ::lib_rtl_output(LIB_RTL_ALWAYS,"+++ Event request type is BM_REQ_ONE [%d].",inc_opt); } else if ( user ) { - ::mbm_add_req(bmid,event_type,trmask,vetomask,BM_MASK_ANY,BM_REQ_USER,BM_FREQ_PERC,100.); + if ( mep ) + ::mbm_add_req(bmid,EVENT_TYPE_MEP,trmask,vetomask,BM_MASK_ANY,BM_REQ_USER,BM_FREQ_PERC,100.); + if ( brst ) + ::mbm_add_req(bmid,EVENT_TYPE_BURST,trmask,vetomask,BM_MASK_ANY,BM_REQ_USER,BM_FREQ_PERC,100.); + if ( evt ) + ::mbm_add_req(bmid,EVENT_TYPE_EVENT,trmask,vetomask,BM_MASK_ANY,BM_REQ_USER,BM_FREQ_PERC,100.); ::lib_rtl_output(LIB_RTL_ALWAYS,"+++ Event request type is BM_REQ_USER."); } else { - ::mbm_add_req(bmid,event_type,trmask,vetomask,BM_MASK_ANY,BM_REQ_ALL,BM_FREQ_PERC,100.); + if ( mep ) + ::mbm_add_req(bmid,EVENT_TYPE_MEP,trmask,vetomask,BM_MASK_ANY,BM_REQ_ALL,BM_FREQ_PERC,100.); + if ( brst ) + ::mbm_add_req(bmid,EVENT_TYPE_BURST,trmask,vetomask,BM_MASK_ANY,BM_REQ_ALL,BM_FREQ_PERC,100.); + if ( evt ) + ::mbm_add_req(bmid,EVENT_TYPE_EVENT,trmask,vetomask,BM_MASK_ANY,BM_REQ_ALL,BM_FREQ_PERC,100.); ::lib_rtl_output(LIB_RTL_ALWAYS,"+++ Event request type is BM_REQ_ALL."); } + long tr_number, len; for(tr_number = 1; tr_number <= count; ++tr_number) { unsigned int mask[4]; diff --git a/Online/PCIE40Data/PCIE40Data/RawBank40.h b/Online/PCIE40Data/PCIE40Data/RawBank40.h index 2a0ac295e..17f0d49f1 100644 --- a/Online/PCIE40Data/PCIE40Data/RawBank40.h +++ b/Online/PCIE40Data/PCIE40Data/RawBank40.h @@ -69,6 +69,7 @@ namespace Online { RawBank40() = default; enum BankType { + Other=1, L0Calo=0, // 0 L0DU, // 1 PrsE, // 2 diff --git a/Online/PCIE40Data/PCIE40Data/pcie40.h b/Online/PCIE40Data/PCIE40Data/pcie40.h index a24b66b05..3cb69695d 100644 --- a/Online/PCIE40Data/PCIE40Data/pcie40.h +++ b/Online/PCIE40Data/PCIE40Data/pcie40.h @@ -19,6 +19,7 @@ // C/C++ include files #include <stdexcept> +#include <cstring> #include "PCIE40Data/Pack.h" @@ -248,6 +249,8 @@ namespace Online { const bank_t* next(const bank_t* e) const; const bank_t* at(size_t which) const; const bank_t* operator[](size_t i) const; + size_t total_length() const; + void* copy_data(void* ptr) const; }; /// A full pcie40 event with multiple bank collection sorted by bank type @@ -287,10 +290,12 @@ namespace Online { event_t& operator=(const event_t& copy) = delete; public: - static std::pair<bool,size_t> collection_offset(unsigned char type); - std::pair<size_t, const bank_t*> get(unsigned char type) const; - size_t num_bank_collections() const; - const bank_collection_t* bank_collection(size_t i) const; + static std::pair<bool,size_t> collection_offset(unsigned char type); + std::pair<size_t, const bank_t*> get(unsigned char type) const; + size_t num_bank_collections() const; + const bank_collection_t* bank_collection(size_t i) const; + size_t total_length() const; + void* copy_data(void* pointer) const; }; /// Collection of mep events as they arrive from the event builder @@ -325,11 +330,12 @@ namespace Online { size_t size() const { return length; } size_t num_events() const { return length; } size_t max_events() const { return capacity; } - const event_t* begin() const; - const event_t* end() const; + const event_t* begin() const; + const event_t* end() const; const event_t* next(const event_t* e) const; const event_t* at(size_t which) const; const event_t* operator[](size_t which) const; + size_t total_length() const; }; /// Constant parameters to access the various records @@ -368,36 +374,40 @@ namespace Online { static constexpr size_t maxTell40Hcal = 8; static constexpr size_t maxTell40Muon = 10; static constexpr size_t maxTell40Rich = 350; + static constexpr size_t maxTell40Other = 100; static constexpr size_t maxTell40 = maxTell40ODIN + maxTell40VP + maxTell40UT - + maxTell40FT + maxTell40Ecal + maxTell40Hcal + maxTell40Muon + maxTell40Rich; - - static constexpr size_t collectionCapacity[] = {maxTell40ODIN, - maxTell40VP, - maxTell40UT, - maxTell40FT, - maxTell40Ecal, - maxTell40Hcal, - maxTell40Muon, - maxTell40Rich}; - - static constexpr size_t collectionSizeODIN = sizeof(bank_collection_t); - static constexpr size_t collectionSizeVP = sizeof(bank_collection_t)+(maxTell40VP-1)*sizeof(bank_t); - static constexpr size_t collectionSizeUT = sizeof(bank_collection_t)+(maxTell40UT-1)*sizeof(bank_t); - static constexpr size_t collectionSizeFT = sizeof(bank_collection_t)+(maxTell40FT-1)*sizeof(bank_t); - static constexpr size_t collectionSizeEcal = sizeof(bank_collection_t)+(maxTell40Ecal-1)*sizeof(bank_t); - static constexpr size_t collectionSizeHcal = sizeof(bank_collection_t)+(maxTell40Hcal-1)*sizeof(bank_t); - static constexpr size_t collectionSizeMuon = sizeof(bank_collection_t)+(maxTell40Muon-1)*sizeof(bank_t); - static constexpr size_t collectionSizeRich = sizeof(bank_collection_t)+(maxTell40Rich-1)*sizeof(bank_t); - - static constexpr size_t collectionOffset = event_t::data_offset; - static constexpr size_t collectionOffsetODIN = collectionOffset; - static constexpr size_t collectionOffsetVP = collectionOffsetODIN + collectionSizeODIN; - static constexpr size_t collectionOffsetUT = collectionOffsetVP + collectionSizeVP; - static constexpr size_t collectionOffsetFT = collectionOffsetUT + collectionSizeUT; - static constexpr size_t collectionOffsetEcal = collectionOffsetFT + collectionSizeFT; - static constexpr size_t collectionOffsetHcal = collectionOffsetEcal + collectionSizeEcal; - static constexpr size_t collectionOffsetMuon = collectionOffsetHcal + collectionSizeHcal; - static constexpr size_t collectionOffsetRich = collectionOffsetMuon + collectionSizeMuon; + + maxTell40FT + maxTell40Ecal + maxTell40Hcal + maxTell40Muon + maxTell40Rich + maxTell40Other; + + static constexpr size_t collectionCapacity[] = {maxTell40ODIN, + maxTell40VP, + maxTell40UT, + maxTell40FT, + maxTell40Ecal, + maxTell40Hcal, + maxTell40Muon, + maxTell40Rich, + maxTell40Other + }; + static constexpr size_t collectionSizeODIN = sizeof(bank_collection_t); + static constexpr size_t collectionSizeVP = sizeof(bank_collection_t)+(maxTell40VP-1)*sizeof(bank_t); + static constexpr size_t collectionSizeUT = sizeof(bank_collection_t)+(maxTell40UT-1)*sizeof(bank_t); + static constexpr size_t collectionSizeFT = sizeof(bank_collection_t)+(maxTell40FT-1)*sizeof(bank_t); + static constexpr size_t collectionSizeEcal = sizeof(bank_collection_t)+(maxTell40Ecal-1)*sizeof(bank_t); + static constexpr size_t collectionSizeHcal = sizeof(bank_collection_t)+(maxTell40Hcal-1)*sizeof(bank_t); + static constexpr size_t collectionSizeMuon = sizeof(bank_collection_t)+(maxTell40Muon-1)*sizeof(bank_t); + static constexpr size_t collectionSizeRich = sizeof(bank_collection_t)+(maxTell40Rich-1)*sizeof(bank_t); + static constexpr size_t collectionSizeOther = sizeof(bank_collection_t)+(maxTell40Other-1)*sizeof(bank_t); + + static constexpr size_t collectionOffset = event_t::data_offset; + static constexpr size_t collectionOffsetODIN = collectionOffset; + static constexpr size_t collectionOffsetVP = collectionOffsetODIN + collectionSizeODIN; + static constexpr size_t collectionOffsetUT = collectionOffsetVP + collectionSizeVP; + static constexpr size_t collectionOffsetFT = collectionOffsetUT + collectionSizeUT; + static constexpr size_t collectionOffsetEcal = collectionOffsetFT + collectionSizeFT; + static constexpr size_t collectionOffsetHcal = collectionOffsetEcal + collectionSizeEcal; + static constexpr size_t collectionOffsetMuon = collectionOffsetHcal + collectionSizeHcal; + static constexpr size_t collectionOffsetRich = collectionOffsetMuon + collectionSizeMuon; + static constexpr size_t collectionOffsetOther = collectionOffsetRich + collectionSizeRich; static constexpr size_t collectionOffsets[] = {collectionOffsetODIN, collectionOffsetVP, @@ -406,10 +416,11 @@ namespace Online { collectionOffsetEcal, collectionOffsetHcal, collectionOffsetMuon, - collectionOffsetRich - }; + collectionOffsetRich, + collectionOffsetOther }; + static constexpr size_t num_bank_collection = (sizeof(collectionOffsets)/sizeof(collectionOffsets[0])); - static constexpr size_t eventRecordLength = collectionOffsetRich + collectionSizeRich; + static constexpr size_t eventRecordLength = collectionOffsetOther + collectionSizeOther; } /// Access to data block @@ -492,19 +503,19 @@ namespace Online { } inline const bank_t* bank_collection_t::begin() const { - return banks; + return this->banks; } inline const bank_t* bank_collection_t::special_begin() const { - return add_ptr<bank_t>(banks,sizeof(bank_t) * (capacity-specials)); + return add_ptr<bank_t>(this->banks,sizeof(bank_t) * (capacity-specials)); } inline const bank_t* bank_collection_t::special_end() const { - return add_ptr<bank_t>(banks,sizeof(bank_t) * capacity); + return add_ptr<bank_t>(this->banks,sizeof(bank_t) * capacity); } inline const bank_t* bank_collection_t::end() const { - return add_ptr<bank_t>(banks,sizeof(bank_t) * length); + return add_ptr<bank_t>(this->banks,sizeof(bank_t) * length); } inline const bank_t* bank_collection_t::next(const bank_t* e) const { @@ -512,11 +523,37 @@ namespace Online { } inline const bank_t* bank_collection_t::at(size_t i) const { - return add_ptr<bank_t>(banks,sizeof(bank_t)*i); + return add_ptr<bank_t>(this->banks,sizeof(bank_t)*i); } inline const bank_t* bank_collection_t::operator[](size_t i) const { - return add_ptr<bank_t>(banks,sizeof(bank_t)*i); + return add_ptr<bank_t>(this->banks,sizeof(bank_t)*i); + } + + inline size_t bank_collection_t::total_length() const { + size_t len = 0; + for( const auto* b=this->begin(); b != this->end(); b=this->next(b) ) + len += b->totalSize(); + for( const auto* b=this->special_begin(); b != this->special_end(); b=this->next(b) ) + len += b->totalSize(); + return len; + } + + inline void* bank_collection_t::copy_data(void* ptr) const { + unsigned char* p = (unsigned char*)ptr; + for( const auto* b=this->begin(); b != this->end(); b=this->next(b) ) { + size_t len = b->hdrSize(); + ::memcpy(p, b, len); + ::memcpy(p + len, b->data(), b->totalSize()-len); + p += b->totalSize(); + } + for( const auto* b=this->special_begin(); b != this->special_end(); b=this->next(b) ) { + size_t len = b->hdrSize(); + ::memcpy(p, b, len); + ::memcpy(p + len, b->data(), b->totalSize()-len); + p += b->totalSize(); + } + return p; } inline std::pair<bool,size_t> event_t::collection_offset(unsigned char type) { @@ -541,6 +578,8 @@ namespace Online { return std::make_pair(true,params::collectionOffsetHcal); case bank_t::Muon: return std::make_pair(true,params::collectionOffsetMuon); + case bank_t::Other: + return std::make_pair(true,params::collectionOffsetOther); default: throw std::runtime_error("Unknown bank type!"); } @@ -563,6 +602,19 @@ namespace Online { return add_ptr<bank_collection_t>(this,params::collectionOffsets[which]); } + inline size_t event_t::total_length() const { + size_t len = 0; + for( size_t i=0, n=this->num_bank_collections(); i<n; ++i) + len += this->bank_collection(i)->total_length(); + return len; + } + + inline void* event_t::copy_data(void* ptr) const { + for( size_t i=0, n=this->num_bank_collections(); i<n; ++i) + ptr = this->bank_collection(i)->copy_data(ptr); + return ptr; + } + inline const event_t* event_collection_t::begin() const { return events; } @@ -582,6 +634,14 @@ namespace Online { inline const event_t* event_collection_t::at(size_t i) const { return add_ptr<event_t>(events,params::eventRecordLength*i); } + + inline size_t event_collection_t::total_length() const { + size_t len = 0; + for( const event_t* e=this->begin(); e != this->end(); e=this->next(e) ) + len += e->total_length(); + return len; + } + } // namespace pcie40 } // namepace Online diff --git a/Online/PCIE40Data/main/pcie40_decode_file.cpp b/Online/PCIE40Data/main/pcie40_decode_file.cpp index 7b07e392f..54f19e0af 100644 --- a/Online/PCIE40Data/main/pcie40_decode_file.cpp +++ b/Online/PCIE40Data/main/pcie40_decode_file.cpp @@ -16,6 +16,7 @@ #include <unistd.h> #include <fcntl.h> #include <cstdlib> +#include <cstring> #include <cstdio> #include <vector> #include <list> @@ -47,10 +48,18 @@ int main(int argc, char *argv[]) { const auto *mep_end = pcie40::add_ptr<pcie40::mep_header_t>(mep_start, sb.st_size-4); ::close(fd); + if ( mep_start == (pcie40::mep_header_t*)MAP_FAILED ) { + ::printf("+++ FAILED mapping mep file %s [%s]\n", argv[1], ::strerror(errno)); + ::exit(errno); + } + start = clock(); ::printf("+++ mapping mep file %p %ld %p\n", (void*)mep_start, sb.st_size, (void*)((char*)mep_start + sb.st_size)); int n_mep = 0; for(const pcie40::mep_header_t* mep = mep_start; mep < mep_end; ) { + unsigned char* p = (unsigned char*)mep; + p += sizeof(long); + mep = (pcie40::mep_header_t*)p; if ( !mep->is_valid() ) break; ::printf("+++ Reading mep[%2d] at %p %6d %p\n", n_mep, (void*)mep, mep->size, (void*)((char*)mep + mep->size)); diff --git a/Online/SmiController/options/TestMEPProd.opts b/Online/SmiController/options/TestMEPProd.opts index f349f3dab..53cf3dcc6 100644 --- a/Online/SmiController/options/TestMEPProd.opts +++ b/Online/SmiController/options/TestMEPProd.opts @@ -30,6 +30,7 @@ Reader.RequireConsumers = 0; Reader.MMapFiles = 0; Reader.ReuseFile = 1; Reader.PackingFactor = 1000; +Reader.HeaderPrefixSize = 8; //Reader.AllocationSizekB = 4096; //Reader.PackingFactor = 4000; //Reader.AllocationSizekB = 50000; diff --git a/Online/SmiController/scripts/EventProcessor.py b/Online/SmiController/scripts/EventProcessor.py index 9ebee4354..a8e3bbb57 100644 --- a/Online/SmiController/scripts/EventProcessor.py +++ b/Online/SmiController/scripts/EventProcessor.py @@ -33,9 +33,9 @@ application.setup_hive(FlowManager("EventLoop"), 40) application.setup_algorithms(writer, 0.05) application.setup_monitoring() application.monSvc.DimUpdateInterval = 1 -application.config.numEventThreads = 2 -application.config.MBM_numConnections = 2 -application.config.MBM_numEventThreads = 2 +application.config.numEventThreads = 1 +application.config.MBM_numConnections = 1 +application.config.MBM_numEventThreads = 1 application.config.MBM_requests = [ 'EvType=3;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=100.0', 'EvType=2;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=100.0', diff --git a/Online/SmiController/scripts/TestMEPProd.sh b/Online/SmiController/scripts/TestMEPProd.sh new file mode 100644 index 000000000..48b19a903 --- /dev/null +++ b/Online/SmiController/scripts/TestMEPProd.sh @@ -0,0 +1,3 @@ +#!/bin/bash +# +`dataflow_task Class2` `dataflow_default_options ${TASK_TYPE}` diff --git a/Online/SmiController/scripts/TestStorageWriter.sh b/Online/SmiController/scripts/TestStorageWriter.sh index ab01e46e6..a12662bb2 100755 --- a/Online/SmiController/scripts/TestStorageWriter.sh +++ b/Online/SmiController/scripts/TestStorageWriter.sh @@ -9,5 +9,6 @@ # # ========================================================================= export INFO_OPTIONS=/group/online/dataflow/options/LHCb/MONITORING/OnlineEnv.opts; -`dataflow_task Class1` `dataflow_default_options ${TASK_TYPE}` +echo "ERROR `dataflow_task Class1` `dataflow_default_options ${TASK_TYPE}`"; +`dataflow_task Class1` `dataflow_default_options ${TASK_TYPE}`; diff --git a/Online/Storage/src/server/fdb_SQLite.cpp b/Online/Storage/src/server/fdb_SQLite.cpp index da2c14614..733995260 100644 --- a/Online/Storage/src/server/fdb_SQLite.cpp +++ b/Online/Storage/src/server/fdb_SQLite.cpp @@ -59,6 +59,8 @@ fdb_SQLite::handler_t::query(std::string& object, access = file.access; length = ::atol(file.size.c_str()); date = file.date; + ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, + "Query '%s'", object.c_str()); return ec; } ::lib_rtl_output(LIB_RTL_ALWAYS,"%s: Query: file '%s' NOT FOUND!", @@ -81,6 +83,8 @@ fdb_SQLite::handler_t::next( std::string& object, date = file.date; ec = this->lock(file.name, handler_t::STATE_READ); if ( ec == system::errc::success ) { + ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, + "Next '%s'", object.c_str()); return system::error_code(system::errc::success, system::system_category()); } return system::error_code(system::errc::protocol_error, system::system_category()); @@ -106,7 +110,7 @@ system::error_code fdb_SQLite::query_object(const std::string& object, access = this->network_file(access); if ( ec == system::errc::success ) { ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Successfully lookup object: '%s'", object.c_str()); + "Lookup '%s'", object.c_str()); return ec; } ::lib_rtl_output(LIB_RTL_ALWAYS,"FAILED to lookup object: '%s' [%s]", @@ -125,7 +129,7 @@ system::error_code fdb_SQLite::query_next( const std::string& object, access = this->network_file(access); if ( ec == system::errc::success ) { ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Successfully lookup object: '%s'", object.c_str()); + "Lookup '%s'", object.c_str()); return ec; } ::lib_rtl_output(LIB_RTL_ALWAYS,"FAILED to lookup object: '%s' [%s]", @@ -146,7 +150,7 @@ system::error_code fdb_SQLite::delete_next( const std::string& object, access = this->network_file(access); if ( ec == system::errc::success ) { ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Successfully lookup sequence object: '%s'", object.c_str()); + "Lookup '%s'", object.c_str()); return ec; } } @@ -168,7 +172,7 @@ system::error_code fdb_SQLite::delete_object(const std::string& object, ec = this->engine->del(object); if ( ec == system::errc::success ) { ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Removed db record: '%s'", object.c_str()); + "Remove '%s'", object.c_str()); return ec; } } @@ -200,7 +204,9 @@ fdb_SQLite::add_object(const std::string& object, auto ec = this->engine->add(object, date, length, acc); if ( ec == system::errc::success ) { ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Added file: '%s' access:%s.", object.c_str(), acc.c_str()); + "Add '%s' %s %s", object.c_str(), + this->debug > 1 ? "access:" : "", + this->debug > 1 ? acc.c_str() : ""); access = this->network_file(acc); return ec; } diff --git a/Online/Storage/src/server/fdb_SQLite.h b/Online/Storage/src/server/fdb_SQLite.h index 1ef04bf78..3ddb34347 100644 --- a/Online/Storage/src/server/fdb_SQLite.h +++ b/Online/Storage/src/server/fdb_SQLite.h @@ -51,7 +51,7 @@ namespace Online { static constexpr int STATE_READ = 1; sqlite::database database; - bool debug { false }; + int debug { 0 }; struct File { std::string name, state, size, date, access; }; @@ -60,7 +60,7 @@ namespace Online { query_file(const std::string& object_name, File& file, int state) = 0; public: - handler_t(bool dbg) + handler_t(int dbg) : debug(dbg) { } diff --git a/Online/Storage/src/server/fdb_db_server.cpp b/Online/Storage/src/server/fdb_db_server.cpp index 4a85a28e1..67c94adc7 100644 --- a/Online/Storage/src/server/fdb_db_server.cpp +++ b/Online/Storage/src/server/fdb_db_server.cpp @@ -191,8 +191,8 @@ http::basic_http_server<db>::handler_t::handle_request(const request_t& req, rep if ( 0 == rep.bytes_sent ) { auto ret = this->HttpRequestHandler::handle_request(req, rep); if ( this->debug > 0 || !(rep.status == reply_t::temp_redirect || rep.status == reply_t::ok) ) { - ::lib_rtl_output(LIB_RTL_INFO,"basic_http_server<db>::handle: Serving %s %s status: %d", - req.method.c_str(), req.uri.c_str(), rep.status); + ::lib_rtl_output(LIB_RTL_INFO,"basic_http_server<db>::handle: Serving %s %s status: %d [%s]", + req.method.c_str(), req.uri.c_str(), rep.status, reply_t::stock_status(rep.status)); for ( const auto& h : rep.headers ) ::lib_rtl_output(LIB_RTL_INFO,"basic_http_server<db>::handle: %-20s = %s", h.name.c_str(), h.value.c_str()); diff --git a/Online/Tell1Data/Tell1Data/RawFile.h b/Online/Tell1Data/Tell1Data/RawFile.h index 051e6aabc..a69ac80c9 100644 --- a/Online/Tell1Data/Tell1Data/RawFile.h +++ b/Online/Tell1Data/Tell1Data/RawFile.h @@ -86,7 +86,7 @@ namespace Online { bool isOpen() const { return m_fd > 0; } bool isMapped() const { return m_begin != m_end; } size_t mapped_size() const { return m_end - m_begin; } - size_t data_size() const { return m_end - m_ptr; } + size_t data_size() const; const unsigned char* begin() const { return m_begin; } const unsigned char* end() const { return m_end; } const unsigned char* pointer() const { return m_ptr; } diff --git a/Online/Tell1Data/src/RawFile.cpp b/Online/Tell1Data/src/RawFile.cpp index 657cbb761..b66d28a68 100644 --- a/Online/Tell1Data/src/RawFile.cpp +++ b/Online/Tell1Data/src/RawFile.cpp @@ -77,6 +77,19 @@ long RawFile::seek(long offset, int whence) { return -1; } +/// Return file size +size_t RawFile::data_size() const { + if ( isOpen() && !m_begin ) { + struct stat sb; + ::fstat(m_fd, &sb); /* To obtain file size */ + return sb.st_size; + } + else if ( m_begin ) { + return m_end - m_begin; + } + return 0; +} + /// Return file position long RawFile::position() const { if ( isOpen() && !m_begin ) { -- GitLab From b65397674df4fb35c5c9cbd626ecd5d6566652ba Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Fri, 5 Mar 2021 10:23:42 +0100 Subject: [PATCH 02/17] Enable conditional build for EventBuilding package if no PCIE40 is found --- Online/EventBuilding/CMakeLists.txt | 12 +++++++++++- Online/FarmConfig/job/BU.sh | 12 ++++++++++++ Online/FarmConfig/job/EBMBM.sh | 12 ++++++++++++ Online/FarmConfig/job/RU.sh | 12 ++++++++++++ Online/FarmConfig/options/EBMBM.opts | 2 ++ 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100755 Online/FarmConfig/job/BU.sh create mode 100755 Online/FarmConfig/job/EBMBM.sh create mode 100755 Online/FarmConfig/job/RU.sh create mode 100644 Online/FarmConfig/options/EBMBM.opts diff --git a/Online/EventBuilding/CMakeLists.txt b/Online/EventBuilding/CMakeLists.txt index fba083de3..255209d10 100755 --- a/Online/EventBuilding/CMakeLists.txt +++ b/Online/EventBuilding/CMakeLists.txt @@ -22,10 +22,20 @@ gaudi_depends_on_subdirs(Online/DIM Online/Dataflow Online/OnlineBase Online/PCIE40Data) -include(Numa) + +find_path(PCIE40_DAQ_INC /usr/include/lhcb/daq40/daq40.hpp) +if ( "${PCIE40_DAQ_INC}" STREQUAL "PCIE40_DAQ_INC-NOTFOUND" ) + message(STATUS "+======================================================================+") + message(STATUS "| PCIE40 DAQ not present. Will not build EventBuilding libraries. |") + message(STATUS "+======================================================================+") + return() +endif() + # fpisani fixed find of external libraries find_package(MPI REQUIRED) +include(Numa) find_package(PkgConfig REQUIRED) + set(OLD_CONFIG_PATH $ENV{PKG_CONFIG_PATH}) # TODO check if there is a better way to identify this path set(ENV{PKG_CONFIG_PATH} /usr/lib64/pkgconfig) diff --git a/Online/FarmConfig/job/BU.sh b/Online/FarmConfig/job/BU.sh new file mode 100755 index 000000000..beca57daf --- /dev/null +++ b/Online/FarmConfig/job/BU.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# ========================================================================= +# +# Default script to start the buffer manager on the HLT farm worker node +# +# Author M.Frank +# Version: 1.0 +# Date: 05/03/2021 +# +# ========================================================================= +# +exec -a ${UTGID} ${DATAFLOW_task} -class=Class1 -opts=../../EventBuilding/options/EB_BU.opts $(AUTO_STARTUP} ${DEBUG_STARTUP} diff --git a/Online/FarmConfig/job/EBMBM.sh b/Online/FarmConfig/job/EBMBM.sh new file mode 100755 index 000000000..30097ae9f --- /dev/null +++ b/Online/FarmConfig/job/EBMBM.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# ========================================================================= +# +# Default script to start the buffer manager on the HLT farm worker node +# +# Author M.Frank +# Version: 1.0 +# Date: 05/03/2021 +# +# ========================================================================= +# +exec -a ${UTGID} ${DATAFLOW_task} -class=Class0 -opts=../options/${TASK_TYPE}.opts; diff --git a/Online/FarmConfig/job/RU.sh b/Online/FarmConfig/job/RU.sh new file mode 100755 index 000000000..c44774a95 --- /dev/null +++ b/Online/FarmConfig/job/RU.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# ========================================================================= +# +# Default script to start the buffer manager on the HLT farm worker node +# +# Author M.Frank +# Version: 1.0 +# Date: 05/03/2021 +# +# ========================================================================= +# +exec -a ${UTGID} ${DATAFLOW_task} -class=Class1 -opts=../../EventBuilding/options/EB_RU.opts $(AUTO_STARTUP} ${DEBUG_STARTUP} diff --git a/Online/FarmConfig/options/EBMBM.opts b/Online/FarmConfig/options/EBMBM.opts new file mode 100644 index 000000000..2ce8dabe5 --- /dev/null +++ b/Online/FarmConfig/options/EBMBM.opts @@ -0,0 +1,2 @@ +#include "$FARMCONFIG_OPTIONS/MEPInit.opts" +MEPManager.InitFlags = "-s=200000 -e=500 -u=20 -b=17 -f -i=Events_0 -c -s=200000 -e=500 -u=20 -b=17 -f -i=Events_1 -c"; -- GitLab From 2ed54c9241438fd8f6590868933d0bc627209d62 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Mon, 8 Mar 2021 15:31:49 +0100 Subject: [PATCH 03/17] Commit first results from EventBuilding setup --- Online/Dataflow/CMakeLists.txt | 4 +- Online/Dataflow/src/Gaucho/DIMMonitoring.cpp | 26 +++++++---- Online/EventBuilding/CMakeLists.txt | 15 +++--- Online/EventBuilding/options/BU_0.opts | 3 ++ Online/EventBuilding/options/BU_1.opts | 3 ++ Online/EventBuilding/options/EB_BU.opts | 14 ++---- Online/EventBuilding/options/EB_BU_1.opts | 0 Online/EventBuilding/options/EB_BU_algo.opts | 7 +++ Online/EventBuilding/options/EB_RU.opts | 14 ++---- Online/EventBuilding/options/EB_RU_1.opts | 0 Online/EventBuilding/options/EB_RU_algo.opts | 10 ++++ .../options/EB_Transport_properties.opts | 8 ++++ .../EventBuilding/options/EB_transport.opts | 10 +--- Online/EventBuilding/options/Logging.opts | 0 Online/EventBuilding/options/MBMSetup.opts | 0 Online/EventBuilding/options/MBM_server.opts | 0 Online/EventBuilding/options/MEPInit.opts | 0 .../EventBuilding/options/MFP_generator.opts | 10 +--- .../options/MFP_generator_params.opts | 7 +++ Online/EventBuilding/options/OnlineEnv.opts | 0 .../options/events_dispatch/BU_dummy.opts | 0 .../options/events_dispatch/FU.opts | 0 .../events_dispatch/MBMSetup_Input.opts | 0 .../events_dispatch/MBMSetup_Input_2.opts | 0 .../events_dispatch/MBM_reader_dummy.opts | 0 .../events_dispatch/MEPInit_Input.opts | 0 .../events_dispatch/MEPInit_Input_2.opts | 0 .../options/events_dispatch/MU.opts | 0 .../options/events_dispatch/OU.opts | 0 .../EventBuilding/options/hosts_example.json | 0 Online/FarmConfig/job/BU.sh | 5 +- Online/FarmConfig/job/Controller.sh | 2 +- Online/FarmConfig/job/RU.sh | 2 +- Online/FarmConfig/job/preamble.sh | 7 ++- Online/FarmConfig/job/runTask.sh | 14 ++---- Online/FarmConfig/options/EBMBM.opts | 11 ++++- Online/SmiController/src/smi_controller.cpp | 46 ++++++++++++------- Online/Storage/src/server/fdb_db_server.cpp | 8 ++-- 38 files changed, 138 insertions(+), 88 deletions(-) create mode 100644 Online/EventBuilding/options/BU_0.opts create mode 100644 Online/EventBuilding/options/BU_1.opts mode change 100644 => 100755 Online/EventBuilding/options/EB_BU.opts mode change 100644 => 100755 Online/EventBuilding/options/EB_BU_1.opts create mode 100755 Online/EventBuilding/options/EB_BU_algo.opts mode change 100644 => 100755 Online/EventBuilding/options/EB_RU.opts mode change 100644 => 100755 Online/EventBuilding/options/EB_RU_1.opts create mode 100755 Online/EventBuilding/options/EB_RU_algo.opts create mode 100755 Online/EventBuilding/options/EB_Transport_properties.opts mode change 100644 => 100755 Online/EventBuilding/options/EB_transport.opts mode change 100644 => 100755 Online/EventBuilding/options/Logging.opts mode change 100644 => 100755 Online/EventBuilding/options/MBMSetup.opts mode change 100644 => 100755 Online/EventBuilding/options/MBM_server.opts mode change 100644 => 100755 Online/EventBuilding/options/MEPInit.opts mode change 100644 => 100755 Online/EventBuilding/options/MFP_generator.opts create mode 100755 Online/EventBuilding/options/MFP_generator_params.opts mode change 100644 => 100755 Online/EventBuilding/options/OnlineEnv.opts mode change 100644 => 100755 Online/EventBuilding/options/events_dispatch/BU_dummy.opts mode change 100644 => 100755 Online/EventBuilding/options/events_dispatch/FU.opts mode change 100644 => 100755 Online/EventBuilding/options/events_dispatch/MBMSetup_Input.opts mode change 100644 => 100755 Online/EventBuilding/options/events_dispatch/MBMSetup_Input_2.opts mode change 100644 => 100755 Online/EventBuilding/options/events_dispatch/MBM_reader_dummy.opts mode change 100644 => 100755 Online/EventBuilding/options/events_dispatch/MEPInit_Input.opts mode change 100644 => 100755 Online/EventBuilding/options/events_dispatch/MEPInit_Input_2.opts mode change 100644 => 100755 Online/EventBuilding/options/events_dispatch/MU.opts mode change 100644 => 100755 Online/EventBuilding/options/events_dispatch/OU.opts mode change 100644 => 100755 Online/EventBuilding/options/hosts_example.json diff --git a/Online/Dataflow/CMakeLists.txt b/Online/Dataflow/CMakeLists.txt index bf780fad6..ade206dfe 100755 --- a/Online/Dataflow/CMakeLists.txt +++ b/Online/Dataflow/CMakeLists.txt @@ -29,7 +29,7 @@ gaudi_depends_on_subdirs(Online/dim Online/PCIE40Data) # include(Numa) -include(PCIE40) +###include(PCIE40) # find_package(Boost REQUIRED COMPONENTS system filesystem regex) find_package(ROOT REQUIRED COMPONENTS Hist RIO) @@ -239,7 +239,7 @@ IF (PCIE40_FOUND) target_include_directories(DataflowPCIE40 BEFORE PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) gaudi_generate_componentslist(DataflowPCIE40) ELSE() - message(STATUS "PCIE40 event builder library shall not be built!") + message(STATUS "+++ Dataflow: PCIE40 event builder library shall not be built!") ENDIF() # # --------------------------------------------------------------------------------------- diff --git a/Online/Dataflow/src/Gaucho/DIMMonitoring.cpp b/Online/Dataflow/src/Gaucho/DIMMonitoring.cpp index 4d8da8f47..8923ca603 100755 --- a/Online/Dataflow/src/Gaucho/DIMMonitoring.cpp +++ b/Online/Dataflow/src/Gaucho/DIMMonitoring.cpp @@ -147,8 +147,10 @@ void DIMMonitoring::handle(const DataflowIncident& inc) { /// Monitoring interface: Undeclare single monitoring item int DIMMonitoring::undeclare(const string& owner, const string& nam) { - string oname = !owner.empty() ? owner : string(""); - m_MonIntf->undeclare(oname+"/"+nam); + if ( m_MonIntf ) { + string oname = !owner.empty() ? owner : string(""); + m_MonIntf->undeclare(oname+"/"+nam); + } return DF_SUCCESS; } @@ -156,8 +158,10 @@ int DIMMonitoring::undeclare(const string& owner, const string& nam) { @param owner Owner identifier of the monitoring information */ int DIMMonitoring::undeclare(const string& owner) { - string oname = !owner.empty() ? owner : string(""); - m_MonIntf->undeclareAll(oname); + if ( m_MonIntf ) { + string oname = !owner.empty() ? owner : string(""); + m_MonIntf->undeclareAll(oname); + } return DF_SUCCESS; } @@ -166,7 +170,9 @@ int DIMMonitoring::i_startMonitoring() { debug("Starting publishing monitor information using DIM...."); // setProperties(); // dis_set_debug_on(); - m_MonIntf->start(); + if ( m_MonIntf ) { + m_MonIntf->start(); + } setRunNo(m_runno); m_started = true; return DF_SUCCESS; @@ -179,8 +185,10 @@ int DIMMonitoring::i_stopMonitoring() { return DF_SUCCESS; } void DIMMonitoring::stopUpdate() { - m_MonIntf->stop(); - stopSaving(); + if ( m_MonIntf ) { + m_MonIntf->stop(); + stopSaving(); + } } int DIMMonitoring::finalize() { @@ -188,7 +196,9 @@ int DIMMonitoring::finalize() { dim_lock(); if (m_started) { m_started = false; - m_MonIntf->stop(); + if ( m_MonIntf ) { + m_MonIntf->stop(); + } } dim_unlock(); detail::deletePtr(m_MonIntf); diff --git a/Online/EventBuilding/CMakeLists.txt b/Online/EventBuilding/CMakeLists.txt index 255209d10..79e205d7c 100755 --- a/Online/EventBuilding/CMakeLists.txt +++ b/Online/EventBuilding/CMakeLists.txt @@ -17,18 +17,21 @@ gaudi_subdir(EventBuilding v0r1) # -gaudi_depends_on_subdirs(Online/DIM - Online/GauchoBase - Online/Dataflow - Online/OnlineBase - Online/PCIE40Data) +## Online/dim Online/GauchoBase Online/PCIE40Data +gaudi_depends_on_subdirs(Online/Dataflow + Online/OnlineBase) -find_path(PCIE40_DAQ_INC /usr/include/lhcb/daq40/daq40.hpp) +# Check for local PCIE40. If not present do not build event builder libraries +find_path(PCIE40_DAQ_INC NAMES "daq40.hpp" PATHS /usr/include/lhcb/daq40) if ( "${PCIE40_DAQ_INC}" STREQUAL "PCIE40_DAQ_INC-NOTFOUND" ) message(STATUS "+======================================================================+") message(STATUS "| PCIE40 DAQ not present. Will not build EventBuilding libraries. |") message(STATUS "+======================================================================+") return() +else() + message(STATUS "+======================================================================+") + message(STATUS "| PCIE40 DAQ found. EventBuilding libraries shall be built. |") + message(STATUS "+======================================================================+") endif() # fpisani fixed find of external libraries diff --git a/Online/EventBuilding/options/BU_0.opts b/Online/EventBuilding/options/BU_0.opts new file mode 100644 index 000000000..e210c041e --- /dev/null +++ b/Online/EventBuilding/options/BU_0.opts @@ -0,0 +1,3 @@ +#pragma print off +#include "$EVENTBUILDINGROOT/options/EB_BU.opts" +MEPManager.Buffers = { "Events_0" }; diff --git a/Online/EventBuilding/options/BU_1.opts b/Online/EventBuilding/options/BU_1.opts new file mode 100644 index 000000000..c0b8d80a4 --- /dev/null +++ b/Online/EventBuilding/options/BU_1.opts @@ -0,0 +1,3 @@ +#pragma print off +#include "$EVENTBUILDINGROOT/options/EB_BU.opts" +MEPManager.Buffers = { "Events_1" }; diff --git a/Online/EventBuilding/options/EB_BU.opts b/Online/EventBuilding/options/EB_BU.opts old mode 100644 new mode 100755 index 205d7a315..1f72a15c4 --- a/Online/EventBuilding/options/EB_BU.opts +++ b/Online/EventBuilding/options/EB_BU.opts @@ -1,11 +1,10 @@ -#pragma print on +#pragma print off #include "$INFO_OPTIONS" #include "$MBM_SETUP_OPTIONS" -#include "$EVENTBUILDINGROOT/options/Logging.opts" -#include "$EVENTBUILDINGROOT/options/Monitoring.opts" +#include "$FARMCONFIG_OPTIONS/Logging.opts" +#include "$FARMCONFIG_OPTIONS/Monitoring.opts" #include "$EVENTBUILDINGROOT/options/EB_transport.opts" - Manager.Services = { //"Dataflow_MBMClient/MEPManager", "EB_BU/BU", @@ -15,12 +14,7 @@ Manager.Services = { Manager.Runable = "Wrap"; Wrap.Callable = "BU"; // algorithm properties -// BU.bu_rank = 4; -// BU.buffer_type = 0; -// BU.MBM_name = @OnlineEnv.Input_Buffer; -// BU.buffer_size = 1073741824; -BU.out_file_prefix = "rand_size_BU"; -// BU.write_to_file = false; +#include "$EVENTBUILDINGROOT/options/EB_BU_algo.opts" // properties of the Transport_unit class set them from the EB_transport.opts file BU.RUs_per_nic = @EB_transport.RUs_per_nic; diff --git a/Online/EventBuilding/options/EB_BU_1.opts b/Online/EventBuilding/options/EB_BU_1.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/EB_BU_algo.opts b/Online/EventBuilding/options/EB_BU_algo.opts new file mode 100755 index 000000000..4f407d2f0 --- /dev/null +++ b/Online/EventBuilding/options/EB_BU_algo.opts @@ -0,0 +1,7 @@ +BU.MBM_name = {}; +BU.buffer_size = {}; +BU.buffer_type = {}; +BU.out_file_prefix = ""; +BU.shmem_prefix = ""; +BU.stop_timeout = 0; +BU.write_to_file = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }; diff --git a/Online/EventBuilding/options/EB_RU.opts b/Online/EventBuilding/options/EB_RU.opts old mode 100644 new mode 100755 index 443d3cf75..7a9ef1729 --- a/Online/EventBuilding/options/EB_RU.opts +++ b/Online/EventBuilding/options/EB_RU.opts @@ -1,7 +1,8 @@ -#pragma print on +#pragma print off #include "$INFO_OPTIONS" #include "$EVENTBUILDINGROOT/options/EB_transport.opts" -#include "$EVENTBUILDINGROOT/options/Logging.opts" +#include "$FARMCONFIG_OPTIONS/Monitoring.opts" +#include "$FARMCONFIG_OPTIONS/Logging.opts" Manager.Services = {"EB_RU/RU", "Dataflow_RunableWrapper/Wrap" @@ -9,14 +10,7 @@ Manager.Services = {"EB_RU/RU", Manager.Runable = "Wrap"; Wrap.Callable = "RU"; // algorithm properties -RU.buffer_type = {}; -RU.PCIe40_ids = {}; -RU.MDF_filename = "/home/fpisani/public/eb_test_file.mdf"; -RU.n_MFPs = 100; -RU.n_fragment = 3000; -RU.MPI_errors_return = true; -RU.PCIe40_timeout = 5; -RU.shmem_prefix = "$SHMEM_PREFIX"; +#include "$EVENTBUILDINGROOT/options/EB_RU_algo.opts" // properties of the Transport_unit class set them from the EB_transport.opts file RU.RUs_per_nic = @EB_transport.RUs_per_nic; diff --git a/Online/EventBuilding/options/EB_RU_1.opts b/Online/EventBuilding/options/EB_RU_1.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/EB_RU_algo.opts b/Online/EventBuilding/options/EB_RU_algo.opts new file mode 100755 index 000000000..3b6f57e29 --- /dev/null +++ b/Online/EventBuilding/options/EB_RU_algo.opts @@ -0,0 +1,10 @@ +RU.MDF_filename = "/home/fpisani/mc_data/biger_file.mdf"; +RU.PCIe40_ids = {}; +RU.PCIe40_names = { 'tdtel022_0', 'tdtel022_1', 'tdtel042_0', 'tdtel042_1', 'tdtel051_1', 'tdtel052_0', 'tdtel052_1', 'tdtel053_0', 'tdtel053_1' }; +RU.PCIe40_timeout = 30; +RU.buffer_sizes = {}; +RU.buffer_type = { 3, 3, 3, 3, 3, 3 }; +RU.n_MFPs = 100; +RU.n_fragment = 3000; +RU.shmem_prefix = "$SHMEM_PREFIX"; +RU.stop_timeout = 0; diff --git a/Online/EventBuilding/options/EB_Transport_properties.opts b/Online/EventBuilding/options/EB_Transport_properties.opts new file mode 100755 index 000000000..85150ab08 --- /dev/null +++ b/Online/EventBuilding/options/EB_Transport_properties.opts @@ -0,0 +1,8 @@ +EB_transport.BU_ranks = {}; +EB_transport.MPI_errors_return = FALSE; +EB_transport.RU_ranks = {}; +EB_transport.RUs_per_nic = {}; +EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.t25565.json"; +EB_transport.n_par_mess = 0; +EB_transport.n_sources_per_ru = { 1, 1, 1, 1, 3, 2 }; +EB_transport.src_ids = {}; diff --git a/Online/EventBuilding/options/EB_transport.opts b/Online/EventBuilding/options/EB_transport.opts old mode 100644 new mode 100755 index 9731e2514..e2980fc46 --- a/Online/EventBuilding/options/EB_transport.opts +++ b/Online/EventBuilding/options/EB_transport.opts @@ -1,11 +1,5 @@ -#pragma print on -#include "$INFO_OPTIONS" -#include "$EVENTBUILDINGROOT/options/Logging.opts" - // EB transport_unit properties -EB_transport.RUs_per_nic = {}; -EB_transport.n_par_mess = 3; -EB_transport.n_sources_per_ru = {3,3,3,3,3,3,3,3,3,3}; +#include "$EVENTBUILDINGROOT/options/EB_Transport_properties.opts" EB_transport.MPI_errors_return = true; EB_transport.OutputLevel = 3; @@ -14,4 +8,4 @@ EB_transport.src_ids = {}; EB_transport.RU_ranks = {}; EB_transport.BU_ranks = {}; EB_transport.ghost_nodes_topology = {}; -EB_transport.ib_config_file = "/home/aperro/Online/hosts.json"; +//EB_transport.ib_config_file = "/home/aperro/Online/hosts.json"; diff --git a/Online/EventBuilding/options/Logging.opts b/Online/EventBuilding/options/Logging.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/MBMSetup.opts b/Online/EventBuilding/options/MBMSetup.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/MBM_server.opts b/Online/EventBuilding/options/MBM_server.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/MEPInit.opts b/Online/EventBuilding/options/MEPInit.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/MFP_generator.opts b/Online/EventBuilding/options/MFP_generator.opts old mode 100644 new mode 100755 index a9b83ce19..5dd523382 --- a/Online/EventBuilding/options/MFP_generator.opts +++ b/Online/EventBuilding/options/MFP_generator.opts @@ -1,17 +1,11 @@ #pragma print on #include "$INFO_OPTIONS" #include "$EVENTBUILDINGROOT/options/EB_transport.opts" -#include "$EVENTBUILDINGROOT/options/Logging.opts" +#include "$FARMCONFIG_OPTIONS/Logging.opts" Manager.Services = {"MFP_generator/MFP_generator", "Dataflow_RunableWrapper/Wrap" }; Manager.Runable = "Wrap"; Wrap.Callable = "MFP_generator"; -MFP_generator.shmem_name = "$SHMEM_NAME"; -MFP_generator.OutputLevel = 3; -MFP_generator.event_rate = 30e7; -MFP_generator.n_banks = 30000; -MFP_generator.bank_size = 100; -MFP_generator.random_sizes = false; -MFP_generator.reconnect = false; +#include "$EVENTBUILDINGROOT/options/MFP_generator_params.opts" diff --git a/Online/EventBuilding/options/MFP_generator_params.opts b/Online/EventBuilding/options/MFP_generator_params.opts new file mode 100755 index 000000000..3f133088e --- /dev/null +++ b/Online/EventBuilding/options/MFP_generator_params.opts @@ -0,0 +1,7 @@ +MFP_generator.OutputLevel = 3; +MFP_generator.bank_size = 100; +MFP_generator.event_rate = 300000000; +MFP_generator.n_banks = 30000; +MFP_generator.random_sizes = FALSE; +MFP_generator.reconnect = FALSE; +MFP_generator.shmem_name = "$SHMEM_NAME"; diff --git a/Online/EventBuilding/options/OnlineEnv.opts b/Online/EventBuilding/options/OnlineEnv.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/events_dispatch/BU_dummy.opts b/Online/EventBuilding/options/events_dispatch/BU_dummy.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/events_dispatch/FU.opts b/Online/EventBuilding/options/events_dispatch/FU.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/events_dispatch/MBMSetup_Input.opts b/Online/EventBuilding/options/events_dispatch/MBMSetup_Input.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/events_dispatch/MBMSetup_Input_2.opts b/Online/EventBuilding/options/events_dispatch/MBMSetup_Input_2.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/events_dispatch/MBM_reader_dummy.opts b/Online/EventBuilding/options/events_dispatch/MBM_reader_dummy.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/events_dispatch/MEPInit_Input.opts b/Online/EventBuilding/options/events_dispatch/MEPInit_Input.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/events_dispatch/MEPInit_Input_2.opts b/Online/EventBuilding/options/events_dispatch/MEPInit_Input_2.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/events_dispatch/MU.opts b/Online/EventBuilding/options/events_dispatch/MU.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/events_dispatch/OU.opts b/Online/EventBuilding/options/events_dispatch/OU.opts old mode 100644 new mode 100755 diff --git a/Online/EventBuilding/options/hosts_example.json b/Online/EventBuilding/options/hosts_example.json old mode 100644 new mode 100755 diff --git a/Online/FarmConfig/job/BU.sh b/Online/FarmConfig/job/BU.sh index beca57daf..d16ee5834 100755 --- a/Online/FarmConfig/job/BU.sh +++ b/Online/FarmConfig/job/BU.sh @@ -9,4 +9,7 @@ # # ========================================================================= # -exec -a ${UTGID} ${DATAFLOW_task} -class=Class1 -opts=../../EventBuilding/options/EB_BU.opts $(AUTO_STARTUP} ${DEBUG_STARTUP} +eval `python -c "import os;s=os.environ['UTGID'];print 'export BU_OPTIONS='+s[s.find('BU'):]+'.opts'"`; +# +exec -a ${UTGID} ${DATAFLOW_task} -class=Class1 -opts=../../EventBuilding/options/${BU_OPTIONS} \ + ${AUTO_STARTUP} ${DEBUG_STARTUP}; diff --git a/Online/FarmConfig/job/Controller.sh b/Online/FarmConfig/job/Controller.sh index ca86cf369..da768bfa6 100755 --- a/Online/FarmConfig/job/Controller.sh +++ b/Online/FarmConfig/job/Controller.sh @@ -37,7 +37,7 @@ if test -z "${DIM_DNS_NODE}"; then fi; # exec -a ${UTGID} `which gentest.exe` libSmiController.so smi_controller \ - -print=1 \ + -print=3 \ -logger=fifo \ -part=${PARTITION_NAME} \ -dns=${DIM_DNS_NODE} \ diff --git a/Online/FarmConfig/job/RU.sh b/Online/FarmConfig/job/RU.sh index c44774a95..cb15638ba 100755 --- a/Online/FarmConfig/job/RU.sh +++ b/Online/FarmConfig/job/RU.sh @@ -9,4 +9,4 @@ # # ========================================================================= # -exec -a ${UTGID} ${DATAFLOW_task} -class=Class1 -opts=../../EventBuilding/options/EB_RU.opts $(AUTO_STARTUP} ${DEBUG_STARTUP} +exec -a ${UTGID} ${DATAFLOW_task} -class=Class1 -opts=../../EventBuilding/options/EB_RU.opts ${AUTO_STARTUP} ${DEBUG_STARTUP} diff --git a/Online/FarmConfig/job/preamble.sh b/Online/FarmConfig/job/preamble.sh index aaf1ae7b5..c199d1077 100755 --- a/Online/FarmConfig/job/preamble.sh +++ b/Online/FarmConfig/job/preamble.sh @@ -9,7 +9,12 @@ export Class0_task="$gaudi_task -tasktype=LHCb::Class0Task " export Class1_task="$gaudi_task -tasktype=LHCb::Class1Task -main=$OPTS/Main.opts " export Class2_task="$gaudi_task -tasktype=LHCb::Class2Task -main=$OPTS/Main.opts " export Checkpoint_task="GaudiCheckpoint.exe libGaudiOnline.so OnlineTask -msgsvc=$msg_svc -tasktype=LHCb::Class1Task -main=$OPTS/Main.opts " -export DATAFLOW_task="gentest.exe libDataflow.so dataflow_run_task -msg=Dataflow_FmcLogger -mon=Dataflow_DIMMonitoring"; +# +if test -p "${LOGFIFO}"; then + export DATAFLOW_task="gentest.exe libDataflow.so dataflow_run_task -msg=fifo -mon=Dataflow_DIMMonitoring"; +else + export DATAFLOW_task="gentest.exe libDataflow.so dataflow_run_task -msg=Dataflow_FmcLogger -mon=Dataflow_DIMMonitoring"; +fi; # # # diff --git a/Online/FarmConfig/job/runTask.sh b/Online/FarmConfig/job/runTask.sh index a0f94c0ef..c095c52ee 100755 --- a/Online/FarmConfig/job/runTask.sh +++ b/Online/FarmConfig/job/runTask.sh @@ -26,11 +26,7 @@ cd $FARMCONFIGROOT/job; export SUBFARM=`echo ${DIM_DNS_NODE} | tr a-z A-Z`; export STATIC_OPTS=${FARMCONFIGROOT}/options; export NON_DYNAMIC_OPTS=/group/online/dataflow/options/${PARTITION_NAME}; -if test "${SUBFARM}" != "CALD07"; then - export DYNAMIC_OPTS=/run/options/${PARTITION_NAME}; -else - export DYNAMIC_OPTS=${NON_DYNAMIC_OPTS}; -fi; +export DYNAMIC_OPTS=/group/online/dataflow/options/${PARTITION_NAME}; if test -z "${DATAINTERFACE}"; then DATAINTERFACE=`python /group/online/dataflow/scripts/getDataInterface.py`; fi; @@ -39,14 +35,12 @@ export ONLINETASKS=/group/online/dataflow/templates; export INFO_OPTIONS=${DYNAMIC_OPTS}/${PARTITION_NAME}_Info.opts; export STORAGE_INFO_OPTIONS=${DYNAMIC_OPTS}/StorageEnv.opts; export SUBFARM_OPTIONS=${DYNAMIC_OPTS}/${PARTITION_NAME}_${SUBFARM}_HLT.opts; -##echo "[ERROR] SUBFARM_OPTIONS=${DYNAMIC_OPTS}/${PARTITION_NAME}_${DIM_DNS_NODE}_HLT.opts"; +# +# echo "[ERROR] INFO_OPTIONS=${INFO_OPTIONS}"; +# echo "[ERROR] SUBFARM_OPTIONS=${DYNAMIC_OPTS}/${PARTITION_NAME}_${DIM_DNS_NODE}_HLT.opts"; # . ./preamble.sh; # -# Test setup: -##if test "${PARTITION_NAME}" = "LHCb"; then -## export LD_LIBRARY_PATH=/home/frankm/cmtuser/OnlineDev_v6r5/InstallArea/${CMTCONFIG}/lib:${LD_LIBRARY_PATH}; -##fi; if test -f ./${TASK_TYPE}.sh; then # echo "RunTask: TASK_TYPE: ${TASK_TYPE} ./${TASK_TYPE}.sh" diff --git a/Online/FarmConfig/options/EBMBM.opts b/Online/FarmConfig/options/EBMBM.opts index 2ce8dabe5..6297f8c50 100644 --- a/Online/FarmConfig/options/EBMBM.opts +++ b/Online/FarmConfig/options/EBMBM.opts @@ -1,2 +1,9 @@ -#include "$FARMCONFIG_OPTIONS/MEPInit.opts" -MEPManager.InitFlags = "-s=200000 -e=500 -u=20 -b=17 -f -i=Events_0 -c -s=200000 -e=500 -u=20 -b=17 -f -i=Events_1 -c"; +#pragma print off +#include "$INFO_OPTIONS" +#include "$MBM_SETUP_OPTIONS" +#include "$FARMCONFIG_OPTIONS/Logging.opts" +Manager.Setup = {"Dataflow_MBMServer/MEPManager"}; +Manager.Services = {"Dataflow_UI/UI"}; +MEPManager.PartitionBuffers = @OnlineEnv.PartitionBuffers; +MEPManager.PartitionName = @OnlineEnv.PartitionName; +MEPManager.InitFlags = "-s=1000000 -e=20 -u=30 -b=12 -t=2 -f -i=Events_0 -c -s=1000000 -e=20 -u=30 -b=12 -f -i=Events_1 -c"; diff --git a/Online/SmiController/src/smi_controller.cpp b/Online/SmiController/src/smi_controller.cpp index 5f29a317c..6bf1b7af8 100644 --- a/Online/SmiController/src/smi_controller.cpp +++ b/Online/SmiController/src/smi_controller.cpp @@ -26,6 +26,7 @@ #include <cerrno> #include <climits> #include <unistd.h> +#include <sys/stat.h> using namespace std; using namespace FiniteStateMachine; @@ -89,27 +90,40 @@ extern "C" int smi_controller(int argc, char** argv) { auto logger = std::make_shared<RTL::Logger::LogDevice>(); RTL::CLI cli(argc, argv, help_ctrl); string logger_type = "term"; + char log_path[PATH_MAX]; int secs_sleep=0; bool dbg = false; - char log_path[PATH_MAX]; - ssize_t len = ::readlink("/proc/self/fd/1", log_path, sizeof(log_path)); - if ( -1 == len ) { - ::strerror_r(errno, log_path, sizeof(log_path)); - ::fprintf(stderr, "Failed to determine stdout file name. [%s]\n", log_path); - return EINVAL; + if ( ::getenv("LOGFIFO") ) { + struct stat stat; + string path = ::getenv("LOGFIFO"); + if ( 0 == ::stat(path.c_str(), &stat) ) { + if ( S_ISFIFO(stat.st_mode) ) { + config.stderr_file = path; + config.stdout_file = path; + } + } } - log_path[len] = 0; - config.stdout_file = log_path; - - len = ::readlink("/proc/self/fd/2", log_path, sizeof(log_path)); - if ( -1 == len ) { - ::strerror_r(errno, log_path, sizeof(log_path)); - ::fprintf(stderr, "Failed to determine stderr file name. [%s]\n", log_path); - return EINVAL; + + if ( config.stderr_file.empty() || config.stdout_file.empty() ) { + ssize_t len = ::readlink("/proc/self/fd/1", log_path, sizeof(log_path)); + if ( -1 == len ) { + ::strerror_r(errno, log_path, sizeof(log_path)); + ::fprintf(stderr, "Failed to determine stdout file name. [%s]\n", log_path); + return EINVAL; + } + log_path[len] = 0; + config.stdout_file = log_path; + + len = ::readlink("/proc/self/fd/2", log_path, sizeof(log_path)); + if ( -1 == len ) { + ::strerror_r(errno, log_path, sizeof(log_path)); + ::fprintf(stderr, "Failed to determine stderr file name. [%s]\n", log_path); + return EINVAL; + } + log_path[len] = 0; + config.stderr_file = log_path; } - log_path[len] = 0; - config.stderr_file = log_path; config.name = RTL::processName(); config.dns = ::getenv("DIM_DNS_NODE") ? ::getenv("DIM_DNS_NODE") : ""; diff --git a/Online/Storage/src/server/fdb_db_server.cpp b/Online/Storage/src/server/fdb_db_server.cpp index 67c94adc7..512d4128e 100644 --- a/Online/Storage/src/server/fdb_db_server.cpp +++ b/Online/Storage/src/server/fdb_db_server.cpp @@ -29,7 +29,7 @@ public: using namespace std; using namespace Online::storage; -static const std::string PATTERN_NEXT = "/next?prefix="; +static const string PATTERN_NEXT = "/next?prefix="; template <> http::HttpRequestHandler::continue_action http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t& rep) { @@ -51,8 +51,7 @@ http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t rep = reply_t::stock_reply(reply_t::not_found); if ( !error_code_ok(ec) ) { - header_t h(http::constants::error_cause, - "Failed to get "+req.uri+" ["+ec.message()+"]"); + header_t h(http::constants::error_cause,"Failed to get "+req.uri+" ["+ec.message()+"]"); ::lib_rtl_output(LIB_RTL_ERROR,"DELETE: %s %-20s = %s", reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); @@ -191,8 +190,9 @@ http::basic_http_server<db>::handler_t::handle_request(const request_t& req, rep if ( 0 == rep.bytes_sent ) { auto ret = this->HttpRequestHandler::handle_request(req, rep); if ( this->debug > 0 || !(rep.status == reply_t::temp_redirect || rep.status == reply_t::ok) ) { + string status = reply_t::stock_status(rep.status); ::lib_rtl_output(LIB_RTL_INFO,"basic_http_server<db>::handle: Serving %s %s status: %d [%s]", - req.method.c_str(), req.uri.c_str(), rep.status, reply_t::stock_status(rep.status)); + req.method.c_str(), req.uri.c_str(), rep.status, status.c_str()); for ( const auto& h : rep.headers ) ::lib_rtl_output(LIB_RTL_INFO,"basic_http_server<db>::handle: %-20s = %s", h.name.c_str(), h.value.c_str()); -- GitLab From dce3e3ae302bc513d2d42d44f60a07fab4528ebb Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Tue, 9 Mar 2021 17:52:52 +0100 Subject: [PATCH 04/17] Simplify options handling --- Online/EventBuilding/src/BU.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Online/EventBuilding/src/BU.cpp b/Online/EventBuilding/src/BU.cpp index 81a1b4ef8..61be24ba5 100644 --- a/Online/EventBuilding/src/BU.cpp +++ b/Online/EventBuilding/src/BU.cpp @@ -185,6 +185,11 @@ int EB::BU::check_buffer() logger.warning << __FUNCTION__ << " no buffer types provided setting to default value " << EB::default_BU_buffer_type << std::flush; } + else if (_buffer_type.size() == 1) { + _buffer_type.resize(_bu_ranks.size(), _buffer_type[0]); + logger.warning << __FUNCTION__ << " Single buffer type provided: " + << _buffer_type[0] << std::flush; + } if (_buffer_type.size() != _bu_ranks.size()) { logger.error << __FUNCTION__ << " Configuration error: not enough buffer types provided " << _buffer_type.size() @@ -198,6 +203,11 @@ int EB::BU::check_buffer() logger.warning << __FUNCTION__ << " no buffer sizes provided setting to default value " << EB::default_BU_buffer_size << std::flush; } + else if (_buffer_sizes.size() == 1) { + _buffer_sizes.resize(_bu_ranks.size(), _buffer_sizes[0]); + logger.warning << __FUNCTION__ << " Single buffer size provided: " + << _buffer_sizes[0] << std::flush; + } if (_buffer_sizes.size() != _bu_ranks.size()) { logger.error << __FUNCTION__ << " Configuration error: not enough buffer sizes provided " << _buffer_sizes.size() @@ -224,6 +234,11 @@ int EB::BU::check_buffer() logger.warning << __FUNCTION__ << " no MBM names provided setting to default value " << EB::default_MBM_name << std::flush; } + else if (_mbm_name.size() == 1) { + _mbm_name.resize(_bu_ranks.size(), _mbm_name[0]); + logger.warning << __FUNCTION__ << " single MBM name provided: " << _mbm_name[0] + << std::flush; + } if (_mbm_name.size() != _bu_ranks.size()) { logger.error << __FUNCTION__ << " Configuration error: not enough MBM names provided " << _mbm_name.size() << "/" -- GitLab From de652d8bda36f53b2b2d58f6ef92f74f944bddd5 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Mon, 15 Mar 2021 10:27:22 +0100 Subject: [PATCH 05/17] Fix storage library and servers --- Online/Dataflow/Dataflow/DiskReader.h | 14 +- Online/Dataflow/options/StorageReader.opts | 34 ++ Online/Dataflow/options/StorageWriter.opts | 2 +- Online/Dataflow/src/Storage/StorageReader.cpp | 42 ++- Online/Dataflow/src/Storage/StorageWriter.cpp | 46 ++- Online/Dataflow/src/Storage/StorageWriter.h | 10 +- Online/Dataflow/src/framework/DiskReader.cpp | 295 ++++++++++++------ Online/GaudiOnline/scripts/readDatafile | 1 + Online/GaudiOnline/src/EventAccess.cpp | 10 +- Online/GaudiOnline/src/MBMEventAccess.cpp | 52 +-- .../GaudiOnlineTests/options/CreateMEP.opts | 2 +- .../scripts/go_test_CreateMEP.sh | 4 +- .../tests/refs/go_create_mep.ref | 2 +- .../tests/refs/go_create_tae.ref | 2 +- Online/HTTP/HTTP/HttpServer.h | 2 + Online/HTTP/src/HttpServer.cpp | 68 ++-- Online/OnlineBase/src/LOG/FifoLog.cpp | 16 +- Online/PCIE40Data/PCIE40Data/RawBank40.h | 4 +- Online/PCIE40Data/PCIE40Data/pcie40.h | 5 +- .../scripts/TestStorageReader.sh | 14 + Online/Storage/Storage/client.h | 4 +- Online/Storage/Storage/client_async.h | 2 +- Online/Storage/Storage/client_sync.h | 2 +- Online/Storage/Storage/communication.h | 2 +- Online/Storage/Storage/fdb_client.h | 18 +- Online/Storage/Storage/fdb_server.h | 7 +- Online/Storage/src/client/client.cpp | 4 +- Online/Storage/src/client/client_async.cpp | 9 +- Online/Storage/src/client/client_sync.cpp | 9 +- Online/Storage/src/client/communication.cpp | 12 +- Online/Storage/src/client/fdb_client.cpp | 31 +- Online/Storage/src/server/fdb_SQLite.cpp | 44 ++- Online/Storage/src/server/fdb_SQLite_bind.cpp | 2 - Online/Storage/src/server/fdb_db_server.cpp | 23 +- Online/Storage/src/server/fdb_fs_server.cpp | 111 ++++--- Online/Storage/src/server/sqlite_test.cpp | 11 +- Online/Storage/tests/src/Setup.cpp | 4 +- Online/Storage/tests/src/Setup.h | 1 + Online/Storage/tests/src/fdb_cli.cpp | 36 ++- Online/Storage/tests/src/fdb_client_test.cpp | 4 +- Online/Tell1Data/Tell1Data/EventHeader.h | 81 +++-- Online/Tell1Data/Tell1Data/RawFile.h | 3 +- Online/Tell1Data/src/RawFile.cpp | 25 +- Online/Tell1Data/src/Tell1Decoder.cpp | 4 +- 44 files changed, 704 insertions(+), 370 deletions(-) create mode 100644 Online/Dataflow/options/StorageReader.opts create mode 100755 Online/SmiController/scripts/TestStorageReader.sh diff --git a/Online/Dataflow/Dataflow/DiskReader.h b/Online/Dataflow/Dataflow/DiskReader.h index 65c99017f..4da4be04c 100644 --- a/Online/Dataflow/Dataflow/DiskReader.h +++ b/Online/Dataflow/Dataflow/DiskReader.h @@ -228,16 +228,22 @@ namespace Online { /// Update run number service void updateRunNumber(int new_run); /// Wait until event buffers are empty before finishing.... - virtual void waitForPendingEvents(int seconds); + virtual void waitForPendingEvents(int seconds); + /// Patch the string array with allowed runs + virtual void checkAllowedRuns(); struct LoadResult { size_t length; int packing; RawFile::EventType type; }; - LoadResult load_data_in_mbm(RawFile::Allocator& allocator, RawFile& file); - int declare_mbm_data(MBM::BufferInfo* info, RawFile& file); - int handle_mbm_request(MBM::BufferInfo* info, RawFile& file); + + /// Load event data from file into the buffer manager + virtual LoadResult load_event_data(RawFile::Allocator& allocator, RawFile& file); + /// Declare event frame to the buffer manager to trigger clients + virtual int declare_mbm_data(MBM::BufferInfo* info, const char* fname, const LoadResult& load); + /// Handle MBM request: load event data and declare to MBM + virtual int handle_mbm_request(MBM::BufferInfo* info, RawFile& file); void save_file_rest(RawFile& file); diff --git a/Online/Dataflow/options/StorageReader.opts b/Online/Dataflow/options/StorageReader.opts new file mode 100644 index 000000000..1ab0bcc91 --- /dev/null +++ b/Online/Dataflow/options/StorageReader.opts @@ -0,0 +1,34 @@ +#pragma print off +#include "$INFO_OPTIONS" +#include "$MBM_SETUP_OPTIONS" +#include "$FARMCONFIGROOT/options/Logging.opts" +#include "$FARMCONFIGROOT/options/Monitoring.opts" +Manager.Services = {"Dataflow_MBMClient/MBM", + "Dataflow_StorageReader/Reader", + "Dataflow_RunableWrapper/Wrap" + }; +Manager.Runable = "Wrap"; +Wrap.Callable = "Reader"; + +Reader.Directories = {"/daqarea/lhcb/data/2016/RAW/FULL/LHCb/COLLISION16/188171"}; +Reader.AllowedRuns = {"0"}; +Reader.DeleteFiles = false; +Reader.SaveRest = false; +Reader.FilePrefix = ""; +Reader.PauseSleep = 1; +Reader.InitialSleep = 1; +Reader.MaxPauseWait = 1; +Reader.RequireConsumers = 0; +Reader.PackingFactor = 1000; +Reader.Buffer = "Events"; +Reader.Server = "XXEB09.lbdaq.cern.ch:8000"; +Reader.Mount = "/objects/data/testing"; + +MBM.PartitionBuffers = @OnlineEnv.PartitionBuffers; +MBM.PartitionName = @OnlineEnv.PartitionName; +MBM.PartitionID = @OnlineEnv.PartitionID; +MBM.Buffers = {"Events"}; + +#include "../options/Monitoring.opts" +Logger.OutputLevel = @OnlineEnv.OutputLevel; +// Logger.OutputLevel = 0; diff --git a/Online/Dataflow/options/StorageWriter.opts b/Online/Dataflow/options/StorageWriter.opts index b48a52f45..cd7003a10 100644 --- a/Online/Dataflow/options/StorageWriter.opts +++ b/Online/Dataflow/options/StorageWriter.opts @@ -28,7 +28,7 @@ Manager.Algorithms = {"Dataflow_StorageWriter/Writer"}; Writer.Server = "XXEB09.lbdaq.cern.ch:8000"; Writer.Mount = "/objects/data/testing"; Writer.FileSizeMB = 800; -Writer.FileSizeMB = 100; +Writer.FileSizeMB = 40; Writer.MinFileSizeMB = 10; Writer.WriteErrorRetry = 100000; Writer.WriteErrorSleep = 3000; diff --git a/Online/Dataflow/src/Storage/StorageReader.cpp b/Online/Dataflow/src/Storage/StorageReader.cpp index 20ab4eb82..8fa94d4ba 100644 --- a/Online/Dataflow/src/Storage/StorageReader.cpp +++ b/Online/Dataflow/src/Storage/StorageReader.cpp @@ -41,14 +41,21 @@ namespace Online { protected: friend class MBMAllocator; std::string m_server; + std::string m_mount; + /// Property: Debug FDB client + int m_debugClient; /// Runable implementation : Run the class implementation virtual int i_run() override; + /// Patch the string array with allowed runs + virtual void checkAllowedRuns() override {} public: /// Standard algorithm constructor StorageReader(const std::string& nam, Context& ctxt); - + /// Default destructor + virtual ~StorageReader() = default; + /// Callback to open new storage file int openFile(int& runno, std::vector<unsigned char>& buffer, RawFile& input); }; } // End namespace Online @@ -87,7 +94,9 @@ DECLARE_DATAFLOW_NAMED_COMPONENT_NS(Online,Dataflow_StorageReader,StorageReader) StorageReader::StorageReader(const string& nam, Context& ctxt) : DiskReader(nam, ctxt) { - declareProperty("Server", m_server); + declareProperty("Server", m_server); + declareProperty("Mount", m_mount = "/objects"); + declareProperty("DebugClient", m_debugClient = 0); } int StorageReader::openFile(int& runno, std::vector<unsigned char>& buffer, RawFile& input) { @@ -100,14 +109,26 @@ int StorageReader::openFile(int& runno, std::vector<unsigned char>& buffer, RawF runno = -1; input.reset(); buffer.clear(); - client.fdbclient = client::create<client::sync>(url.host, url.port, 10000); + client.fdbclient = client::create<client::sync>(url.host, url.port, 10000, m_debugClient); client.create_client = std::function(client::create<client::sync>); for(const auto& run : m_allowedRuns ) { - string obj = "/objects/Run_"+run; - auto reply = client.next_object_delete(obj, date, length); + char fname[PATH_MAX]; + const char* crun = run.c_str(); + const char* cmnt = m_mount.c_str(); + const char* pref = m_filePrefix.c_str(); + if ( run[0] == '*' ) + ::snprintf(fname, sizeof(fname), "%s/%s", cmnt, pref); + else if ( !::isdigit(run[0]) ) + ::snprintf(fname, sizeof(fname), "%s/%s%s", cmnt, pref, crun); + else if ( ::isdigit(crun[0]) ) { + long runno = ::strtol(crun, 0, 10); + ::snprintf(fname, sizeof(fname), "%s/%s%010ld", cmnt, pref, runno); + } + + auto reply = client.next_object_delete(fname, date, length); if ( reply.status == reply.ok ) { buffer = move(reply.content); - input.map(&buffer.at(0), buffer.size()); + input.map_memory(&buffer.at(0), buffer.size()); runno = ::atol(run.c_str()); return DF_SUCCESS; } @@ -135,7 +156,11 @@ int StorageReader::i_run() { ::lib_rtl_sleep(100); continue; } - while ( m_receiveEvts && GO_PROCESS == m_goValue ) { + else if ( !m_receiveEvts ) { + break; + } + while ( (m_receiveEvts && GO_PROCESS == m_goValue) || + (0 != current_input.data_size()) ) { if ( m_muDelay > 0 ) { ::usleep(m_muDelay); } @@ -181,9 +206,10 @@ int StorageReader::i_run() { } } } - current_input.reset(); + current_input.reset(true); // Bad file: Cannot read input (m_eventsIN==0) updateRunNumber(0); + } /// Before actually declaring PAUSED, we wait until no events are pending anymore. waitForPendingEvents(m_maxPauseWait); diff --git a/Online/Dataflow/src/Storage/StorageWriter.cpp b/Online/Dataflow/src/Storage/StorageWriter.cpp index 33b056d44..c8b61a392 100644 --- a/Online/Dataflow/src/Storage/StorageWriter.cpp +++ b/Online/Dataflow/src/Storage/StorageWriter.cpp @@ -53,6 +53,7 @@ StorageWriter::StorageWriter(const string& nam, Context& ctxt) declareProperty("NumThreads", m_num_threads = 1); declareProperty("MinFileSizeMB", m_minFileSizeMB = 3000); declareProperty("ForceMDF", m_force_mdf = 0); + declareProperty("DebugClient", m_debugClient = 0); } /// Default destructor @@ -67,7 +68,8 @@ int StorageWriter::initialize() { m_bufferSize *= 1024*1024; m_curr_run = 0; m_cancelled = 0; - // m_client.fdbclient = storage::client::create<storage::client::sync>(url.host, url.port, 10000); + // m_client.fdbclient = + // storage::client::create<storage::client::sync>(url.host, url.port, 10000, m_debugClient); // m_client.create_client = std::function(storage::client::create<storage::client::sync>); for(Buffer& b : m_free) ::free(b.buffer); @@ -167,7 +169,7 @@ StorageWriter::Buffer& StorageWriter::get_buffer() { void StorageWriter::flush_buffer(Buffer& buff) { if ( buff.buffer != nullptr ) { lock_guard<mutex> bufferLock(m_mutex); - m_todo.push_back(buff); + m_todo.emplace_back(buff); buff = {nullptr, nullptr}; } buff = m_shutdown ? Buffer() : get_buffer(); @@ -214,20 +216,22 @@ int StorageWriter::save_buffer(Buffer& buff, const void* data, long length) { int StorageWriter::save_pcie40_as_mdf(Buffer& buff, const uint8_t* start, long len) { auto* mep_start = (pcie40::mep_header_t*)start; auto* mep_end = pcie40::add_ptr<pcie40::mep_header_t>(start, len); - std::unique_ptr<pcie40::event_collection_t> ev; pcie40::decoder_t decoder; long nev = 0; for(const pcie40::mep_header_t *m, *mep = mep_start; mep < mep_end; ) { if ( mep->is_valid() ) { const pcie40::multi_fragment_t *mfp = mep->multi_fragment(0); + std::unique_ptr<pcie40::event_collection_t> ev; uint16_t packing = mfp->header.packing; nev += packing; decoder.decode(ev, mep); /// Save the events one by one to the buffer for( auto* e=ev->begin(); e != ev->end(); e=ev->next(e) ) { - size_t length = e->total_length(); - int sc = ensure_buffer(buff, length); + uint32_t hdrvsn = 3; + size_t hdrlen = EventHeader::sizeOf(hdrvsn); + size_t length = e->total_length(); + int sc = ensure_buffer(buff, length + hdrlen); if ( sc == DF_SUCCESS ) { if ( 0 == m_curr_run ) { const auto* odin = e->bank_collection(0)->at(0); @@ -238,9 +242,28 @@ int StorageWriter::save_pcie40_as_mdf(Buffer& buff, const uint8_t* start, long l m_curr_bunch = sodin->bunch_id(); } } + const uint8_t* b_beg = buff.pointer; + EventHeader* hdr = (EventHeader*)buff.pointer; + hdr->setChecksum(0); + hdr->setCompression(0); + hdr->setHeaderVersion(hdrvsn); + hdr->setSpare(0); + hdr->setDataType(EventHeader::BODY_TYPE_BANKS); + hdr->setSubheaderLength(sizeof(EventHeader::Header1)); + hdr->setSize(length); + EventHeader::SubHeader h = hdr->subHeader(); + h.H1->setTriggerMask(~0u,~0u,~0u,~0u); + h.H1->setRunNumber(m_curr_run); + h.H1->setOrbitNumber(m_curr_orbit); + h.H1->setBunchID(m_curr_bunch); + buff.pointer += hdrlen; for( size_t i=0, n=e->num_bank_collections(); i<n; ++i) { buff.pointer = (uint8_t*)e->bank_collection(i)->copy_data(buff.pointer); } + if ( buff.pointer-b_beg != hdr->recordSize() ) { + error("++ Event length inconsistency: %ld <> %ld %ld %ld", + buff.pointer-b_beg, hdr->recordSize(), length, hdrlen); + } } } /// Move to the next MEP if any @@ -309,18 +332,19 @@ int StorageWriter::execute(const Context::EventData& event) { m_shutdown ? "Shutdown requested" : "??????????"); return status; } + /// Auto detect data type: first check for PCIE40 MEP format auto* mep_hdr = (pcie40::mep_header_t*)start; - if( mep_hdr->magic == mep_hdr->MagicPattern ) { - status = m_force_mdf + if( mep_hdr->is_valid() ) { + status = this->m_force_mdf ? save_pcie40_as_mdf(buff, start, mep_hdr->size*sizeof(uint32_t)) : save_buffer (buff, start, mep_hdr->size*sizeof(uint32_t)); return status; } + /// Auto detect data type: first check for MDF/BURST format auto* mdf_hdr = (EventHeader*)start; - if ( mdf_hdr->size0() == mdf_hdr->size1() && - mdf_hdr->size0() == mdf_hdr->size2() ) { + if ( mdf_hdr->is_mdf() ) { status = save_mdf_buffer(buff, start, len); return status; } @@ -423,8 +447,8 @@ int StorageWriter::writeBuffer(const Buffer& buff) { string url; client_t cl; storage::uri_t srv(m_server); - cl.fdbclient = storage::client::create<storage::client::sync>(srv.host, srv.port, 10000); - cl.create_client = std::function(storage::client::create<storage::client::sync>); + cl.fdbclient = + storage::client::create<storage::client::sync>(srv.host, srv.port, 10000, m_debugClient); auto reply = cl.save_object_record(fname, url, len); if ( reply.status == reply.temp_redirect ) { /// OK. the registration was now successful. Send the data. diff --git a/Online/Dataflow/src/Storage/StorageWriter.h b/Online/Dataflow/src/Storage/StorageWriter.h index bffe85a36..e5322a67a 100644 --- a/Online/Dataflow/src/Storage/StorageWriter.h +++ b/Online/Dataflow/src/Storage/StorageWriter.h @@ -73,12 +73,14 @@ namespace Online { /// Property: Number of retries when write connection fails int m_write_error_retry; /// Property: Poll timeout to detect transfer buffers [microseconds] - int m_poll_tmo {100}; + int m_poll_tmo {100}; /// Property: Cancel timeout to empty pending buffers - int m_cancel_tmo {100}; + int m_cancel_tmo {100}; /// Property: Force output in MDF format - int m_force_mdf {0}; - + int m_force_mdf {0}; + /// Property: Debug FDB client + int m_debugClient {0}; + /// Buffer handling thread std::vector<thread_t> m_threads; /// Mutex to lock the event buffer when filling/saving diff --git a/Online/Dataflow/src/framework/DiskReader.cpp b/Online/Dataflow/src/framework/DiskReader.cpp index cd12af3ad..cb1295159 100644 --- a/Online/Dataflow/src/framework/DiskReader.cpp +++ b/Online/Dataflow/src/framework/DiskReader.cpp @@ -16,21 +16,22 @@ //========================================================================== // Framework includes -#include "Dataflow/DiskReader.h" -#include "Dataflow/DataflowTask.h" -#include "Dataflow/ControlPlug.h" -#include "Dataflow/MBMClient.h" -#include "Dataflow/Incidents.h" -#include "Dataflow/Plugins.h" -#include "Tell1Data/Tell1Decoder.h" -#include "RTL/rtl.h" -#include "RTL/readdir.h" +#include <Dataflow/DiskReader.h> +#include <Dataflow/DataflowTask.h> +#include <Dataflow/ControlPlug.h> +#include <Dataflow/MBMClient.h> +#include <Dataflow/Incidents.h> +#include <Dataflow/Plugins.h> +#include <Tell1Data/Tell1Decoder.h> +#include <PCIE40Data/pcie40.h> +#include <RTL/rtl.h> +#include <RTL/readdir.h> #include <fcntl.h> #include <cerrno> #include <cstring> #include <sstream> -#include "dim/dic.h" -#include "dim/dis.h" +#include <dim/dic.h> +#include <dim/dis.h> #ifdef _WIN32 #include <io.h> #else @@ -199,17 +200,7 @@ int DiskReader::initialize() { m_mbmInfo[nam] = &m_mbmInfos[i]; m_mbmInfos[i].attach(bm_name.c_str()); } - // Patch the string array with allowed runs - for(size_t i=0; i<m_allowedRuns.size(); ++i) { - const char* crun = m_allowedRuns[i].c_str(); - if ( ::isdigit(crun[0]) && crun[0] != '*' ) { - char text[PATH_MAX]; - long runno = ::strtol(crun,0,10); - ::snprintf(text,sizeof(text),"%s%07ld_",m_filePrefix.c_str(),runno); - m_allowedRuns[i] = text; - info("Add run %s to allowed run-list.",m_allowedRuns[i].c_str()); - } - } + checkAllowedRuns(); return sc; } @@ -328,6 +319,21 @@ int DiskReader::cancel() { return DF_SUCCESS; } + +/// Patch the string array with allowed runs +void DiskReader::checkAllowedRuns() { + for(size_t i=0; i<m_allowedRuns.size(); ++i) { + const char* crun = m_allowedRuns[i].c_str(); + if ( ::isdigit(crun[0]) && crun[0] != '*' ) { + char text[PATH_MAX]; + long runno = ::strtol(crun,0,10); + ::snprintf(text,sizeof(text),"%s%07ld_",m_filePrefix.c_str(),runno); + m_allowedRuns[i] = text; + info("Add run %s to allowed run-list.",m_allowedRuns[i].c_str()); + } + } +} + void DiskReader::waitForPendingEvents(int seconds) { size_t count; do { @@ -411,58 +417,151 @@ void DiskReader::updateRunNumber(int new_run) { void DiskReader::save_file_rest(RawFile& file) { if ( file.isOpen() ) { if ( m_deleteFiles && m_saveRest ) file.saveRestOfFile(); - file.reset(); + file.reset(true); } } +/// Load event data from file into the buffer manager DiskReader::LoadResult -DiskReader::load_data_in_mbm(RawFile::Allocator& allocator, RawFile& file) { - off_t file_position = file.position(); - RawFile::EventType type_found; - RawFile::EventType type_in = RawFile::EventType(m_inputType); - int packing_factor = -1; - long length = 0; - if ( m_packingFactor == 1 ) { - length = file.read_event(type_in, type_found, allocator, 0); - packing_factor = 1; - } - else { - unsigned char* data = allocator(m_preAllocSize); - length = 0; - if ( data ) { - auto ret = file.read_multiple_events(m_packingFactor, type_in, - type_found, data, m_preAllocSize); - length = ret.first > 0 ? ret.second : 0; - packing_factor = ret.first; - } - } - if ( length < 0 ) { - file.reset(); +DiskReader::load_event_data(RawFile::Allocator& allocator, RawFile& file) { + int size[3]; + uint8_t *data_ptr, *alloc_ptr; + off_t position = file.position(); + static constexpr int peek = int(3*sizeof(int)); + int status = file.read(size, peek); + + if ( status < peek ) { + file.reset(true); return {0, -1, RawFile::NO_INPUT_TYPE}; } - else if ( length == 0 ) { // MBM Error - // Set back the file position to the beginning of the event and continue. - // If there was a cancel in between, the file shall be saved. - file.position(file_position); - return {0, -1, RawFile::NO_INPUT_TYPE}; + // + // Auto detect data type: first check for PCIE40 MEP format + auto* mep_hdr = (pcie40::mep_header_t*)size; + if ( mep_hdr->magic == mep_hdr->MagicPattern ) { + int data_size = mep_hdr->size*sizeof(uint32_t); + data_ptr = allocator(data_size); + ::memcpy(data_ptr, size, peek); + status = file.read(data_ptr+peek, data_size-peek); + if ( status < int(data_size-peek) ) { + file.reset(true); + return {0, -1, RawFile::NO_INPUT_TYPE}; + } + return {size_t(data_size), 1, RawFile::MEP_INPUT_TYPE}; + } + // + // Now check for MDF format: 3 times same size + auto* mdf_hdr = (EventHeader*)size; + if ( mdf_hdr->is_mdf() ) { + int num_evts = 1; + int data_size = size[0]; + int alloc_size = m_packingFactor == 1 ? mdf_hdr->recordSize() : m_preAllocSize; + + if ( data_size > alloc_size ) { + file.position(position); + return {0, -1, RawFile::NO_INPUT_TYPE}; + } + alloc_ptr = data_ptr = allocator(alloc_size); + ::memcpy(data_ptr, mdf_hdr, peek); + status = file.read(data_ptr + peek, mdf_hdr->recordSize() - peek); + if ( status < mdf_hdr->recordSize() - peek ) { + file.reset(true); + return {0, -1, RawFile::NO_INPUT_TYPE}; + } + data_ptr += size[0]; + for ( ; num_evts < m_packingFactor; ) { + if ( peek + data_size > alloc_size ) { + file.reset(true); + return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; + } + position = file.position(); + status = file.read(data_ptr, peek); + if ( status < peek ) { + file.reset(true); + return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; + } + mep_hdr = (pcie40::mep_header_t*)size; + if ( mep_hdr->magic == mep_hdr->MagicPattern ) { + file.position(position); + return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; + } + mdf_hdr = (EventHeader*)data_ptr; + if ( mdf_hdr->recordSize() + data_size > alloc_size ) { + file.position(position); + return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; + } + status = file.read(data_ptr + peek, mdf_hdr->recordSize() - peek); + if ( status < mdf_hdr->recordSize() - peek ) { + file.reset(true); + return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; + } + data_size += mdf_hdr->recordSize(); + data_ptr += mdf_hdr->recordSize(); + ++num_evts; + } + return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; } - return {size_t(length), packing_factor, type_found}; + // + // Now the only thing left is Tell1 MEP format + { + static int id = -1; + int data_size = sizeof(MEPEVENT)+sizeof(Tell1MEP)+size[0]; + MEPEVENT* e = (MEPEVENT*)(alloc_ptr=allocator(data_size)); + Tell1MEP* me = (Tell1MEP*)e->data; + me->setSize(size[0]); + e->refCount = 1; + e->evID = ++id; + e->begin = 0; + e->packing = -1; + e->valid = 1; + e->magic = mep_magic_pattern(); + for (size_t j = 0; j < MEP_MAX_PACKING; ++j) { + e->events[j].begin = 0; + e->events[j].evID = 0; + e->events[j].status = EVENT_TYPE_OK; + e->events[j].signal = 0; + } + data_ptr = (unsigned char*)me->start(); + ::memcpy(data_ptr, size+1, 2*sizeof(size[0])); + status = file.read(data_ptr + 2*sizeof(size[0]), me->size() - 2*sizeof(int)); + if ( status < int(me->size() - 2*sizeof(int)) ) { // End-of file, continue with next file + file.reset(true); + return {0, -1, RawFile::NO_INPUT_TYPE}; + } + data_ptr += me->size(); + return {size_t(data_ptr-alloc_ptr), 1, RawFile::MEP_INPUT_TYPE}; + } + // + // Last chance: we have a corrrupted MDF record. Try to sweep to the next MDF frame + long skip = file.scanToNextMDF(); + if ( skip > 0 ) { // Just move on to next record! + warning("Corrupted file found: %s at position %ld. " + "Skip %ld bytes after sweep to next MDF record.", + file.cname(), position, skip); + return this->load_event_data(allocator, file); + } + error("Corrupted file found: %s at position %ld. Skip rest of file!", + file.cname(), position); + file.reset(true); + return {0, -1, RawFile::NO_INPUT_TYPE}; } -int DiskReader::declare_mbm_data(MBM::BufferInfo* mbm_info, RawFile& file) { - int status, partid = context.mbm->partitionID(); - MBM::EventDesc& dsc = m_producer->event(); +/// Declare event frame to the buffer manager to trigger clients +int DiskReader::declare_mbm_data(MBM::BufferInfo* mbm_info, const char* fname, const LoadResult& load) { + int pid = context.mbm->partitionID(); + MBM::EventDesc& dsc = this->m_producer->event(); EventHeader* hdr = (EventHeader*)dsc.data; - if ( hdr->size0() == hdr->size1() && hdr->size0() == hdr->size2() ) { + + dsc.len = load.length; + if ( hdr->is_mdf() ) { // If the first bank is a MDF header, we copy the real trigger mask - ::memcpy(dsc.mask,&hdr->subHeader().H1->triggerMask()[0],sizeof(dsc.mask)); context.manager.setRunNumber(hdr->subHeader().H1->runNumber()); - dsc.type = (m_packingFactor == 1) ? EVENT_TYPE_EVENT : EVENT_TYPE_BURST; + ::memcpy(dsc.mask, &hdr->subHeader().H1->triggerMask()[0], sizeof(dsc.mask)); + dsc.type = (load.packing == 1 && m_packingFactor) ? EVENT_TYPE_EVENT : EVENT_TYPE_BURST; } else { // If MEP, we emulate a trigger mask with the partition ID dsc.type = EVENT_TYPE_MEP; - dsc.mask[0] = partid; + dsc.mask[0] = pid; dsc.mask[1] = ~0x0; dsc.mask[2] = ~0x0; dsc.mask[3] = ~0x0; @@ -471,30 +570,32 @@ int DiskReader::declare_mbm_data(MBM::BufferInfo* mbm_info, RawFile& file) { // This should be a rare case, since there ARE (were?) consumers. // Though: In this case the event is really lost! // But what can I do... - int cons_wait = waitForConsumers(mbm_info); + int cons_wait = this->waitForConsumers(mbm_info); if ( cons_wait != DF_SUCCESS ) { - error("No consumers (partition:%d event type:%d) present", partid, dsc.type); - error("Save rest of file and finish. Skipping rest of file: %s", file.cname()); + error("No consumers (partition:%d event type:%d) present", pid, dsc.type); + error("Save rest of file and finish. Skipping rest of file: %s", fname); // If we did not see an MDF header, the file may also be corrupted: if ( dsc.type == EVENT_TYPE_MEP ) { - error("If Moores are alive, this file may be corrupted: %s", file.cname()); + error("If Moores are alive, this file may be corrupted: %s", fname); } return DF_ERROR; } + debug("++ Declared MBM data %p -> %p [%ld bytes]", dsc.data, ((char*)dsc.data)+dsc.len, dsc.len); + int status = MBM_ERROR; { lock_guard<mutex> lck(m_prodLock); // // Declare the event to the buffer manager // try { - status = m_producer->declareEvent(); + status = this->m_producer->declareEvent(); } catch (const exception& e) { - info("Exception while delareEvent: %s File:%s.", e.what(), file.cname()); + info("Exception while delareEvent: %s File:%s.", e.what(), fname); status = MBM_ERROR; } catch(...) { - info("UNKNOWN Exception while delareEvent: File:%s.", file.cname()); + info("UNKNOWN Exception while delareEvent: File:%s.", fname); status = MBM_ERROR; } if (status != MBM_NORMAL) { @@ -504,14 +605,14 @@ int DiskReader::declare_mbm_data(MBM::BufferInfo* mbm_info, RawFile& file) { // Now send space // try { - status = m_producer->sendSpace(); + status = this->m_producer->sendSpace(); } catch (const exception& e) { - info("Exception while sendSpace: %s File:%s.", e.what(), file.cname()); + info("Exception while sendSpace: %s File:%s.", e.what(), fname); status = MBM_ERROR; } catch(...) { - info("UNKNOWN Exception while sendSpace: File:%s.", file.cname()); + info("UNKNOWN Exception while sendSpace: File:%s.", fname); status = MBM_ERROR; } } @@ -521,45 +622,41 @@ int DiskReader::declare_mbm_data(MBM::BufferInfo* mbm_info, RawFile& file) { return DF_SUCCESS; } +/// Handle MBM request: load event data and declare to MBM int DiskReader::handle_mbm_request(MBM::BufferInfo* mbmInfo, RawFile& input) { - MBMAllocator allocator(this); - MBM::EventDesc& dsc = m_producer->event(); - off_t file_pos = input.position(); - auto load = load_data_in_mbm(allocator, input); - auto type_found = load.type; - auto packing = load.packing; - dsc.len = load.length; - if ( packing <= 0 && m_reuse_file ) { - debug("Re-use input file: %s",input.cname()); - input.seek(0, SEEK_SET); - return DF_CONTINUE;; - } - else if ( packing <= 0 ) { - input.reset(); + MBMAllocator allocator(this); + off_t pos = input.position(); + auto load = this->load_event_data(allocator, input); + + if ( load.packing <= 0 ) { + ( m_reuse_file ) ? input.seek(0, SEEK_SET) : input.reset(true); return DF_CONTINUE; } - m_eventsIN += packing; - m_inputType = type_found; + m_eventsIN += load.packing; + m_inputType = load.type; + + int status = this->declare_mbm_data(mbmInfo, input.cname(), load); + switch( status ) { + case DF_CONTINUE: + return DF_CONTINUE; - int status = declare_mbm_data(mbmInfo, input); - if ( status == DF_SUCCESS ) { - m_eventsOUT += packing; - m_evtCountFile += packing; + case DF_SUCCESS: + m_eventsOUT += load.packing; + m_evtCountFile += load.packing; // If we have exceeded the total number of events per file, close it! - if ( m_max_events_per_file>0 && m_evtCountFile>m_max_events_per_file ) { - input.reset(); - } + if ( m_max_events_per_file > 0 && m_evtCountFile > m_max_events_per_file ) + input.reset(true); return DF_SUCCESS; - } - else if ( status == DF_CONTINUE ) { - return DF_CONTINUE;; - } - else if ( status == DF_ERROR ) { - input.position(file_pos); - save_file_rest(input); + + case DF_ERROR: + input.position(pos); + this->save_file_rest(input); /// Before actually declaring ERROR, we wait until no events are pending anymore. - waitForPendingEvents(m_maxConsWait); + this->waitForPendingEvents(m_maxConsWait); return DF_ERROR; + + default: + break; } return DF_SUCCESS; } diff --git a/Online/GaudiOnline/scripts/readDatafile b/Online/GaudiOnline/scripts/readDatafile index 334910292..af1eb9f7d 100755 --- a/Online/GaudiOnline/scripts/readDatafile +++ b/Online/GaudiOnline/scripts/readDatafile @@ -9,6 +9,7 @@ import GaudiOnline GaudiOnline.readDatafile(['${1}']) END-OF-OPTS # +# gdb --args `which python` `which gaudirun.py` /tmp/${USER}_ReadMDF.py --application=Online::OnlineEventApp rm /tmp/${USER}_ReadMDF.py; } diff --git a/Online/GaudiOnline/src/EventAccess.cpp b/Online/GaudiOnline/src/EventAccess.cpp index 7ed12c4ef..4d095c1b5 100644 --- a/Online/GaudiOnline/src/EventAccess.cpp +++ b/Online/GaudiOnline/src/EventAccess.cpp @@ -58,10 +58,12 @@ namespace { } #endif template <typename BANK_TYPE> inline bool checkBank(const BANK_TYPE* bank) { - return bank->magic() == BANK_TYPE::MagicPattern && - bank->size() >= 0 && - bank->type() >= 0 && - bank->type() < Tell1Bank::LastType; + return + // Check for Tell1 bank magic word or PCIE40 magic word + (bank->magic() == BANK_TYPE::MagicPattern || bank->magic() == 0xFACE) && + (bank->size() >= 0) && + (bank->type() >= 0) && + (bank->type() < Tell1Bank::LastType); } inline bool checkHeader(const EventHeader* header) { diff --git a/Online/GaudiOnline/src/MBMEventAccess.cpp b/Online/GaudiOnline/src/MBMEventAccess.cpp index 84ea60b74..9a1eb323d 100644 --- a/Online/GaudiOnline/src/MBMEventAccess.cpp +++ b/Online/GaudiOnline/src/MBMEventAccess.cpp @@ -147,38 +147,44 @@ int MBMEventAccess::fill_cache() { } sc = ::mbm_get_event(bmid, &ev_data, &ev_len, &ev_type, trmask, config.partitionID); if ( sc == MBM_NORMAL ) { - shared_guard_t burst; + union _data { + int* mbm; + EventHeader* tell1; + pcie40::mep_header_t* tell40; + datapointer_t pointer; + _data(int* p) { mbm = p; } + } data(ev_data); switch(ev_type) { case EVENT_TYPE_EVENT: - case EVENT_TYPE_BURST: { - auto events = make_unique<event_collection_t>(convertMultiMDF(datapointer_t(ev_data), size_t(ev_len))); - burst = make_shared<mbm_guard_t<event_collection_t> >(move(events), event_traits::tell1::data_type, this, bmid); - break; - } + case EVENT_TYPE_BURST: case EVENT_TYPE_MEP: { - auto events = convertPCIE40MEP(datapointer_t(ev_data), size_t(ev_len)); - burst = make_shared<mbm_guard_t<pcie40::event_collection_t> >(move(events), event_traits::tell40::data_type, this, bmid); + shared_guard_t burst; + if( data.tell40->is_valid() ) { + auto evts = convertPCIE40MEP(data.pointer, size_t(ev_len)); + burst = make_shared<mbm_guard_t<pcie40::event_collection_t> >(move(evts), event_traits::tell40::data_type, this, bmid); + } + else if ( data.tell1->is_mdf() ) { + auto evts = make_unique<event_collection_t>(convertMultiMDF(data.pointer, size_t(ev_len))); + burst = make_shared<mbm_guard_t<event_collection_t> >(move(evts), event_traits::tell1::data_type, this, bmid); + } + else { + m_logger->error("Execute: Cannot determine event type. Drop event buffer."); + break; + } + if ( burst.get() && !burst->empty() ) { + queueBurst(move(burst)); + printInfo(); + return ONLINE_OK; + } + m_logger->error("MBM: Empty burst encountered."); break; } default: m_logger->error("MBM: Unknown MBM event type: %d", ev_type); - ::mbm_free_event(bmid); - requeueConsumer(bmid); - { - lock_t lock(m_burstLock); - ++monitor.burstsRelease; - } - return ONLINE_OK; - } - if ( !burst->empty() ) { - queueBurst(move(burst)); - printInfo(); - return ONLINE_OK; + break; } - m_logger->error("MBM: Empty burst encountered."); ::mbm_free_event(bmid); - requeueConsumer(bmid); - { + requeueConsumer(bmid); { lock_t lock(m_burstLock); ++monitor.burstsRelease; } diff --git a/Online/GaudiOnlineTests/options/CreateMEP.opts b/Online/GaudiOnlineTests/options/CreateMEP.opts index 74dd191a2..493752455 100755 --- a/Online/GaudiOnlineTests/options/CreateMEP.opts +++ b/Online/GaudiOnlineTests/options/CreateMEP.opts @@ -1,4 +1,4 @@ -ApplicationMgr.DLLs = { "MDF" }; +ApplicationMgr.Dlls = { "MDF" }; ApplicationMgr.SvcOptMapping += { "Gaudi::MultiFileCatalog/FileCatalog", "Gaudi::IODataManager/IODataManager" }; ApplicationMgr.TopAlg = { "Online::RawEventTestCreator/RawEventGen", "StoreExplorerAlg" }; ApplicationMgr.EvtMax = 2000; diff --git a/Online/GaudiOnlineTests/scripts/go_test_CreateMEP.sh b/Online/GaudiOnlineTests/scripts/go_test_CreateMEP.sh index 1e8f55759..8a5ad8339 100755 --- a/Online/GaudiOnlineTests/scripts/go_test_CreateMEP.sh +++ b/Online/GaudiOnlineTests/scripts/go_test_CreateMEP.sh @@ -41,4 +41,6 @@ END-OF-OPTS # cat ${opts_file}; `which gentest.exe` libGaudiKernel.so GaudiMain ${opts_file}; -rm ${opts_file}; +if test -f ${opts_file}; then + rm ${opts_file}; +fi; diff --git a/Online/GaudiOnlineTests/tests/refs/go_create_mep.ref b/Online/GaudiOnlineTests/tests/refs/go_create_mep.ref index 76529ec8c..08484b5bb 100644 --- a/Online/GaudiOnlineTests/tests/refs/go_create_mep.ref +++ b/Online/GaudiOnlineTests/tests/refs/go_create_mep.ref @@ -11,7 +11,7 @@ JobOptionsSvc INFO //GP:================================================================================ //GP: include "/tmp/CreateMEP.opts" (0,0) //GP: include "/afs/cern.ch/lhcb/software/releases/LHCB/LHCB_v26r2/DAQ/MDF/options/CreateMEP.opts" (1,10) -ApplicationMgr.DLLs = [ "MDF" ] ; //GP: (1,1) +ApplicationMgr.Dlls = [ "MDF" ] ; //GP: (1,1) ApplicationMgr.SvcOptMapping += [ "Gaudi::MultiFileCatalog/FileCatalog" , "Gaudi::IODataManager/IODataManager" ] ;//GP: (1,1) ApplicationMgr.TopAlg = [ "LHCb::RawEventTestCreator/RawEventGen" , "StoreExplorerAlg" ] ;//GP: (1,1) ApplicationMgr.EvtMax = 2000; //GP: (1,1) diff --git a/Online/GaudiOnlineTests/tests/refs/go_create_tae.ref b/Online/GaudiOnlineTests/tests/refs/go_create_tae.ref index 1b37663fd..0d2b59e26 100644 --- a/Online/GaudiOnlineTests/tests/refs/go_create_tae.ref +++ b/Online/GaudiOnlineTests/tests/refs/go_create_tae.ref @@ -12,7 +12,7 @@ JobOptionsSvc INFO //GP:================================================================================ //GP: include "/tmp/CreateMEP.opts" (0,0) //GP: include "/afs/cern.ch/lhcb/software/releases/LHCB/LHCB_v26r2/DAQ/MDF/options/CreateMEP.opts" (1,10) -ApplicationMgr.DLLs = [ "MDF" ] ; //GP: (1,1) +ApplicationMgr.Dlls = [ "MDF" ] ; //GP: (1,1) ApplicationMgr.SvcOptMapping += [ "Gaudi::MultiFileCatalog/FileCatalog" , "Gaudi::IODataManager/IODataManager" ] ;//GP: (1,1) ApplicationMgr.TopAlg = [ "LHCb::RawEventTestCreator/RawEventGen" , "StoreExplorerAlg" ] ;//GP: (1,1) ApplicationMgr.EvtMax = 2000; //GP: (1,1) diff --git a/Online/HTTP/HTTP/HttpServer.h b/Online/HTTP/HTTP/HttpServer.h index 4bca6d92a..196877edf 100644 --- a/Online/HTTP/HTTP/HttpServer.h +++ b/Online/HTTP/HTTP/HttpServer.h @@ -343,6 +343,8 @@ namespace http { virtual continue_action handle_update(const HttpRequest& req, HttpReply& rep); /// Handle a request and produce a reply. virtual continue_action handle_request(const HttpRequest& req, HttpReply& rep); + /// Handle possible statistics summaries. + virtual void handle_stat(const HttpRequest& req, HttpReply& rep); }; /// Basic HTTP server interface implementation diff --git a/Online/HTTP/src/HttpServer.cpp b/Online/HTTP/src/HttpServer.cpp index 366d5e97c..cb5bdd316 100644 --- a/Online/HTTP/src/HttpServer.cpp +++ b/Online/HTTP/src/HttpServer.cpp @@ -96,6 +96,10 @@ void HttpConnection::stop() { if ( ec ) { std::cout << "HttpConnection: STOP: " << ec.message() << std::endl << std::flush; } + auto now = system_clock::now(); + request.netio += std::chrono::duration_cast<milliseconds>(now-request.start); + request.start = now; + handler.handle_stat(request, reply); } if ( handler.debug ) { std::cout << "HttpConnection: STOP." << std::endl << std::flush; @@ -137,7 +141,22 @@ void HttpConnection::do_next(int next_action) { do_write(); } else if ( next_action == HttpRequestHandler::close ) { + // We do not shurdown immediately. + // When the connection gets closed by the client, + // shutdown will be Invoked automatically. do_shutdown(); + auto self(shared_from_this()); + socket.async_read_some(asio::buffer(buffer), + [this, self](system::error_code ec, std::size_t bytes) { + if ( handler.debug ) { + std::cout << "HttpConnection: do_write: STOP " + << bytes << " bytes. error code[" + << ec.value() << "]: " << ec.message().c_str() + << std::endl << std::flush; + } + manager.stop(shared_from_this()); + if ( self.get() ) {} + }); } else { do_shutdown(); @@ -147,8 +166,8 @@ void HttpConnection::do_next(int next_action) { /// Perform an graceful shutdown of the connection void HttpConnection::do_shutdown() { system::error_code ignored_ec; - //socket.shutdown(asio::ip::tcp::socket::shutdown_send,ignored_ec); - socket.shutdown(asio::ip::tcp::socket::shutdown_both,ignored_ec); + socket.shutdown(asio::ip::tcp::socket::shutdown_send,ignored_ec); + //socket.shutdown(asio::ip::tcp::socket::shutdown_both,ignored_ec); if ( handler.debug ) { std::cout << "HttpConnection: SHUTDOWN." << std::endl << std::flush; } @@ -330,32 +349,25 @@ void HttpConnection::do_write() { next = handler.handle_request(request, reply); now = system_clock::now(); request.handling += std::chrono::duration_cast<milliseconds>(now-request.start); - request.start = now; + request.start = now; do_next(next); } - if ( ec != asio::error::operation_aborted ) { - switch(next) { - case HttpRequestHandler::read: - return; - case HttpRequestHandler::write: - return; - default: - // We know that the transaction is over. Trigger an additional receive - // which will fail, but which is used to close the connection. - socket.async_read_some(asio::buffer(buffer), - [this, self](system::error_code ec, std::size_t bytes) { - if ( handler.debug ) { - std::cout << "HttpConnection: do_write: STOP " - << bytes << " bytes. error code[" - << ec.value() << "]: " << ec.message().c_str() - << std::endl << std::flush; - } - manager.stop(shared_from_this()); - if ( self.get() ) {} - }); - if ( self.get() ) {} - return; - } + else /* if ( ec != asio::error::operation_aborted ) */ { + // We know that the transaction is over. Trigger an additional receive + // which will fail, but which is used to close the connection. + socket.async_read_some(asio::buffer(buffer), + [this, self](system::error_code ec, std::size_t bytes) { + if ( handler.debug ) { + std::cout << "HttpConnection: do_write: STOP " + << bytes << " bytes. error code[" + << ec.value() << "]: " << ec.message().c_str() + << std::endl << std::flush; + } + manager.stop(shared_from_this()); + if ( self.get() ) {} + }); + if ( self.get() ) {} + return; } }); } @@ -679,6 +691,10 @@ HttpRequestHandler::handle_update(const HttpRequest& /* req */, HttpReply& rep) return write; } +/// Handle possible statistics summaries. +void HttpRequestHandler::handle_stat(const HttpRequest& /* req */, HttpReply& /* rep */) { +} + /// Handle a request and produce a reply. HttpRequestHandler::continue_action HttpRequestHandler::handle_request(const HttpRequest& req, HttpReply& rep) { diff --git a/Online/OnlineBase/src/LOG/FifoLog.cpp b/Online/OnlineBase/src/LOG/FifoLog.cpp index 511eb0f33..b58b7279c 100644 --- a/Online/OnlineBase/src/LOG/FifoLog.cpp +++ b/Online/OnlineBase/src/LOG/FifoLog.cpp @@ -335,15 +335,17 @@ void Logger::Implementation::read_data(int fd, string& data) { /// Poll data from stdout/stderr pipes void Logger::Implementation::poll() { while ( 1 ) { - struct epoll_event ep[2]; - int nc = ::epoll_wait(this->epoll_fd, ep, sizeof(ep)/sizeof(ep[0]), 100); + struct epoll_event ep; + int nc = ::epoll_wait(this->epoll_fd, &ep, 1, 100); if ( nc > 0 ) { for( int i=0; i < nc; ++i ) { - if ( ep[i].events&EPOLLIN ) { - if ( ep[i].data.fd == this->stdout_fd[0] ) - this->read_data(this->stdout_fd[0], this->stdout_buffer); - else if ( ep[i].data.fd == this->stderr_fd[0] ) - this->read_data(this->stderr_fd[0], this->stderr_buffer); + if ( ep.events&EPOLLIN ) { + if ( ep.data.fd == this->stdout_fd[0] ) + this->read_data(ep.data.fd, this->stdout_buffer); + else if ( ep.data.fd == this->stderr_fd[0] ) + this->read_data(ep.data.fd, this->stderr_buffer); + else + this->read_data(ep.data.fd, this->stdout_buffer); } } } diff --git a/Online/PCIE40Data/PCIE40Data/RawBank40.h b/Online/PCIE40Data/PCIE40Data/RawBank40.h index 17f0d49f1..78d20aaf3 100644 --- a/Online/PCIE40Data/PCIE40Data/RawBank40.h +++ b/Online/PCIE40Data/PCIE40Data/RawBank40.h @@ -167,9 +167,9 @@ namespace Online { } /// Header size - int hdrSize() const + static int hdrSize() { - return sizeof(RawBank40) - sizeof(m_data); + return sizeof(RawBank40) - sizeof(RawBank40::m_data); } /// Return size of the data body part of the bank diff --git a/Online/PCIE40Data/PCIE40Data/pcie40.h b/Online/PCIE40Data/PCIE40Data/pcie40.h index 3cb69695d..0eaaa1dab 100644 --- a/Online/PCIE40Data/PCIE40Data/pcie40.h +++ b/Online/PCIE40Data/PCIE40Data/pcie40.h @@ -195,7 +195,7 @@ namespace Online { public: static constexpr uint16_t MagicPattern = 0xCEFA; /// Magic Word (0xCEFA) - uint16_t magic {MagicPattern}; + uint16_t magic {MagicPattern}; /// Number of Sources (PCIe40s) uint16_t num_source {0}; /// Length of the MEP (without Header) @@ -541,14 +541,13 @@ namespace Online { inline void* bank_collection_t::copy_data(void* ptr) const { unsigned char* p = (unsigned char*)ptr; + size_t len = bank_t::hdrSize(); for( const auto* b=this->begin(); b != this->end(); b=this->next(b) ) { - size_t len = b->hdrSize(); ::memcpy(p, b, len); ::memcpy(p + len, b->data(), b->totalSize()-len); p += b->totalSize(); } for( const auto* b=this->special_begin(); b != this->special_end(); b=this->next(b) ) { - size_t len = b->hdrSize(); ::memcpy(p, b, len); ::memcpy(p + len, b->data(), b->totalSize()-len); p += b->totalSize(); diff --git a/Online/SmiController/scripts/TestStorageReader.sh b/Online/SmiController/scripts/TestStorageReader.sh new file mode 100755 index 000000000..a12662bb2 --- /dev/null +++ b/Online/SmiController/scripts/TestStorageReader.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# ========================================================================= +# +# Generic farm task startup script +# +# Author M.Frank +# Version: 1.0 +# Date: 20/05/2013 +# +# ========================================================================= +export INFO_OPTIONS=/group/online/dataflow/options/LHCb/MONITORING/OnlineEnv.opts; +echo "ERROR `dataflow_task Class1` `dataflow_default_options ${TASK_TYPE}`"; +`dataflow_task Class1` `dataflow_default_options ${TASK_TYPE}`; + diff --git a/Online/Storage/Storage/client.h b/Online/Storage/Storage/client.h index 8a6e7750e..77518766d 100644 --- a/Online/Storage/Storage/client.h +++ b/Online/Storage/Storage/client.h @@ -52,11 +52,11 @@ namespace Online { public: /// Static constructor for concrete implementations template <typename T> - static std::unique_ptr<client> create(const std::string& host, const std::string& port, int tmo); + static std::unique_ptr<client> create(const std::string& host, const std::string& port, int tmo, int dbg); public: /// Initializing constructor - client(const std::string& host, const std::string& port, int tmo); + client(const std::string& host, const std::string& port, int tmo, int dbg); /// Default constructor client() = delete; /// NO Move constructor diff --git a/Online/Storage/Storage/client_async.h b/Online/Storage/Storage/client_async.h index 58272735e..82e3fab82 100644 --- a/Online/Storage/Storage/client_async.h +++ b/Online/Storage/Storage/client_async.h @@ -59,7 +59,7 @@ namespace Online { /// NO assignment operator client_async& operator=(const client_async& copy) = delete; /// Initializing constructor: No need to call open if this constructor is issued - client_async(const std::string& host, const std::string& port, int tmo=10000); + client_async(const std::string& host, const std::string& port, int tmo, int dbg); /// Default destructor virtual ~client_async(); diff --git a/Online/Storage/Storage/client_sync.h b/Online/Storage/Storage/client_sync.h index 01b436b26..8fe6168f7 100644 --- a/Online/Storage/Storage/client_sync.h +++ b/Online/Storage/Storage/client_sync.h @@ -59,7 +59,7 @@ namespace Online { /// NO assignment operator client_sync& operator=(const client_sync& copy) = delete; /// Initializing constructor: No need to call open if this constructor is issued - client_sync(const std::string& host, const std::string& port, int tmo=10000); + client_sync(const std::string& host, const std::string& port, int tmo, int dbg); /// Default destructor virtual ~client_sync(); diff --git a/Online/Storage/Storage/communication.h b/Online/Storage/Storage/communication.h index 046d8ecff..fb343dcd9 100644 --- a/Online/Storage/Storage/communication.h +++ b/Online/Storage/Storage/communication.h @@ -40,7 +40,7 @@ namespace Online { /// Namespace for the storage implementation namespace storage { - bool error_code_ok(const boost::system::error_code& ec); + bool error_code_ok(const boost::system::error_code& ec, bool debug=true); typedef http::Uri uri_t; typedef http::HttpConnection connection_t; diff --git a/Online/Storage/Storage/fdb_client.h b/Online/Storage/Storage/fdb_client.h index 18ad15ef9..9059d94a4 100644 --- a/Online/Storage/Storage/fdb_client.h +++ b/Online/Storage/Storage/fdb_client.h @@ -36,15 +36,16 @@ namespace Online { */ class fdb_client { public: - typedef std::unique_ptr<client>(create_t)(const std::string& host, const std::string& port, int tmo); + typedef std::unique_ptr<client>(create_t)(const std::string& host, const std::string& port, int tmo, int dbg); public: - std::function<create_t> create_client; + std::function<create_t> create_client {client::create<client::sync>}; std::unique_ptr<client> fdbclient; std::string fdbserver; int dataPort; int dataTMO {1000}; - + int debug {0}; + public: /// Default constructor fdb_client() = default; @@ -69,13 +70,16 @@ namespace Online { reply_t save_object(const std::string& location, const void* data, std::size_t length); /// Read object data from the specified location without removing disk object - reply_t get_object(const std::string& location, time_t& date, std::size_t& length); + reply_t get_object(const std::string& location, std::time_t& date, std::size_t& length); /// Read AND Delete object data from disk at the specified location - reply_t delete_object(const std::string& location, time_t& date, std::size_t& length); + reply_t delete_object(const std::string& location, std::time_t& date, std::size_t& length); /// Read object data from the specified location without removing disk object - reply_t next_object_get(const std::string& location, time_t& date, std::size_t& length); + reply_t next_object_get(const std::string& location, std::time_t& date, std::size_t& length); /// Read object data from the specified location with removing disk object - reply_t next_object_delete(const std::string& location, time_t& date, std::size_t& length); + reply_t next_object_delete(const std::string& location, std::time_t& date, std::size_t& length); + + /// Helper: Delete the specified object data from the database + reply_t db_object_delete(const std::string& prefix, std::time_t& date, std::size_t& length); }; } // End namespace storage diff --git a/Online/Storage/Storage/fdb_server.h b/Online/Storage/Storage/fdb_server.h index c6d9aa1bd..9ac1c18ff 100644 --- a/Online/Storage/Storage/fdb_server.h +++ b/Online/Storage/Storage/fdb_server.h @@ -44,7 +44,7 @@ namespace http { /// Standard constructor explicit handler_t() = default; /// Standard destructor - virtual ~handler_t() = default; + virtual ~handler_t(); /// Specific handler for GET requests virtual continue_action handle_get(const request_t& req, reply_t& rep) override { @@ -70,6 +70,11 @@ namespace http { virtual continue_action handle_request(const request_t& req, reply_t& rep) override { return this->HttpRequestHandler::handle_request(req, rep); } + /// Handle possible statistics summaries. + virtual void handle_stat(const request_t& req, reply_t& rep) override { + this->HttpRequestHandler::handle_stat(req, rep); + } + }; } diff --git a/Online/Storage/src/client/client.cpp b/Online/Storage/src/client/client.cpp index 601f830ed..70bde187e 100644 --- a/Online/Storage/src/client/client.cpp +++ b/Online/Storage/src/client/client.cpp @@ -22,8 +22,8 @@ using namespace Online::storage; /// Initializing constructor -client::client(const std::string& h, const std::string& p, int tmo) - : host(h), port(p), timeout(tmo) +client::client(const std::string& h, const std::string& p, int tmo, int dbg) + : host(h), port(p), timeout(tmo), debug(dbg) { } diff --git a/Online/Storage/src/client/client_async.cpp b/Online/Storage/src/client/client_async.cpp index 0ec1c135d..c5f4b7428 100644 --- a/Online/Storage/src/client/client_async.cpp +++ b/Online/Storage/src/client/client_async.cpp @@ -82,13 +82,14 @@ void Online::storage::client_async::io_t::close() { } template <> -std::unique_ptr<client> client::create<client::async>(const string& host, const string& port, int tmo) { - return unique_ptr<client>(new client_async(host,port,tmo)); +std::unique_ptr<client> client::create<client::async>(const string& host, const string& port, int tmo, int dbg) { + auto obj = make_unique<client_async>(host, port, tmo, dbg); + return obj; } /// Initializing constructor -client_async::client_async(const string& h, const string& p, int tmo) - : client(h,p,tmo), io(make_unique<io_t>(this)) +client_async::client_async(const string& h, const string& p, int tmo, int dbg) + : client(h, p, tmo, dbg), io(make_unique<io_t>(this)) { } diff --git a/Online/Storage/src/client/client_sync.cpp b/Online/Storage/src/client/client_sync.cpp index 7d537c582..8694145a0 100644 --- a/Online/Storage/src/client/client_sync.cpp +++ b/Online/Storage/src/client/client_sync.cpp @@ -83,13 +83,14 @@ void Online::storage::client_sync::io_t::close() { } template <> -std::unique_ptr<client> client::create<client::sync>(const string& host, const string& port, int tmo) { - return unique_ptr<client>(new client_sync(host,port,tmo)); +std::unique_ptr<client> client::create<client::sync>(const string& host, const string& port, int tmo, int dbg) { + auto obj = make_unique<client_sync>(host, port, tmo, dbg); + return obj; } /// Initializing constructor -client_sync::client_sync(const string& h, const string& p, int tmo) - : client(h,p,tmo), io(make_unique<io_t>(this)) +client_sync::client_sync(const string& h, const string& p, int tmo, int dbg) + : client(h, p, tmo, dbg), io(make_unique<io_t>(this)) { } diff --git a/Online/Storage/src/client/communication.cpp b/Online/Storage/src/client/communication.cpp index 448f10d8c..88ab8d78d 100644 --- a/Online/Storage/src/client/communication.cpp +++ b/Online/Storage/src/client/communication.cpp @@ -21,13 +21,15 @@ using namespace std; -bool Online::storage::error_code_ok(const boost::system::error_code& ec) { +bool Online::storage::error_code_ok(const boost::system::error_code& ec, bool debug) { if ( !ec ) { return true; } - std::cout << "Bad error code[" - << ec.value() << "] (" - << ec.category().name() << ") " - << ec.message() << std::endl; + if ( debug ) { + std::cout << "Bad error code[" + << ec.value() << "] (" + << ec.category().name() << ") " + << ec.message() << std::endl; + } return false; } diff --git a/Online/Storage/src/client/fdb_client.cpp b/Online/Storage/src/client/fdb_client.cpp index 34a82ed88..3067da8ef 100644 --- a/Online/Storage/src/client/fdb_client.cpp +++ b/Online/Storage/src/client/fdb_client.cpp @@ -32,8 +32,8 @@ reply_t fdb_client::get_object(const string& location, time_t& date, size_t& len for ( const auto& h : reply.headers ) { if ( h.name == http::constants::location ) { uri_t u(h.value); - unique_ptr<client> cl(create_client(u.host, u.port, dataTMO)); - if ( error_code_ok(cl->open()) ) { + unique_ptr<client> cl(create_client(u.host, u.port, dataTMO, this->debug)); + if ( error_code_ok(cl->open(), this->debug) ) { reply = cl->get(u.path); if ( reply.status == reply_t::ok ) { const header_t* hdr = reply.header(http::constants::date); @@ -63,8 +63,8 @@ reply_t fdb_client::delete_object(const string& location, time_t& date, size_t& for ( const auto& h : reply.headers ) { if ( h.name == http::constants::location ) { uri_t u(h.value); - unique_ptr<client> cl(create_client(u.host, u.port, dataTMO)); - if ( error_code_ok(cl->open()) ) { + unique_ptr<client> cl(create_client(u.host, u.port, dataTMO, this->debug)); + if ( error_code_ok(cl->open(), this->debug) ) { reply = cl->del(u.path); if ( reply.status == reply_t::ok ) { const header_t* hdr = reply.header(http::constants::date); @@ -93,8 +93,8 @@ reply_t fdb_client::next_object_get(const string& prefix, time_t& date, size_t& for ( const auto& h : reply.headers ) { if ( h.name == http::constants::location ) { uri_t u(h.value); - unique_ptr<client> cl(create_client(u.host, u.port, dataTMO)); - if ( error_code_ok(cl->open()) ) { + unique_ptr<client> cl(create_client(u.host, u.port, dataTMO, this->debug)); + if ( error_code_ok(cl->open(), this->debug) ) { reply = cl->get(u.path); if ( reply.status == reply_t::ok ) { const header_t* hdr = reply.header(http::constants::date); @@ -123,8 +123,8 @@ reply_t fdb_client::next_object_delete(const string& prefix, time_t& date, size_ for ( const auto& h : reply.headers ) { if ( h.name == http::constants::location ) { uri_t u(h.value); - unique_ptr<client> cl(create_client(u.host, u.port, dataTMO)); - if ( error_code_ok(cl->open()) ) { + unique_ptr<client> cl(create_client(u.host, u.port, dataTMO, this->debug)); + if ( error_code_ok(cl->open(), this->debug) ) { reply = cl->del(u.path); if ( reply.status == reply_t::ok ) { const header_t* hdr = reply.header(http::constants::date); @@ -142,6 +142,17 @@ reply_t fdb_client::next_object_delete(const string& prefix, time_t& date, size_ return reply; } +/// Helper: Delete the specified object data from the database +reply_t fdb_client::db_object_delete(const string& location, time_t& date, size_t& length) { + reply_t reply = fdbclient->request(http::constants::del, location); + length = 0; + date = 0; + if ( reply.status == reply_t::temp_redirect ) { + reply.status = reply_t::ok; + } + return reply; +} + /// Save object record to database and return the location to store the data reply_t fdb_client::save_object_record(const string& location, string& url, size_t len) { struct tm tim; @@ -174,8 +185,8 @@ reply_t fdb_client::save_object_data(const string& location, const void* data, s { http::constants::date, ::gmtime_r(&now, &tim) } }; uri_t u(location); - unique_ptr<client> cl(create_client(u.host, u.port, dataTMO)); - if ( error_code_ok(cl->open()) ) { + unique_ptr<client> cl(create_client(u.host, u.port, dataTMO, this->debug)); + if ( error_code_ok(cl->open(), this->debug) ) { auto reply = cl->put(u.path, data, len, hdrs); if ( reply.status == reply_t::created ) { return reply; diff --git a/Online/Storage/src/server/fdb_SQLite.cpp b/Online/Storage/src/server/fdb_SQLite.cpp index 733995260..661ac40e7 100644 --- a/Online/Storage/src/server/fdb_SQLite.cpp +++ b/Online/Storage/src/server/fdb_SQLite.cpp @@ -22,6 +22,11 @@ using namespace boost; using namespace Online::storage; +namespace { + template<typename T> inline int _prt(const T* o) { + return o->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG; + } +} system::error_code fdb_SQLite::handler_t::initialize(const std::string& db_name) { std::string err; @@ -59,12 +64,10 @@ fdb_SQLite::handler_t::query(std::string& object, access = file.access; length = ::atol(file.size.c_str()); date = file.date; - ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Query '%s'", object.c_str()); + ::lib_rtl_output(_prt(this), "Query '%s'", object.c_str()); return ec; } - ::lib_rtl_output(LIB_RTL_ALWAYS,"%s: Query: file '%s' NOT FOUND!", - this->database.name(), object.c_str()); + ::lib_rtl_output(LIB_RTL_ALWAYS,"Query: file '%s' NOT FOUND!", object.c_str()); return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); } @@ -77,20 +80,18 @@ fdb_SQLite::handler_t::next( std::string& object, File file; system::error_code ec = this->query_file(object, file, handler_t::STATE_WRITTEN); if ( ec == system::errc::success ) { - object = file.name; + object = file.name; access = file.access; - length = ::atol(file.size.c_str()); - date = file.date; + length = ::atol(file.size.c_str()); + date = file.date; ec = this->lock(file.name, handler_t::STATE_READ); if ( ec == system::errc::success ) { - ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Next '%s'", object.c_str()); + ::lib_rtl_output(_prt(this), "Next '%s'", object.c_str()); return system::error_code(system::errc::success, system::system_category()); } return system::error_code(system::errc::protocol_error, system::system_category()); } - ::lib_rtl_output(LIB_RTL_ALWAYS,"%s: Query: file '%s' NOT FOUND!", - this->database.name(), object.c_str()); + ::lib_rtl_output(LIB_RTL_ALWAYS,"Query: file '%s' NOT FOUND!", object.c_str()); return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); } @@ -109,8 +110,7 @@ system::error_code fdb_SQLite::query_object(const std::string& object, auto ec = this->engine->query(obj, access, date, length); access = this->network_file(access); if ( ec == system::errc::success ) { - ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Lookup '%s'", object.c_str()); + ::lib_rtl_output(_prt(this), "Lookup '%s'", object.c_str()); return ec; } ::lib_rtl_output(LIB_RTL_ALWAYS,"FAILED to lookup object: '%s' [%s]", @@ -128,8 +128,7 @@ system::error_code fdb_SQLite::query_next( const std::string& object, auto ec = this->engine->query(obj, access, date, length); access = this->network_file(access); if ( ec == system::errc::success ) { - ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Lookup '%s'", object.c_str()); + ::lib_rtl_output(_prt(this), "Lookup '%s'", object.c_str()); return ec; } ::lib_rtl_output(LIB_RTL_ALWAYS,"FAILED to lookup object: '%s' [%s]", @@ -146,11 +145,10 @@ system::error_code fdb_SQLite::delete_next( const std::string& object, std::string obj = object; auto ec = this->engine->next(obj, access, date, length); if ( ec == system::errc::success ) { - ec = this->engine->del(object); + ec = this->engine->del(_location_prefix+access); access = this->network_file(access); if ( ec == system::errc::success ) { - ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Lookup '%s'", object.c_str()); + ::lib_rtl_output(_prt(this), "Lookup '%s'", object.c_str()); return ec; } } @@ -168,15 +166,14 @@ system::error_code fdb_SQLite::delete_object(const std::string& object, std::string obj = object; auto ec = this->engine->query(obj, access, date, length); if ( ec == system::errc::success ) { - access = this->network_file(access); ec = this->engine->del(object); + access = this->network_file(access); if ( ec == system::errc::success ) { - ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Remove '%s'", object.c_str()); + ::lib_rtl_output(_prt(this), "Remove '%s'", object.c_str()); return ec; } } - ::lib_rtl_output(LIB_RTL_ERROR,"FAILED to remove db record: '%s' [%s]", + ::lib_rtl_output(_prt(this), "FAILED to remove: '%s' [%s]", object.c_str(), ec.message().c_str()); return ec; } @@ -203,8 +200,7 @@ fdb_SQLite::add_object(const std::string& object, std::string acc = object.substr(_location_prefix.length(), std::string::npos); auto ec = this->engine->add(object, date, length, acc); if ( ec == system::errc::success ) { - ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Add '%s' %s %s", object.c_str(), + ::lib_rtl_output(_prt(this), "Add '%s' %s %s", object.c_str(), this->debug > 1 ? "access:" : "", this->debug > 1 ? acc.c_str() : ""); access = this->network_file(acc); diff --git a/Online/Storage/src/server/fdb_SQLite_bind.cpp b/Online/Storage/src/server/fdb_SQLite_bind.cpp index e782f3d8e..bea063ef6 100644 --- a/Online/Storage/src/server/fdb_SQLite_bind.cpp +++ b/Online/Storage/src/server/fdb_SQLite_bind.cpp @@ -89,8 +89,6 @@ namespace { file.access = query_record.get<std::string>(4); return system::error_code(system::errc::success, system::system_category()); } - ::lib_rtl_output(LIB_RTL_ALWAYS,"%s: query: file %s NOT FOUND!", - this->query_record.db().name(), object_name.c_str()); return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); } diff --git a/Online/Storage/src/server/fdb_db_server.cpp b/Online/Storage/src/server/fdb_db_server.cpp index 512d4128e..5f2b63cbb 100644 --- a/Online/Storage/src/server/fdb_db_server.cpp +++ b/Online/Storage/src/server/fdb_db_server.cpp @@ -31,6 +31,12 @@ using namespace Online::storage; static const string PATTERN_NEXT = "/next?prefix="; + +/// Standard destructor +template <> http::basic_http_server<db>::handler_t::~handler_t() { +} + +/// Specific handler for GET requests template <> http::HttpRequestHandler::continue_action http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t& rep) { size_t length = 0; @@ -47,10 +53,10 @@ http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t rep = reply_t::stock_reply(reply_t::not_found); else if ( ec == boost::system::errc::permission_denied ) rep = reply_t::stock_reply(reply_t::unauthorized); - else if ( !error_code_ok(ec) ) + else if ( !error_code_ok(ec, this->debug) ) rep = reply_t::stock_reply(reply_t::not_found); - if ( !error_code_ok(ec) ) { + if ( !error_code_ok(ec, this->debug) ) { header_t h(http::constants::error_cause,"Failed to get "+req.uri+" ["+ec.message()+"]"); ::lib_rtl_output(LIB_RTL_ERROR,"DELETE: %s %-20s = %s", reply_t::stock_status(rep.status).c_str(), @@ -64,6 +70,7 @@ http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t return write; } +/// Specific handler for DELETE requests template <> http::HttpRequestHandler::continue_action http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, reply_t& rep) { size_t length = 0; @@ -72,7 +79,7 @@ http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, repl boost::system::error_code ec; { dbase_t::lock_t lock(dbase.get()); if ( get_next ) - ec = dbase->delete_next(req.uri.substr(PATTERN_NEXT.length()), access_name, date, length); + ec = dbase->delete_next(req.uri.substr(PATTERN_NEXT.length())+'%', access_name, date, length); else ec = dbase->delete_object(req.uri, access_name, date, length); } @@ -83,7 +90,7 @@ http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, repl else if ( !error_code_ok(ec) ) rep = reply_t::stock_reply(reply_t::not_found); - if ( !error_code_ok(ec) ) { + if ( !error_code_ok(ec, this->debug) ) { header_t h(http::constants::error_cause,"Failed to delete "+req.uri+" ["+ec.message()+"]"); ::lib_rtl_output(LIB_RTL_ERROR,"DELETE: %s %-20s = %s", reply_t::stock_status(rep.status).c_str(), @@ -97,6 +104,7 @@ http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, repl return write; } +/// Specific handler for PUT requests template <> http::HttpRequestHandler::continue_action http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t& rep) { const header_t *hdr_date, *hdr_len; @@ -130,7 +138,7 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t h.name.c_str(), h.value.c_str()); rep.headers.emplace_back(move(h)); } - else if ( !error_code_ok(ec) ) { + else if ( !error_code_ok(ec, this->debug) ) { header_t h(http::constants::error_cause, "Failed to add object "+req.uri+" in dbase: "+ec.message()); rep = reply_t::stock_reply(reply_t::bad_request); @@ -151,6 +159,7 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t return write; } +/// Specific handler for POST requests template <> http::HttpRequestHandler::continue_action http::basic_http_server<db>::handler_t::handle_update(const request_t& req, reply_t& rep) { const header_t *hdr_state; @@ -166,7 +175,7 @@ http::basic_http_server<db>::handler_t::handle_update(const request_t& req, repl dbase_t::lock_t lock(dbase.get()); ec = dbase->update_object_state(req.uri, hdr_state->value); } - if ( !error_code_ok(ec) ) { + if ( !error_code_ok(ec, this->debug) ) { header_t h(http::constants::error_cause, "Failed to update object "+req.uri+" in dbase: "+ec.message()); rep = reply_t::stock_reply(reply_t::bad_request); @@ -189,7 +198,7 @@ template <> http::HttpRequestHandler::continue_action http::basic_http_server<db>::handler_t::handle_request(const request_t& req, reply_t& rep) { if ( 0 == rep.bytes_sent ) { auto ret = this->HttpRequestHandler::handle_request(req, rep); - if ( this->debug > 0 || !(rep.status == reply_t::temp_redirect || rep.status == reply_t::ok) ) { + if ( this->debug > 0 ) { string status = reply_t::stock_status(rep.status); ::lib_rtl_output(LIB_RTL_INFO,"basic_http_server<db>::handle: Serving %s %s status: %d [%s]", req.method.c_str(), req.uri.c_str(), rep.status, status.c_str()); diff --git a/Online/Storage/src/server/fdb_fs_server.cpp b/Online/Storage/src/server/fdb_fs_server.cpp index c9d7d72d8..eb5a0e6b4 100644 --- a/Online/Storage/src/server/fdb_fs_server.cpp +++ b/Online/Storage/src/server/fdb_fs_server.cpp @@ -137,6 +137,11 @@ public: using namespace Online::storage; +/// Standard destructor +template <> http::basic_http_server<fs>::handler_t::~handler_t() { +} + +/// Specific handler for GET requests template <> http::HttpRequestHandler::continue_action http::basic_http_server<fs>::handler_t::handle_get(const request_t& req, reply_t& rep) { auto* ctxt = (fs_io*)rep.context.get(); @@ -164,7 +169,7 @@ http::basic_http_server<fs>::handler_t::handle_get(const request_t& req, reply_t // Now open the file, read a chunk and send it. // The rest gets sent by consecutive calls boost::system::error_code ec = ctxt->open_read(fname); - if ( !error_code_ok(ec) ) { + if ( !error_code_ok(ec, this->debug) ) { rep = reply_t::stock_reply(reply_t::not_found); rep.headers.emplace_back(constants::error_cause,"File '"+fname+"' does not exist"); } @@ -183,30 +188,35 @@ http::basic_http_server<fs>::handler_t::handle_get(const request_t& req, reply_t ctxt->st_data += rd; } else { - ::lib_rtl_output(LIB_RTL_ERROR, - "+++ %s: Failed to read data from '%s' [%s] only got %ld out of %ld bytes", + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read data '%s' [%s] only got %ld out of %ld bytes", req.method.c_str(), req.uri.c_str(), ::strerror(errno), rd, len); } if ( ctxt->st_data == ctxt->st_size ) { - ::lib_rtl_output(LIB_RTL_INFO, - "+++ %s: Prepared last chunk from '%s' total:%ld / %ld bytes", - req.method.c_str(), req.uri.c_str(), - ctxt->st_data, ctxt->st_size); + ::lib_rtl_output(LIB_RTL_INFO, "+++ %s: Prepared last chunk '%s' %.1f MB", + req.method.c_str(), req.uri.c_str(), double(ctxt->st_size)/(1024e0*1024e0)); } return write; } else if ( ctxt && ctxt->st_size == ctxt->st_data ) { + std::chrono::time_point<std::chrono::system_clock> null; + long net = std::chrono::duration_cast<std::chrono::milliseconds>(req.netio-null).count(); + long wrt = std::chrono::duration_cast<std::chrono::milliseconds>(req.handling-null).count(); + double mb = double(ctxt->st_size)/(1024e0*1024e0); + ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ %s: %ld bytes netio: %ld ms %.1f MB/s wrt: %ld ms %.1f MB/s", + req.method.c_str(), ctxt->st_size, + net, mb/std::max(1e-6, double(net)/1e3), + wrt, mb/std::max(1e-6, double(wrt)/1e3)); return none; } - ::lib_rtl_output(LIB_RTL_ERROR, - "+++ %s: Failed to read data from '%s' size:%ld / %ld %s [Inconsistemt context]", + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read data '%s' size:%ld / %ld %s [Inconsistemt context]", req.method.c_str(), req.uri.c_str(), rep.bytes_sent, rep.bytes_total, rep.stock_status(rep.status).c_str()); rep.context.reset(); return none; } +/// Specific handler for DELETE requests template <> http::HttpRequestHandler::continue_action http::basic_http_server<fs>::handler_t::handle_delete(const request_t& req, reply_t& rep) { auto* ctxt = (fs_io*)rep.context.get(); @@ -236,7 +246,7 @@ http::basic_http_server<fs>::handler_t::handle_delete(const request_t& req, repl // The rest gets sent by consecutive calls ec = ctxt->open_read(fname); - if ( !error_code_ok(ec) ) { + if ( !error_code_ok(ec, this->debug) ) { rep = reply_t::stock_reply(reply_t::not_found); rep.headers.emplace_back(constants::error_cause,"File '"+fname+"' does not exist"); } @@ -255,35 +265,39 @@ http::basic_http_server<fs>::handler_t::handle_delete(const request_t& req, repl ctxt->st_data += rd; } else { - ::lib_rtl_output(LIB_RTL_ERROR, - "+++ %s: Failed to read data from '%s' [%s] only got %ld out of %ld bytes", - req.method.c_str(), req.uri.c_str(), - ::strerror(errno), rd, len); + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read data '%s' [%s] only got %ld out of %ld bytes", + req.method.c_str(), req.uri.c_str(), ::strerror(errno), rd, len); } if ( ctxt->st_data == ctxt->st_size ) { const std::string fname = dbase->local_file(req.uri); ctxt->close(); ec = ctxt->unlink(fname.c_str()); - if ( !error_code_ok(ec) ) { + if ( !error_code_ok(ec, this->debug) ) { } - ::lib_rtl_output(LIB_RTL_INFO, - "+++ %s: Prepared last chunk from '%s' total:%ld / %ld bytes", - req.method.c_str(), req.uri.c_str(), - ctxt->st_data, ctxt->st_size); + ::lib_rtl_output(LIB_RTL_INFO, "+++ %s: Prepared last chunk '%s' %.1f MB", + req.method.c_str(), req.uri.c_str(), double(ctxt->st_size)/(1024e0*1024e0)); } return write; } else if ( ctxt && ctxt->st_size == ctxt->st_data ) { + std::chrono::time_point<std::chrono::system_clock> null; + long net = std::chrono::duration_cast<std::chrono::milliseconds>(req.netio-null).count(); + long wrt = std::chrono::duration_cast<std::chrono::milliseconds>(req.handling-null).count(); + double mb = double(ctxt->st_size)/(1024e0*1024e0); + ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ %s: %ld bytes netio: %ld ms %.1f MB/s wrt: %ld ms %.1f MB/s", + req.method.c_str(), ctxt->st_size, + net, mb/std::max(1e-6, double(net)/1e3), + wrt, mb/std::max(1e-6, double(wrt)/1e3)); return none; } - ::lib_rtl_output(LIB_RTL_ERROR, - "+++ %s: Failed to read data from '%s' size:%ld / %ld %s [Inconsistemt context]", + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read data '%s' size:%ld / %ld %s [Inconsistemt context]", req.method.c_str(), req.uri.c_str(), rep.bytes_sent, rep.bytes_total, rep.stock_status(rep.status).c_str()); rep.context.reset(); return none; } +/// Specific handler for PUT requests template <> http::HttpRequestHandler::continue_action http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t& rep) { auto* ctxt = (fs_io*)rep.context.get(); @@ -320,20 +334,22 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t if ( -1 == ::stat(dir.c_str(), &stat) ) { ret_stat = ::mkdir(dir.c_str(), 0777); if ( ret_stat != 0 ) { - char err[1024]; - ::strerror_r(errno, err, sizeof(err)); - ::lib_rtl_output(LIB_RTL_ERROR, - "+++ %s: Failed to create parent directory %s [%s]", - req.method.c_str(), dir.c_str(), err); - if ( errno == EACCES || errno == ENOENT || errno == EPERM || errno == EROFS ) - rep = reply_t::stock_reply(reply_t::unauthorized); - else - rep = reply_t::stock_reply(reply_t::bad_request); - rep.headers.emplace_back(constants::error_cause,err); - return write; + ::lib_rtl_sleep(10); + // Wait and then check if another thread created the directory + if ( -1 == ::stat(dir.c_str(), &stat) ) { + char err[1024]; + ::strerror_r(errno, err, sizeof(err)); + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to create parent directory %s [%s]", + req.method.c_str(), dir.c_str(), err); + if ( errno == EACCES || errno == ENOENT || errno == EPERM || errno == EROFS ) + rep = reply_t::stock_reply(reply_t::unauthorized); + else + rep = reply_t::stock_reply(reply_t::bad_request); + rep.headers.emplace_back(constants::error_cause,err); + return write; + } } - ::lib_rtl_output(LIB_RTL_INFO, - "+++ %s: Created parent directory %s", + ::lib_rtl_output(LIB_RTL_INFO, "+++ %s: Created parent directory %s", req.method.c_str(), dir.c_str()); } } @@ -346,17 +362,15 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t // Now open the file, read a chunk and send it. // The rest gets sent by handle_request_cont_full boost::system::error_code ec = ctxt->open_write(fname); - if ( !error_code_ok(ec) ) { + if ( !error_code_ok(ec, this->debug) ) { rep = reply_t::stock_reply(reply_t::forbidden); - rep.headers.emplace_back(constants::error_cause, - "Failed to open file "+fname+" ["+ec.message()+"]"); + rep.headers.emplace_back(constants::error_cause, "Failed to open file "+fname+" ["+ec.message()+"]"); } if ( req.content.empty() ) { return write; } // This should not happen: The client must first receive the continue! - ::lib_rtl_output(LIB_RTL_ERROR, - "+++ %s: Received non-empty data on request to write " + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Received non-empty data on request to write " "'%s' [Protocol Violation]", req.method.c_str(), fname.c_str()); //req.content.clear(); return write; @@ -370,8 +384,7 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t long wrt = ctxt->write(len, &req.content.at(0)); ctxt->st_data += wrt; if ( wrt != len ) { - ::lib_rtl_output(LIB_RTL_ERROR, - "+++ %s: Failed to write data chunk from '%s' " + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to write data chunk '%s' " "[%s] only wrote %ld out of %ld bytes", req.method.c_str(), req.uri.c_str(), ::strerror(errno), wrt, len); } @@ -386,8 +399,8 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t double mb = double(ctxt->st_size)/(1024e0*1024e0); ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ %s: Wrote data '%s' %.0f %cB", req.method.c_str(), req.uri.c_str(), mb > 10e0 ? mb : mb*1024e0, mb > 10e0 ? 'M' : 'k'); - ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ %s: netio: %ld ms %.1f MB/s wrt: %ld ms %.1f MB/s", - req.method.c_str(), + ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ %s: %ld bytes netio: %ld ms %.1f MB/s wrt: %ld ms %.1f MB/s", + req.method.c_str(), ctxt->st_size, net, mb/std::max(1e-6, double(net)/1e3), wrt, mb/std::max(1e-6, double(wrt)/1e3)); rep.context.reset(); @@ -398,8 +411,8 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t rep.headers.emplace_back(constants::content_location, req.uri); uri_t u(dbase->server); - std::unique_ptr<client> cl(client::create<client::sync>(u.host, u.port, 10000)); - if ( error_code_ok(cl->open()) ) { + std::unique_ptr<client> cl(client::create<client::sync>(u.host, u.port, 10000, this->debug)); + if ( error_code_ok(cl->open(), this->debug) ) { client::reqheaders_t hdrs { { http::constants::state, "WRITTEN" } }; @@ -409,14 +422,12 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t return write; } } - ::lib_rtl_output(LIB_RTL_ERROR, - "+++ %s: FAILED to update '%s' to state WRITTEN!", + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: FAILED to update '%s' to state WRITTEN!", req.method.c_str(), req.uri.c_str()); return write; } - ::lib_rtl_output(LIB_RTL_ERROR, - "+++ %s: Finished request handling for '%s' with %ld /%ld bytes", - req.method.c_str(), req.uri.c_str(), ctxt->st_data, ctxt->st_size); + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Finished request '%s' %ld bytes", + req.method.c_str(), req.uri.c_str(), ctxt ? ctxt->st_size : 0); /// The request is handled. Trigger the shutdown of the connection return none; } diff --git a/Online/Storage/src/server/sqlite_test.cpp b/Online/Storage/src/server/sqlite_test.cpp index 1ae89609b..3ebc8f0d4 100644 --- a/Online/Storage/src/server/sqlite_test.cpp +++ b/Online/Storage/src/server/sqlite_test.cpp @@ -21,7 +21,7 @@ gentest.exe libStorageClientTest.so sqlite_populate_database_direct -database=sq gentest.exe libStorageClientTest.so sqlite_update_database_direct -database=sqlite_test.dbase -stream=HLT1 -run=11223346 -count=100 -gentest.exe libStorageClientTest.so sqlite_read_database_direct -database=/home/frankm/storage_files.dbase +gentest.exe libStorageServer.so fdb_cli_dumpdb -database=/home/frankm/storage_files.dbase */ // Framework inclde files #include <CPP/sqlite.h> @@ -37,7 +37,7 @@ using namespace sqlite; namespace { struct Setup { - string name, database, stream, log; + string name, database, stream, log, entry; size_t count = 0; long run = 0; int prt = LIB_RTL_INFO; @@ -51,6 +51,7 @@ namespace { cli.getopt("database", 8, database); cli.getopt("stream", 5, stream); cli.getopt("count", 5, count); + cli.getopt("entry", 5, entry); cli.getopt("run", 3, run); cli.getopt("logger", 4, log); cli.getopt("print", 4, prt); @@ -257,7 +258,7 @@ extern "C" int sqlite_update_database_direct(int argc, char** argv) { } return 0; } - +// // //========================================================================== extern "C" int fdb_cli_dumpdb(int argc, char** argv) { @@ -270,9 +271,9 @@ extern "C" int fdb_cli_dumpdb(int argc, char** argv) { return 0; } }; - Setup setup("fdb_cli_delete", argc, argv, [](int,char**) { + Setup setup("fdb_cli_dumpdb", argc, argv, [](int,char**) { ::fprintf(stderr, - "fdb_cli_delete -opt [-opt] \n" + "fdb_cli_dumpdb -opt [-opt] \n" " -database=<file-path> Path to the SQLite file to dump. \n" " -help Print this help. \n"); }); diff --git a/Online/Storage/tests/src/Setup.cpp b/Online/Storage/tests/src/Setup.cpp index 4914ffbc8..187812f60 100644 --- a/Online/Storage/tests/src/Setup.cpp +++ b/Online/Storage/tests/src/Setup.cpp @@ -41,6 +41,7 @@ Setup::Setup(const std::string& n, int argc, char* argv[], void (*help)(int,char cli.getopt("file", 4, file); cli.getopt("logger", 4, log); cli.getopt("print", 4, prt); + cli.getopt("debug", 4, debug); RTL::Logger::install_fifolog(log.c_str(), RTL::Logger::log_args(prt)); ::lib_rtl_output(LIB_RTL_DEBUG,"%s: Test starting....", name.c_str()); } @@ -52,8 +53,7 @@ Setup::~Setup() { fdb_client Setup::client() { fdb_client client; uri_t url(this->server); - client.fdbclient = client::create<client::sync>(url.host, url.port, 10000); - client.create_client = std::function(client::create<client::sync>); + client.fdbclient = client::create<client::sync>(url.host, url.port, 10000, debug); return client; } diff --git a/Online/Storage/tests/src/Setup.h b/Online/Storage/tests/src/Setup.h index d7fb676f7..570063baa 100644 --- a/Online/Storage/tests/src/Setup.h +++ b/Online/Storage/tests/src/Setup.h @@ -30,6 +30,7 @@ namespace Online { std::string server, log, url, file, name, check_file; int prt = LIB_RTL_INFO; + int debug = 0; public: Setup(const std::string& n, int argc, char* argv[], void (*help)(int,char**)=nullptr); diff --git a/Online/Storage/tests/src/fdb_cli.cpp b/Online/Storage/tests/src/fdb_cli.cpp index 217ca01df..bc3fac4f1 100644 --- a/Online/Storage/tests/src/fdb_cli.cpp +++ b/Online/Storage/tests/src/fdb_cli.cpp @@ -16,7 +16,10 @@ gentest.exe libStorageCli.so fdb_test_client_get -server=${HOST}:8000 -url=/objects/data/072908_0000000072.raw -gentest.exe libStorageCli.so fdb_cli_get -server=${HOST}:8000 -url=/objects/data/072908_0000000072.raw -file=/home/frankm/data/072908_0000000072.raw +gentest.exe libStorageCli.so fdb_cli_save -server=${HOST}:8000 -url=/objects/data/072908_0000000072.raw +gentest.exe libStorageCli.so fdb_cli_put -server=${HOST}:8000 -url=/objects/data/072908_0000000072.raw + +gentest.exe libStorageCli.so fdb_cli_get -server=${HOST}:8000 -url=/objects/data/072908_0000000072.raw gentest.exe libStorageCli.so fdb_test_delete -server=${HOST}:8000 -url=/objects/data/072908_0000000072.raw -file=/home/frankm/data/072908_0000000072.raw @@ -25,6 +28,10 @@ gentest.exe libStorageCli.so fdb_test_put -server=${HOST}:8000 -url=/ob gentest.exe libStorageCli.so fdb_test_client_save -server=${HOST}:8000 -url=/objects/data/072908_0099999999.raw -file=/home/frankm/data/072908_0000000072.raw gentest.exe libStorageCli.so fdb_test_save -server=${HOST}:8000 -url=/objects/data/072908_0099999999.raw -file=/home/frankm/data/072908_0000000072.raw + +gentest.exe libStorageCli.so fdb_cli_db_delete -server=${HOST}:8000 -url=/objects/data/testing/0000000000/2021-03-10__14-34/0000000000_mon0101_14-34-53_21842.raw + + */ // Framework inclde files @@ -170,3 +177,30 @@ extern "C" int fdb_cli_delete(int argc, char** argv) { } return 0; } +// +//========================================================================== +extern "C" int fdb_cli_db_delete(int argc, char** argv) { + Setup setup("fdb_cli_db_delete",argc, argv, [](int,char**) { + ::fprintf(stderr, + "fdb_cli_db_delete -opt [-opt] \n" + " Remove entry from the database only. \n\n" + " -server=<name:port> Server access specification. \n" + " -url=<url-spec> URL of the file to resolve \n" + " -print=<level> Set print level 1=DEBUG, 5=FATAL \n" + " -help Print this help. \n"); + }); + time_t date = 0; + size_t length = 0; + auto client = setup.client(); + auto reply = client.db_object_delete(setup.url, date, length); + if ( reply.status == reply_t::ok ) { + ::lib_rtl_output(LIB_RTL_ALWAYS, "Successfully removed dbase entry: %s", + setup.url.c_str()); + } + else { + ::lib_rtl_output(LIB_RTL_ALWAYS, "FAILED to remove dbase entry: %s", + setup.url.c_str()); + setup.print(reply); + } + return 0; +} diff --git a/Online/Storage/tests/src/fdb_client_test.cpp b/Online/Storage/tests/src/fdb_client_test.cpp index 41de88ee2..e2c1c5c46 100644 --- a/Online/Storage/tests/src/fdb_client_test.cpp +++ b/Online/Storage/tests/src/fdb_client_test.cpp @@ -81,7 +81,7 @@ extern "C" int fdb_test_client_get(int argc, char** argv) { " -print=<level> Set print level 1=DEBUG, 5=FATAL\n"); }); uri_t url(setup.server); - auto client = client::create<client::sync>(url.host, url.port, 10000); + auto client = client::create<client::sync>(url.host, url.port, 10000, setup.debug); auto reply = client->get(setup.url); reply.content.push_back(0); reply.print(cout,"fdb_client_get_test: "); @@ -113,7 +113,7 @@ extern "C" int fdb_test_client_save(int argc, char** argv) { return err; } uri_t url(setup.server); - auto client = client::create<client::sync>(url.host, url.port, 10000); + auto client = client::create<client::sync>(url.host, url.port, 10000, setup.debug); client::reqheaders_t hdrs { { http::constants::content_length, stat.st_size }, { http::constants::content_type, "rawdata/lhcb" }, diff --git a/Online/Tell1Data/Tell1Data/EventHeader.h b/Online/Tell1Data/Tell1Data/EventHeader.h index 665c458b5..9f8c4273b 100644 --- a/Online/Tell1Data/Tell1Data/EventHeader.h +++ b/Online/Tell1Data/Tell1Data/EventHeader.h @@ -72,33 +72,46 @@ namespace Online { /// Spare unsigned char m_spare[1]; - struct PACKED_DATA HeaderTriggerMask { + struct PACKED_DATA HeaderTriggerMask { /// Trigger mask used for event selection unsigned int m_trMask[4]; - HeaderTriggerMask() { + HeaderTriggerMask() { m_trMask[0] = m_trMask[1] = m_trMask[2] = m_trMask[3] = 0; } + /// Accessor: Number of bits in the trigger mask - unsigned int maskBits() const { return sizeof(m_trMask)*8; } + unsigned int maskBits() const { return sizeof(m_trMask)*8; } + /// Accessor: trigger mask - std::array<unsigned int, 4> triggerMask() const { + std::array<unsigned int, 4> triggerMask() const { return {m_trMask[0], m_trMask[1], m_trMask[2], m_trMask[3]}; } + /// Update the trigger mask of the event - void setTriggerMask(const std::array<unsigned int,4>& mask){ + void setTriggerMask(const std::array<unsigned int,4>& mask) { m_trMask[0] = mask[0]; m_trMask[1] = mask[1]; m_trMask[2] = mask[2]; m_trMask[3] = mask[3]; } + /// Update the trigger mask of the event - void setTriggerMask(const unsigned int* mask){ + void setTriggerMask(const unsigned int* mask) { m_trMask[0] = mask[0]; m_trMask[1] = mask[1]; m_trMask[2] = mask[2]; m_trMask[3] = mask[3]; } + + /// Update the trigger mask of the event + void setTriggerMask(unsigned int m0, unsigned int m1, unsigned int m2, unsigned int m3) { + m_trMask[0] = m0; + m_trMask[1] = m1; + m_trMask[2] = m2; + m_trMask[3] = m3; + } }; + struct PACKED_DATA Header0 { typedef long long int int_64_t; /// Event type identifier @@ -130,14 +143,14 @@ namespace Online { return {m_trMask[0], m_trMask[1], m_trMask[2], m_trMask[3]}; } /// Update the trigger mask of the event - void setTriggerMask(const std::array<unsigned int,4>& mask){ + void setTriggerMask(const std::array<unsigned int,4>& mask) { m_trMask[0] = mask[0]; m_trMask[1] = mask[1]; m_trMask[2] = mask[2]; m_trMask[3] = mask[3]; } /// Update the trigger mask of the event - void setTriggerMask(const unsigned int* mask){ + void setTriggerMask(const unsigned int* mask) { m_trMask[0] = mask[0]; m_trMask[1] = mask[1]; m_trMask[2] = mask[2]; @@ -203,60 +216,62 @@ namespace Online { } /// Default destructor ~EventHeader() {} + /// Check if this is really an MDF header + bool is_mdf() const + { return m_size[0] > 0 && m_size[0]==m_size[1] && m_size[0]==m_size[2]; } /// Access record size - unsigned int recordSize() const { return m_size[0]; } + int recordSize() const { return int(m_size[0]); } /// Accessor: event size - unsigned int size() const - { return m_size[0]-sizeOf(headerVersion()); } + unsigned int size() const { return m_size[0]-sizeOf(headerVersion()); } /// Update event size void setSize(unsigned int val) - { m_size[0]=m_size[1]=m_size[2]=val+sizeOf(headerVersion()); } + { m_size[0]=m_size[1]=m_size[2]=val+sizeOf(headerVersion()); } /// For checks: return 0th. size word - unsigned int size0() const { return m_size[0]; } + unsigned int size0() const { return m_size[0]; } /// For checks: return 1rst. size word - unsigned int size1() const { return m_size[1]; } + unsigned int size1() const { return m_size[1]; } /// For checks: return 2nd. size word - unsigned int size2() const { return m_size[2]; } + unsigned int size2() const { return m_size[2]; } /// For special stuff: modify 3rd. size word by hand - void setSize2(unsigned int val) { m_size[2] = val; } + void setSize2(unsigned int val) { m_size[2] = val; } /// Accessor: checksum of the event data - unsigned int checkSum() const { return m_checkSum; } + unsigned int checkSum() const { return m_checkSum; } /// Update checksum of the event data - void setChecksum(unsigned int val) { m_checkSum = val; } - /// Accessor: Identifier of the compression method - unsigned char compression() const { return m_compression; } + void setChecksum(unsigned int val) { m_checkSum = val; } + /// Accessor: Identifier of the compression method + unsigned char compression() const { return m_compression; } /// Update the identifier of the compression method - void setCompression(unsigned int val) { m_compression=(unsigned char)val; } + void setCompression(unsigned int val) { m_compression=(unsigned char)val; } /// Accessor: length of the event header - unsigned int subheaderLength() const { return (m_hdr&0x0F)*sizeof(int); } + unsigned int subheaderLength() const { return (m_hdr&0x0F)*sizeof(int); } /// Update the length of the event header void setSubheaderLength(unsigned int l) { l = l%sizeof(int) ? (l/sizeof(int)) + 1 : l/sizeof(int); m_hdr = (unsigned char)((0xF0&m_hdr) + (0x0F&l)); } /// Accessor: version of the event header - unsigned int headerVersion() const { return m_hdr>>4; } + unsigned int headerVersion() const { return m_hdr>>4; } /// Update the version of the event header void setHeaderVersion(unsigned int vsn) - { m_hdr = (unsigned char)(((vsn<<4)+(m_hdr&0xF))&0xFF); } + { m_hdr = (unsigned char)(((vsn<<4)+(m_hdr&0xF))&0xFF); } /// Accessor: hdr field - unsigned char hdr() const { return m_hdr; } + unsigned char hdr() const { return m_hdr; } /// Update hdr field - void setHdr(unsigned char val) { m_hdr = val; } + void setHdr(unsigned char val) { m_hdr = val; } /// Accessor: event type identifier - unsigned char dataType() const { return m_dataType; } + unsigned char dataType() const { return m_dataType; } /// Update the event type - void setDataType(unsigned char val) { m_dataType = val; } + void setDataType(unsigned char val) { m_dataType = val; } /// Set spare word - void setSpare(unsigned char val) { m_spare[0] = val; } + void setSpare(unsigned char val) { m_spare[0] = val; } /// Access to data payload (Header MUST be initialized) - char* data() { return ((char*)this)+sizeOf(headerVersion()); } + char* data() { return ((char*)this)+sizeOf(headerVersion()); } /// Access to data payload (Header MUST be initialized) - const char* data() const { return ((char*)this)+sizeOf(headerVersion()); } + const char* data() const { return ((char*)this)+sizeOf(headerVersion()); } /// Access to sub-headers - SubHeader subHeader0() { return SubHeader(m_spare-1); } - SubHeader subHeader() const { return SubHeader(m_spare+1); } + SubHeader subHeader0() { return SubHeader(m_spare-1); } + SubHeader subHeader() const { return SubHeader(m_spare+1); } //const SubHeader subHeader() const { return SubHeader(m_spare+1); } }; } // End namespace LHCb diff --git a/Online/Tell1Data/Tell1Data/RawFile.h b/Online/Tell1Data/Tell1Data/RawFile.h index a69ac80c9..0a60c9e75 100644 --- a/Online/Tell1Data/Tell1Data/RawFile.h +++ b/Online/Tell1Data/Tell1Data/RawFile.h @@ -97,7 +97,8 @@ namespace Online { long write(const void* data, int len); long write(const void* data, size_t len); int open(); - int map(const void* data, size_t len); + int map_memory(const void* data, size_t len); + int unmap_memory(); int openMapped(); int openWrite(); int unlink(); diff --git a/Online/Tell1Data/src/RawFile.cpp b/Online/Tell1Data/src/RawFile.cpp index b66d28a68..2327f422a 100644 --- a/Online/Tell1Data/src/RawFile.cpp +++ b/Online/Tell1Data/src/RawFile.cpp @@ -183,14 +183,22 @@ int RawFile::openMapped() { return fd; } -int RawFile::map(const void* ptr, size_t len) { - if ( m_fd > 0 ) close(); +int RawFile::map_memory(const void* ptr, size_t len) { + m_begin = m_ptr = m_end = nullptr; + this->close(); m_fd = -1; m_ptr = m_begin = (unsigned char*)ptr; m_end = m_begin + len; return 1; } +int RawFile::unmap_memory() { + m_begin = m_ptr = m_end = nullptr; + this->close(); + m_fd = -1; + return 1; +} + long RawFile::write(const void* data, int len) { const unsigned char* p = (const unsigned char*) data; int tmp = len; @@ -223,10 +231,13 @@ long RawFile::read(void* pointer, int len) { m_ptr += len; return len; } - len = m_end - m_ptr; - ::memcpy(p, m_ptr, len); - m_ptr = m_end; - return 0; + else if ( m_ptr < m_end ) { + len = m_end - m_ptr; + ::memcpy(p, m_ptr, len); + m_ptr = m_end; + return len; + } + return -1; } int tmp = 0; while (tmp < len) { @@ -281,7 +292,7 @@ long RawFile::read_event(EventType expected, off_t file_position = this->seek(0, SEEK_CUR); int status = this->read((unsigned char*)size_buf, sizeof(size_buf)); if ( data ) *data = 0; - if (status <= 0) { + if ( status <= 0 ) { this->close(); return -1; } diff --git a/Online/Tell1Data/src/Tell1Decoder.cpp b/Online/Tell1Data/src/Tell1Decoder.cpp index e069825dd..8df5386d6 100644 --- a/Online/Tell1Data/src/Tell1Decoder.cpp +++ b/Online/Tell1Data/src/Tell1Decoder.cpp @@ -241,8 +241,8 @@ static void print_previous_bank(const Tell1Bank* prev) { /// Check sanity of raw bank structure bool Online::checkRawBank(const Tell1Bank* b, bool throw_exc, bool print_cout) { typedef Tell1Printout _P; - // Check bank's magic word - if ( b->magic() == Tell1Bank::MagicPattern ) { + // Check bank's magic word: Either Tell1 magic word or PCIE40 magic word + if ( b->magic() == Tell1Bank::MagicPattern || b->magic() == 0xFACE ) { // Crude check on the bank type if ( b->type() < Tell1Bank::LastType || b->type() >= Tell1Bank::DaqErrorBase ) { // Crude check on the bank length -- GitLab From 6569b5ae3c989e8c0d1d109287b8cec7256ac04d Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Tue, 16 Mar 2021 17:47:56 +0100 Subject: [PATCH 06/17] Fix to event builder options after debugging --- Online/Dataflow/Dataflow/DiskReader.h | 28 ++++------- Online/Dataflow/src/framework/DiskReader.cpp | 47 +++++++++---------- Online/EventBuilding/options/BU_0.opts | 3 +- Online/EventBuilding/options/BU_1.opts | 3 +- Online/EventBuilding/options/EB_BU_algo.opts | 4 +- Online/EventBuilding/options/EB_RU_algo.opts | 2 +- .../options/EB_Transport_properties.opts | 4 +- .../EventBuilding/options/EB_transport.opts | 8 ++-- Online/FarmConfig/job/EBPass.sh | 47 +++++++++++++++++++ Online/FarmConfig/job/EBStorage.sh | 12 +++++ Online/FarmConfig/job/preamble.sh | 26 ++++++++++ Online/FarmConfig/options/EBMBM.opts | 2 +- Online/FarmConfig/options/EBStorage.opts | 42 +++++++++++++++++ Online/GaudiOnline/src/FileEventOutput.cpp | 1 + 14 files changed, 175 insertions(+), 54 deletions(-) create mode 100755 Online/FarmConfig/job/EBPass.sh create mode 100755 Online/FarmConfig/job/EBStorage.sh create mode 100644 Online/FarmConfig/options/EBStorage.opts diff --git a/Online/Dataflow/Dataflow/DiskReader.h b/Online/Dataflow/Dataflow/DiskReader.h index 4da4be04c..09fa3810b 100644 --- a/Online/Dataflow/Dataflow/DiskReader.h +++ b/Online/Dataflow/Dataflow/DiskReader.h @@ -91,9 +91,9 @@ namespace Online { public: /// Scan directory for matching files - size_t scanDirectory(const std::string& dir_name); + size_t scanDirectory(const std::string& dir_name); /// Scan directory for matching files - size_t scanFiles(); + size_t scanFiles(); /// Open a new data file RawFile openFile(); @@ -213,20 +213,12 @@ namespace Online { static bool check_consumers_partid(const MBM::BufferInfo& info, int pid); static bool check_consumers(const MBM::BufferInfo& info, int pid, int evtyp); - /// Scan single directory for matching files - //virtual size_t scanDirectory(const std::string& dir_name); - /// Scan directories for matching files - //virtual size_t scanFiles(); - /// Open a new data file - //virtual RawFile openFile(); - - - /// If the GO service is present, wait until processing is enabled - int waitForGo(); - /// Wait until consumers are ready (if required) - int waitForConsumers(MBM::BufferInfo* mbmInfo); /// Update run number service void updateRunNumber(int new_run); + /// If the GO service is present, wait until processing is enabled + virtual int waitForGo(); + /// Wait until consumers are ready (if required) + virtual int waitForConsumers(MBM::BufferInfo* mbmInfo); /// Wait until event buffers are empty before finishing.... virtual void waitForPendingEvents(int seconds); /// Patch the string array with allowed runs @@ -245,10 +237,10 @@ namespace Online { /// Handle MBM request: load event data and declare to MBM virtual int handle_mbm_request(MBM::BufferInfo* info, RawFile& file); - void save_file_rest(RawFile& file); + virtual void save_file_rest(RawFile& file); /// Runable implementation : Run the class implementation - virtual int i_run() = 0; + virtual int i_run() = 0; public: /// Standard algorithm constructor @@ -280,5 +272,5 @@ namespace Online { /// IRunable implementation : Run the class implementation virtual int run() override; }; -} // End namespace Online -#endif // ONLINE_DATAFLOW_INPUTREADER_H +} // End namespace Online +#endif // ONLINE_DATAFLOW_INPUTREADER_H diff --git a/Online/Dataflow/src/framework/DiskReader.cpp b/Online/Dataflow/src/framework/DiskReader.cpp index cb1295159..8fc1e2685 100644 --- a/Online/Dataflow/src/framework/DiskReader.cpp +++ b/Online/Dataflow/src/framework/DiskReader.cpp @@ -414,6 +414,7 @@ void DiskReader::updateRunNumber(int new_run) { if ( m_runSvcID ) ::dis_update_service(m_runSvcID); } +/// On pause: save rest of unprocessed data void DiskReader::save_file_rest(RawFile& file) { if ( file.isOpen() ) { if ( m_deleteFiles && m_saveRest ) file.saveRestOfFile(); @@ -432,7 +433,7 @@ DiskReader::load_event_data(RawFile::Allocator& allocator, RawFile& file) { if ( status < peek ) { file.reset(true); - return {0, -1, RawFile::NO_INPUT_TYPE}; + return { 0, -1, RawFile::NO_INPUT_TYPE }; } // // Auto detect data type: first check for PCIE40 MEP format @@ -444,66 +445,63 @@ DiskReader::load_event_data(RawFile::Allocator& allocator, RawFile& file) { status = file.read(data_ptr+peek, data_size-peek); if ( status < int(data_size-peek) ) { file.reset(true); - return {0, -1, RawFile::NO_INPUT_TYPE}; + return { 0, -1, RawFile::NO_INPUT_TYPE }; } - return {size_t(data_size), 1, RawFile::MEP_INPUT_TYPE}; + return { size_t(data_size), 1, RawFile::MEP_INPUT_TYPE }; } // // Now check for MDF format: 3 times same size auto* mdf_hdr = (EventHeader*)size; if ( mdf_hdr->is_mdf() ) { int num_evts = 1; - int data_size = size[0]; + int data_size = mdf_hdr->recordSize(); int alloc_size = m_packingFactor == 1 ? mdf_hdr->recordSize() : m_preAllocSize; if ( data_size > alloc_size ) { file.position(position); - return {0, -1, RawFile::NO_INPUT_TYPE}; + return { 0, -1, RawFile::NO_INPUT_TYPE }; } alloc_ptr = data_ptr = allocator(alloc_size); ::memcpy(data_ptr, mdf_hdr, peek); status = file.read(data_ptr + peek, mdf_hdr->recordSize() - peek); if ( status < mdf_hdr->recordSize() - peek ) { file.reset(true); - return {0, -1, RawFile::NO_INPUT_TYPE}; + return { 0, -1, RawFile::NO_INPUT_TYPE }; } data_ptr += size[0]; for ( ; num_evts < m_packingFactor; ) { - if ( peek + data_size > alloc_size ) { - file.reset(true); - return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; - } position = file.position(); status = file.read(data_ptr, peek); if ( status < peek ) { file.reset(true); - return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; + return { size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE }; } - mep_hdr = (pcie40::mep_header_t*)size; + mep_hdr = (pcie40::mep_header_t*)data_ptr; if ( mep_hdr->magic == mep_hdr->MagicPattern ) { file.position(position); - return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; + return { size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE }; } mdf_hdr = (EventHeader*)data_ptr; if ( mdf_hdr->recordSize() + data_size > alloc_size ) { file.position(position); - return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; + return { size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE }; } status = file.read(data_ptr + peek, mdf_hdr->recordSize() - peek); if ( status < mdf_hdr->recordSize() - peek ) { file.reset(true); - return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; + return { size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE }; } data_size += mdf_hdr->recordSize(); data_ptr += mdf_hdr->recordSize(); ++num_evts; } - return {size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE}; + return { size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE }; } // // Now the only thing left is Tell1 MEP format { static int id = -1; + static constexpr int peek_mep = peek - sizeof(int); int data_size = sizeof(MEPEVENT)+sizeof(Tell1MEP)+size[0]; MEPEVENT* e = (MEPEVENT*)(alloc_ptr=allocator(data_size)); Tell1MEP* me = (Tell1MEP*)e->data; @@ -520,15 +518,16 @@ DiskReader::load_event_data(RawFile::Allocator& allocator, RawFile& file) { e->events[j].status = EVENT_TYPE_OK; e->events[j].signal = 0; } - data_ptr = (unsigned char*)me->start(); - ::memcpy(data_ptr, size+1, 2*sizeof(size[0])); - status = file.read(data_ptr + 2*sizeof(size[0]), me->size() - 2*sizeof(int)); - if ( status < int(me->size() - 2*sizeof(int)) ) { // End-of file, continue with next file + data_ptr = (uint8_t*)me->start(); + ::memcpy(data_ptr, &size[1], peek_mep); + status = file.read(data_ptr + peek_mep, me->size() - peek_mep); + if ( status < int(me->size() - peek_mep) ) { + // End-of file, continue with next file file.reset(true); - return {0, -1, RawFile::NO_INPUT_TYPE}; + return { 0, -1, RawFile::NO_INPUT_TYPE }; } data_ptr += me->size(); - return {size_t(data_ptr-alloc_ptr), 1, RawFile::MEP_INPUT_TYPE}; + return { size_t(data_ptr-alloc_ptr), 1, RawFile::MEP_INPUT_TYPE }; } // // Last chance: we have a corrrupted MDF record. Try to sweep to the next MDF frame @@ -542,7 +541,7 @@ DiskReader::load_event_data(RawFile::Allocator& allocator, RawFile& file) { error("Corrupted file found: %s at position %ld. Skip rest of file!", file.cname(), position); file.reset(true); - return {0, -1, RawFile::NO_INPUT_TYPE}; + return { 0, -1, RawFile::NO_INPUT_TYPE }; } /// Declare event frame to the buffer manager to trigger clients @@ -556,7 +555,7 @@ int DiskReader::declare_mbm_data(MBM::BufferInfo* mbm_info, const char* fname, c // If the first bank is a MDF header, we copy the real trigger mask context.manager.setRunNumber(hdr->subHeader().H1->runNumber()); ::memcpy(dsc.mask, &hdr->subHeader().H1->triggerMask()[0], sizeof(dsc.mask)); - dsc.type = (load.packing == 1 && m_packingFactor) ? EVENT_TYPE_EVENT : EVENT_TYPE_BURST; + dsc.type = (1 == load.packing && 1 == m_packingFactor) ? EVENT_TYPE_EVENT : EVENT_TYPE_BURST; } else { // If MEP, we emulate a trigger mask with the partition ID diff --git a/Online/EventBuilding/options/BU_0.opts b/Online/EventBuilding/options/BU_0.opts index e210c041e..fc05a9c5c 100644 --- a/Online/EventBuilding/options/BU_0.opts +++ b/Online/EventBuilding/options/BU_0.opts @@ -1,3 +1,4 @@ #pragma print off #include "$EVENTBUILDINGROOT/options/EB_BU.opts" -MEPManager.Buffers = { "Events_0" }; +MEPManager.Buffers = { "Events_0" }; +BU.MBM_name = { "Events_0" }; diff --git a/Online/EventBuilding/options/BU_1.opts b/Online/EventBuilding/options/BU_1.opts index c0b8d80a4..33f12dc5b 100644 --- a/Online/EventBuilding/options/BU_1.opts +++ b/Online/EventBuilding/options/BU_1.opts @@ -1,3 +1,4 @@ #pragma print off #include "$EVENTBUILDINGROOT/options/EB_BU.opts" -MEPManager.Buffers = { "Events_1" }; +MEPManager.Buffers = { "Events_1" }; +BU.MBM_name = { "Events_1" }; diff --git a/Online/EventBuilding/options/EB_BU_algo.opts b/Online/EventBuilding/options/EB_BU_algo.opts index 4f407d2f0..59f599362 100755 --- a/Online/EventBuilding/options/EB_BU_algo.opts +++ b/Online/EventBuilding/options/EB_BU_algo.opts @@ -1,6 +1,6 @@ -BU.MBM_name = {}; +BU.MBM_name = { 'Input', 'Input', 'Input', 'Input', 'Input', 'Input' }; BU.buffer_size = {}; -BU.buffer_type = {}; +BU.buffer_type = { 2, 2, 2, 2, 2, 2 }; BU.out_file_prefix = ""; BU.shmem_prefix = ""; BU.stop_timeout = 0; diff --git a/Online/EventBuilding/options/EB_RU_algo.opts b/Online/EventBuilding/options/EB_RU_algo.opts index 3b6f57e29..ad70f5203 100755 --- a/Online/EventBuilding/options/EB_RU_algo.opts +++ b/Online/EventBuilding/options/EB_RU_algo.opts @@ -1,6 +1,6 @@ RU.MDF_filename = "/home/fpisani/mc_data/biger_file.mdf"; RU.PCIe40_ids = {}; -RU.PCIe40_names = { 'tdtel022_0', 'tdtel022_1', 'tdtel042_0', 'tdtel042_1', 'tdtel051_1', 'tdtel052_0', 'tdtel052_1', 'tdtel053_0', 'tdtel053_1' }; +RU.PCIe40_names = { 'tdtel022_0', 'tdtel022_1', 'tdtel031_0', 'tdtel031_1', 'tdtel032_0', 'tdtel033_0', 'tdtel033_1', 'tdtel042_0', 'tdtel042_1' }; RU.PCIe40_timeout = 30; RU.buffer_sizes = {}; RU.buffer_type = { 3, 3, 3, 3, 3, 3 }; diff --git a/Online/EventBuilding/options/EB_Transport_properties.opts b/Online/EventBuilding/options/EB_Transport_properties.opts index 85150ab08..f44bef70b 100755 --- a/Online/EventBuilding/options/EB_Transport_properties.opts +++ b/Online/EventBuilding/options/EB_Transport_properties.opts @@ -2,7 +2,7 @@ EB_transport.BU_ranks = {}; EB_transport.MPI_errors_return = FALSE; EB_transport.RU_ranks = {}; EB_transport.RUs_per_nic = {}; -EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.t25565.json"; +EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.d25197.json"; EB_transport.n_par_mess = 0; -EB_transport.n_sources_per_ru = { 1, 1, 1, 1, 3, 2 }; +EB_transport.n_sources_per_ru = { 1, 1, 3, 2, 1, 1 }; EB_transport.src_ids = {}; diff --git a/Online/EventBuilding/options/EB_transport.opts b/Online/EventBuilding/options/EB_transport.opts index 593c72269..63f024e4b 100755 --- a/Online/EventBuilding/options/EB_transport.opts +++ b/Online/EventBuilding/options/EB_transport.opts @@ -1,6 +1,3 @@ -// EB transport_unit properties -#include "$EVENTBUILDINGROOT/options/EB_Transport_properties.opts" - EB_transport.MPI_errors_return = true; EB_transport.OutputLevel = 3; // an empty array will trigger the default value in the code @@ -8,4 +5,7 @@ EB_transport.src_ids = {}; EB_transport.RU_ranks = {}; EB_transport.BU_ranks = {}; EB_transport.ghost_nodes_topology = {}; -EB_transport.ib_config_file = "$EVENTBUILDINGROOT/options/hosts_example.json"; +//EB_transport.ib_config_file = "$EVENTBUILDINGROOT/options/hosts_example.json"; + +// EB transport_unit properties +#include "$EVENTBUILDINGROOT/options/EB_Transport_properties.opts" diff --git a/Online/FarmConfig/job/EBPass.sh b/Online/FarmConfig/job/EBPass.sh new file mode 100755 index 000000000..a282a8614 --- /dev/null +++ b/Online/FarmConfig/job/EBPass.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# ========================================================================= +# +# Default script to start the buffer manager on the HLT farm worker node +# +# Author M.Frank +# Version: 1.0 +# Date: 05/03/2021 +# +# ========================================================================= +# +cat > /tmp/${UTGID}.py <<EOF +import Configurables +import GaudiOnline +import OnlineEnvBase +import os + +from Configurables import Online__FlowManager as FlowManager +application = GaudiOnline.Passthrough(outputLevel=OnlineEnvBase.OutputLevel, + partitionName=OnlineEnvBase.PartitionName, + partitionID=OnlineEnvBase.PartitionID, + classType=GaudiOnline.Class1) +items = os.environ['UTGID'].split('_') +id = items[-1] +application.setup_fifolog() +application.log(GaudiOnline.MSG_INFO,'+++ OnlineEnv: %s Level:%d',OnlineEnvBase.__file__,OnlineEnvBase.OutputLevel) +application.setup_mbm_access('Events_'+id, True) +writer = None +writer = application.setup_mbm_output('EventOutput') +writer.MBM_buffer = 'Output' +writer.MBM_maxConsumerWait = 10 +# +application.setup_hive(FlowManager("EventLoop"), 40) +application.setup_algorithms(writer, 0.05) +application.setup_monitoring() +application.monSvc.DimUpdateInterval = 1 +application.config.numEventThreads = 1 +application.config.MBM_numConnections = 1 +application.config.MBM_numEventThreads = 1 +application.config.MBM_requests = [ + 'EvType=3;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0', + 'EvType=2;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0', + 'EvType=1;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0' +] +EOF +export PYTHONPATH=/group/online/dataflow/options/${PARTITION}/HLT:${PYTHONPATH}; +exec -a ${UTGID} python `which gaudirun.py` /tmp/${UTGID}.py --application=OnlineEvents diff --git a/Online/FarmConfig/job/EBStorage.sh b/Online/FarmConfig/job/EBStorage.sh new file mode 100755 index 000000000..98e1eadf0 --- /dev/null +++ b/Online/FarmConfig/job/EBStorage.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# ========================================================================= +# +# Generic farm task startup script +# +# Author M.Frank +# Version: 1.0 +# Date: 20/05/2013 +# +# ========================================================================= +# echo "INFO_OPTIONS=${INFO_OPTIONS}"; +`dataflow_task Class1` -opts=../options/${TASK_TYPE}.opts; diff --git a/Online/FarmConfig/job/preamble.sh b/Online/FarmConfig/job/preamble.sh index c199d1077..966ee4fd7 100755 --- a/Online/FarmConfig/job/preamble.sh +++ b/Online/FarmConfig/job/preamble.sh @@ -10,6 +10,7 @@ export Class1_task="$gaudi_task -tasktype=LHCb::Class1Task -main=$OPTS/Main.opts export Class2_task="$gaudi_task -tasktype=LHCb::Class2Task -main=$OPTS/Main.opts " export Checkpoint_task="GaudiCheckpoint.exe libGaudiOnline.so OnlineTask -msgsvc=$msg_svc -tasktype=LHCb::Class1Task -main=$OPTS/Main.opts " # +# if test -p "${LOGFIFO}"; then export DATAFLOW_task="gentest.exe libDataflow.so dataflow_run_task -msg=fifo -mon=Dataflow_DIMMonitoring"; else @@ -17,6 +18,31 @@ else fi; # # +dataflow_specialized_options() +{ + if test -n "${1}"; then + echo "-opts=/group/online/dataflow/options/${PARTITION_NAME}/MONITORING/${1}.opts"; + else + echo "-opts=/group/online/dataflow/options/${PARTITION_NAME}/MONITORING/${UTGID}.opts"; + fi; +} +# +# +dataflow_default_options() +{ + echo "-opts=/group/online/dataflow/options/${PARTITION_NAME}/MONITORING/${UTGID}.opts"; +} +# +# +dataflow_task() +{ + if test -p "${LOGFIFO}"; then + echo "exec -a ${UTGID} gentest.exe libDataflow.so dataflow_run_task -msg=fifo -mon=Dataflow_DIMMonitoring -class=$1"; + else + echo "exec -a ${UTGID} gentest.exe libDataflow.so dataflow_run_task -msg=Dataflow_FmcLogger -mon=Dataflow_DIMMonitoring -class=$1"; + fi; +} +# # mbmmon() { diff --git a/Online/FarmConfig/options/EBMBM.opts b/Online/FarmConfig/options/EBMBM.opts index 6297f8c50..bbc5f2dae 100644 --- a/Online/FarmConfig/options/EBMBM.opts +++ b/Online/FarmConfig/options/EBMBM.opts @@ -6,4 +6,4 @@ Manager.Setup = {"Dataflow_MBMServer/MEPManager"}; Manager.Services = {"Dataflow_UI/UI"}; MEPManager.PartitionBuffers = @OnlineEnv.PartitionBuffers; MEPManager.PartitionName = @OnlineEnv.PartitionName; -MEPManager.InitFlags = "-s=1000000 -e=20 -u=30 -b=12 -t=2 -f -i=Events_0 -c -s=1000000 -e=20 -u=30 -b=12 -f -i=Events_1 -c"; +MEPManager.InitFlags = "-s=1000000 -e=20 -u=30 -b=12 -t=2 -f -i=Events_0 -c -s=1000000 -e=20 -u=30 -b=12 -f -i=Events_1 -c -s=500000 -e=30 -u=10 -b=12 -f -i=Output -c"; diff --git a/Online/FarmConfig/options/EBStorage.opts b/Online/FarmConfig/options/EBStorage.opts new file mode 100644 index 000000000..80419561c --- /dev/null +++ b/Online/FarmConfig/options/EBStorage.opts @@ -0,0 +1,42 @@ +#pragma print off +#include "$INFO_OPTIONS" +#include "$FARMCONFIGROOT/options/Logging.opts" +#include "$FARMCONFIGROOT/options/Monitoring.opts" +// +Manager.Services = {"Dataflow_MBMClient/MBM", + "Dataflow_MBMSelector/EventProc", + "Dataflow_RunableWrapper/Wrap" + }; +Manager.Algorithms = {"Dataflow_EmptyProcessor/Empty"}; +Manager.Runable = "Wrap"; +Wrap.Callable = "EventProc"; +// +EventProc.REQ1 = "EvType=1;TriggerMask=0xffffffff,0xffffffff,0xffffffff,0xffffffff;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0"; +EventProc.REQ2 = "EvType=2;TriggerMask=0xffffffff,0xffffffff,0xffffffff,0xffffffff;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0"; +EventProc.REQ3 = "EvType=3;TriggerMask=0xffffffff,0xffffffff,0xffffffff,0xffffffff;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0"; +EventProc.Input = "Output"; +// +// +OnlineEnv.PartitionBuffers = true; +MBM.PartitionBuffers = @OnlineEnv.PartitionBuffers; +MBM.PartitionName = @OnlineEnv.PartitionName; +MBM.PartitionID = @OnlineEnv.PartitionID; +MBM.Buffers = {"Output"}; +// +// +Manager.Algorithms = {"Dataflow_StorageWriter/Writer"}; +Writer.Server = "XXEB09.lbdaq.cern.ch:8000"; +Writer.Mount = "/objects/data/testing"; +Writer.FileSizeMB = 500; +Writer.MinFileSizeMB = 10; +Writer.WriteErrorRetry = 100000; +Writer.WriteErrorSleep = 3000; +Writer.FileNameFormat = 1; +Writer.PollTimeout = 100000; // micro-seconds +Writer.NumBuffers = 6; +Writer.NumThreads = 4; +Writer.CancelTimeout = 100; // seconds +Writer.ForceMDF = true; +// +Logger.OutputLevel = 0; +// diff --git a/Online/GaudiOnline/src/FileEventOutput.cpp b/Online/GaudiOnline/src/FileEventOutput.cpp index d43b087f3..0b84c2dfb 100644 --- a/Online/GaudiOnline/src/FileEventOutput.cpp +++ b/Online/GaudiOnline/src/FileEventOutput.cpp @@ -42,6 +42,7 @@ public: public: /// Default constructor file_transaction_t() = delete; + /// Initializing constructor file_transaction_t(const string& name, FileEventOutput* out) : file(name), output(out) {} /// Move constructor file_transaction_t(file_transaction_t&& copy) = default; -- GitLab From a6acccee0c7c08fd4c3e46c474a746026f404292 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Tue, 16 Mar 2021 19:57:12 +0100 Subject: [PATCH 07/17] Improve HTTP server functionality: Allow source info access from HttpRequest --- Online/HTTP/HTTP/HttpRequest.h | 11 +++++++++ Online/HTTP/src/HttpRequest.cpp | 27 +++++++++++++++++++++ Online/HTTP/src/HttpServer.cpp | 7 +++--- Online/Storage/src/server/fdb_db_server.cpp | 17 +++++++++++-- 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/Online/HTTP/HTTP/HttpRequest.h b/Online/HTTP/HTTP/HttpRequest.h index ea1c12d58..60ca66c61 100644 --- a/Online/HTTP/HTTP/HttpRequest.h +++ b/Online/HTTP/HTTP/HttpRequest.h @@ -33,6 +33,9 @@ // Framework include files #include <HTTP/HttpHeader.h> +// Boost inlcude files +#include <boost/asio.hpp> + // C/C++ include files #include <vector> #include <chrono> @@ -79,6 +82,8 @@ namespace http { reqheaders_t headers {}; /// The optional content sent with the request. content_t content {}; + /// Socket for the connection. + boost::asio::ip::tcp::socket* socket {nullptr}; /// Copy construction is allowed here HttpRequest(const HttpRequest&) = default; @@ -93,6 +98,12 @@ namespace http { /// Access header by name const HttpHeader* header(const std::string& name) const; + /// Access requester host endpoint + boost::asio::ip::tcp::endpoint remote() const; + /// Access requester remote address + boost::asio::ip::address remote_address() const; + /// Access requester remote host name + std::string remote_host_name() const; }; } // End namespace http #endif // HTTP_HTTP_HTTPREQUEST_H diff --git a/Online/HTTP/src/HttpRequest.cpp b/Online/HTTP/src/HttpRequest.cpp index 0b49a04ca..09772f12b 100644 --- a/Online/HTTP/src/HttpRequest.cpp +++ b/Online/HTTP/src/HttpRequest.cpp @@ -34,6 +34,8 @@ // C/C++ include files #include <cstring> +using namespace boost; + /// Access header by name const http::HttpHeader* http::HttpRequest::header(const std::string& name) const { for ( const auto& h : headers ) { @@ -42,3 +44,28 @@ const http::HttpHeader* http::HttpRequest::header(const std::string& name) const } return 0; } + +/// Access source host +asio::ip::tcp::endpoint http::HttpRequest::remote() const { + if ( this->socket ) { + system::error_code ec; + asio::ip::tcp::endpoint end = this->socket->remote_endpoint(ec); + if ( !ec ) { + return end; + } + throw std::runtime_error("HttpRequest::remote: Cannot determine remote " + "endpoint: "+ec.message()); + } + throw std::runtime_error("HttpRequest::remote: Invalid socket handle."); +} + +/// Access requester remote address +boost::asio::ip::address http::HttpRequest::remote_address() const { + return this->remote().address(); +} + +/// Access requester remote host name +std::string http::HttpRequest::remote_host_name() const { + return this->remote().address().to_string(); +} + diff --git a/Online/HTTP/src/HttpServer.cpp b/Online/HTTP/src/HttpServer.cpp index cb5bdd316..45c464f6e 100644 --- a/Online/HTTP/src/HttpServer.cpp +++ b/Online/HTTP/src/HttpServer.cpp @@ -50,9 +50,10 @@ HttpConnection::HttpConnection(asio::ip::tcp::socket s, { if ( buffer_size > 0 ) buffer.resize(buffer_size); else buffer.resize(16*1024); - request.state = HttpRequestParser::indeterminate; - request.start = system_clock::now(); - request.netio = std::chrono::time_point<system_clock>(system_clock::duration::zero()); + request.socket = &this->socket; + request.state = HttpRequestParser::indeterminate; + request.start = system_clock::now(); + request.netio = std::chrono::time_point<system_clock>(system_clock::duration::zero()); request.handling = std::chrono::time_point<system_clock>(system_clock::duration::zero()); } diff --git a/Online/Storage/src/server/fdb_db_server.cpp b/Online/Storage/src/server/fdb_db_server.cpp index 5f2b63cbb..3ec17e764 100644 --- a/Online/Storage/src/server/fdb_db_server.cpp +++ b/Online/Storage/src/server/fdb_db_server.cpp @@ -30,7 +30,8 @@ using namespace std; using namespace Online::storage; static const string PATTERN_NEXT = "/next?prefix="; - +static constexpr const double kByte = 1024e0; +static constexpr const double MByte = kByte*kByte; /// Standard destructor template <> http::basic_http_server<db>::handler_t::~handler_t() { @@ -58,14 +59,18 @@ http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t if ( !error_code_ok(ec, this->debug) ) { header_t h(http::constants::error_cause,"Failed to get "+req.uri+" ["+ec.message()+"]"); - ::lib_rtl_output(LIB_RTL_ERROR,"DELETE: %s %-20s = %s", + ::lib_rtl_output(LIB_RTL_ERROR,"GET: %s %-20s = %s", reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); rep.headers.emplace_back(move(h)); } else { + bool mb = length > 3*MByte; rep = reply_t::stock_reply(reply_t::temp_redirect); rep.headers.emplace_back(http::constants::location,access_name); + ::lib_rtl_output(LIB_RTL_INFO,"GET: '%s' %.1f %cB [%s]", + access_name.c_str(), double(length)/(mb ? MByte : kByte), mb ? 'M' : 'k', + req.remote_address().to_string().c_str()); } return write; } @@ -98,8 +103,12 @@ http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, repl rep.headers.emplace_back(move(h)); } else { + bool mb = length > 3*MByte; rep = reply_t::stock_reply(reply_t::temp_redirect); rep.headers.emplace_back(http::constants::location,access_name); + ::lib_rtl_output(LIB_RTL_INFO,"DELETE:'%s' %.1f %cB [%s]", + access_name.c_str(), double(length)/(mb ? MByte : kByte), mb ? 'M' : 'k', + req.remote_address().to_string().c_str()); } return write; } @@ -148,12 +157,16 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t rep.headers.emplace_back(move(h)); } else { + bool mb = len > 3*MByte; rep = reply_t::stock_reply(reply_t::temp_redirect); rep.content.clear(); rep.headers.clear(); rep.headers.emplace_back(http::constants::location,access_name); rep.headers.emplace_back(http::constants::data_length,len); rep.headers.emplace_back(http::constants::date,date); + ::lib_rtl_output(LIB_RTL_INFO,"PUT: '%s' %.1f %cB [%s]", + req.uri.c_str(), double(len)/(mb ? MByte : kByte), mb ? 'M' : 'k', + req.remote_address().to_string().c_str()); } } return write; -- GitLab From 5d343b14206258fa86a3c6f5aec87253ca4c32fb Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Tue, 23 Mar 2021 18:58:38 +0100 Subject: [PATCH 08/17] Results from event building debugging --- Online/Dataflow/options/StorageWriter.opts | 7 +- Online/Dataflow/src/Storage/StorageWriter.cpp | 4 +- Online/Dataflow/src/framework/Receiver.cpp | 8 +- Online/EventBuilding/EventBuilding/BU.hpp | 1 + Online/EventBuilding/include/mbm_writer.hpp | 1 + .../EventBuilding/include/mbm_writer_impl.hpp | 20 +- Online/EventBuilding/options/EB_RU_algo.opts | 2 +- .../options/EB_Transport_properties.opts | 4 +- Online/EventBuilding/src/BU.cpp | 51 +-- Online/EventBuilding/src/pcie40_reader.cpp | 10 +- Online/FarmConfig/job/Controller.sh | 2 +- Online/FarmConfig/job/EBPass.sh | 35 +- Online/FarmConfig/options/EBMBM.opts | 2 +- .../GaudiOnline/components/EventProcessor.cpp | 11 +- Online/GaudiOnline/components/InputAlg.cpp | 28 +- Online/GaudiOnline/components/InputAlg.h | 7 + .../GaudiOnline/components/OnlineEventApp.cpp | 19 + Online/GaudiOnline/components/Passthrough.cpp | 12 +- Online/GaudiOnline/src/EventAccess.cpp | 25 +- Online/OnlineBase/src/MBM/mbmlib_client.cpp | 4 +- Online/OnlineBase/src/MBM/mbmlib_server.cpp | 3 +- Online/PCIE40Data/PCIE40Data/RawBank40.h | 175 ++++++---- Online/PCIE40Data/PCIE40Data/pcie40.h | 74 ++-- Online/PCIE40Data/PCIE40Data/pcie40_writer.h | 10 +- Online/PCIE40Data/src/pcie40decoder.cpp | 107 +++--- Online/Storage/Storage/fdb_dbase.h | 113 ++++-- Online/Storage/Storage/fdb_server.h | 12 +- Online/Storage/src/server/fdb_SQLite.cpp | 328 ++++++++---------- Online/Storage/src/server/fdb_SQLite.h | 135 ++----- Online/Storage/src/server/fdb_SQLite_bind.cpp | 56 +-- .../Storage/src/server/fdb_SQLite_direct.cpp | 147 -------- Online/Storage/src/server/fdb_db_server.cpp | 32 +- Online/Storage/src/server/fdb_dbase.cpp | 217 ++++++++++++ Online/Storage/src/server/sqlite_test.cpp | 91 ++--- Online/Tell1Data/Tell1Data/Tell1Bank.h | 178 +++++----- 35 files changed, 1055 insertions(+), 876 deletions(-) create mode 100644 Online/Storage/src/server/fdb_dbase.cpp diff --git a/Online/Dataflow/options/StorageWriter.opts b/Online/Dataflow/options/StorageWriter.opts index cd7003a10..1bb434963 100644 --- a/Online/Dataflow/options/StorageWriter.opts +++ b/Online/Dataflow/options/StorageWriter.opts @@ -27,15 +27,16 @@ MBM.Buffers = {"Events"}; Manager.Algorithms = {"Dataflow_StorageWriter/Writer"}; Writer.Server = "XXEB09.lbdaq.cern.ch:8000"; Writer.Mount = "/objects/data/testing"; -Writer.FileSizeMB = 800; Writer.FileSizeMB = 40; +Writer.FileSizeMB = 800; +Writer.FileSizeMB = 100; Writer.MinFileSizeMB = 10; Writer.WriteErrorRetry = 100000; Writer.WriteErrorSleep = 3000; Writer.FileNameFormat = 1; Writer.PollTimeout = 100000; // micro-seconds -Writer.NumBuffers = 6; -Writer.NumThreads = 4; +Writer.NumBuffers = 5; +Writer.NumThreads = 3; Writer.CancelTimeout = 100; // seconds Writer.ForceMDF = true; // diff --git a/Online/Dataflow/src/Storage/StorageWriter.cpp b/Online/Dataflow/src/Storage/StorageWriter.cpp index c8b61a392..e5851dd8d 100644 --- a/Online/Dataflow/src/Storage/StorageWriter.cpp +++ b/Online/Dataflow/src/Storage/StorageWriter.cpp @@ -419,9 +419,9 @@ string StorageWriter::makeFileName() const { ::gmtime_r(&now, &tm); ::strftime(txt1,sizeof(txt1),"%Y-%m-%d__%H-%M",&tm); ::strftime(txt2,sizeof(txt2),"%H-%M-%S",&tm); - ::snprintf(fname, sizeof(fname), "%s/%010d/%s/%010d_%s_%s_%d.raw", + ::snprintf(fname, sizeof(fname), "%s/%010d/%s/%010d_%s_%s_%06d_%d.raw", m_mount.c_str(), m_curr_run, txt1, m_curr_run, - RTL::nodeNameShort().c_str(), txt2, ++seq); + RTL::nodeNameShort().c_str(), txt2, ::lib_rtl_pid(), ++seq); break; } case 0: // Fall-through diff --git a/Online/Dataflow/src/framework/Receiver.cpp b/Online/Dataflow/src/framework/Receiver.cpp index 42d0d644f..aa4954290 100755 --- a/Online/Dataflow/src/framework/Receiver.cpp +++ b/Online/Dataflow/src/framework/Receiver.cpp @@ -59,10 +59,10 @@ int Receiver::initialize() { if ( DF_SUCCESS == sc ) { try { m_recvEvents = true; - declareMonitor("Events","IN", m_recvReq=0, "Total number of events received."); - declareMonitor("Events","OUT", m_evtDecl=0, "Total number of events declared to MBM."); - declareMonitor("ErrorsIn", m_recvError=0, "Total number of receive errors."); - declareMonitor("BytesIn", m_recvBytes=0, "Total number of bytes received from clients."); + declareMonitor("Events", "IN", m_recvReq=0, "Total number of events received."); + declareMonitor("Events", "OUT", m_evtDecl=0, "Total number of events declared to MBM."); + declareMonitor("ErrorsIn", m_recvError=0, "Total number of receive errors."); + declareMonitor("BytesIn", m_recvBytes=0, "Total number of bytes received from clients."); if ( 0 == context.mbm ) return error("Failed to access buffer manager service."); else if ( DF_SUCCESS != (sc=subscribeNetwork()) ) diff --git a/Online/EventBuilding/EventBuilding/BU.hpp b/Online/EventBuilding/EventBuilding/BU.hpp index 68a63dd46..7a95bd047 100644 --- a/Online/EventBuilding/EventBuilding/BU.hpp +++ b/Online/EventBuilding/EventBuilding/BU.hpp @@ -114,6 +114,7 @@ namespace EB { int _MEP_count = 0; int _discarted_MEP_count = 0; int _incomplete_MEP_count = 0; + int _corrupted_MEP_count = 0; std::vector<int> _incomplete_MEP_srcs; buffer_interface::Buffer_writer<MEP::MEP_header>* _recv_buff; diff --git a/Online/EventBuilding/include/mbm_writer.hpp b/Online/EventBuilding/include/mbm_writer.hpp index 9f67343b8..b1152826f 100644 --- a/Online/EventBuilding/include/mbm_writer.hpp +++ b/Online/EventBuilding/include/mbm_writer.hpp @@ -38,6 +38,7 @@ public: protected: Online::DataflowComponent::Context* _context; std::unique_ptr<MBM::Producer> _producer; + }; #include "mbm_writer_impl.hpp" diff --git a/Online/EventBuilding/include/mbm_writer_impl.hpp b/Online/EventBuilding/include/mbm_writer_impl.hpp index 2251637f0..732082a66 100644 --- a/Online/EventBuilding/include/mbm_writer_impl.hpp +++ b/Online/EventBuilding/include/mbm_writer_impl.hpp @@ -57,7 +57,7 @@ T* Mbm_writer<T>::try_write_next_element(size_t size) status = _producer->getSpaceTry(size); - if (status == MBM_NORMAL) { + if(status == MBM_NORMAL){ MBM::EventDesc& dsc = _producer->event(); ret_val = reinterpret_cast<T*>(dsc.data); dsc.len = size; @@ -68,15 +68,6 @@ T* Mbm_writer<T>::try_write_next_element(size_t size) dsc.mask[1] = ~0x0; dsc.mask[2] = ~0x0; dsc.mask[3] = ~0x0; - - // TODO move this to write_complete - status = _producer->declareEvent(); - if (status != MBM_NORMAL) { - // TODO add proper error handling, like cancelling pending requests - std::ostringstream err_mess; - err_mess << "Mbm_writer: write_complete declareEvent error " << status; - throw std::runtime_error(err_mess.str()); - } } else if (status == MBM_NO_ROOM) { ret_val = NULL; } else { @@ -91,6 +82,7 @@ T* Mbm_writer<T>::try_write_next_element(size_t size) template<class T> void Mbm_writer<T>::write_complete() { + // TODO status and ret_Val should consistent int status; if (!this->is_set()) { std::ostringstream err_mess; @@ -98,6 +90,14 @@ void Mbm_writer<T>::write_complete() throw std::logic_error(err_mess.str()); } + status = _producer->declareEvent(); + if (status != MBM_NORMAL) { + // TODO add proper error handling, like cancelling pending requests + std::ostringstream err_mess; + err_mess << "Mbm_writer: write_complete declareEvent error " << status; + throw std::runtime_error(err_mess.str()); + } + status = _producer->sendSpace(); if (status != MBM_NORMAL) { // TODO add proper error handling, like cancelli pending requests diff --git a/Online/EventBuilding/options/EB_RU_algo.opts b/Online/EventBuilding/options/EB_RU_algo.opts index ad70f5203..793a81403 100755 --- a/Online/EventBuilding/options/EB_RU_algo.opts +++ b/Online/EventBuilding/options/EB_RU_algo.opts @@ -1,6 +1,6 @@ RU.MDF_filename = "/home/fpisani/mc_data/biger_file.mdf"; RU.PCIe40_ids = {}; -RU.PCIe40_names = { 'tdtel022_0', 'tdtel022_1', 'tdtel031_0', 'tdtel031_1', 'tdtel032_0', 'tdtel033_0', 'tdtel033_1', 'tdtel042_0', 'tdtel042_1' }; +RU.PCIe40_names = { 'tdtel022_0', 'tdtel022_1', 'tdtel041_0', 'tdtel041_1', 'tdtel042_0', 'tdtel042_1', 'tdtel043_0', 'tdtel043_1', 'tdtel062_0', 'tdtel062_1', 'tdtel063_0', 'tdtel063_1' }; RU.PCIe40_timeout = 30; RU.buffer_sizes = {}; RU.buffer_type = { 3, 3, 3, 3, 3, 3 }; diff --git a/Online/EventBuilding/options/EB_Transport_properties.opts b/Online/EventBuilding/options/EB_Transport_properties.opts index f44bef70b..9ce1e0eb8 100755 --- a/Online/EventBuilding/options/EB_Transport_properties.opts +++ b/Online/EventBuilding/options/EB_Transport_properties.opts @@ -2,7 +2,7 @@ EB_transport.BU_ranks = {}; EB_transport.MPI_errors_return = FALSE; EB_transport.RU_ranks = {}; EB_transport.RUs_per_nic = {}; -EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.d25197.json"; +EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.J25197.json"; EB_transport.n_par_mess = 0; -EB_transport.n_sources_per_ru = { 1, 1, 3, 2, 1, 1 }; +EB_transport.n_sources_per_ru = { 1, 1, 3, 3, 2, 2 }; EB_transport.src_ids = {}; diff --git a/Online/EventBuilding/src/BU.cpp b/Online/EventBuilding/src/BU.cpp index 3b4ecc4bd..d16903321 100644 --- a/Online/EventBuilding/src/BU.cpp +++ b/Online/EventBuilding/src/BU.cpp @@ -36,6 +36,7 @@ EB::BU::BU(const std::string& nam, DataflowContext& ctxt) : Transport_unit(nam, declareMonitor("MEP_counter", _MEP_count, "Number of build MEPs in the RUN"); declareMonitor("discarted_MEP_counter", _discarted_MEP_count, "Number of discarted MEPs in the RUN"); declareMonitor("incomplete_MEP_counter", _incomplete_MEP_count, "Number of incomplete MEPs in the RUN"); + declareMonitor("corrupted_MEP_counter", _corrupted_MEP_count, "Number of corrupted MEPs in the RUN"); logger.set_name(name); } @@ -431,31 +432,34 @@ int EB::BU::run() // At the end of the run there is no MEP to check if (!_end_of_run) { - check_MEP(); - - if (logger.is_active(Online::PrintLevel::DEBUG)) { - logger.debug << "active MEP\n"; - if (logger.is_active(Online::PrintLevel::VERBOSE)) { - _curr_mep->print(logger.verbose, true); - logger.verbose << std::flush; - } else { - _curr_mep->print(logger.debug, false); + if(check_MEP()){ + if (logger.is_active(Online::PrintLevel::DEBUG)) { + logger.debug << "active MEP\n"; + if (logger.is_active(Online::PrintLevel::VERBOSE)) { + _curr_mep->print(logger.verbose, true); + logger.verbose << std::flush; + } else { + _curr_mep->print(logger.debug, false); + } + logger.debug << std::flush; } - logger.debug << std::flush; - } - if (_write_to_file[_my_idx]) { - // TODO add error checking - _file_writer.write(_curr_mep); - } + if (_write_to_file[_my_idx]) { + // TODO add error checking + _file_writer.write(_curr_mep); + } - _curr_mep = NULL; - if (_discarted) { - _discard_buff->write_complete(); - _discarted_MEP_count++; + _curr_mep = NULL; + if (_discarted) { + _discard_buff->write_complete(); + _discarted_MEP_count++; + } else { + _recv_buff->write_complete(); + _MEP_count++; + } } else { - _recv_buff->write_complete(); - _MEP_count++; + logger.error << " CORRUPTED MEP received" << std::flush; + _corrupted_MEP_count++; } } @@ -651,7 +655,7 @@ bool EB::BU::check_MEP() reinterpret_cast<MFP::MFP_header*>(mep_start + _data_offset_words[k] * MEP::MEP_WORD_SIZE); if (!header->is_valid()) { logger.error << "corrupted MEP: invalid header\n"; - _curr_mep->print(logger.error, true); + _curr_mep->print(logger.debug, true); logger.error << std::flush; return false; } @@ -660,7 +664,7 @@ bool EB::BU::check_MEP() curr_ev_id = header->ev_id; } else if (curr_ev_id != header->ev_id) { logger.error << "corrupted MEP: mixed ev ids got " << header->ev_id << " expected " << curr_ev_id << "\n"; - _curr_mep->print(logger.error, true); + _curr_mep->print(logger.debug, true); logger.error << std::flush; return false; } @@ -735,6 +739,7 @@ void EB::BU::reset_counters() logger.info << "resetting counters" << std::flush; _MEP_count = 0; _discarted_MEP_count = 0; + _corrupted_MEP_count = 0; _incomplete_MEP_count = 0; std::fill(_incomplete_MEP_srcs.begin(), _incomplete_MEP_srcs.end(), 0); } diff --git a/Online/EventBuilding/src/pcie40_reader.cpp b/Online/EventBuilding/src/pcie40_reader.cpp index 9794750a6..7edbfb863 100644 --- a/Online/EventBuilding/src/pcie40_reader.cpp +++ b/Online/EventBuilding/src/pcie40_reader.cpp @@ -452,6 +452,14 @@ int PCIe40_frag_reader::build_MFP() get_padding(_size_list.back(), 1 << _align); MFP::MFP_header* new_header = _internal_buffer_writer.try_write_next_element(MFP_size); if (new_header != NULL) { + if((_frag_list.size() != _type_list.size()) || (_frag_list.size() != _size_list.size())){ + bool flag = true; + while(flag){ + sleep(1); + } + } + + new_header->magic = MFP::MFP_magic; new_header->n_banks = _frag_list.size(); new_header->packet_size = MFP_size; @@ -520,4 +528,4 @@ void PCIe40_frag_reader::cancel() std::vector<std::tuple<void*, size_t>> PCIe40_frag_reader::get_full_buffer() { return _internal_buffer_reader.get_full_buffer(); -} \ No newline at end of file +} diff --git a/Online/FarmConfig/job/Controller.sh b/Online/FarmConfig/job/Controller.sh index da768bfa6..548fde6fe 100755 --- a/Online/FarmConfig/job/Controller.sh +++ b/Online/FarmConfig/job/Controller.sh @@ -37,7 +37,7 @@ if test -z "${DIM_DNS_NODE}"; then fi; # exec -a ${UTGID} `which gentest.exe` libSmiController.so smi_controller \ - -print=3 \ + -print=4 \ -logger=fifo \ -part=${PARTITION_NAME} \ -dns=${DIM_DNS_NODE} \ diff --git a/Online/FarmConfig/job/EBPass.sh b/Online/FarmConfig/job/EBPass.sh index a282a8614..c0b2fc734 100755 --- a/Online/FarmConfig/job/EBPass.sh +++ b/Online/FarmConfig/job/EBPass.sh @@ -9,39 +9,46 @@ # # ========================================================================= # -cat > /tmp/${UTGID}.py <<EOF +rm -rf /tmp/${UTGID}.py; +# +cat > /tmp/${UTGID}.py <</EOF import Configurables import GaudiOnline -import OnlineEnvBase +import OnlineEnvBase as OnlineEnv import os from Configurables import Online__FlowManager as FlowManager -application = GaudiOnline.Passthrough(outputLevel=OnlineEnvBase.OutputLevel, - partitionName=OnlineEnvBase.PartitionName, - partitionID=OnlineEnvBase.PartitionID, +application = GaudiOnline.Passthrough(outputLevel=OnlineEnv.OutputLevel, + partitionName=OnlineEnv.PartitionName, + partitionID=OnlineEnv.PartitionID, classType=GaudiOnline.Class1) items = os.environ['UTGID'].split('_') id = items[-1] application.setup_fifolog() -application.log(GaudiOnline.MSG_INFO,'+++ OnlineEnv: %s Level:%d',OnlineEnvBase.__file__,OnlineEnvBase.OutputLevel) +application.log(GaudiOnline.MSG_INFO,'+++ OnlineEnv: %s Level:%d',OnlineEnv.__file__,OnlineEnv.OutputLevel) application.setup_mbm_access('Events_'+id, True) writer = None writer = application.setup_mbm_output('EventOutput') writer.MBM_buffer = 'Output' writer.MBM_maxConsumerWait = 10 # -application.setup_hive(FlowManager("EventLoop"), 40) -application.setup_algorithms(writer, 0.05) +application.setup_hive(FlowManager("EventLoop"), 30) +application.setup_algorithms(writer=writer, acceptRate=0.01) application.setup_monitoring() +# +# application.monSvc.DimUpdateInterval = 1 application.config.numEventThreads = 1 -application.config.MBM_numConnections = 1 -application.config.MBM_numEventThreads = 1 +application.config.MBM_numConnections = 7 +application.config.MBM_numEventThreads = 8 application.config.MBM_requests = [ - 'EvType=3;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0', - 'EvType=2;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0', - 'EvType=1;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=USER;Frequency=PERC;Perc=100.0' + 'EvType=3;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=100.0', + 'EvType=2;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=100.0', + 'EvType=1;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=100.0' ] -EOF +/EOF +# +# export PYTHONPATH=/group/online/dataflow/options/${PARTITION}/HLT:${PYTHONPATH}; +export RTL_SLEEP_ON_FATAL=1; exec -a ${UTGID} python `which gaudirun.py` /tmp/${UTGID}.py --application=OnlineEvents diff --git a/Online/FarmConfig/options/EBMBM.opts b/Online/FarmConfig/options/EBMBM.opts index bbc5f2dae..cd3a10d31 100644 --- a/Online/FarmConfig/options/EBMBM.opts +++ b/Online/FarmConfig/options/EBMBM.opts @@ -6,4 +6,4 @@ Manager.Setup = {"Dataflow_MBMServer/MEPManager"}; Manager.Services = {"Dataflow_UI/UI"}; MEPManager.PartitionBuffers = @OnlineEnv.PartitionBuffers; MEPManager.PartitionName = @OnlineEnv.PartitionName; -MEPManager.InitFlags = "-s=1000000 -e=20 -u=30 -b=12 -t=2 -f -i=Events_0 -c -s=1000000 -e=20 -u=30 -b=12 -f -i=Events_1 -c -s=500000 -e=30 -u=10 -b=12 -f -i=Output -c"; +MEPManager.InitFlags = "-s=1000000 -e=50 -u=20 -b=12 -t=1 -n=0 -f -i=Events_0 -c -s=1000000 -e=50 -u=20 -b=12 -t=1 -n=1 -f -i=Events_1 -c -s=500000 -e=50 -u=5 -b=12 -t=1 -f -i=Output -c"; diff --git a/Online/GaudiOnline/components/EventProcessor.cpp b/Online/GaudiOnline/components/EventProcessor.cpp index 0f539d242..0f8a0f90e 100644 --- a/Online/GaudiOnline/components/EventProcessor.cpp +++ b/Online/GaudiOnline/components/EventProcessor.cpp @@ -121,10 +121,15 @@ namespace Online { for(size_t i=0; i < event->num_bank_collections(); ++i) { const auto* bc = event->bank_collection(i); for(const auto* b=bc->begin(); b != bc->end(); b = bc->next(b)) { - result->adoptBank((LHCb::RawBank*)b, false); + if ( b->type() < b->LastType ) { + result->adoptBank((LHCb::RawBank*)b, false); + } + } + for(const auto* b=bc->special_begin(); b != bc->special_end(); b = bc->next(b)) { + if ( b->type() < b->LastType ) { + result->adoptBank((LHCb::RawBank*)b, false); + } } - for(const auto* b=bc->special_begin(); b != bc->special_end(); b = bc->next(b)) - result->adoptBank((LHCb::RawBank*)b, false); } return result; } diff --git a/Online/GaudiOnline/components/InputAlg.cpp b/Online/GaudiOnline/components/InputAlg.cpp index 04ca7fdeb..98a8a434f 100644 --- a/Online/GaudiOnline/components/InputAlg.cpp +++ b/Online/GaudiOnline/components/InputAlg.cpp @@ -56,6 +56,28 @@ StatusCode Online::InputAlg::stop() { return StatusCode::SUCCESS; } +/// Add error banks to the data service +Online::InputAlg::daq_error_t +Online::InputAlg::get_errors(const event_traits::record_t& record) const { + daq_error_t banks; + auto* event = record.tell40_event; + for(size_t i=0; i < event->num_bank_collections(); ++i) { + const auto* bc = event->bank_collection(i); + for(const auto* b=bc->begin(); b != bc->end(); b = bc->next(b)) { + if ( b->type() >= RawBank40::DaqErrorBase ) { + banks.emplace_back(b); + } + } + for(const auto* b=bc->special_begin(); b != bc->special_end(); b = bc->next(b)) { + if ( b->type() < b->LastType ) { + banks.emplace_back(b); + } + } + } + return banks; +} + + /// Execute single event StatusCode Online::InputAlg::process(EventContext const& /* ctxt */) const { EventAccess::event_t e(m_io->pop()); @@ -65,7 +87,11 @@ StatusCode Online::InputAlg::process(EventContext const& /* ctxt */) const { event = create_event<event_traits::tell1>(e.second->at(e.first)); } else if ( e.second->type() == event_traits::tell40::data_type ) { - event = create_event<event_traits::tell40>(e.second->at(e.first)); + const auto& record = e.second->at(e.first); + event = create_event<event_traits::tell40>(record); + if ( m_declareData.value() ) { + m_daqError.put(move(get_errors(record))); + } } if ( m_declareData.value() ) { m_rawEvent.put(move(event)); diff --git a/Online/GaudiOnline/components/InputAlg.h b/Online/GaudiOnline/components/InputAlg.h index a920a5638..b4a99e369 100644 --- a/Online/GaudiOnline/components/InputAlg.h +++ b/Online/GaudiOnline/components/InputAlg.h @@ -32,12 +32,16 @@ namespace Online { class InputAlg : public EventProcessor { protected: + typedef std::vector<const RawBank40*> daq_error_t; + Gaudi::Property<bool> m_declareData{this,"DeclareData", true, "Declare or drop data"}; Gaudi::Property<bool> m_enableHalt{this, "EnableHalt", true, "Enable halt the event loop"}; Gaudi::Property<std::string> m_ioService{this, "IOServiceName","Online::IOService/IOService","Name of IO service"}; DataObjectWriteHandle<LHCb::RawEvent> m_rawEvent{this, "RawLocation", LHCb::RawEventLocation::Default}; DataObjectWriteHandle<evt_desc_t> m_rawGuard{this, "RawGuard", LHCb::RawEventLocation::Default+"Guard"}; + DataObjectWriteHandle<daq_error_t> m_daqError{this, "DAQErrors", LHCb::RawEventLocation::Default+"DAQErrors"}; + /// Reference to the I/O service SmartIF<IOService> m_io; @@ -46,6 +50,9 @@ namespace Online { /// Allow to escape halt mutable int m_halt; + /// Add error banks to the data service + daq_error_t get_errors(const event_traits::record_t& record) const; + public: using EventProcessor::EventProcessor; /// Initialize the algorithm diff --git a/Online/GaudiOnline/components/OnlineEventApp.cpp b/Online/GaudiOnline/components/OnlineEventApp.cpp index 67f495c91..16cb0324e 100644 --- a/Online/GaudiOnline/components/OnlineEventApp.cpp +++ b/Online/GaudiOnline/components/OnlineEventApp.cpp @@ -259,6 +259,25 @@ int OnlineEventApp::startApplication() { for(size_t i=0; i<m_config->mbm.num_event_threads; ++i) m_eventAccess.emplace_back(make_unique<thread>(&OnlineEventApp::event_access,ref(*this),i)); +#if 0 + static bool first = true; + if ( first ) { + static sa_sigaction new_act; + static sa_sigaction old_act; + first = false; + new_act.sa_handler = nullptr; + new_act.sa_sigaction = segv_handler; + new_act.sa_flags = SA_SIGINFO; + new_act.sa_mask = 0; + new_act.sa_restorer = nullptr; + sigemptyset(&new_act.sa_mask); + sigaddset(&new_act.sa_mask,SIGSEGV); + + if ( 0 != ::sigaction(SIGSEGV, &new_act, &old_act) ) { + m_logger->error("+++ Failed to install SEGV handler."); + } + } +#endif return status; } return m_logger->error("+++ Inconsistent thread state! [FSM failure]"); diff --git a/Online/GaudiOnline/components/Passthrough.cpp b/Online/GaudiOnline/components/Passthrough.cpp index 32387b86e..5393fb9a2 100644 --- a/Online/GaudiOnline/components/Passthrough.cpp +++ b/Online/GaudiOnline/components/Passthrough.cpp @@ -145,11 +145,13 @@ StatusCode Passthrough::execute(EventContext const& ctxt) const { } /// If mothing is specified everything will be downscaled - if ( m_downScale.empty() && m_rate < 1.0 ) { - double frac = double(::rand()) / double(RAND_MAX); - if ( m_rate < frac ) { - execState(ctxt).setFilterPassed(false); - return _halt(delay); + if ( m_downScale.empty() && m_triggerTypesToPass.empty() && m_calibTypesToPass.empty() ) { + if ( m_rate < 1.0 ) { + double frac = double(::rand()) / double(RAND_MAX); + if ( m_rate < frac ) { + execState(ctxt).setFilterPassed(false); + return _halt(delay); + } } execState(ctxt).setFilterPassed(true); return _halt(delay); diff --git a/Online/GaudiOnline/src/EventAccess.cpp b/Online/GaudiOnline/src/EventAccess.cpp index 4d095c1b5..6b7c2b547 100644 --- a/Online/GaudiOnline/src/EventAccess.cpp +++ b/Online/GaudiOnline/src/EventAccess.cpp @@ -247,25 +247,35 @@ namespace { /// The event is a PCIE40 MEP structure with multiple events, which must be decoded std::unique_ptr<pcie40::event_collection_t> EventAccess::convertPCIE40MEP(datapointer_t start, size_t len) const { - datapointer_t end = start + len; std::unique_ptr<pcie40::event_collection_t> events; + datapointer_t end = start + len; + pcie40::decoder_t decoder; + if ( end > start ) { - pcie40::decoder_t decoder; static constexpr size_t max_bank = 20000; static constexpr size_t max_source = 2000; static constexpr size_t max_packing = 35000; const auto* pmep_hdr = reinterpret_cast<const pcie40::mep_header_t*>(start); if ( 0 == pmep_hdr->size ) { m_logger->error("MEP with invalid size encountered: %d", pmep_hdr->size); + decoder.initialize(events,0); return events; } if ( 0 == pmep_hdr->num_source || pmep_hdr->num_source > max_source ) { m_logger->error("MEP with invalid number of sources encountered: %d", pmep_hdr->num_source); + decoder.initialize(events,0); return events; } - uint32_t packing = pmep_hdr->multi_fragment(0)->header.packing; + uint32_t packing = pmep_hdr->multi_fragment(0)->header.packing; if ( 0 == packing || packing > max_packing ) { - m_logger->error("MEP with invalid packing factor encountered: %d", packing); + decoder.initialize(events,0); + try { + throw std::runtime_error("MEP with invalid packing factor encountered"); + } + catch(...) { + m_logger->error("MEP with invalid packing factor encountered: %d", packing); + return events; + } return events; } /// Header checks done. Now decode the buffer @@ -283,6 +293,12 @@ EventAccess::convertPCIE40MEP(datapointer_t start, size_t len) const { } ++num_bank; } + for( const pcie40::bank_t* b=coll->special_begin(); b != coll->special_end(); b=coll->next(b) ) { + if ( b->magic() != pcie40::bank_t::MagicPattern ) { + _error("Bad magic pattern in raw bank!\n"); + } + ++num_bank; + } } if ( num_bank == 0 ) { m_logger->error("Event with ZERO banks encountered"); @@ -294,6 +310,7 @@ EventAccess::convertPCIE40MEP(datapointer_t start, size_t len) const { return events; } m_logger->error("convertMultiMDF: Encountered empty MDF burst!"); + decoder.initialize(events,0); return events; } diff --git a/Online/OnlineBase/src/MBM/mbmlib_client.cpp b/Online/OnlineBase/src/MBM/mbmlib_client.cpp index 095294c99..6abede2e1 100755 --- a/Online/OnlineBase/src/MBM/mbmlib_client.cpp +++ b/Online/OnlineBase/src/MBM/mbmlib_client.cpp @@ -146,9 +146,9 @@ int _mbm_shutdown (void* /* param */) { } ::lib_rtl_sleep(200); for(int i=0; i<cnt; ++i) { // Now close communication channels and - bm = ids[i]; // unmape the global sections. + bm = ids[i]; // unmape the global sections if owned. bm->communication.close_server(); - if ( bm->buff_add ) { + if ( bm->buff_add && bm->own_buffer ) { ::lib_rtl_unmap_section(bm->buff_add); } bm->buff_add = 0; diff --git a/Online/OnlineBase/src/MBM/mbmlib_server.cpp b/Online/OnlineBase/src/MBM/mbmlib_server.cpp index e86943c30..0c3d206e7 100755 --- a/Online/OnlineBase/src/MBM/mbmlib_server.cpp +++ b/Online/OnlineBase/src/MBM/mbmlib_server.cpp @@ -1247,7 +1247,8 @@ int mbmsrv_get_event(ServerBMID bm, MSG& msg) { ServerBMID_t::LOCK lock(bm->lockid); USER* u = CHECKED_CONSUMER(msg.user); if ( u->state == S_wevent ) { - ::lib_rtl_output(LIB_RTL_ERROR,"++bm_server++ Too many calls to mbm_get_event\n"); + ::lib_rtl_output(LIB_RTL_ERROR,"++bm_server++ Too many calls to " + "mbm_get_event '%s'\n", u->name); return MBM_NO_REPLY; } _mbmsrv_rel_event(bm, u); diff --git a/Online/PCIE40Data/PCIE40Data/RawBank40.h b/Online/PCIE40Data/PCIE40Data/RawBank40.h index 78d20aaf3..d896a1073 100644 --- a/Online/PCIE40Data/PCIE40Data/RawBank40.h +++ b/Online/PCIE40Data/PCIE40Data/RawBank40.h @@ -68,84 +68,105 @@ namespace Online { /// Dummy Constructor RawBank40() = default; - enum BankType { - Other=1, - L0Calo=0, // 0 - L0DU, // 1 - PrsE, // 2 - EcalE, // 3 - HcalE, // 4 - PrsTrig, // 5 - EcalTrig, // 6 - HcalTrig, // 7 - Velo, // 8 - Rich, // 9 - TT, // 10 - IT, // 11 - OT, // 12 - Muon, // 13 - L0PU, // 14 - DAQ, // 15 - ODIN, // 16 - HltDecReports, // 17 - VeloFull, // 18 - TTFull, // 19 - ITFull, // 20 - EcalPacked, // 21 - HcalPacked, // 22 - PrsPacked, // 23 - L0Muon, // 24 - ITError, // 25 - TTError, // 26 - ITPedestal, // 27 - TTPedestal, // 28 - VeloError, // 29 - VeloPedestal, // 30 - VeloProcFull, // 31 - OTRaw, // 32 - OTError, // 33 - EcalPackedError, // 34 - HcalPackedError, // 35 - PrsPackedError, // 36 - L0CaloFull, // 37 - L0CaloError, // 38 - L0MuonCtrlAll, // 39 - L0MuonProcCand, // 40 - L0MuonProcData, // 41 - L0MuonRaw, // 42 - L0MuonError, // 43 - GaudiSerialize, // 44 - GaudiHeader, // 45 - TTProcFull, // 46 - ITProcFull, // 47 - TAEHeader, // 48 - MuonFull, // 49 - MuonError, // 50 - TestDet, // 51 - L0DUError, // 52 - HltRoutingBits, // 53 - HltSelReports, // 54 - HltVertexReports,// 55 - HltLumiSummary, // 56 - L0PUFull, // 57 - L0PUError, // 58 - DstBank, // 59 - DstData, // 60 - DstAddress, // 61 - FileID, // 62 - VP, // 63 - FTCluster, // 64 - VL, // 65 - UT, // 66 - UTFull, // 67 - UTError, // 68 - UTPedestal, // 69 - HC, // 70 - HltTrackReports, // 71 - HCError, // 72 - VPRetinaCluster, // 73 + + /// Define bank types for RawBank + enum BankType { + L0Calo = 0, // 0 + L0DU, // 1 + PrsE, // 2 + EcalE, // 3 + HcalE, // 4 + PrsTrig, // 5 + EcalTrig, // 6 + HcalTrig, // 7 + Velo, // 8 + Rich, // 9 + TT, // 10 + IT, // 11 + OT, // 12 + Muon, // 13 + L0PU, // 14 + DAQ, // 15 + ODIN, // 16 + HltDecReports, // 17 + VeloFull, // 18 + TTFull, // 19 + ITFull, // 20 + EcalPacked, // 21 + HcalPacked, // 22 + PrsPacked, // 23 + L0Muon, // 24 + ITError, // 25 + TTError, // 26 + ITPedestal, // 27 + TTPedestal, // 28 + VeloError, // 29 + VeloPedestal, // 30 + VeloProcFull, // 31 + OTRaw, // 32 + OTError, // 33 + EcalPackedError, // 34 + HcalPackedError, // 35 + PrsPackedError, // 36 + L0CaloFull, // 37 + L0CaloError, // 38 + L0MuonCtrlAll, // 39 + L0MuonProcCand, // 40 + L0MuonProcData, // 41 + L0MuonRaw, // 42 + L0MuonError, // 43 + GaudiSerialize, // 44 + GaudiHeader, // 45 + TTProcFull, // 46 + ITProcFull, // 47 + TAEHeader, // 48 + MuonFull, // 49 + MuonError, // 50 + TestDet, // 51 + L0DUError, // 52 + HltRoutingBits, // 53 + HltSelReports, // 54 + HltVertexReports, // 55 + HltLumiSummary, // 56 + L0PUFull, // 57 + L0PUError, // 58 + DstBank, // 59 + DstData, // 60 + DstAddress, // 61 + FileID, // 62 + VP, // 63 + FTCluster, // 64 + VL, // 65 + UT, // 66 + UTFull, // 67 + UTError, // 68 + UTPedestal, // 69 + HC, // 70 + HltTrackReports, // 71 + HCError, // 72 + VPRetinaCluster, // 73 + FTGeneric, // 74 + FTCalibration, // 75 + FTNZS, // 76 + Calo, // 77 + CaloError, // 78 + MuonSpecial, // 79 + RichCommissioning, // 80 + RichError, // 81 + FTSpecial, // 82 + // Add new types here. Don't forget to update also RawBank.cpp - LastType // LOOP Marker; add new bank types ONLY before! + LastType, // LOOP Marker; add new bank types ONLY before! + Other = 1, + DaqErrorBase = 192, // Lowest DaqError type available in Run 3 (EDMS2100937) + // Banks above are reserved for DAQ, add only generic DaqError types below. + DaqErrorFragmentThrottled = 250, + DaqErrorBXIDCorrupted = 251, + DaqErrorBXIDJump = 252, + DaqErrorFragmentMissing = 253, + DaqErrorFragmentTruncated = 254, + DaqErrorInvalid = 255 + // 255 is the highest type allowed by the Run 3 raw-data format (8-bit unsigned) }; /// Magic pattern for Raw bank headers diff --git a/Online/PCIE40Data/PCIE40Data/pcie40.h b/Online/PCIE40Data/PCIE40Data/pcie40.h index 0eaaa1dab..46089556d 100644 --- a/Online/PCIE40Data/PCIE40Data/pcie40.h +++ b/Online/PCIE40Data/PCIE40Data/pcie40.h @@ -290,8 +290,9 @@ namespace Online { event_t& operator=(const event_t& copy) = delete; public: - static std::pair<bool,size_t> collection_offset(unsigned char type); - std::pair<size_t, const bank_t*> get(unsigned char type) const; + static size_t collection_offset_source_id(unsigned short src_id); + static std::pair<bool,size_t> collection_offset(unsigned short src_id, unsigned char type); + std::pair<size_t, const bank_t*> get(unsigned short src_id, unsigned char type) const; size_t num_bank_collections() const; const bank_collection_t* bank_collection(size_t i) const; size_t total_length() const; @@ -347,6 +348,8 @@ namespace Online { namespace params { typedef unsigned short detsource_t; + static constexpr size_t INVALID_BANK_TYPE = ~0x0UL; + static constexpr detsource_t sourceid_ODIN = 0; static constexpr detsource_t sourceid_VP = 2; static constexpr detsource_t sourceid_UT = 5; @@ -389,14 +392,14 @@ namespace Online { maxTell40Other }; static constexpr size_t collectionSizeODIN = sizeof(bank_collection_t); - static constexpr size_t collectionSizeVP = sizeof(bank_collection_t)+(maxTell40VP-1)*sizeof(bank_t); - static constexpr size_t collectionSizeUT = sizeof(bank_collection_t)+(maxTell40UT-1)*sizeof(bank_t); - static constexpr size_t collectionSizeFT = sizeof(bank_collection_t)+(maxTell40FT-1)*sizeof(bank_t); - static constexpr size_t collectionSizeEcal = sizeof(bank_collection_t)+(maxTell40Ecal-1)*sizeof(bank_t); - static constexpr size_t collectionSizeHcal = sizeof(bank_collection_t)+(maxTell40Hcal-1)*sizeof(bank_t); - static constexpr size_t collectionSizeMuon = sizeof(bank_collection_t)+(maxTell40Muon-1)*sizeof(bank_t); - static constexpr size_t collectionSizeRich = sizeof(bank_collection_t)+(maxTell40Rich-1)*sizeof(bank_t); - static constexpr size_t collectionSizeOther = sizeof(bank_collection_t)+(maxTell40Other-1)*sizeof(bank_t); + static constexpr size_t collectionSizeVP = sizeof(bank_collection_t)+(maxTell40VP*sizeof(bank_t)); + static constexpr size_t collectionSizeUT = sizeof(bank_collection_t)+(maxTell40UT*sizeof(bank_t)); + static constexpr size_t collectionSizeFT = sizeof(bank_collection_t)+(maxTell40FT*sizeof(bank_t)); + static constexpr size_t collectionSizeEcal = sizeof(bank_collection_t)+(maxTell40Ecal*sizeof(bank_t)); + static constexpr size_t collectionSizeHcal = sizeof(bank_collection_t)+(maxTell40Hcal*sizeof(bank_t)); + static constexpr size_t collectionSizeMuon = sizeof(bank_collection_t)+(maxTell40Muon*sizeof(bank_t)); + static constexpr size_t collectionSizeRich = sizeof(bank_collection_t)+(maxTell40Rich*sizeof(bank_t)); + static constexpr size_t collectionSizeOther = sizeof(bank_collection_t)+(maxTell40Other*sizeof(bank_t)); static constexpr size_t collectionOffset = event_t::data_offset; static constexpr size_t collectionOffsetODIN = collectionOffset; @@ -555,37 +558,56 @@ namespace Online { return p; } - inline std::pair<bool,size_t> event_t::collection_offset(unsigned char type) { + inline size_t event_t::collection_offset_source_id(unsigned short src_id) { + switch(src_id) { + case params::sourceid_top5_ODIN: return params::collectionOffsetODIN; + case params::sourceid_top5_VP: return params::collectionOffsetVP; + case params::sourceid_top5_UT: return params::collectionOffsetUT; + case params::sourceid_top5_FT: return params::collectionOffsetFT; + case params::sourceid_top5_Ecal: return params::collectionOffsetEcal; + case params::sourceid_top5_Hcal: return params::collectionOffsetHcal; + case params::sourceid_top5_Muon: return params::collectionOffsetMuon; + case params::sourceid_top5_Rich: return params::collectionOffsetRich; + default: return params::collectionOffsetOther; + } + } + + inline std::pair<bool,size_t> event_t::collection_offset(unsigned short src_id, unsigned char type) { + size_t offset = event_t::collection_offset_source_id(src_id¶ms::sourceid_TOP5); switch ( type ) { case bank_t::ODIN: - return std::make_pair(true,params::collectionOffsetODIN); case bank_t::VP: - return std::make_pair(true,params::collectionOffsetVP); case bank_t::UT: - return std::make_pair(true,params::collectionOffsetUT); - case bank_t::UTFull: - case bank_t::UTError: - case bank_t::UTPedestal: - return std::make_pair(false,params::collectionOffsetUT); case bank_t::FTCluster: - return std::make_pair(true,params::collectionOffsetFT); case bank_t::Rich: - return std::make_pair(true,params::collectionOffsetRich); case bank_t::EcalPacked: - return std::make_pair(true,params::collectionOffsetEcal); case bank_t::HcalPacked: - return std::make_pair(true,params::collectionOffsetHcal); case bank_t::Muon: - return std::make_pair(true,params::collectionOffsetMuon); + return std::make_pair(true,offset); + + case bank_t::UTFull: + case bank_t::UTError: + case bank_t::UTPedestal: + return std::make_pair(false,params::collectionOffsetUT); + case bank_t::Other: + case bank_t::TestDet: return std::make_pair(true,params::collectionOffsetOther); + case bank_t::DaqErrorBase: + case bank_t::DaqErrorFragmentThrottled: + case bank_t::DaqErrorBXIDCorrupted: + case bank_t::DaqErrorBXIDJump: + case bank_t::DaqErrorFragmentMissing: + case bank_t::DaqErrorFragmentTruncated: + case bank_t::DaqErrorInvalid: + return std::make_pair(false,params::collectionOffsetOther); default: - throw std::runtime_error("Unknown bank type!"); + return std::make_pair(false,params::INVALID_BANK_TYPE); } } - inline std::pair<size_t, const bank_t*> event_t::get(unsigned char type) const { - auto ret = event_t::collection_offset(type); + inline std::pair<size_t, const bank_t*> event_t::get(unsigned short src_id, unsigned char type) const { + auto ret = event_t::collection_offset(src_id, type); const auto* c = add_ptr<bank_collection_t>(banks,ret.second); if ( ret.first ) { return std::make_pair(c->length,c->banks); diff --git a/Online/PCIE40Data/PCIE40Data/pcie40_writer.h b/Online/PCIE40Data/PCIE40Data/pcie40_writer.h index 155dd8a30..1769f8144 100644 --- a/Online/PCIE40Data/PCIE40Data/pcie40_writer.h +++ b/Online/PCIE40Data/PCIE40Data/pcie40_writer.h @@ -67,7 +67,7 @@ namespace Online { event_writer_t& operator=(const event_writer_t& copy) = delete; public: - std::pair<size_t, bank_t*> get(unsigned char type); + std::pair<size_t, bank_t*> get(unsigned short src_id, unsigned char type); bank_collection_t* bank_collection(size_t which); }; @@ -121,10 +121,12 @@ namespace Online { return add_ptr<bank_t>(banks, sizeof(bank_t) * which); } - inline std::pair<size_t, bank_t*> event_writer_t::get(unsigned char type) { - auto ret = event_t::collection_offset(type); + inline std::pair<size_t, bank_t*> event_writer_t::get(unsigned short src_id, unsigned char type) { + auto ret = event_t::collection_offset(src_id, type); auto* c = add_ptr<bank_collection_t>(banks, ret.second); - if ( ret.first ) { + if ( ret.second == params::INVALID_BANK_TYPE ) + return std::make_pair(0, nullptr); + else if ( ret.first ) { return std::make_pair(c->length, c->banks); } return std::make_pair(c->specials, add_ptr<bank_t>(c, (c->capacity - c->specials)*sizeof(bank_t))); diff --git a/Online/PCIE40Data/src/pcie40decoder.cpp b/Online/PCIE40Data/src/pcie40decoder.cpp index 5fdf66175..3afadbde0 100644 --- a/Online/PCIE40Data/src/pcie40decoder.cpp +++ b/Online/PCIE40Data/src/pcie40decoder.cpp @@ -21,19 +21,28 @@ #include <cstdarg> #include <vector> #include <map> +#include <unistd.h> using namespace Online; using namespace Online::pcie40; #define __UNLIKELY( x ) __builtin_expect( ( x ), 0 ) + namespace { - void _error(const char* fmt,...) { + + void _error(const char* ,...) {} + + void _error2(const char* fmt,...) { + char text[1024]; va_list args; va_start(args,fmt); - ::vprintf(fmt,args); + ::vsnprintf(text, sizeof(text),fmt,args); va_end(args); + text[sizeof(text)-1] = 0; + ::write(fileno(stdout), text, strlen(text)); } - inline bank_t& allocate_regular_bank(event_t* e, size_t offset) { + + inline bank_t* allocate_regular_bank(event_t* e, size_t offset) { bank_collection_writer_t* c = add_ptr<bank_collection_writer_t>(e,offset); ++c->length; #ifdef PCIE40_ENABLE_CHECKS @@ -47,13 +56,13 @@ namespace { if ( __UNLIKELY(b.magic() != b.MagicPattern) ) { _error("Bad magic pattern in bank!\n"); } - return b; + return &b; #else - return c->banks[c->length-1]; + return &c->banks[c->length-1]; #endif } - inline bank_t& allocate_special_bank(event_t* e, size_t offset) { + inline bank_t* allocate_special_bank(event_t* e, size_t offset) { bank_collection_writer_t* c = add_ptr<bank_collection_writer_t>(e,offset); ++c->specials; #ifdef PCIE40_ENABLE_CHECKS @@ -63,63 +72,79 @@ namespace { if ( c->length + c->specials > c->capacity ) { _error("Bank allocation error: Too many banks!\n"); } - bank_t& b = c->banks[c->length - c->specials]; + bank_t& b = c->banks[c->capacity - c->specials]; if ( b.magic() != b.MagicPattern ) { _error("Bad magic pattern in bank!\n"); } - return b; + return &b; #else - return c->banks[c->capacity - c->specials]; + return &c->banks[c->capacity - c->specials]; #endif } - inline bank_t& allocate_bank(event_t* e, unsigned char type) { - auto ret = event_t::collection_offset(type); - if ( __UNLIKELY(!ret.first) ) - allocate_special_bank(e,ret.second); + inline bank_t* allocate_bank(event_t* e, unsigned short src_id, unsigned char type) { + auto ret = event_t::collection_offset(src_id, type); + if ( __UNLIKELY(ret.second == params::INVALID_BANK_TYPE) ) + return nullptr; + else if ( __UNLIKELY(!ret.first) ) + return allocate_special_bank(e,ret.second); return allocate_regular_bank(e,ret.second); } size_t link_fragment(event_collection_writer_t* ec, const multi_fragment_t* mfp, bool debug) { size_t num_bank = 0; - unsigned short src_id = mfp->header.source_id; + unsigned short src_id = mfp->header.source_id; const size_t align = mfp->header.alignment; const uint8_t version = mfp->header.version; const uint8_t *typs = mfp->types(); const uint16_t *lens = mfp->sizes(); const frontend_data_t *curr = mfp->data(); - for (size_t j = 0, cnt = 0, n=mfp->packingFactor(); cnt<n; ++cnt, ++typs, ++lens) { - auto typx = *typs; + bool run = true; + if ( (const char*)typs > ((const char*)mfp)+6*sizeof(int) ) { + _error2("Inconsistent TYPES pointer\n"); + while(run) ::sleep(1); + } + for (size_t j=0, cnt=0, n=mfp->packingFactor(); cnt<n; ++cnt, ++typs, ++lens) { + auto typx = *typs; + auto length = *lens; event_t* e = ec->at(j); - bank_t& b = allocate_bank(e, typx); -#ifdef PCIE40_ENABLE_CHECKS - if ( __UNLIKELY(e->magic != MAGIC_PATTERN) ) { - _error("Data corruption in event!\n"); - } - if ( __UNLIKELY(b.magic() != b.MagicPattern) ) { - _error("Data corruption in raw bank!\n"); + bank_t* b = allocate_bank(e, src_id, typx); + + if ( nullptr == b ) { + _error2("ERROR +++ Ignore bank: Unknown bank type:%3d Source ID:%3d Size:%4d vsn:%d j:%ld cnt:%ld n:%ld\n", + int(typx), int(src_id), int(length), int(version), j, cnt, n); + while(run) ::sleep(1); } + else { +#ifdef PCIE40_ENABLE_CHECKS + if ( __UNLIKELY(e->magic != MAGIC_PATTERN) ) { + _error("Data corruption in event!\n"); + } + if ( __UNLIKELY(b->magic() != b->MagicPattern) ) { + _error("Data corruption in raw bank!\n"); + } #endif - const void* data = curr->data(); - if ( debug ) { - ::printf("+++ Reading bank[%2ld] at %p len:%4d %p typ:%3d src:%3d vsn:%d\n", - cnt, (void*)data, int(*lens), (void*)((char*)data + *lens), - typx, src_id, version); - } - //b.setMagic(); - b.setSize(*lens); - b.setSourceID(src_id); - b.setData(data); - b.setType((RawBank40::BankType)typx); - b.setVersion(version); + const void* data = curr->data(); + if ( debug ) { + ::printf("+++ Reading bank[%2ld] at %p len:%4d %p typ:%3d src:%3d vsn:%d\n", + cnt, (void*)data, int(length), (void*)((char*)data + length), + typx, src_id, version); + } + //b->setMagic(); + b->setSize(length); + b->setSourceID(src_id); + b->setData(data); + b->setType((RawBank40::BankType)typx); + b->setVersion(version); #if 0 - int* p1 = (int*)b.data(); - int* p2 = (int*)curr->data(); - for(size_t i=0; i<b.size()/sizeof(int); ++i) - p1[i] = p2[i]; + int* p1 = (int*)b->data(); + int* p2 = (int*)curr->data(); + for(size_t i=0; i<b->size()/sizeof(int); ++i) + p1[i] = p2[i]; #endif - ++num_bank; - curr = curr->next(*lens, align); + ++num_bank; + } + curr = curr->next(length, align); ++j; } return num_bank; diff --git a/Online/Storage/Storage/fdb_dbase.h b/Online/Storage/Storage/fdb_dbase.h index aa8050fd3..f4c2415d7 100644 --- a/Online/Storage/Storage/fdb_dbase.h +++ b/Online/Storage/Storage/fdb_dbase.h @@ -47,6 +47,73 @@ namespace Online { static std::unique_ptr<fdb_dbase_t> create(Args... args); public: + + /// Data file properties + /** + * + * \author M.Frank + * \version 1.0 + * \date 02.02.2021 + */ + struct file_t { + std::string name, state, size, date, host; + }; + + /// Interface class to database handler + /** + * To implement a new database technology in principle only + * this class needs to be re-implemented e.g. using MYSQL. + * + * \author M.Frank + * \version 1.0 + * \date 02.02.2021 + */ + class handler_t { + public: + typedef fdb_dbase_t::file_t file_t; + static constexpr int STATE_OPEN = 0; + static constexpr int STATE_WRITTEN = 1; + static constexpr int STATE_READ = 2; + + bool _inited = false; + int _debug { 0 }; + + /// Check the existence of a given object in the database + virtual boost::system::error_code + query_file(const std::string& object_name, file_t& file, int state) = 0; + + public: + + /// Initializing constructor + handler_t(int dbg); + + /// Default destructor + virtual ~handler_t(); + + /// Check the existence of a given object in the database + virtual boost::system::error_code query(std::string& object, + std::string& host, + std::string& date, + std::size_t& length); + + /// Check the existence of a given object in the database + virtual boost::system::error_code next( std::string& object, + std::string& host, + std::string& date, + std::size_t& length); + + /// Add a new object to the database + virtual boost::system::error_code add( const std::string& object, + const std::string& date, + std::size_t length, + const std::string& host) = 0; + + /// Remove an object from the database + virtual boost::system::error_code del( const std::string& object) = 0; + + /// lock database record + virtual boost::system::error_code set( const std::string& object, int value) = 0; + }; /// File database lock /** * \author M.Frank @@ -56,6 +123,7 @@ namespace Online { class lock_t final { /// Reference to locked object fdb_dbase_t* fdb; + public: /// Standard constructor lock_t(fdb_dbase_t* db) : fdb(db) { fdb->lock(); } @@ -63,59 +131,60 @@ namespace Online { ~lock_t() { fdb->unlock(); } }; - std::mutex _lock; - std::string _server; - std::string _location_prefix; - - std::string network_file(const std::string& obj) const { - return "http://" + _server + (obj[0] == '/' ? obj : '/'+obj); - } + std::mutex _lock; + std::string _server; + std::string _location_prefix; + std::unique_ptr<handler_t> _engine; + int _debug {0}; public: /// Standard constructor - fdb_dbase_t(const std::string& server) - : _server(server), _location_prefix("/objects") {} + fdb_dbase_t(const std::string& server); /// Standard destructor - virtual ~fdb_dbase_t() { _lock.unlock(); } + virtual ~fdb_dbase_t(); /// Take global lock of the database obect virtual void lock() { _lock.lock(); } /// Release global lock of the database obect virtual void unlock() { _lock.unlock(); } - /// Check the existence of a given object in the database - virtual boost::system::error_code query_next( const std::string& object_name, - std::string& access_name, - std::string& date, - std::size_t& length) = 0; + /// Access the node specification of the next free node + virtual std::string get_free_host_uri(const std::string& ) const; + + /// Transform the object name to the object key for the database lookup + virtual std::string object_key(const std::string& obj) const; + + /// Transform the object key and the host specs to the network name of the file + virtual std::string network_file(const std::string& host, const std::string& obj) const; + /// Check the existence of a given object in the database virtual boost::system::error_code query_object( const std::string& object_name, std::string& access_name, std::string& date, - std::size_t& length) = 0; + std::size_t& length); + /// Get the next object with the name matching the prefix virtual boost::system::error_code delete_next( const std::string& prefix, std::string& access_name, std::string& date, - std::size_t& length) = 0; + std::size_t& length); + /// Check the existence of a given object in the database virtual boost::system::error_code delete_object(const std::string& object_name, std::string& access_name, std::string& date, - std::size_t& length) = 0; - /// Check the existence of a given object in the database - virtual boost::system::error_code lock_object( const std::string& object_name) = 0; + std::size_t& length); /// Add a new object to the database virtual boost::system::error_code add_object( const std::string& object_name, const std::string& date, std::size_t length, - std::string& access_name) = 0; + std::string& access_name); /// Update the object state of an object in the database virtual boost::system::error_code update_object_state(const std::string& object_name, - const std::string& state) = 0; + const std::string& state); }; } // End namespace storage } // End namespace Online diff --git a/Online/Storage/Storage/fdb_server.h b/Online/Storage/Storage/fdb_server.h index 9ac1c18ff..4df72257b 100644 --- a/Online/Storage/Storage/fdb_server.h +++ b/Online/Storage/Storage/fdb_server.h @@ -132,12 +132,12 @@ namespace Online { file_dir.c_str(), ::strerror(errno)); ::exit(EINVAL); } - if ( !file_dir.empty() ) { - ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ File repository: %s", file_dir.c_str()); - } - if ( !server.empty() ) { - ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ Server URI: %s", server.c_str()); - } + std::stringstream str; + if ( !file_dir.empty() ) str << " File repository: " << file_dir; + if ( !server.empty() ) str << " Server URI: " << server; + if ( !local.empty() ) str << " Local URI: " << local; + ::lib_rtl_output(LIB_RTL_ALWAYS, "+++%s", str.str().c_str()); + uri_t uri(local); ptr = std::make_unique<http::basic_http_server<T> >(uri.host, uri.port); ptr->implementation->buffer_size = buffer_size; diff --git a/Online/Storage/src/server/fdb_SQLite.cpp b/Online/Storage/src/server/fdb_SQLite.cpp index 661ac40e7..3cfee40e0 100644 --- a/Online/Storage/src/server/fdb_SQLite.cpp +++ b/Online/Storage/src/server/fdb_SQLite.cpp @@ -22,220 +22,170 @@ using namespace boost; using namespace Online::storage; -namespace { - template<typename T> inline int _prt(const T* o) { - return o->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG; - } -} -system::error_code -fdb_SQLite::handler_t::initialize(const std::string& db_name) { - std::string err; - const char* nam = db_name.c_str(); - this->database = sqlite::database::open(db_name, err); - if ( this->database.db ) { - const char* sql = "CREATE TABLE IF NOT EXISTS Files (" - "Name TEXT PRIMARY KEY, " - "State INT NOT NULL, " - "Size INT NOT NULL, " - "Date TEXT NOT NULL, " - "Access TEXT NOT NULL)"; - if ( this->database.execute(err, sql) != sqlite::traits::OK ) { - ::lib_rtl_output(LIB_RTL_ERROR,"%s: Create table: SQL error: %s", nam, err.c_str()); - return system::error_code(system::errc::permission_denied, system::system_category()); - } - ::lib_rtl_output(LIB_RTL_INFO,"FDB Database server: Database %s", nam); - ::lib_rtl_output(LIB_RTL_INFO,"FDB Database server: Table FILES created successfully"); - return system::error_code(system::errc::success, system::system_category()); - } - ::lib_rtl_output(LIB_RTL_INFO,"%s: FAILED to access db: [%s]", nam, err.c_str()); - return system::error_code(system::errc::permission_denied, system::system_category()); +/// Initializing constructor +SQLite_handler_t::SQLite_handler_t(const std::string& p, int dbg) + : fdb_dbase_t::handler_t(dbg), path(p) +{ + this->init(path); } -/// Check the existence of a given object in the database -system::error_code -fdb_SQLite::handler_t::query(std::string& object, - std::string& access, - std::string& date, - std::size_t& length) { - File file; - system::error_code ec = this->query_file(object, file, handler_t::STATE_WRITTEN); - if ( ec == system::errc::success ) { - object = file.name; - access = file.access; - length = ::atol(file.size.c_str()); - date = file.date; - ::lib_rtl_output(_prt(this), "Query '%s'", object.c_str()); - return ec; +/// Default destructor +SQLite_handler_t::~SQLite_handler_t() { + this->fini(); + if ( this->database.handle() ) { + this->database.commit(); + this->database.close(); } - ::lib_rtl_output(LIB_RTL_ALWAYS,"Query: file '%s' NOT FOUND!", object.c_str()); - return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); } -/// Check the existence of a given object in the database -boost::system::error_code -fdb_SQLite::handler_t::next( std::string& object, - std::string& access, - std::string& date, - std::size_t& length) { - File file; - system::error_code ec = this->query_file(object, file, handler_t::STATE_WRITTEN); - if ( ec == system::errc::success ) { - object = file.name; - access = file.access; - length = ::atol(file.size.c_str()); - date = file.date; - ec = this->lock(file.name, handler_t::STATE_READ); - if ( ec == system::errc::success ) { - ::lib_rtl_output(_prt(this), "Next '%s'", object.c_str()); +/// Initialize object +system::error_code +SQLite_handler_t::init(const std::string& db_name) { + if ( !this->_inited ) { + std::string err; + const char* nam = db_name.c_str(); + this->database = sqlite::database::open(db_name, err); + if ( this->database.db ) { + const char* sql = "CREATE TABLE IF NOT EXISTS Files (" + "Name TEXT PRIMARY KEY, " + "State INT NOT NULL, " + "Size INT NOT NULL, " + "Date TEXT NOT NULL, " + "Host TEXT NOT NULL)"; + if ( this->database.execute(err, sql) != sqlite::traits::OK ) { + ::lib_rtl_output(LIB_RTL_ERROR,"%s: Create table: SQL error: %s", nam, err.c_str()); + return system::error_code(system::errc::permission_denied, system::system_category()); + } + ::lib_rtl_output(LIB_RTL_INFO,"FDB Database server: Database %s", nam); + ::lib_rtl_output(LIB_RTL_INFO,"FDB Database server: Table FILES created successfully"); + /// Create prepared statement to insert records + this->insert_record.prepare(database, + "INSERT INTO Files (Name, State, Size, Date, Host) " + "VALUES (?, ?, ?, ?, ?)"); + this->delete_record.prepare(database, + "DELETE FROM Files WHERE Name=?1 "); + this->query_record.prepare (database, + "SELECT Name, State, Size, Date, Host FROM Files " + "WHERE Name LIKE ?1 AND State = ?2 "); + this->lock_record.prepare (database, + "UPDATE Files SET State=?1 WHERE Name=?2 "); + this->_inited = true; return system::error_code(system::errc::success, system::system_category()); } - return system::error_code(system::errc::protocol_error, system::system_category()); + ::lib_rtl_output(LIB_RTL_INFO,"%s: FAILED to access db: [%s]", nam, err.c_str()); + return system::error_code(system::errc::permission_denied, system::system_category()); } - ::lib_rtl_output(LIB_RTL_ALWAYS,"Query: file '%s' NOT FOUND!", object.c_str()); - return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); + return system::error_code(system::errc::success, system::system_category()); } -/// Standard destructor -fdb_SQLite::~fdb_SQLite() { - engine.reset(); -} - -/// Check the existence of a given object in the database -system::error_code fdb_SQLite::query_object(const std::string& object, - std::string& access, - std::string& date, - std::size_t& length) -{ - std::string obj = object; - auto ec = this->engine->query(obj, access, date, length); - access = this->network_file(access); - if ( ec == system::errc::success ) { - ::lib_rtl_output(_prt(this), "Lookup '%s'", object.c_str()); - return ec; +/// Finalize object +void SQLite_handler_t::fini() { + if ( this->_inited ) { + this->insert_record.finalize(); + this->delete_record.finalize(); + this->query_record.finalize(); + this->lock_record.finalize(); + this->database.close(); + this->_inited = false; } - ::lib_rtl_output(LIB_RTL_ALWAYS,"FAILED to lookup object: '%s' [%s]", - object.c_str(), ec.message().c_str()); - return ec; } - + /// Check the existence of a given object in the database -system::error_code fdb_SQLite::query_next( const std::string& object, - std::string& access, - std::string& date, - std::size_t& length) -{ - std::string obj = object; - auto ec = this->engine->query(obj, access, date, length); - access = this->network_file(access); - if ( ec == system::errc::success ) { - ::lib_rtl_output(_prt(this), "Lookup '%s'", object.c_str()); - return ec; +system::error_code +SQLite_handler_t::query_file(const std::string& object_name, file_t& file, int state) { + this->query_record.reset(); + this->query_record.bind(1, object_name); + this->query_record.bind(2, state); + int ret = this->query_record.execute(); + while ( ret == SQLITE_ROW ) { + file.name = query_record.get<std::string>(0); + file.state = query_record.get<std::string>(1); + file.size = query_record.get<std::string>(2); + file.date = query_record.get<std::string>(3); + file.host = query_record.get<std::string>(4); + return system::error_code(system::errc::success, system::system_category()); } - ::lib_rtl_output(LIB_RTL_ALWAYS,"FAILED to lookup object: '%s' [%s]", - object.c_str(), ec.message().c_str()); - return ec; + return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); } -/// Check the existence of the next object of a sequence -system::error_code fdb_SQLite::delete_next( const std::string& object, - std::string& access, - std::string& date, - std::size_t& length) -{ - std::string obj = object; - auto ec = this->engine->next(obj, access, date, length); - if ( ec == system::errc::success ) { - ec = this->engine->del(_location_prefix+access); - access = this->network_file(access); - if ( ec == system::errc::success ) { - ::lib_rtl_output(_prt(this), "Lookup '%s'", object.c_str()); - return ec; - } +/// Add a new object to the database +system::error_code +SQLite_handler_t::add (const std::string& object_name, + const std::string& date, + std::size_t length, + const std::string& host) { + this->insert_record.reset(); + this->insert_record.bind(1, object_name); + this->insert_record.bind(2, STATE_OPEN); + this->insert_record.bind(3, length); + this->insert_record.bind(4, date); + this->insert_record.bind(5, host); + this->database.begin(); + int ret = this->insert_record.execute(); + this->insert_record.reset(); + this->database.commit(); + if ( ret == SQLITE_DONE ) { + return system::error_code(system::errc::success, system::system_category()); } - ::lib_rtl_output(LIB_RTL_ERROR,"FAILED to lookup sequence object: '%s' [%s]", - object.c_str(), ec.message().c_str()); - return ec; -} - -/// Check the existence of a given object in the database -system::error_code fdb_SQLite::delete_object(const std::string& object, - std::string& access, - std::string& date, - std::size_t& length) -{ - std::string obj = object; - auto ec = this->engine->query(obj, access, date, length); - if ( ec == system::errc::success ) { - ec = this->engine->del(object); - access = this->network_file(access); - if ( ec == system::errc::success ) { - ::lib_rtl_output(_prt(this), "Remove '%s'", object.c_str()); - return ec; - } + else if ( ret == SQLITE_CONSTRAINT_PRIMARYKEY ) { + return system::error_code(system::errc::file_exists, system::system_category()); + } + else if ( ret == SQLITE_CONSTRAINT_FOREIGNKEY ) { + return system::error_code(system::errc::file_exists, system::system_category()); } - ::lib_rtl_output(_prt(this), "FAILED to remove: '%s' [%s]", - object.c_str(), ec.message().c_str()); - return ec; + else if ( ret != SQLITE_OK ) { + return system::error_code(system::errc::file_exists, system::system_category()); + } + return system::error_code(system::errc::success, system::system_category()); } -/// Check the existence of a given object in the database -system::error_code fdb_SQLite::lock_object(const std::string& object) -{ - size_t length = 0; - std::string access, date, obj = object; - auto ec = this->engine->query(obj, access, date, length); - if ( ec == system::errc::success ) { - return this->engine->lock(object, handler_t::STATE_READ); - } +/// Remove an object from the database +system::error_code +SQLite_handler_t::del (const std::string& object_name) { + this->delete_record.reset(); + this->delete_record.bind(1, object_name); + this->database.begin(); + int ret = this->delete_record.execute(); + this->delete_record.reset(); + this->database.commit(); + if ( ret == SQLITE_OK ) + return system::error_code(system::errc::success, system::system_category()); + else if ( ret == SQLITE_DONE ) + return system::error_code(system::errc::success, system::system_category()); return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); } -/// Add a new object to the database +/// lock database record system::error_code -fdb_SQLite::add_object(const std::string& object, - const std::string& date, - std::size_t length, - std::string& access) -{ - std::string acc = object.substr(_location_prefix.length(), std::string::npos); - auto ec = this->engine->add(object, date, length, acc); - if ( ec == system::errc::success ) { - ::lib_rtl_output(_prt(this), "Add '%s' %s %s", object.c_str(), - this->debug > 1 ? "access:" : "", - this->debug > 1 ? acc.c_str() : ""); - access = this->network_file(acc); - return ec; - } - ::lib_rtl_output(LIB_RTL_ERROR,"FAILED to add: '%s' access: %s [%s]", - object.c_str(), access.c_str(), ec.message().c_str()); - return ec; +SQLite_handler_t::set (const std::string& object_name, int value) { + this->lock_record.reset(); + this->lock_record.bind(1, value); + this->lock_record.bind(2, object_name); + this->database.begin(); + int ret = this->lock_record.execute(); + this->lock_record.reset(); + this->database.commit(); + if ( ret == SQLITE_DONE ) + return system::error_code(system::errc::success, system::system_category()); + else if ( ret == SQLITE_OK ) + return system::error_code(system::errc::success, system::system_category()); + return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); } -/// Update the object state of an object in the database -boost::system::error_code -fdb_SQLite::update_object_state(const std::string& object, const std::string& state) { - handler_t::File file; - system::error_code ec; - std::string obj = object; - if ( state == "WRITTEN" ) { - ec = this->engine->query_file(obj, file, handler_t::STATE_OPEN); - if ( ec == system::errc::success ) { - ec = this->engine->lock(object, handler_t::STATE_WRITTEN); - } - } - else if ( state == "READ" ) { - ec = this->engine->query_file(obj, file, handler_t::STATE_WRITTEN); - if ( ec == system::errc::success ) { - ec = this->engine->lock(object, handler_t::STATE_READ); - } - } - if ( ec == system::errc::success ) { - ::lib_rtl_output(this->debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Update '%s' NEW state: %s", object.c_str(), state.c_str()); - return ec; - } - ::lib_rtl_output(LIB_RTL_ERROR,"FAILED update '%s' to state: %s [%s]", - object.c_str(), state.c_str(), ec.message().c_str()); - return ec; +#include <Storage/fdb_server.h> +class Online::storage::db::traits { +public: + typedef fdb_dbase_t dbase_t; +}; + +extern "C" int fdb_sqlite_server(int argc, char** argv) { + Online::storage::SrvRun<Online::storage::db> s; + s.create(argc, argv); + auto* sql = new Online::storage::fdb_dbase_t(s.server); + sql->_debug = s.application_debug; + sql->_engine.reset(new SQLite_handler_t(s.dbase, s.application_debug)); + s.ptr->implementation->dbase.reset(sql); + s.start(); + return 0; } diff --git a/Online/Storage/src/server/fdb_SQLite.h b/Online/Storage/src/server/fdb_SQLite.h index 3ddb34347..d20063d52 100644 --- a/Online/Storage/src/server/fdb_SQLite.h +++ b/Online/Storage/src/server/fdb_SQLite.h @@ -27,126 +27,53 @@ namespace Online { /// Namespace for the storage interface namespace storage { - /// Simple implementation of a storage database based on a file system directory. + /// Interface class to database handler /** + * To implement a new database technology in principle only + * this class needs to be re-implemented e.g. using MYSQL. * * \author M.Frank * \version 1.0 * \date 02.02.2021 */ - class fdb_SQLite : public fdb_dbase_t { + class SQLite_handler_t : public fdb_dbase_t::handler_t { public: + std::string path; + sqlite::database database; + sqlite::statement insert_record; + sqlite::statement query_record; + sqlite::statement delete_record; + sqlite::statement lock_record; - /// Interface class to database handler - /** - * - * \author M.Frank - * \version 1.0 - * \date 02.02.2021 - */ - class handler_t { - public: - static constexpr int STATE_OPEN = 0; - static constexpr int STATE_WRITTEN = 1; - static constexpr int STATE_READ = 1; - - sqlite::database database; - int debug { 0 }; - struct File { - std::string name, state, size, date, access; - }; - /// Check the existence of a given object in the database - virtual boost::system::error_code - query_file(const std::string& object_name, File& file, int state) = 0; + /// Check the existence of a given object in the database + virtual boost::system::error_code + query_file(const std::string& object_name, file_t& file, int state) override; - public: - handler_t(int dbg) - : debug(dbg) - { - } - virtual ~handler_t() { - if ( database.handle() ) { - database.commit(); - database.close(); - } - } - - boost::system::error_code initialize(const std::string& db_name); - - /// Check the existence of a given object in the database - virtual boost::system::error_code query(std::string& object_name, - std::string& access_name, - std::string& date, - std::size_t& length); - /// Check the existence of a given object in the database - virtual boost::system::error_code next( std::string& object_name, - std::string& access_name, - std::string& date, - std::size_t& length); - /// Add a new object to the database - virtual boost::system::error_code add( const std::string& object_name, - const std::string& date, - std::size_t length, - const std::string& access_name) = 0; - /// Remove an object from the database - virtual boost::system::error_code del( const std::string& object_name) = 0; - /// lock database record - virtual boost::system::error_code lock( const std::string& object_name, int value) = 0; - }; - - std::unique_ptr<handler_t> engine; - int debug {0}; - public: - /// Standard constructor - using fdb_dbase_t::fdb_dbase_t; - /// Standard destructor - virtual ~fdb_SQLite(); + /// Initializing constructor + SQLite_handler_t(const std::string& p, int dbg); - /// Check the existence of a given object in the database - virtual boost::system::error_code - query_next( const std::string& object_name, - std::string& access_name, - std::string& date, - std::size_t& length) override; + /// Default destructor + virtual ~SQLite_handler_t(); - /// Check the existence of a given object in the database - virtual boost::system::error_code - query_object( const std::string& object_name, - std::string& access_name, - std::string& date, - std::size_t& length) override; + /// Initialize object + boost::system::error_code init(const std::string& db_name); - /// Check the existence of the next object of a sequence - virtual boost::system::error_code - delete_next( const std::string& object_name, - std::string& access_name, - std::string& date, - std::size_t& length) override; + /// Finalize object + void fini(); - /// Check the existence of a given object in the database - virtual boost::system::error_code - delete_object(const std::string& object_name, - std::string& access_name, - std::string& date, - std::size_t& length) override; - - /// Check the existence of a given object in the database - virtual boost::system::error_code - lock_object( const std::string& object_name) override; - /// Add a new object to the database - virtual boost::system::error_code - add_object( const std::string& object_name, - const std::string& date, - std::size_t length, - std::string& access_name) override; - - /// Update the object state of an object in the database - virtual boost::system::error_code - update_object_state(const std::string& object_name, - const std::string& state) override; + boost::system::error_code add( const std::string& object, + const std::string& date, + std::size_t length, + const std::string& host) override; + + /// Remove an object from the database + boost::system::error_code del( const std::string& object) override; + + /// lock database record + boost::system::error_code set( const std::string& object, int value) override; }; } // End namespace storage } // End namespace Online diff --git a/Online/Storage/src/server/fdb_SQLite_bind.cpp b/Online/Storage/src/server/fdb_SQLite_bind.cpp index bea063ef6..0c136cbaa 100644 --- a/Online/Storage/src/server/fdb_SQLite_bind.cpp +++ b/Online/Storage/src/server/fdb_SQLite_bind.cpp @@ -12,6 +12,7 @@ // // Author : Markus Frank //========================================================================== +#if 0 // Framework include files #include "fdb_SQLite.h" @@ -24,12 +25,6 @@ namespace { class handler_t : public Online::storage::fdb_SQLite::handler_t { public: - std::string path; - sqlite::statement insert_record; - sqlite::statement query_record; - sqlite::statement delete_record; - sqlite::statement lock_record; - bool inited = false; /// Standard constructor handler_t(const std::string& p, int dbg) @@ -43,38 +38,6 @@ namespace { this->fini(); } - /// Initialize object - void init(const std::string& db_name) { - if ( !inited ) { - if ( this->initialize(db_name) == system::errc::success ) { - /// Create prepared statement to insert records - this->insert_record.prepare(database, - "INSERT INTO Files (Name, State, Size, Date, Access) " - "VALUES (?, ?, ?, ?, ?)"); - this->delete_record.prepare(database, - "DELETE FROM Files WHERE Name=?1 "); - this->query_record.prepare (database, - "SELECT Name, State, Size, Date, Access FROM Files " - "WHERE Name LIKE ?1 AND State = ?2 "); - this->lock_record.prepare (database, - "UPDATE Files SET State=?1 WHERE Name=?2 "); - } - inited = true; - } - } - - /// Finalize object - void fini() { - if ( inited ) { - this->insert_record.finalize(); - this->delete_record.finalize(); - this->query_record.finalize(); - this->lock_record.finalize(); - this->database.close(); - inited = false; - } - } - /// Check the existence of a given object in the database virtual system::error_code query_file(const std::string& object_name, File& file, int state) override { this->query_record.reset(); @@ -82,11 +45,11 @@ namespace { this->query_record.bind(2, state); int ret = this->query_record.execute(); while ( ret == SQLITE_ROW ) { - file.name = query_record.get<std::string>(0); - file.state = query_record.get<std::string>(1); - file.size = query_record.get<std::string>(2); - file.date = query_record.get<std::string>(3); - file.access = query_record.get<std::string>(4); + file.name = query_record.get<std::string>(0); + file.state = query_record.get<std::string>(1); + file.size = query_record.get<std::string>(2); + file.date = query_record.get<std::string>(3); + file.host = query_record.get<std::string>(4); return system::error_code(system::errc::success, system::system_category()); } return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); @@ -96,13 +59,13 @@ namespace { virtual system::error_code add (const std::string& object_name, const std::string& date, std::size_t length, - const std::string& access_name) override { + const std::string& host) override { this->insert_record.reset(); this->insert_record.bind(1, object_name); this->insert_record.bind(2, STATE_OPEN); this->insert_record.bind(3, length); this->insert_record.bind(4, date); - this->insert_record.bind(5, access_name); + this->insert_record.bind(5, host); this->database.begin(); int ret = this->insert_record.execute(); this->insert_record.reset(); @@ -138,7 +101,7 @@ namespace { } /// lock database record - virtual system::error_code lock (const std::string& object_name, int value) override { + virtual system::error_code set (const std::string& object_name, int value) override { this->lock_record.reset(); this->lock_record.bind(1, value); this->lock_record.bind(2, object_name); @@ -171,3 +134,4 @@ extern "C" int fdb_sqlite_bind_server(int argc, char** argv) { s.start(); return 0; } +#endif diff --git a/Online/Storage/src/server/fdb_SQLite_direct.cpp b/Online/Storage/src/server/fdb_SQLite_direct.cpp index a1ef87ac4..e69de29bb 100644 --- a/Online/Storage/src/server/fdb_SQLite_direct.cpp +++ b/Online/Storage/src/server/fdb_SQLite_direct.cpp @@ -1,147 +0,0 @@ -//========================================================================== -// LHCb Online software suite -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see OnlineSys/LICENSE. -// -//-------------------------------------------------------------------------- -// -// Package : RPC -// -// Author : Markus Frank -//========================================================================== -// -// gdb --args gentest.exe libStorageClient.so fdb_sqlite_direct_server -local_port=8000 -fssrv_sser=pluscc08 -fssrv_port=8001 -threads=1 -database=/home/frankm/storage_files.dbase -log=/proc/self/fd/2 -// -// Framework include files -#include "fdb_SQLite.h" -#include <RTL/rtl.h> - -// C/C++ files - -using namespace boost; - -namespace { - - constexpr static int RELEASE_BUFF_SIZE = 10000000; - class handler_t : public Online::storage::fdb_SQLite::handler_t { - public: - struct Reader { - std::vector<File> files; - static int callback(void* ptr, int /* argc */, char** argv, char** /* name */) { - Reader* rdr = (Reader*)ptr; - File file {argv[0], argv[1], argv[2], argv[3], argv[4]}; - rdr->files.emplace_back(file); - return 0; - } - }; - - handler_t(const std::string& db_name, int dbg) - : Online::storage::fdb_SQLite::handler_t(dbg) - { - std::string error; - this->initialize(db_name); - this->database.execute_sql(error,"PRAGMA cache_size=10000"); - this->database.execute_sql(error,"PRAGMA journal_mode=OFF"); - } - - /// Check the existence of a given object in the database - virtual system::error_code - query_file(const std::string& object_name, File& file, int state) override { - Reader reader; - std::string error; - int ret = this->database.execute_sql(error, - &reader, - Reader::callback, - "SELECT Name, State, Size, Date, Access FROM Files " - "WHERE Name LIKE '%s%%' AND State=%d LIMIT 1", - object_name.c_str(), state); - ::sqlite3_release_memory(RELEASE_BUFF_SIZE); - if ( ret != sqlite::traits::OK ) { - ::lib_rtl_output(LIB_RTL_ALWAYS,"%s: Query: file %s SQL Error [%s]", - this->database.name(), object_name.c_str(), error.c_str()); - return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); - } - else if ( reader.files.empty() ) { - ::lib_rtl_output(LIB_RTL_ALWAYS,"%s: Query: file %s NOT FOUND!", - this->database.name(), object_name.c_str()); - return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); - } - file = std::move(reader.files[0]); - return system::error_code(system::errc::success, system::system_category()); - } - - /// Add a new object to the database - virtual system::error_code add (const std::string& object_name, - const std::string& date, - std::size_t length, - const std::string& access_name) override { - std::string error; - int ret = this->database.execute_sql(error, - "INSERT INTO Files (Name, State, Size, Date, Access) " - "VALUES ('%s', %d, %ld, '%s', '%s')", - object_name.c_str(), STATE_OPEN, length, - date.c_str(), access_name.c_str()); - ::sqlite3_release_memory(RELEASE_BUFF_SIZE); - if ( ret == SQLITE_CONSTRAINT_PRIMARYKEY ) { - return system::error_code(system::errc::file_exists, system::system_category()); - } - else if ( ret == SQLITE_CONSTRAINT_FOREIGNKEY ) { - return system::error_code(system::errc::file_exists, system::system_category()); - } - else if ( ret != SQLITE_OK ) { - return system::error_code(system::errc::file_exists, system::system_category()); - } - return system::error_code(system::errc::success, system::system_category()); - } - - /// Remove an object from the database - virtual system::error_code del (const std::string& object_name) override { - std::string error; - int ret = this->database.execute_sql(error, - "DELETE FROM Files WHERE Name='%s'", - object_name.c_str()); - int num = this->database.changes(); - num = 1;// This does not work: - ::sqlite3_release_memory(RELEASE_BUFF_SIZE); - if ( ret == SQLITE_OK && num == 1 ) - return system::error_code(system::errc::success, system::system_category()); - return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); - } - - /// lock database record - virtual system::error_code lock (const std::string& object_name, int value) override { - std::string error; - int ret = this->database.execute_sql(error, - "UPDATE Files SET State=%d" - " WHERE Name='%s' AND State=%d", - value, object_name.c_str(), value); - int num = database.changes(); - num = 1;// This does not work: - ::sqlite3_release_memory(RELEASE_BUFF_SIZE); - if ( ret == SQLITE_OK && num == 1 ) - return system::error_code(system::errc::success, system::system_category()); - return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); - } - }; -} - -#include <Storage/fdb_server.h> -class Online::storage::db::traits { -public: - typedef fdb_dbase_t dbase_t; -}; - -extern "C" int fdb_sqlite_direct_server(int argc, char** argv) { - Online::storage::SrvRun<Online::storage::db> s; - s.create(argc, argv); - auto* sql = new Online::storage::fdb_SQLite(s.server); - sql->engine.reset(new handler_t(s.dbase, s.application_debug)); - sql->debug = s.application_debug; - s.ptr->implementation->dbase.reset(sql); - s.start(); - return 0; -} - diff --git a/Online/Storage/src/server/fdb_db_server.cpp b/Online/Storage/src/server/fdb_db_server.cpp index 3ec17e764..4e6dc0a29 100644 --- a/Online/Storage/src/server/fdb_db_server.cpp +++ b/Online/Storage/src/server/fdb_db_server.cpp @@ -29,10 +29,20 @@ public: using namespace std; using namespace Online::storage; -static const string PATTERN_NEXT = "/next?prefix="; static constexpr const double kByte = 1024e0; static constexpr const double MByte = kByte*kByte; +static inline string object_name(const string& obj, string opt="") { + static const string PATTERN_NEXT = "/next?prefix="; + bool get_next = (0 == ::strncasecmp(obj.c_str(), + PATTERN_NEXT.c_str(), + PATTERN_NEXT.length())); + if ( get_next ) { + return obj.substr(PATTERN_NEXT.length())+opt; + } + return obj; +} + /// Standard destructor template <> http::basic_http_server<db>::handler_t::~handler_t() { } @@ -41,14 +51,11 @@ template <> http::basic_http_server<db>::handler_t::~handler_t() { template <> http::HttpRequestHandler::continue_action http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t& rep) { size_t length = 0; - string date, access_name; - bool get_next = (0 == ::strncasecmp(req.uri.c_str(),PATTERN_NEXT.c_str(),PATTERN_NEXT.length())); + string date, access_name, obj = object_name(req.uri); + boost::system::error_code ec; { dbase_t::lock_t lock(dbase.get()); - if ( get_next ) - ec = dbase->query_next(req.uri.substr(PATTERN_NEXT.length()), access_name, date, length); - else - ec = dbase->query_object(req.uri, access_name, date, length); + ec = dbase->query_object(req.uri, access_name, date, length); } if ( ec == boost::system::errc::no_such_file_or_directory ) rep = reply_t::stock_reply(reply_t::not_found); @@ -79,14 +86,11 @@ http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t template <> http::HttpRequestHandler::continue_action http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, reply_t& rep) { size_t length = 0; - string date, access_name; - bool get_next = (0 == ::strncasecmp(req.uri.c_str(),PATTERN_NEXT.c_str(),PATTERN_NEXT.length())); + string date, access_name, obj = object_name(req.uri,"%"); + boost::system::error_code ec; { dbase_t::lock_t lock(dbase.get()); - if ( get_next ) - ec = dbase->delete_next(req.uri.substr(PATTERN_NEXT.length())+'%', access_name, date, length); - else - ec = dbase->delete_object(req.uri, access_name, date, length); + ec = dbase->delete_object(obj, access_name, date, length); } if ( ec == boost::system::errc::no_such_file_or_directory ) rep = reply_t::stock_reply(reply_t::not_found); @@ -107,7 +111,7 @@ http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, repl rep = reply_t::stock_reply(reply_t::temp_redirect); rep.headers.emplace_back(http::constants::location,access_name); ::lib_rtl_output(LIB_RTL_INFO,"DELETE:'%s' %.1f %cB [%s]", - access_name.c_str(), double(length)/(mb ? MByte : kByte), mb ? 'M' : 'k', + obj.c_str(), double(length)/(mb ? MByte : kByte), mb ? 'M' : 'k', req.remote_address().to_string().c_str()); } return write; diff --git a/Online/Storage/src/server/fdb_dbase.cpp b/Online/Storage/src/server/fdb_dbase.cpp new file mode 100644 index 000000000..83e6ad294 --- /dev/null +++ b/Online/Storage/src/server/fdb_dbase.cpp @@ -0,0 +1,217 @@ +//========================================================================== +// LHCb Online software suite +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see OnlineSys/LICENSE. +// +//-------------------------------------------------------------------------- +// +// Package : RPC +// +// Author : Markus Frank +//========================================================================== + +// Framework include files +#include <Storage/fdb_dbase.h> +#include <RTL/rtl.h> + +// C/C++ files + +using namespace boost; +using namespace Online::storage; + +namespace { + template<typename T> inline int _prt(const T* o) { + return o->_debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG; + } +} + +/// Initializing constructor +fdb_dbase_t::handler_t::handler_t(int dbg) : _debug(dbg) { +} + +/// Default destructor +fdb_dbase_t::handler_t::~handler_t() { +} + +/// Check the existence of a given object in the database +system::error_code +fdb_dbase_t::handler_t::query(std::string& object, + std::string& host, + std::string& date, + std::size_t& length) { + file_t file; + system::error_code ec = this->query_file(object, file, handler_t::STATE_WRITTEN); + if ( ec == system::errc::success ) { + object = file.name; + host = file.host; + length = ::atol(file.size.c_str()); + date = file.date; + ::lib_rtl_output(_prt(this), "Query '%s'", object.c_str()); + return ec; + } + ::lib_rtl_output(LIB_RTL_ALWAYS,"Query: file '%s' NOT FOUND!", object.c_str()); + return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); +} + +/// Check the existence of a given object in the database +boost::system::error_code +fdb_dbase_t::handler_t::next( std::string& object, + std::string& host, + std::string& date, + std::size_t& length) { + file_t file; + system::error_code ec = this->query_file(object, file, handler_t::STATE_WRITTEN); + if ( ec == system::errc::success ) { + object = file.name; + host = file.host; + length = ::atol(file.size.c_str()); + date = file.date; + ec = this->set(object, handler_t::STATE_READ); + if ( ec == system::errc::success ) { + ::lib_rtl_output(_prt(this), "Next '%s'", object.c_str()); + return system::error_code(system::errc::success, system::system_category()); + } + return system::error_code(system::errc::protocol_error, system::system_category()); + } + ::lib_rtl_output(LIB_RTL_ALWAYS,"Query: file '%s' NOT FOUND!", object.c_str()); + return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); +} + +/// Standard constructor +fdb_dbase_t::fdb_dbase_t(const std::string& server) + : _server(server), _location_prefix("/objects") { +} + +/// Standard destructor +fdb_dbase_t::~fdb_dbase_t() { + _engine.reset(); + _lock.unlock(); +} + +/// Access the node specification of the next free node +std::string fdb_dbase_t::get_free_host_uri(const std::string& ) const { + return "http://" + _server; +} + +/// Transform the object name to the object key for the database lookup +std::string fdb_dbase_t::object_key(const std::string& obj) const { + return obj.substr(_location_prefix.length(), std::string::npos); +} + +/// Transform the object key and the host specs to the network name of the file +std::string fdb_dbase_t::network_file(const std::string& host, const std::string& obj) const { + return host + (obj[0] == '/' ? obj : '/'+obj); +} + +/// Check the existence of a given object in the database +system::error_code fdb_dbase_t::query_object(const std::string& object, + std::string& access, + std::string& date, + std::size_t& length) +{ + std::string host, obj = this->object_key(object); + auto ec = this->_engine->query(obj, host, date, length); + if ( ec == system::errc::success ) { + access = this->network_file(host, obj); + ::lib_rtl_output(_prt(this), "Lookup '%s'", obj.c_str()); + return ec; + } + ::lib_rtl_output(LIB_RTL_ALWAYS,"FAILED to lookup object: '%s' [%s]", + object.c_str(), ec.message().c_str()); + return ec; +} + +/// Check the existence of the next object of a sequence +system::error_code fdb_dbase_t::delete_next( const std::string& object, + std::string& access, + std::string& date, + std::size_t& length) +{ + std::string host, obj = this->object_key(object); + auto ec = this->_engine->next(obj, host, date, length); + if ( ec == system::errc::success ) { + ec = this->_engine->del(obj); + access = this->network_file(host, obj); + if ( ec == system::errc::success ) { + ::lib_rtl_output(_prt(this), "Lookup '%s'", obj.c_str()); + return ec; + } + } + ::lib_rtl_output(LIB_RTL_ERROR,"FAILED to lookup sequence object: '%s' [%s]", + object.c_str(), ec.message().c_str()); + return ec; +} + +/// Check the existence of a given object in the database +system::error_code fdb_dbase_t::delete_object(const std::string& object, + std::string& access, + std::string& date, + std::size_t& length) +{ + std::string host, obj = this->object_key(object); + auto ec = this->_engine->query(obj, host, date, length); + if ( ec == system::errc::success ) { + ec = this->_engine->del(obj); + access = this->network_file(host, obj); + if ( ec == system::errc::success ) { + ::lib_rtl_output(_prt(this), "Remove '%s'", obj.c_str()); + return ec; + } + } + ::lib_rtl_output(_prt(this), "FAILED to remove: '%s' [%s]", + object.c_str(), ec.message().c_str()); + return ec; +} + +/// Add a new object to the database +system::error_code +fdb_dbase_t::add_object(const std::string& object, + const std::string& date, + std::size_t length, + std::string& access) +{ + std::string obj = this->object_key(object); + std::string host = this->get_free_host_uri(object); + auto ec = this->_engine->add(obj, date, length, host); + if ( ec == system::errc::success ) { + access = this->network_file(host, obj); + ::lib_rtl_output(_prt(this), "Add '%s' %s %s", object.c_str(), + this->_debug > 1 ? "access:" : "", + this->_debug > 1 ? access.c_str() : ""); + return ec; + } + ::lib_rtl_output(LIB_RTL_ERROR,"FAILED to add: '%s' access: %s [%s]", + object.c_str(), access.c_str(), ec.message().c_str()); + return ec; +} + +/// Update the object state of an object in the database +boost::system::error_code +fdb_dbase_t::update_object_state(const std::string& object, const std::string& state) { + file_t file; + system::error_code ec; + std::string obj = this->object_key(object); + if ( state == "WRITTEN" ) { + ec = this->_engine->query_file(obj, file, handler_t::STATE_OPEN); + if ( ec == system::errc::success ) { + ec = this->_engine->set(obj, handler_t::STATE_WRITTEN); + } + } + else if ( state == "READ" ) { + ec = this->_engine->query_file(obj, file, handler_t::STATE_WRITTEN); + if ( ec == system::errc::success ) { + ec = this->_engine->set(obj, handler_t::STATE_READ); + } + } + if ( ec == system::errc::success ) { + ::lib_rtl_output(this->_debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, + "Update '%s' NEW state: %s", object.c_str(), state.c_str()); + return ec; + } + ::lib_rtl_output(LIB_RTL_ERROR,"FAILED update '%s' to state: %s [%s]", + object.c_str(), state.c_str(), ec.message().c_str()); + return ec; +} diff --git a/Online/Storage/src/server/sqlite_test.cpp b/Online/Storage/src/server/sqlite_test.cpp index 3ebc8f0d4..af0577abe 100644 --- a/Online/Storage/src/server/sqlite_test.cpp +++ b/Online/Storage/src/server/sqlite_test.cpp @@ -27,6 +27,7 @@ gentest.exe libStorageServer.so fdb_cli_dumpdb -database=/home/frankm/storage_fi #include <CPP/sqlite.h> #include <HTTP/HttpHeader.h> #include <RTL/Logger.h> +#include "fdb_SQLite.h" // C/C++ include files #include <fstream> @@ -35,7 +36,11 @@ gentest.exe libStorageServer.so fdb_cli_dumpdb -database=/home/frankm/storage_fi using namespace std; using namespace sqlite; +// +// +//========================================================================== namespace { + struct Setup { string name, database, stream, log, entry; size_t count = 0; @@ -71,7 +76,9 @@ namespace { } }; } - +// +// +//========================================================================== extern "C" int sqlite_create_database(int argc, char** argv) { Setup setup("sqlite_create_database", argc, argv); auto db = setup.db(); @@ -81,7 +88,7 @@ extern "C" int sqlite_create_database(int argc, char** argv) { "State INT NOT NULL, " "Size INT NOT NULL, " "Date TEXT NOT NULL, " - "Access TEXT NOT NULL)"; + "Host TEXT NOT NULL)"; if ( db.execute(error, sql) != sqlite::traits::OK ) { ::lib_rtl_output(LIB_RTL_ERROR,"%s: failed to execute %s : %s", db.name(), sql, error.c_str()); @@ -90,30 +97,31 @@ extern "C" int sqlite_create_database(int argc, char** argv) { db.close(); return 0; } - +// +// +//========================================================================== extern "C" int sqlite_populate_database(int argc, char** argv) { Setup setup("sqlite_populate_database", argc, argv); auto db = setup.db(); try { sqlite::statement insert = statement::create(db, - "INSERT INTO Files ('Name', 'State', 'Size', 'Date', 'Access') " + "INSERT INTO Files ('Name', 'State', 'Size', 'Date', 'Host') " "VALUES ( ? , ? , ? , ? , ? )"); for(size_t i=0; i<setup.count; ++i) { std::string date = http::HttpHeader::now(); + std::string host = "http://127.0.0.1:8100"; size_t length = 4*1024; - char obj[1024], access[1024]; + char obj[1024]; ::snprintf(obj, sizeof(obj), "/objects/%08ld/%s/%010ld_%08ld.raw", setup.run, setup.stream.c_str(), setup.run, i); - ::snprintf(access, sizeof(access), "/files/daqarea/lhcb/%08ld/%s/%010ld_%08ld.raw", - setup.run, setup.stream.c_str(), setup.run, i); insert.reset(); insert.bind(1, obj); insert.bind(2, 0); insert.bind(3, length); insert.bind(4, date); - insert.bind(5, access); + insert.bind(5, host); int ret = insert.execute(); if ( ret != sqlite::traits::OK ) { ::lib_rtl_output(LIB_RTL_ERROR,"%s: failed INSERT: %s",db.name(),insert.errmsg()); @@ -130,24 +138,25 @@ extern "C" int sqlite_populate_database(int argc, char** argv) { } return 0; } - +// +// +//========================================================================== extern "C" int sqlite_populate_database_direct(int argc, char** argv) { Setup setup("sqlite_populate_database", argc, argv); auto db = setup.db(); try { for(size_t i=0; i<setup.count; ++i) { std::string error, date = http::HttpHeader::now(); + std::string host = "http://127.0.0.1:8100"; size_t length = 4*1024; - char obj[1024], access[1024]; + char obj[1024]; ::snprintf(obj, sizeof(obj), "/objects/%08ld/%s/%010ld_%08ld.raw", setup.run, setup.stream.c_str(), setup.run, i); - ::snprintf(access, sizeof(access), "/files/daqarea/lhcb/%08ld/%s/%010ld_%08ld.raw", - setup.run, setup.stream.c_str(), setup.run, i); int ret = db.execute_sql(error, - "INSERT INTO Files ('Name', 'State', 'Size', 'Date', 'Access') " + "INSERT INTO Files ('Name', 'State', 'Size', 'Date', 'Host') " "VALUES ( '%s' , %d , %ld , '%s' , '%s' )", - obj, 0, length, date.c_str(), access); + obj, 0, length, date.c_str(), host.c_str()); if ( ret != sqlite::traits::OK ) { ::lib_rtl_output(LIB_RTL_ERROR,"%s: failed INSERT: %s",db.name(),db.errmsg()); return EINVAL; @@ -161,16 +170,16 @@ extern "C" int sqlite_populate_database_direct(int argc, char** argv) { } return 0; } - +// +// +//========================================================================== extern "C" int sqlite_read_database_direct(int argc, char** argv) { - struct File { - std::string name, state, size, date, access; - }; + typedef Online::storage::fdb_dbase_t::file_t file_t; struct Reader { - std::vector<File> files; + std::vector<file_t> files; static int callback(void* ptr, int /* argc */, char **argv, char **/*name*/) { Reader* rdr = (Reader*)ptr; - File file {argv[0], argv[1], argv[2], argv[3], argv[4]}; + file_t file {argv[0], argv[1], argv[2], argv[3], argv[4]}; rdr->files.emplace_back(file); return 0; } @@ -181,7 +190,7 @@ extern "C" int sqlite_read_database_direct(int argc, char** argv) { int ret = db.execute_sql(error, &reader, Reader::callback, - "SELECT Name, State, Size, Date, Access" + "SELECT Name, State, Size, Date, Host" " FROM Files" " WHERE Size>%d",0); if ( ret != sqlite::traits::OK ) { @@ -189,8 +198,8 @@ extern "C" int sqlite_read_database_direct(int argc, char** argv) { try { std::stringstream s; for(size_t i=0; i<reader.files.size(); ++i) { - const File& f = reader.files[i]; - s << f.name << " '" << f.state << "' '" << f.size << "' '" << f.date << "' " << f.access; + const file_t& f = reader.files[i]; + s << f.name << " '" << f.state << "' '" << f.size << "' '" << f.date << "' " << f.host; ::lib_rtl_output(LIB_RTL_INFO, "TABLE: %s", s.str().c_str()); s.str(""); } @@ -202,16 +211,16 @@ extern "C" int sqlite_read_database_direct(int argc, char** argv) { } return 0; } - +// +// +//========================================================================== extern "C" int sqlite_update_database_direct(int argc, char** argv) { - struct File { - std::string name, state, size, date, access; - }; + typedef Online::storage::fdb_dbase_t::file_t file_t; struct Reader { - std::vector<File> files; + std::vector<file_t> files; static int callback(void* ptr, int /* argc */, char** argv, char** /* name */) { Reader* rdr = (Reader*)ptr; - File file {argv[0], argv[1], argv[2], argv[3], argv[4]}; + file_t file {argv[0], argv[1], argv[2], argv[3], argv[4]}; rdr->files.emplace_back(file); return 0; } @@ -224,14 +233,14 @@ extern "C" int sqlite_update_database_direct(int argc, char** argv) { int ret = db.execute_sql(error, &reader, Reader::callback, - "SELECT Name, State, Size, Date, Access" + "SELECT Name, State, Size, Date, Host" " FROM Files" " WHERE Size>%d",0); if ( ret != sqlite::traits::OK ) { ::lib_rtl_output(LIB_RTL_INFO, "SQL Failure: %s", error.c_str()); } for(size_t i=0; i<reader.files.size(); ++i) { - const File& f = reader.files[i]; + const file_t& f = reader.files[i]; if ( f.state == "0" ) { ret = db.execute_sql(error, "UPDATE Files" @@ -262,11 +271,11 @@ extern "C" int sqlite_update_database_direct(int argc, char** argv) { // //========================================================================== extern "C" int fdb_cli_dumpdb(int argc, char** argv) { - struct File { std::string name, state, size, date, access; }; + typedef Online::storage::fdb_dbase_t::file_t file_t; struct Reader { static int callback(void* ptr, int /* argc */, char **argv, char **/*name*/) { - std::vector<File>* f = (std::vector<File>*)ptr; - File file {argv[0], argv[1], argv[2], argv[3], argv[4]}; + std::vector<file_t>* f = (std::vector<file_t>*)ptr; + file_t file {argv[0], argv[1], argv[2], argv[3], argv[4]}; f->emplace_back(file); return 0; } @@ -278,7 +287,7 @@ extern "C" int fdb_cli_dumpdb(int argc, char** argv) { " -help Print this help. \n"); }); string error; - std::vector<File> files; + std::vector<file_t> files; sqlite::database database = setup.db(); if ( database.handle() == nullptr ) { ::lib_rtl_output(LIB_RTL_ERROR,"%s: Can't open database [%s]", @@ -286,16 +295,16 @@ extern "C" int fdb_cli_dumpdb(int argc, char** argv) { return EINVAL; } int ret = database.execute_sql(error, &files, Reader::callback, - "SELECT Name, State, Size, Date, Access" + "SELECT Name, State, Size, Date, Host" " FROM Files" " WHERE Size>0"); if ( ret == sqlite::traits::OK ) { for(size_t i=0; i<files.size(); ++i) { - const File& f = files[i]; - ::lib_rtl_output(LIB_RTL_INFO, "%4ld File: %s %9s bytes %s", - i, f.name.c_str(), f.size.c_str(), f.date.c_str()); - ::lib_rtl_output(LIB_RTL_INFO, " Key: %s State:%s", - f.access.c_str(), f.state.c_str()); + const file_t& f = files[i]; + ::lib_rtl_output(LIB_RTL_INFO, "%4ld File: %s Host: %s %s", + i, f.name.c_str(), f.host.c_str(), f.date.c_str()); + ::lib_rtl_output(LIB_RTL_INFO, " State:%s %9s bytes", + f.state.c_str(), f.size.c_str()); } } database.close(); diff --git a/Online/Tell1Data/Tell1Data/Tell1Bank.h b/Online/Tell1Data/Tell1Data/Tell1Bank.h index 0c7d302b1..4f4e263f5 100755 --- a/Online/Tell1Data/Tell1Data/Tell1Bank.h +++ b/Online/Tell1Data/Tell1Data/Tell1Bank.h @@ -57,88 +57,104 @@ namespace Online { public: - enum BankType { - L0Calo=0, // 0 - L0DU, // 1 - PrsE, // 2 - EcalE, // 3 - HcalE, // 4 - PrsTrig, // 5 - EcalTrig, // 6 - HcalTrig, // 7 - Velo, // 8 - Rich, // 9 - TT, // 10 - IT, // 11 - OT, // 12 - Muon, // 13 - L0PU, // 14 - DAQ, // 15 - ODIN, // 16 - HltDecReports, // 17 - VeloFull, // 18 - TTFull, // 19 - ITFull, // 20 - EcalPacked, // 21 - HcalPacked, // 22 - PrsPacked, // 23 - L0Muon, // 24 - ITError, // 25 - TTError, // 26 - ITPedestal, // 27 - TTPedestal, // 28 - VeloError, // 29 - VeloPedestal, // 30 - VeloProcFull, // 31 - OTRaw, // 32 - OTError, // 33 - EcalPackedError, // 34 - HcalPackedError, // 35 - PrsPackedError, // 36 - L0CaloFull, // 37 - L0CaloError, // 38 - L0MuonCtrlAll, // 39 - L0MuonProcCand, // 40 - L0MuonProcData, // 41 - L0MuonRaw, // 42 - L0MuonError, // 43 - GaudiSerialize, // 44 - GaudiHeader, // 45 - TTProcFull, // 46 - ITProcFull, // 47 - TAEHeader, // 48 - MuonFull, // 49 - MuonError, // 50 - TestDet, // 51 - L0DUError, // 52 - HltRoutingBits, // 53 - HltSelReports, // 54 - HltVertexReports,// 55 - HltLumiSummary, // 56 - L0PUFull, // 57 - L0PUError, // 58 - DstBank, // 59 - DstData, // 60 - DstAddress, // 61 - FileID, // 62 - VP, // 63 - FTCluster, // 64 - VL, // 65 - UT, // 66 - UTFull, // 67 - UTError, // 68 - UTPedestal, // 69 - HC, // 70 - HltTrackReports, // 71 - HCError, // 72 - VPRetinaCluster, // 73 - FTGeneric, // 74 - FTCalibration, // 75 - FTNZS, // 76 - // Add new types here. Don't forget to update also RawBank.cpp - LastType, // LOOP Marker; add new bank types ONLY before! + /// Define bank types for RawBank + enum BankType { + L0Calo = 0, // 0 + L0DU, // 1 + PrsE, // 2 + EcalE, // 3 + HcalE, // 4 + PrsTrig, // 5 + EcalTrig, // 6 + HcalTrig, // 7 + Velo, // 8 + Rich, // 9 + TT, // 10 + IT, // 11 + OT, // 12 + Muon, // 13 + L0PU, // 14 + DAQ, // 15 + ODIN, // 16 + HltDecReports, // 17 + VeloFull, // 18 + TTFull, // 19 + ITFull, // 20 + EcalPacked, // 21 + HcalPacked, // 22 + PrsPacked, // 23 + L0Muon, // 24 + ITError, // 25 + TTError, // 26 + ITPedestal, // 27 + TTPedestal, // 28 + VeloError, // 29 + VeloPedestal, // 30 + VeloProcFull, // 31 + OTRaw, // 32 + OTError, // 33 + EcalPackedError, // 34 + HcalPackedError, // 35 + PrsPackedError, // 36 + L0CaloFull, // 37 + L0CaloError, // 38 + L0MuonCtrlAll, // 39 + L0MuonProcCand, // 40 + L0MuonProcData, // 41 + L0MuonRaw, // 42 + L0MuonError, // 43 + GaudiSerialize, // 44 + GaudiHeader, // 45 + TTProcFull, // 46 + ITProcFull, // 47 + TAEHeader, // 48 + MuonFull, // 49 + MuonError, // 50 + TestDet, // 51 + L0DUError, // 52 + HltRoutingBits, // 53 + HltSelReports, // 54 + HltVertexReports, // 55 + HltLumiSummary, // 56 + L0PUFull, // 57 + L0PUError, // 58 + DstBank, // 59 + DstData, // 60 + DstAddress, // 61 + FileID, // 62 + VP, // 63 + FTCluster, // 64 + VL, // 65 + UT, // 66 + UTFull, // 67 + UTError, // 68 + UTPedestal, // 69 + HC, // 70 + HltTrackReports, // 71 + HCError, // 72 + VPRetinaCluster, // 73 + FTGeneric, // 74 + FTCalibration, // 75 + FTNZS, // 76 + Calo, // 77 + CaloError, // 78 + MuonSpecial, // 79 + RichCommissioning, // 80 + RichError, // 81 + FTSpecial, // 82 - DaqErrorBase = 192 // Lowest DaqError type available in Run 3 (EDMS2100937) + // Add new types here. Don't forget to update also RawBank.cpp + LastType, // LOOP Marker; add new bank types ONLY before! + + DaqErrorBase = 192, // Lowest DaqError type available in Run 3 (EDMS2100937) + // Banks above are reserved for DAQ, add only generic DaqError types below. + DaqErrorFragmentThrottled = 250, + DaqErrorBXIDCorrupted = 251, + DaqErrorBXIDJump = 252, + DaqErrorFragmentMissing = 253, + DaqErrorFragmentTruncated = 254, + DaqErrorInvalid = 255 + // 255 is the highest type allowed by the Run 3 raw-data format (8-bit unsigned) }; /// Magic pattern for Raw bank headers -- GitLab From 8f842d68731d8d0651146b8de7b7eee0376c4858 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Sun, 28 Mar 2021 21:17:38 +0200 Subject: [PATCH 09/17] Data flow updates --- .../Dataflow/src/framework/DataflowTask.cpp | 2 +- .../options/EB_Transport_properties.opts | 2 +- Online/EventBuilding/src/BU.cpp | 2 +- Online/EventBuilding/src/RU.cpp | 2 +- Online/EventData/CMakeLists.txt | 23 ++ .../EventData}/EventAccess.h | 20 +- .../EventData}/EventOutput.h | 8 +- .../EventData}/EventTraits.h | 22 +- .../EventData}/FileEventAccess.h | 8 +- .../EventData}/FileEventOutput.h | 8 +- .../EventData}/MBMEventAccess.h | 8 +- .../EventData}/MBMEventOutput.h | 8 +- .../EventData}/Macros.h | 6 +- .../EventData}/NetEventAccess.h | 12 +- .../src/EventAccess.cpp | 24 +- .../src/EventOutput.cpp | 2 +- .../src/FileEventAccess.cpp | 2 +- .../src/FileEventOutput.cpp | 2 +- .../src/MBMEventAccess.cpp | 2 +- .../src/MBMEventOutput.cpp | 2 +- .../src/NetEventAccess.cpp | 2 +- Online/FarmConfig/job/EBPass.sh | 9 +- Online/GaudiOnline/CMakeLists.txt | 9 +- .../GaudiOnline/GaudiOnline/Configuration.h | 8 +- Online/GaudiOnline/GaudiOnline/ITaskFSM.h | 1 + .../GaudiOnline/OnlineApplication.h | 1 - .../GaudiOnline/QueuedFlowManager.h | 9 +- Online/GaudiOnline/components/Components.cpp | 6 +- .../GaudiOnline/components/EventProcessor.cpp | 389 ++++++++++-------- .../GaudiOnline/components/EventProcessor.h | 48 ++- Online/GaudiOnline/components/ExpandTAE.cpp | 2 +- Online/GaudiOnline/components/ForceTAE.cpp | 2 +- Online/GaudiOnline/components/IOService.h | 2 +- Online/GaudiOnline/components/InputAlg.cpp | 50 +-- Online/GaudiOnline/components/InputAlg.h | 21 +- .../GaudiOnline/components/OnlineEventApp.cpp | 6 +- .../GaudiOnline/components/OnlineEventApp.h | 7 +- Online/GaudiOnline/components/OutputAlg.cpp | 63 ++- Online/GaudiOnline/components/Passthrough.cpp | 140 +++---- .../python/GaudiOnline/OnlineApplication.py | 2 + .../python/GaudiOnline/Passthrough.py | 3 +- .../python/GaudiOnline/ReadDatafile.py | 3 +- .../GaudiOnline/configureEventConsumer.py | 2 +- Online/GaudiOnline/src/Configuration.cpp | 4 +- Online/GaudiOnline/src/OnlineApplication.cpp | 4 +- Online/GaudiOnline/src/QueuedFlowManager.cpp | 2 + .../components/RawEventTestDump.cpp | 24 +- Online/OnlineBase/OnlineBase/RTL/Logger.h | 11 + Online/OnlineBase/src/RTL/Logger.cpp | 25 +- Online/PCIE40Data/PCIE40Data/pcie40.h | 12 +- Online/PCIE40Data/PCIE40Data/pcie40decoder.h | 15 +- Online/PCIE40Data/src/pcie40decoder.cpp | 279 ++++++++----- Online/SmiController/src/SmiController.cpp | 6 +- 53 files changed, 786 insertions(+), 546 deletions(-) create mode 100755 Online/EventData/CMakeLists.txt rename Online/{GaudiOnline/GaudiOnline => EventData/EventData}/EventAccess.h (96%) rename Online/{GaudiOnline/GaudiOnline => EventData/EventData}/EventOutput.h (98%) rename Online/{GaudiOnline/GaudiOnline => EventData/EventData}/EventTraits.h (88%) rename Online/{GaudiOnline/GaudiOnline => EventData/EventData}/FileEventAccess.h (96%) rename Online/{GaudiOnline/GaudiOnline => EventData/EventData}/FileEventOutput.h (91%) rename Online/{GaudiOnline/GaudiOnline => EventData/EventData}/MBMEventAccess.h (95%) rename Online/{GaudiOnline/GaudiOnline => EventData/EventData}/MBMEventOutput.h (93%) rename Online/{GaudiOnline/GaudiOnline => EventData/EventData}/Macros.h (90%) rename Online/{GaudiOnline/GaudiOnline => EventData/EventData}/NetEventAccess.h (94%) rename Online/{GaudiOnline => EventData}/src/EventAccess.cpp (96%) rename Online/{GaudiOnline => EventData}/src/EventOutput.cpp (99%) rename Online/{GaudiOnline => EventData}/src/FileEventAccess.cpp (99%) rename Online/{GaudiOnline => EventData}/src/FileEventOutput.cpp (99%) rename Online/{GaudiOnline => EventData}/src/MBMEventAccess.cpp (99%) rename Online/{GaudiOnline => EventData}/src/MBMEventOutput.cpp (99%) rename Online/{GaudiOnline => EventData}/src/NetEventAccess.cpp (99%) diff --git a/Online/Dataflow/src/framework/DataflowTask.cpp b/Online/Dataflow/src/framework/DataflowTask.cpp index c8133babf..24de39174 100755 --- a/Online/Dataflow/src/framework/DataflowTask.cpp +++ b/Online/Dataflow/src/framework/DataflowTask.cpp @@ -320,7 +320,7 @@ int DataflowTask::unload() { app_terminate(); declareState(ST_OFFLINE); ::lib_rtl_sleep(100); - ::exit(0); + ::_exit(0); return DF_SUCCESS; } diff --git a/Online/EventBuilding/options/EB_Transport_properties.opts b/Online/EventBuilding/options/EB_Transport_properties.opts index 9ce1e0eb8..d365afbf6 100755 --- a/Online/EventBuilding/options/EB_Transport_properties.opts +++ b/Online/EventBuilding/options/EB_Transport_properties.opts @@ -2,7 +2,7 @@ EB_transport.BU_ranks = {}; EB_transport.MPI_errors_return = FALSE; EB_transport.RU_ranks = {}; EB_transport.RUs_per_nic = {}; -EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.J25197.json"; +EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.FV2976.json"; EB_transport.n_par_mess = 0; EB_transport.n_sources_per_ru = { 1, 1, 3, 3, 2, 2 }; EB_transport.src_ids = {}; diff --git a/Online/EventBuilding/src/BU.cpp b/Online/EventBuilding/src/BU.cpp index 53ac993d9..b13c621a2 100644 --- a/Online/EventBuilding/src/BU.cpp +++ b/Online/EventBuilding/src/BU.cpp @@ -585,7 +585,7 @@ int EB::BU::receive_sizes() if (_full_size_words == _data_offset_words[0]) { _full_size_words = 0; std::fill(_data_offset_words.begin(), _data_offset_words.end(), 0); - logger.info << "end of run" << std::flush; + logger.warning << "end of run" << std::flush; } else { // If only a subset of the MFPs are 0-sized the MEP is incomplete the src ids are reported and the BU goes into // ERROR diff --git a/Online/EventBuilding/src/RU.cpp b/Online/EventBuilding/src/RU.cpp index c17071f2d..e436c23f2 100644 --- a/Online/EventBuilding/src/RU.cpp +++ b/Online/EventBuilding/src/RU.cpp @@ -620,7 +620,7 @@ int EB::RU::load_mpfs() // the end of run will trigger a round of zero-sized MFPs _end_of_run = true; _send_empty = true; - logger.info << "end of run" << std::flush; + logger.warning << "end of run" << std::flush; break; } else { _end_of_run = false; diff --git a/Online/EventData/CMakeLists.txt b/Online/EventData/CMakeLists.txt new file mode 100755 index 000000000..7d3629849 --- /dev/null +++ b/Online/EventData/CMakeLists.txt @@ -0,0 +1,23 @@ +############################################################################### +# (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +# Package: EventData +############################################################################### +gaudi_subdir(EventData v0r1) +# +gaudi_depends_on_subdirs(Online/Tell1Data + Online/PCIE40Data + Online/OnlineBase) +# +gaudi_add_library(EventData src/*.cpp + PUBLIC_HEADERS EventData + INCLUDE_DIRS OnlineBase Tell1Data PCIE40Data + LINK_LIBRARIES OnlineBase Tell1Data PCIE40Data) +target_compile_options(EventData PRIVATE -Wno-address-of-packed-member) diff --git a/Online/GaudiOnline/GaudiOnline/EventAccess.h b/Online/EventData/EventData/EventAccess.h similarity index 96% rename from Online/GaudiOnline/GaudiOnline/EventAccess.h rename to Online/EventData/EventData/EventAccess.h index 999d8d278..278d9df23 100644 --- a/Online/GaudiOnline/GaudiOnline/EventAccess.h +++ b/Online/EventData/EventData/EventAccess.h @@ -12,13 +12,12 @@ // // Author : Markus Frank //========================================================================== -#ifndef ONLINE_GAUDIONLINE_EVENTACCESS_H -#define ONLINE_GAUDIONLINE_EVENTACCESS_H +#ifndef ONLINE_EVENTDATA_EVENTACCESS_H +#define ONLINE_EVENTDATA_EVENTACCESS_H /// Framework include files -#include <GaudiOnline/Macros.h> -#include <GaudiOnline/EventTraits.h> - +#include <EventData/Macros.h> +#include <EventData/EventTraits.h> #include <CPP/Interactor.h> #include <RTL/Logger.h> #include "RTL/Pack.h" @@ -37,6 +36,7 @@ /// Online namespace declaration namespace Online { + /// Base class to access online event data /** @class EventAccess * @@ -129,6 +129,13 @@ namespace Online { /// Container to bank referentes to MDF headers containing event blocks burst_collection_t m_bursts; + /// Definition of the monitoring data block + /** + * + * \author M.Frank + * \version 1.0 + * \date 25/04/2019 + */ struct monitor_t { /// Monitoring item: Count of bursts which were received from the input source std::size_t burstsIn = 0; @@ -166,6 +173,7 @@ namespace Online { /// Default constructor EventAccess(std::unique_ptr<RTL::Logger>&& logger); + /// Standard destructor virtual ~EventAccess(); @@ -225,4 +233,4 @@ namespace Online { }; } // End namespace Online #include "RTL/Unpack.h" -#endif // ONLINE_GAUDIONLINE_EVENTACCESS_H +#endif // ONLINE_EVENTDATA_EVENTACCESS_H diff --git a/Online/GaudiOnline/GaudiOnline/EventOutput.h b/Online/EventData/EventData/EventOutput.h similarity index 98% rename from Online/GaudiOnline/GaudiOnline/EventOutput.h rename to Online/EventData/EventData/EventOutput.h index ba9712480..83bdd95f5 100644 --- a/Online/GaudiOnline/GaudiOnline/EventOutput.h +++ b/Online/EventData/EventData/EventOutput.h @@ -12,11 +12,11 @@ // // Author : Markus Frank //========================================================================== -#ifndef ONLINE_GAUDIONLINE_EVENTOUTPUT_H -#define ONLINE_GAUDIONLINE_EVENTOUTPUT_H +#ifndef ONLINE_EVENTDATA_EVENTOUTPUT_H +#define ONLINE_EVENTDATA_EVENTOUTPUT_H /// Framework include files -#include <GaudiOnline/Macros.h> +#include <EventData/Macros.h> #include <Tell1Data/Tell1Bank.h> #include <CPP/Interactor.h> #include <RTL/Logger.h> @@ -223,4 +223,4 @@ namespace Online { } } // End namespace Online -#endif // ONLINE_GAUDIONLINE_EVENTOUTPUT_H +#endif // ONLINE_EVENTDATA_EVENTOUTPUT_H diff --git a/Online/GaudiOnline/GaudiOnline/EventTraits.h b/Online/EventData/EventData/EventTraits.h similarity index 88% rename from Online/GaudiOnline/GaudiOnline/EventTraits.h rename to Online/EventData/EventData/EventTraits.h index 86f5fe93d..f8f89db03 100644 --- a/Online/GaudiOnline/GaudiOnline/EventTraits.h +++ b/Online/EventData/EventData/EventTraits.h @@ -12,8 +12,8 @@ // // Author : Markus Frank //========================================================================== -#ifndef ONLINE_GAUDIONLINE_EVENTTRAITS_H -#define ONLINE_GAUDIONLINE_EVENTTRAITS_H +#ifndef ONLINE_EVENTDATA_EVENTTRAITS_H +#define ONLINE_EVENTDATA_EVENTTRAITS_H /// Framework include files #include <PCIE40Data/pcie40.h> @@ -66,6 +66,16 @@ namespace Online { record_t(const pcie40::event_t* p) { pointer = p; } record_t(const record_t& p) { pointer = p.data; } operator bool () const { return data != 0; } + bool is_tell1() const { + return data != nullptr && + tell1_event->size0() > 0 && + tell1_event->size0() == tell1_event->size1() && + tell1_event->size0() == tell1_event->size2(); + } + bool is_tell40() const { + return data != nullptr && + tell40_event->pattern() == pcie40::MAGIC_PATTERN; + } }; /// Event container definition for bursts: Contains only the MDFHeader banks typedef std::vector<record_t> event_collection_t; @@ -83,6 +93,9 @@ namespace Online { static event_type& get_event(record_t r) { return *(r.tell1_event); } + static const odin_type* get_odin(const bank_type* b) { + return b ? b->begin<odin_type>() : nullptr; + } static size_t num_collections(const event_type&) { return 1; } @@ -117,6 +130,9 @@ namespace Online { static event_type& get_event(record_t r) { return *(r.tell40_event); } + static const odin_type* get_odin(const bank_type* b) { + return b ? b->begin<odin_type>() : nullptr; + } static size_t num_collections(const event_type& e) { return e.num_bank_collections(); } @@ -147,4 +163,4 @@ namespace Online { } } // End namespace Online -#endif // ONLINE_GAUDIONLINE_EVENTTRAITS_H +#endif // ONLINE_EVENTDATA_EVENTTRAITS_H diff --git a/Online/GaudiOnline/GaudiOnline/FileEventAccess.h b/Online/EventData/EventData/FileEventAccess.h similarity index 96% rename from Online/GaudiOnline/GaudiOnline/FileEventAccess.h rename to Online/EventData/EventData/FileEventAccess.h index 0f68b5cdb..cb68e925b 100644 --- a/Online/GaudiOnline/GaudiOnline/FileEventAccess.h +++ b/Online/EventData/EventData/FileEventAccess.h @@ -12,11 +12,11 @@ // // Author : Markus Frank //========================================================================== -#ifndef ONLINE_GAUDIONLINE_FILEEVENTACCESS_H -#define ONLINE_GAUDIONLINE_FILEEVENTACCESS_H +#ifndef ONLINE_EVENTDATA_FILEEVENTACCESS_H +#define ONLINE_EVENTDATA_FILEEVENTACCESS_H /// Framework include files -#include "GaudiOnline/EventAccess.h" +#include "EventData/EventAccess.h" #include "Tell1Data/DirectoryScan.h" #include "MBM/Requirement.h" @@ -119,4 +119,4 @@ namespace Online { virtual void close() override; }; } // End namespace Online -#endif // ONLINE_GAUDIONLINE_FILEEVENTACCESS_H +#endif // ONLINE_EVENTDATA_FILEEVENTACCESS_H diff --git a/Online/GaudiOnline/GaudiOnline/FileEventOutput.h b/Online/EventData/EventData/FileEventOutput.h similarity index 91% rename from Online/GaudiOnline/GaudiOnline/FileEventOutput.h rename to Online/EventData/EventData/FileEventOutput.h index ec0dd6065..65e3937e9 100644 --- a/Online/GaudiOnline/GaudiOnline/FileEventOutput.h +++ b/Online/EventData/EventData/FileEventOutput.h @@ -12,11 +12,11 @@ // // Author : Markus Frank //========================================================================== -#ifndef ONLINE_GAUDIONLINE_FILEEVENTOUTPUT_H -#define ONLINE_GAUDIONLINE_FILEEVENTOUTPUT_H +#ifndef ONLINE_EVENTDATA_FILEEVENTOUTPUT_H +#define ONLINE_EVENTDATA_FILEEVENTOUTPUT_H /// Framework include files -#include <GaudiOnline/EventOutput.h> +#include <EventData/EventOutput.h> /// C/C++ include files #include <list> @@ -61,4 +61,4 @@ namespace Online { virtual int cancel() override; }; } // End namespace Online -#endif // ONLINE_GAUDIONLINE_FILEEVENTOUTPUT_H +#endif // ONLINE_EVENTDATA_FILEEVENTOUTPUT_H diff --git a/Online/GaudiOnline/GaudiOnline/MBMEventAccess.h b/Online/EventData/EventData/MBMEventAccess.h similarity index 95% rename from Online/GaudiOnline/GaudiOnline/MBMEventAccess.h rename to Online/EventData/EventData/MBMEventAccess.h index 696de69dd..847cc399f 100644 --- a/Online/GaudiOnline/GaudiOnline/MBMEventAccess.h +++ b/Online/EventData/EventData/MBMEventAccess.h @@ -12,11 +12,11 @@ // // Author : Markus Frank //========================================================================== -#ifndef ONLINE_GAUDIONLINE_MBMEVENTACCESS_H -#define ONLINE_GAUDIONLINE_MBMEVENTACCESS_H +#ifndef ONLINE_EVENTDATA_MBMEVENTACCESS_H +#define ONLINE_EVENTDATA_MBMEVENTACCESS_H /// Framework include files -#include "GaudiOnline/EventAccess.h" +#include "EventData/EventAccess.h" #include "MBM/Requirement.h" #include "MBM/bmdef.h" @@ -113,4 +113,4 @@ namespace Online { virtual void close() override; }; } // End namespace Online -#endif // ONLINE_GAUDIONLINE_MBMEVENTACCESS_H +#endif // ONLINE_EVENTDATA_MBMEVENTACCESS_H diff --git a/Online/GaudiOnline/GaudiOnline/MBMEventOutput.h b/Online/EventData/EventData/MBMEventOutput.h similarity index 93% rename from Online/GaudiOnline/GaudiOnline/MBMEventOutput.h rename to Online/EventData/EventData/MBMEventOutput.h index 99e9b3793..7a60e2978 100644 --- a/Online/GaudiOnline/GaudiOnline/MBMEventOutput.h +++ b/Online/EventData/EventData/MBMEventOutput.h @@ -12,11 +12,11 @@ // // Author : Markus Frank //========================================================================== -#ifndef ONLINE_GAUDIONLINE_MBMEVENTOUTPUT_H -#define ONLINE_GAUDIONLINE_MBMEVENTOUTPUT_H +#ifndef ONLINE_EVENTDATA_MBMEVENTOUTPUT_H +#define ONLINE_EVENTDATA_MBMEVENTOUTPUT_H /// Framework include files -#include <GaudiOnline/EventOutput.h> +#include <EventData/EventOutput.h> #include <MBM/BufferInfo.h> #include <MBM/bmdef.h> @@ -83,4 +83,4 @@ namespace Online { virtual int cancel() override; }; } // End namespace Online -#endif // ONLINE_GAUDIONLINE_MBMEVENTOUTPUT_H +#endif // ONLINE_EVENTDATA_MBMEVENTOUTPUT_H diff --git a/Online/GaudiOnline/GaudiOnline/Macros.h b/Online/EventData/EventData/Macros.h similarity index 90% rename from Online/GaudiOnline/GaudiOnline/Macros.h rename to Online/EventData/EventData/Macros.h index 60977c670..388d900a9 100644 --- a/Online/GaudiOnline/GaudiOnline/Macros.h +++ b/Online/EventData/EventData/Macros.h @@ -12,8 +12,8 @@ // // Author : Markus Frank //========================================================================== -#ifndef ONLINE_GAUDIONLINE_MACROS_H -#define ONLINE_GAUDIONLINE_MACROS_H +#ifndef ONLINE_EVENTDATA_MACROS_H +#define ONLINE_EVENTDATA_MACROS_H /// Framework include files @@ -38,4 +38,4 @@ namespace Online { x& operator=(const x& copy) = delete; \ x& operator=(x&& copy) = delete -#endif // ONLINE_GAUDIONLINE_MACROS_H +#endif // ONLINE_EVENTDATA_MACROS_H diff --git a/Online/GaudiOnline/GaudiOnline/NetEventAccess.h b/Online/EventData/EventData/NetEventAccess.h similarity index 94% rename from Online/GaudiOnline/GaudiOnline/NetEventAccess.h rename to Online/EventData/EventData/NetEventAccess.h index 2132458ad..a0e246393 100644 --- a/Online/GaudiOnline/GaudiOnline/NetEventAccess.h +++ b/Online/EventData/EventData/NetEventAccess.h @@ -12,14 +12,14 @@ // // Author : Markus Frank //========================================================================== -#ifndef ONLINE_GAUDIONLINE_NETEVENTACCESS_H -#define ONLINE_GAUDIONLINE_NETEVENTACCESS_H +#ifndef ONLINE_EVENTDATA_NETEVENTACCESS_H +#define ONLINE_EVENTDATA_NETEVENTACCESS_H /// Framework include files #define TRANSFER_NS BoostAsio -#include "NET/Transfer.h" -#include "MBM/Requirement.h" -#include "GaudiOnline/EventAccess.h" +#include <NET/Transfer.h> +#include <MBM/Requirement.h> +#include <EventData/EventAccess.h> /// Online namespace declaration namespace Online { @@ -113,4 +113,4 @@ namespace Online { virtual void close() override; }; } // End namespace Online -#endif // ONLINE_GAUDIONLINE_NETEVENTACCESS_H +#endif // ONLINE_EVENTDATA_NETEVENTACCESS_H diff --git a/Online/GaudiOnline/src/EventAccess.cpp b/Online/EventData/src/EventAccess.cpp similarity index 96% rename from Online/GaudiOnline/src/EventAccess.cpp rename to Online/EventData/src/EventAccess.cpp index 6b7c2b547..c1c1eea2e 100644 --- a/Online/GaudiOnline/src/EventAccess.cpp +++ b/Online/EventData/src/EventAccess.cpp @@ -15,7 +15,7 @@ //========================================================================== /// Framework include files -#include <GaudiOnline/EventAccess.h> +#include <EventData/EventAccess.h> #include <Tell1Data/EventHeader.h> #include <Tell1Data/Tell1Decoder.h> #include <PCIE40Data/pcie40decoder.h> @@ -235,21 +235,23 @@ EventAccess::convertPCIE40MEP(datapointer_t start, size_t /* len */) const { namespace { using namespace pcie40; - - void _error(const char* fmt,...) { - va_list args; - va_start(args,fmt); - ::vprintf(fmt,args); - va_end(args); - } } /// The event is a PCIE40 MEP structure with multiple events, which must be decoded std::unique_ptr<pcie40::event_collection_t> EventAccess::convertPCIE40MEP(datapointer_t start, size_t len) const { + struct _printer { + RTL::Logger& logger; + _printer(RTL::Logger& e) : logger(e) {} + /// Printout operator + void operator()(int lvl, const char* source, const char* msg) { + logger.printmsg(lvl, source, msg); + } + } printer(*m_logger); + pcie40::decoder_t::logger_t logger = printer; + pcie40::decoder_t decoder(logger); std::unique_ptr<pcie40::event_collection_t> events; datapointer_t end = start + len; - pcie40::decoder_t decoder; if ( end > start ) { static constexpr size_t max_bank = 20000; @@ -289,13 +291,13 @@ EventAccess::convertPCIE40MEP(datapointer_t start, size_t len) const { const pcie40::bank_collection_t* coll=ev->bank_collection(j); for( const pcie40::bank_t* b=coll->begin(); b != coll->end(); b=coll->next(b) ) { if ( b->magic() != pcie40::bank_t::MagicPattern ) { - _error("Bad magic pattern in raw bank!\n"); + m_logger->error("Bad magic pattern in raw bank!\n"); } ++num_bank; } for( const pcie40::bank_t* b=coll->special_begin(); b != coll->special_end(); b=coll->next(b) ) { if ( b->magic() != pcie40::bank_t::MagicPattern ) { - _error("Bad magic pattern in raw bank!\n"); + m_logger->error("Bad magic pattern in raw bank!\n"); } ++num_bank; } diff --git a/Online/GaudiOnline/src/EventOutput.cpp b/Online/EventData/src/EventOutput.cpp similarity index 99% rename from Online/GaudiOnline/src/EventOutput.cpp rename to Online/EventData/src/EventOutput.cpp index 686be7b52..62da98a3e 100644 --- a/Online/GaudiOnline/src/EventOutput.cpp +++ b/Online/EventData/src/EventOutput.cpp @@ -15,7 +15,7 @@ //========================================================================== /// Framework include files -#include "GaudiOnline/EventOutput.h" +#include "EventData/EventOutput.h" #include "Tell1Data/EventHeader.h" #include "Tell1Data/Tell1Decoder.h" #include "RTL/rtl.h" diff --git a/Online/GaudiOnline/src/FileEventAccess.cpp b/Online/EventData/src/FileEventAccess.cpp similarity index 99% rename from Online/GaudiOnline/src/FileEventAccess.cpp rename to Online/EventData/src/FileEventAccess.cpp index dde72835e..dcb79f247 100644 --- a/Online/GaudiOnline/src/FileEventAccess.cpp +++ b/Online/EventData/src/FileEventAccess.cpp @@ -21,7 +21,7 @@ //========================================================================== /// Framework include files -#include <GaudiOnline/FileEventAccess.h> +#include <EventData/FileEventAccess.h> #include <MBM/bmdef.h> /// C/C++ include files diff --git a/Online/GaudiOnline/src/FileEventOutput.cpp b/Online/EventData/src/FileEventOutput.cpp similarity index 99% rename from Online/GaudiOnline/src/FileEventOutput.cpp rename to Online/EventData/src/FileEventOutput.cpp index 0b84c2dfb..4c9ea338c 100644 --- a/Online/GaudiOnline/src/FileEventOutput.cpp +++ b/Online/EventData/src/FileEventOutput.cpp @@ -15,7 +15,7 @@ //========================================================================== /// Framework include files -#include <GaudiOnline/FileEventOutput.h> +#include <EventData/FileEventOutput.h> #include <Tell1Data/RawFile.h> #include "RTL/strdef.h" diff --git a/Online/GaudiOnline/src/MBMEventAccess.cpp b/Online/EventData/src/MBMEventAccess.cpp similarity index 99% rename from Online/GaudiOnline/src/MBMEventAccess.cpp rename to Online/EventData/src/MBMEventAccess.cpp index 9a1eb323d..3687d6a8b 100644 --- a/Online/GaudiOnline/src/MBMEventAccess.cpp +++ b/Online/EventData/src/MBMEventAccess.cpp @@ -14,7 +14,7 @@ //========================================================================== /// Framework include files -#include "GaudiOnline/MBMEventAccess.h" +#include "EventData/MBMEventAccess.h" /// C/C++ include files #include <iomanip> diff --git a/Online/GaudiOnline/src/MBMEventOutput.cpp b/Online/EventData/src/MBMEventOutput.cpp similarity index 99% rename from Online/GaudiOnline/src/MBMEventOutput.cpp rename to Online/EventData/src/MBMEventOutput.cpp index e50dd2575..4dfeb85e9 100644 --- a/Online/GaudiOnline/src/MBMEventOutput.cpp +++ b/Online/EventData/src/MBMEventOutput.cpp @@ -15,7 +15,7 @@ //========================================================================== /// Framework include files -#include <GaudiOnline/MBMEventOutput.h> +#include <EventData/MBMEventOutput.h> #include <Tell1Data/EventHeader.h> #include <Tell1Data/Tell1Decoder.h> diff --git a/Online/GaudiOnline/src/NetEventAccess.cpp b/Online/EventData/src/NetEventAccess.cpp similarity index 99% rename from Online/GaudiOnline/src/NetEventAccess.cpp rename to Online/EventData/src/NetEventAccess.cpp index ee8af60c4..7e2488a9f 100644 --- a/Online/GaudiOnline/src/NetEventAccess.cpp +++ b/Online/EventData/src/NetEventAccess.cpp @@ -21,7 +21,7 @@ //========================================================================== /// Framework include files -#include "GaudiOnline/NetEventAccess.h" +#include "EventData/NetEventAccess.h" #include "CPP/TimeSensor.h" #include "CPP/Event.h" #include "MBM/bmdef.h" diff --git a/Online/FarmConfig/job/EBPass.sh b/Online/FarmConfig/job/EBPass.sh index c0b2fc734..f220525a2 100755 --- a/Online/FarmConfig/job/EBPass.sh +++ b/Online/FarmConfig/job/EBPass.sh @@ -36,11 +36,16 @@ application.setup_hive(FlowManager("EventLoop"), 30) application.setup_algorithms(writer=writer, acceptRate=0.01) application.setup_monitoring() # +writer.UseRawData = False +application.input.DeclareData = True +application.input.DeclareEvent = False +application.input.DeclareErrors = False +# # application.monSvc.DimUpdateInterval = 1 application.config.numEventThreads = 1 application.config.MBM_numConnections = 7 -application.config.MBM_numEventThreads = 8 +application.config.MBM_numEventThreads = 6 application.config.MBM_requests = [ 'EvType=3;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=100.0', 'EvType=2;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=100.0', @@ -50,5 +55,5 @@ application.config.MBM_requests = [ # # export PYTHONPATH=/group/online/dataflow/options/${PARTITION}/HLT:${PYTHONPATH}; -export RTL_SLEEP_ON_FATAL=1; +###export RTL_SLEEP_ON_FATAL=1; exec -a ${UTGID} python `which gaudirun.py` /tmp/${UTGID}.py --application=OnlineEvents diff --git a/Online/GaudiOnline/CMakeLists.txt b/Online/GaudiOnline/CMakeLists.txt index 661a910a6..3df57fd2e 100755 --- a/Online/GaudiOnline/CMakeLists.txt +++ b/Online/GaudiOnline/CMakeLists.txt @@ -20,6 +20,7 @@ gaudi_depends_on_subdirs(GaudiKernel Online/Parsers Online/Tell1Data Online/PCIE40Data + Online/EventData Online/OnlineBase) # add_definitions(-DDD4HEP_USE_TINYXML) @@ -36,14 +37,14 @@ include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} ${TBB_INCL # gaudi_add_library(GaudiOnline src/*.cpp PUBLIC_HEADERS GaudiOnline - INCLUDE_DIRS dim OnlineBase Tell1Data PCIE40Data - LINK_LIBRARIES dim dimlogLib Boost OnlineBase Tell1Data PCIE40Data GaudiKernel) + INCLUDE_DIRS dim OnlineBase Tell1Data PCIE40Data EventData + LINK_LIBRARIES dim dimlogLib Boost OnlineBase Tell1Data PCIE40Data EventData GaudiKernel) target_compile_options(GaudiOnline PRIVATE -Wno-address-of-packed-member) target_compile_definitions(GaudiOnline PRIVATE -DMessageSvc=OnlineMessageSvc) # gaudi_add_module(GaudiOnlineComp components/*.cpp src/*.cpp - INCLUDE_DIRS OnlineBase ROOT ${NUMA_INCLUDE_DIR} Tell1Data PCIE40Data GaudiKernel cppgsl - LINK_LIBRARIES Tell1Data PCIE40Data GaudiKernel GaudiAlgLib DAQEventLib dim dimlogLib OnlineBase GaudiOnline RPC Parsers ${NUMA_LIBRARIES} -lrt) + INCLUDE_DIRS OnlineBase ROOT ${NUMA_INCLUDE_DIR} Tell1Data PCIE40Data EventData GaudiKernel cppgsl + LINK_LIBRARIES Tell1Data PCIE40Data EventData GaudiKernel GaudiAlgLib DAQEventLib dim dimlogLib OnlineBase GaudiOnline RPC Parsers ${NUMA_LIBRARIES} -lrt) target_compile_options(GaudiOnlineComp PRIVATE -Wno-address-of-packed-member) # target_compile_definitions(GaudiOnlineComp PRIVATE -DMessageSvc=OnlineMessageSvc) diff --git a/Online/GaudiOnline/GaudiOnline/Configuration.h b/Online/GaudiOnline/GaudiOnline/Configuration.h index c9f3888dc..063376d23 100644 --- a/Online/GaudiOnline/GaudiOnline/Configuration.h +++ b/Online/GaudiOnline/GaudiOnline/Configuration.h @@ -16,10 +16,10 @@ #define GAUDIONLINE_CONFIGURATION_H /// Framework include files -#include "GaudiOnline/MBMEventAccess.h" -#include "GaudiOnline/NetEventAccess.h" -#include "GaudiOnline/FileEventAccess.h" -#include "GaudiKernel/Service.h" +#include <EventData/MBMEventAccess.h> +#include <EventData/NetEventAccess.h> +#include <EventData/FileEventAccess.h> +#include <GaudiKernel/Service.h> /// C/C++ include files diff --git a/Online/GaudiOnline/GaudiOnline/ITaskFSM.h b/Online/GaudiOnline/GaudiOnline/ITaskFSM.h index 86b308e4e..4f18b2826 100755 --- a/Online/GaudiOnline/GaudiOnline/ITaskFSM.h +++ b/Online/GaudiOnline/GaudiOnline/ITaskFSM.h @@ -15,6 +15,7 @@ #ifndef ONLINE_GAUDIONLINE_ITASKFSM_H #define ONLINE_GAUDIONLINE_ITASKFSM_H +/// C/C++ include files #include <string> // Forward declarations diff --git a/Online/GaudiOnline/GaudiOnline/OnlineApplication.h b/Online/GaudiOnline/GaudiOnline/OnlineApplication.h index 325f5ce0e..e0fcc1093 100644 --- a/Online/GaudiOnline/GaudiOnline/OnlineApplication.h +++ b/Online/GaudiOnline/GaudiOnline/OnlineApplication.h @@ -17,7 +17,6 @@ /// Framework include files #include <GaudiOnline/ITaskFSM.h> -#include <GaudiOnline/Macros.h> #include "Configuration.h" #include <Gaudi/Application.h> diff --git a/Online/GaudiOnline/GaudiOnline/QueuedFlowManager.h b/Online/GaudiOnline/GaudiOnline/QueuedFlowManager.h index b2c2cb7cc..a828ec835 100644 --- a/Online/GaudiOnline/GaudiOnline/QueuedFlowManager.h +++ b/Online/GaudiOnline/GaudiOnline/QueuedFlowManager.h @@ -16,11 +16,10 @@ #define ONLINE_GAUDIONLINE_QUEUEDFLOWMANAGER_H /// Framework include files -#include "GaudiOnline/Macros.h" -#include "GaudiKernel/SmartIF.h" -#include "GaudiKernel/EventContext.h" -#include "GaudiKernel/IHiveWhiteBoard.h" -#include "GaudiKernel/ThreadLocalContext.h" +#include <GaudiKernel/SmartIF.h> +#include <GaudiKernel/EventContext.h> +#include <GaudiKernel/IHiveWhiteBoard.h> +#include <GaudiKernel/ThreadLocalContext.h> #include <Gaudi/Interfaces/IQueueingEventProcessor.h> #include <mutex> diff --git a/Online/GaudiOnline/components/Components.cpp b/Online/GaudiOnline/components/Components.cpp index 76c7a8f48..469f395be 100644 --- a/Online/GaudiOnline/components/Components.cpp +++ b/Online/GaudiOnline/components/Components.cpp @@ -17,12 +17,12 @@ using namespace Online; #include <Gaudi/PluginService.h> -#include <GaudiOnline/MBMEventAccess.h> +#include <EventData/MBMEventAccess.h> DECLARE_FACTORY(MBMEventAccess, Gaudi::PluginService::Factory<EventAccess*(std::unique_ptr<RTL::Logger>&&)>) -#include <GaudiOnline/NetEventAccess.h> +#include <EventData/NetEventAccess.h> DECLARE_FACTORY(NetEventAccess, Gaudi::PluginService::Factory<EventAccess*(std::unique_ptr<RTL::Logger>&&)>) -#include <GaudiOnline/FileEventAccess.h> +#include <EventData/FileEventAccess.h> DECLARE_FACTORY(FileEventAccess, Gaudi::PluginService::Factory<EventAccess*(std::unique_ptr<RTL::Logger>&&)>) diff --git a/Online/GaudiOnline/components/EventProcessor.cpp b/Online/GaudiOnline/components/EventProcessor.cpp index 0f8a0f90e..352b642be 100644 --- a/Online/GaudiOnline/components/EventProcessor.cpp +++ b/Online/GaudiOnline/components/EventProcessor.cpp @@ -15,15 +15,17 @@ /// Framework include files #include "EventProcessor.h" -#include <GaudiOnline/EventTraits.h> -#include <GaudiOnline/EventOutput.h> -#include <GaudiKernel/MsgStream.h> +#include <EventData/EventTraits.h> +#include <EventData/EventOutput.h> #include <Tell1Data/EventHeader.h> #include <Tell1Data/Tell1Decoder.h> #include <Tell1Data/RunInfo.h> #include <PCIE40Data/pcie40decoder.h> +#include <PCIE40Data/RawBank40.h> #include <PCIE40Data/sodin.h> +#include <GaudiKernel/MsgStream.h> + // C/C++ include files #include <exception> #include <stdexcept> @@ -31,31 +33,6 @@ using namespace std; using namespace Online; -namespace { - struct BankHeader { - /// Magic word (by definition 0xCBCB) - unsigned short magic; - /// Bank length in bytes (must be >= 0) - unsigned short length; - /// Bank type (must be >= 0) - unsigned char type; - /// Version identifier (must be >= 0) - unsigned char version; - /// Source ID (valid source IDs are > 0; invalid ones 0) - short sourceID; - BankHeader() = delete; - BankHeader(BankHeader&&) = delete; - BankHeader(const BankHeader&) = delete; - template<typename T> BankHeader(unsigned short m, const T* c) - : magic(m), type(c->type()), version(c->version()) - { - length = c->size() + sizeof(BankHeader); - } - BankHeader& operator=(BankHeader&&) = delete; - BankHeader& operator=(const BankHeader&) = delete; - }; -} - /// Initialize the algorithm StatusCode EventProcessor::initialize() { m_logger = make_unique<RTL::Logger>(RTL::Logger::getGlobalDevice(),name(),msgLevel()); @@ -87,153 +64,131 @@ StatusCode EventProcessor::execute(EventContext const& ctxt) const { return StatusCode::FAILURE; } +bool EventProcessor::type_found(int required_type, const std::vector<int>& good_types) const { + if ( good_types.empty() ) + return true; + if ( std::find( good_types.begin(), good_types.end(), required_type) == good_types.end() ) + return false; + return true; +} + + namespace Online { - /// Create raw event object from banks template <typename traits> - std::unique_ptr<LHCb::RawEvent> EventProcessor::create_event(const event_traits::record_t&) const { - return std::unique_ptr<LHCb::RawEvent>(); + const typename traits::odin_type* + EventProcessor::get_odin(event_traits::record_t event) const { + const auto* bank = get_odin_bank<traits>(event); + return bank ? traits::get_odin(bank) : nullptr; } + + template <typename traits> + const typename traits::bank_type* + EventProcessor::get_odin_bank(event_traits::record_t record) const { + auto& e = traits::get_event(record); + for(size_t i=0; i<traits::num_collections(e); ++i) { + typename traits::bank_iteration_t iter(e, i); + for(const auto* bnk = iter.begin(); bnk != iter.end(); bnk = iter.next(bnk) ) { + if ( bnk->type() == traits::bank_type::ODIN ) + return bnk; + } + } + return nullptr; + } + /// Create raw event object from banks template <> - std::unique_ptr<LHCb::RawEvent> EventProcessor::create_event<event_traits::tell1>(const event_traits::record_t& record) const { - auto event = make_unique<LHCb::RawEvent>(); - auto* header = record.tell1_event; - auto* start = record.data + header->sizeOf(header->headerVersion()); - auto* end = record.data + header->size(); + EventProcessor::evt_data_t + EventProcessor::create_event<event_traits::tell1>(event_traits::record_t record) const { + const event_traits::tell1::event_type& event = *record.tell1_event; + auto* start = record.data + event.sizeOf(event.headerVersion()); + auto* end = record.data + event.size(); size_t num_banks = 0; + evt_data_t evt_data; + + evt_data.reserve(512); while ( start < end ) { - LHCb::RawBank* b = (LHCb::RawBank*)start; - int len = b->totalSize(); - event->adoptBank(b, false); - start += len; + Tell1Bank* b = (Tell1Bank*)start; + evt_data.emplace_back(b, b->data()); + start += b->totalSize(); if ( ++num_banks < 2000 ) continue; m_logger->error("Exceeded maximum number of banks [Banks were dropped]"); break; } - return event; + return evt_data; } template <> - std::unique_ptr<LHCb::RawEvent> EventProcessor::create_event<event_traits::tell40>(const event_traits::record_t& record) const { - auto result = make_unique<LHCb::RawEvent>(); - auto* event = record.tell40_event; - for(size_t i=0; i < event->num_bank_collections(); ++i) { - const auto* bc = event->bank_collection(i); - for(const auto* b=bc->begin(); b != bc->end(); b = bc->next(b)) { - if ( b->type() < b->LastType ) { - result->adoptBank((LHCb::RawBank*)b, false); - } - } - for(const auto* b=bc->special_begin(); b != bc->special_end(); b = bc->next(b)) { - if ( b->type() < b->LastType ) { - result->adoptBank((LHCb::RawBank*)b, false); - } - } + EventProcessor::evt_data_t + EventProcessor::create_event<event_traits::tell40>(event_traits::record_t record) const { + const event_traits::tell40::event_type& event = *record.tell40_event; + evt_data_t evt_data; + evt_data.reserve(512); + for(size_t i=0; i < event.num_bank_collections(); ++i) { + const auto* bc = event.bank_collection(i); + for(const auto* b=bc->begin(); b != bc->end(); b = bc->next(b)) + evt_data.emplace_back((BankHeader*)b, b->data()); + for(const auto* b=bc->special_begin(); b != bc->special_end(); b = bc->next(b)) + evt_data.emplace_back((BankHeader*)b, b->data()); } - return result; + return evt_data; } template <typename traits> void EventProcessor::put_event(string& loc, const evt_desc_t& event, size_t eid) const { auto evt = create_event<traits>(event.second->at(eid)); + auto obj = make_unique<AnyDataWrapper<evt_data_t> >(move(evt)); loc += (eid<event.first ? "prev" : "next"); - if ( !eventSvc()->registerObject(loc, evt.release()).isSuccess() ) { - m_logger->except("EventProcessor","+++ Failed to register TAE leaf %s",loc.c_str()); + if ( eventSvc()->registerObject(loc, obj.get()).isSuccess() ) { + obj.release(); + return; } + m_logger->except("EventProcessor","+++ Failed to register TAE leaf %s",loc.c_str()); } - template <typename traits> - void EventProcessor::expand_tae(const evt_desc_t& event, bool force, double probability, size_t forced_half_window) const { - using namespace event_traits; - size_t eid = event.first; - auto record = event.second->at(eid); - auto* odin = get_odin_bank<traits>(record); - if ( odin ) { - const auto* info = (typename traits::odin_type*)odin->data(); - bool central = info->tae_central(); - size_t half_window = info->tae_window(); - if ( force ) { - double frac = double(::rand()) / double(RAND_MAX); - if ( frac <= probability ) { - central = true; - half_window = forced_half_window; - } - } - if ( central ) { - if ( eid > half_window && event.second->length-eid > half_window ) { - string prev, next; - traits::set_tae(record, half_window); - for ( size_t i=1; i<=half_window; ++i ) { - put_event<traits>(prev, event, eid-i); - put_event<traits>(next, event, eid+i); - } - } - } - } - } - - template <typename traits> - const typename traits::bank_type* - EventProcessor::get_odin_bank(const event_traits::record_t& record) const - { - auto& e = traits::get_event(record); - for(size_t i=0; i<traits::num_collections(e); ++i) { - typename traits::bank_iteration_t iter(e, i); - for(const auto* bnk = iter.begin(); bnk != iter.end(); bnk = iter.next(bnk) ) { - if ( bnk->type() == traits::bank_type::ODIN ) return bnk; - } + namespace { + template <typename bank_type> size_t + output_bank(EventOutput::transaction_t* tr, bank_type* b, const void* data) { + Tell1Bank* bnk = tr->get<Tell1Bank>(); + ::memcpy((void*)bnk, b, bank_type::hdrSize()); + ::memcpy(bnk->data(), data, b->totalSize()-bank_type::hdrSize()); + bnk->setMagic(); + tr->advance(b->totalSize()); + return b->totalSize(); } - return nullptr; } - - template <typename traits> - void EventProcessor::force_tae(const event_traits::record_t& record, - double probability, - size_t half_window) const - { - double frac = double(::rand()) / double(RAND_MAX); - if ( probability >= frac ) { - traits::set_tae(record, half_window); - } - } - + template <typename traits> - void EventProcessor::output_mdf(const LHCb::RawEvent& evt, - const std::vector<int>& routing_mask, - EventOutput& output) const + size_t EventProcessor::output_mdf(const evt_data_t& evt, + const mask_t& routing_mask, + EventOutput& output) const { typedef typename traits::bank_type bank_type; - const bank_type* daq_bank = nullptr; - const bank_type* hlt_bank = nullptr; - const size_t hdr_length = EventHeader::sizeOf(3); - size_t data_length = hdr_length; + const EventHeader* evthdr = nullptr; + const uint32_t* hlt_mask = nullptr; + const size_t hdr_len = EventHeader::sizeOf(3); + size_t data_len = hdr_len; - for(int i=0; i < bank_type::LastType; ++i) { - auto banks = evt.banks(LHCb::RawBank::BankType(i)); - for(const auto* bnk : banks ) { - const bank_type* b = (const bank_type*)bnk; - if ( i == bank_type::DAQ && b->version() == DAQ_STATUS_BANK ) { - daq_bank = reinterpret_cast<const bank_type*>(b); - continue; - } - else if ( i == bank_type::HltRoutingBits && !banks.empty() ) { - hlt_bank = reinterpret_cast<const bank_type*>(*(banks.begin())); - } - data_length += b->totalSize(); + for( const auto& dsc : evt ) { + const auto* bank = dsc.first; + if ( bank->type() == bank_type::DAQ && bank->version() == DAQ_STATUS_BANK ) { + evthdr = reinterpret_cast<const EventHeader*>(dsc.second); + continue; } + else if ( bank->type() == bank_type::HltRoutingBits ) { + hlt_mask = reinterpret_cast<const uint32_t*>(dsc.second); + } + data_len += bank->totalSize(); } unsigned int m[] = { ~0x0U, ~0x0U, ~0x0U, ~0x0U }; - if ( hlt_bank ) { - const unsigned int* hlt_mask = (const unsigned int*)hlt_bank->data(); + if ( hlt_mask ) { m[0] = hlt_mask[0]; m[1] = hlt_mask[1]; m[2] = hlt_mask[2]; } - else if ( daq_bank ) { - const EventHeader* hdr = (const EventHeader*)daq_bank->data(); - auto daq_mask = hdr->subHeader().H1->triggerMask(); + else if ( evthdr ) { + auto daq_mask = evthdr->subHeader().H1->triggerMask(); m[0] = daq_mask[0]; m[1] = daq_mask[1]; m[2] = daq_mask[2]; @@ -260,7 +215,7 @@ namespace Online { else if ( routing_mask.size() > 0 ) { m_logger->except("Unknown trigger masdk configuration. Cannot process event"); } - auto* tr = output.getTransaction(data_length); + auto* tr = output.getTransaction(data_len); if ( !tr ) { m_logger->except("Event output failed [Cannot reserve output space]"); } @@ -269,14 +224,13 @@ namespace Online { ev_hdr->setChecksum(0); ev_hdr->setCompression(0); ev_hdr->setHeaderVersion(3); - ev_hdr->setSize(data_length-hdr_length); + ev_hdr->setSize(data_len-hdr_len); ev_hdr->setDataType(EventHeader::BODY_TYPE_BANKS); ev_hdr->setSubheaderLength(sizeof(EventHeader::Header1)); auto* h = ev_hdr->subHeader().H1; h->setTriggerMask(m); - if ( daq_bank ) { - const EventHeader* hdr = (const EventHeader*)daq_bank->data(); - const auto* dh = hdr->subHeader().H1; + if ( evthdr ) { + const auto* dh = evthdr->subHeader().H1; h->setRunNumber(dh->runNumber()); h->setOrbitNumber(dh->orbitNumber()); h->setBunchID(dh->bunchID()); @@ -286,56 +240,157 @@ namespace Online { h->setOrbitNumber(0); h->setBunchID(0); } - tr->advance(hdr_length); - for(int i=0; i<bank_type::LastType; ++i) { - auto banks = evt.banks(LHCb::RawBank::BankType(i)); - int cnt = 0; - for(const auto* bnk : banks ) { - const bank_type* b = (const bank_type*)bnk; - if ( (void*)b != (void*)daq_bank ) { - BankHeader hdr(Tell1Bank::MagicPattern, b); - size_t hdr_len = sizeof(BankHeader); - if ( b->magic() != bank_type::MagicPattern ) { - m_logger->info("Bad bank[%d]: %d %ld %ld transaction length:%ld", - ++cnt,int(b->type()), hdr_len, b->totalSize(), tr->length); - } - tr->add_data(EventOutput::datapointer_t(&hdr), hdr_len); - tr->add_data(EventOutput::datapointer_t(b->data()), b->totalSize()-hdr_len); + tr->advance(hdr_len); + for(const auto& dsc : evt) { + const auto* bank = dsc.first; + if ( (void*)dsc.second != (void*)evthdr ) { + if ( bank->magic() != bank_type::MagicPattern ) { + m_logger->info("Bad bank: %d %ld transaction length:%ld", + int(bank->type()), bank->totalSize(), tr->length); } + output_bank(tr, bank, dsc.second); } } if ( !output.end(tr) ) { m_logger->except("Failed to commit event output!"); } + return data_len; + } + + /// Output PCIE40 or TELL1 event in MDF format + template <typename traits> size_t EventProcessor::output_mdf + (const typename traits::event_type& evt, const mask_t& routing_mask, EventOutput& output) const + { + event_traits::record_t record(&evt); + evt_data_t banks(create_event<traits>(record)); + return output_mdf<event_traits::tell1>(banks, routing_mask, output); + } + + /// Output PCIE40 event in MDF format + size_t EventProcessor::output_mdf(EventAccess::record_t record, + const mask_t& routing_mask, + EventOutput& output) const + { + if ( record.is_tell40() ) + return output_mdf<event_traits::tell40>(*record.tell40_event, routing_mask, output); + else if ( record.is_tell1() ) + return output_mdf<event_traits::tell1>(*record.tell1_event, routing_mask, output); + return 0; + } + + /// Output PCIE40 event in MDF format + void EventProcessor::output_pcie40(const EventAccess::guard_t* guard, EventOutput& output) const { + if ( guard && !guard->empty() ) { + EventAccess::record_t rec = guard->at(0); + const pcie40::event_collection_t* events = + pcie40::add_ptr<pcie40::event_collection_t>(rec.data, + - sizeof(pcie40::event_collection_t::capacity) + - sizeof(pcie40::event_collection_t::length) + - sizeof(pcie40::event_collection_t::mep) + - sizeof(pcie40::event_collection_t::magic)); + if ( nullptr != events->mep ) { + auto* tr = output.getTransaction(events->mep->size); + if ( !tr ) { + m_logger->except("+++ Event output failed [Cannot reserve output space]"); + } + tr->add_data(EventAccess::datapointer_t(events->mep), events->mep->size); + if ( !output.end(tr) ) { + m_logger->except("+++ Failed to commit event output!"); + } + } + } + } + + /// Add error banks to the data service + EventProcessor::evt_data_t EventProcessor::get_errors(event_traits::record_t record) const { + evt_data_t banks; + if ( record.is_tell40() ) { + auto& evt = event_traits::tell40::get_event(record); + for(size_t i=0; i < evt.num_bank_collections(); ++i) { + const auto* bc = evt.bank_collection(i); + for(const auto* b=bc->begin(); b != bc->end(); b = bc->next(b)) { + if ( b->type() >= RawBank40::DaqErrorBase ) + banks.emplace_back((event_traits::tell1::bank_type*)b, b->data()); + } + for(const auto* b=bc->special_begin(); b != bc->special_end(); b = bc->next(b)) { + if ( b->type() >= RawBank40::DaqErrorBase ) + banks.emplace_back((event_traits::tell1::bank_type*)b, b->data()); + } + } + } + return banks; + } + + template <typename traits> + void EventProcessor::expand_tae(const evt_desc_t& event, bool force, double probability, size_t forced_half_window) const { + using namespace event_traits; + size_t eid = event.first; + auto record = event.second->at(eid); + const auto* info = get_odin<traits>(record); + if ( info ) { + bool central = info->tae_central(); + size_t half_window = info->tae_window(); + if ( force ) { + double frac = double(::rand()) / double(RAND_MAX); + if ( frac <= probability ) { + central = true; + half_window = forced_half_window; + } + } + if ( central ) { + if ( eid > half_window && event.second->length-eid > half_window ) { + string prev, next; + traits::set_tae(record, half_window); + for ( size_t i=1; i<=half_window; ++i ) { + put_event<traits>(prev, event, eid-i); + put_event<traits>(next, event, eid+i); + } + } + } + } } + template <typename traits> - void EventProcessor::output_tae(const evt_desc_t& event, const std::vector<int>& routing_mask, EventOutput& output) const { + void EventProcessor::force_tae(event_traits::record_t record, + double probability, + size_t half_window) const + { + double frac = double(::rand()) / double(RAND_MAX); + if ( probability >= frac ) { + traits::set_tae(record, half_window); + } + } + + template <typename traits> + void EventProcessor::output_tae(const evt_desc_t& event, mask_t& routing_mask, EventOutput& output) const { if ( event.first || routing_mask.empty() || output.isCancelled() ) {} } template <typename traits> - void EventProcessor::output_mep(const evt_desc_t& event, const std::vector<int>& routing_mask, EventOutput& output) const { + void EventProcessor::output_mep(const evt_desc_t& event, mask_t& routing_mask, EventOutput& output) const { if ( event.first || routing_mask.empty() || output.isCancelled() ) {} } - + #define INSTANTIATE(x) \ + template const typename x::odin_type* \ + EventProcessor::get_odin< x >(event_traits::record_t r) const; \ template const typename x::bank_type* \ - EventProcessor::get_odin_bank< x >(const event_traits::record_t& r) const; \ + EventProcessor::get_odin_bank< x >(event_traits::record_t r) const; \ template void \ - EventProcessor::force_tae< x >(const event_traits::record_t& event, double probability, size_t half_window) const; \ + EventProcessor::force_tae< x >(event_traits::record_t event, double probability, size_t half_window) const; \ template void \ EventProcessor::put_event< x >(string& loc, const evt_desc_t& event, size_t eid) const; \ template void \ EventProcessor::expand_tae< x >(const evt_desc_t& event, bool force, double probability, size_t forced_half_window) const; \ + template size_t \ + EventProcessor::output_mdf< x >(const evt_data_t& event, const mask_t& routing_mask, EventOutput& output) const; \ + template size_t \ + EventProcessor::output_mdf< x >(const x::event_type& evt, const mask_t& routing_mask, EventOutput& output) const; \ template void \ - EventProcessor::output_mdf< x >(const LHCb::RawEvent& event, \ - const std::vector<int>& routing_mask, \ - EventOutput& output) const; \ - template void \ - EventProcessor::output_tae< x >(const evt_desc_t& event, const std::vector<int>& routing_mask, EventOutput& output) const; \ + EventProcessor::output_tae< x >(const evt_desc_t& event, const mask_t& routing_mask, EventOutput& output) const; \ template void \ - EventProcessor::output_mep< x >(const evt_desc_t& event, const std::vector<int>& routing_mask, EventOutput& output) const + EventProcessor::output_mep< x >(const evt_desc_t& event, const mask_t& routing_mask, EventOutput& output) const INSTANTIATE(event_traits::tell1); diff --git a/Online/GaudiOnline/components/EventProcessor.h b/Online/GaudiOnline/components/EventProcessor.h index fdb822c67..209b7a947 100644 --- a/Online/GaudiOnline/components/EventProcessor.h +++ b/Online/GaudiOnline/components/EventProcessor.h @@ -16,10 +16,9 @@ #define GAUDIONLINE_EVENTPROCESSOR_H /// Framework include files -#include <GaudiOnline/EventAccess.h> +#include <EventData/EventAccess.h> #include <GaudiKernel/Algorithm.h> #include <GaudiKernel/DataObjectHandle.h> -#include <Event/RawEvent.h> #include <RTL/Logger.h> /// Online namespace declaration @@ -27,7 +26,8 @@ namespace Online { /// Forward declarations class EventOutput; - + typedef Tell1Bank BankHeader; + /// Online algorithm to feed the TES with TAE events from the basic raw event. /** * @@ -36,35 +36,57 @@ namespace Online { * @date 25/04/2019 */ class EventProcessor : public Gaudi::Algorithm { - protected: + public: + typedef std::vector<std::pair<const BankHeader*, const void*> > evt_data_t; typedef std::pair<size_t, EventAccess::shared_guard_t> evt_desc_t; - + typedef const std::vector<int> mask_t; + + protected: /// Reference to output logger std::unique_ptr<RTL::Logger> m_logger; + bool type_found(int required, const std::vector<int>& good_types) const; + template <typename traits> - const typename traits::bank_type* get_odin_bank(const event_traits::record_t& record) const; + const typename traits::odin_type* get_odin(event_traits::record_t record) const; template <typename traits> - void force_tae(const event_traits::record_t& event, double probability, size_t half_window) const; + const typename traits::bank_type* get_odin_bank(event_traits::record_t event) const; template <typename traits> - void put_event(std::string& loc, const evt_desc_t& event, size_t eid) const; + void put_event(std::string& loc, const evt_desc_t& event, size_t eid) const; template <typename traits> - std::unique_ptr<LHCb::RawEvent> create_event(const event_traits::record_t& event) const; + evt_data_t create_event(event_traits::record_t record) const; template <typename traits> - void expand_tae(const evt_desc_t& event, bool force, double probability, size_t forced_half_window) const; + size_t output_mdf(const evt_data_t& event, const mask_t& routing_mask, EventOutput& output) const; + /// Output PCIE40 or TELL1 event in MDF format template <typename traits> - void output_mdf(const LHCb::RawEvent& event, const std::vector<int>& routing_mask, EventOutput& output) const; + size_t output_mdf(const typename traits::event_type& event, const mask_t& routing_mask, EventOutput& output) const; + + /// Output PCIE40 or TELL1 event in MDF format + size_t output_mdf(event_traits::record_t record, const mask_t& routing_mask, EventOutput& output) const; + + /// Output PCIE40 event in PCIE40-MEP format + void output_pcie40(const EventAccess::guard_t* guard, EventOutput& output) const; template <typename traits> - void output_tae(const evt_desc_t& event, const std::vector<int>& routing_mask, EventOutput& output) const; + void force_tae(event_traits::record_t event, double probability, size_t half_window) const; template <typename traits> - void output_mep(const evt_desc_t& event, const std::vector<int>& routing_mask, EventOutput& output) const; + void expand_tae(const evt_desc_t& event, bool force, double probability, size_t forced_half_window) const; + + template <typename traits> + void output_tae(const evt_desc_t& event, const mask_t& routing_mask, EventOutput& output) const; + + template <typename traits> + void output_mep(const evt_desc_t& event, const mask_t& routing_mask, EventOutput& output) const; + + /// Add error banks to the data service + evt_data_t get_errors(event_traits::record_t event) const; + public: using Algorithm::Algorithm; diff --git a/Online/GaudiOnline/components/ExpandTAE.cpp b/Online/GaudiOnline/components/ExpandTAE.cpp index 1c7befd5a..681a032b8 100644 --- a/Online/GaudiOnline/components/ExpandTAE.cpp +++ b/Online/GaudiOnline/components/ExpandTAE.cpp @@ -43,7 +43,7 @@ namespace Online { Gaudi::Property<double> m_probability{this, "Probability", 0.0, ""}; /// Data guard location in TES - DataObjectReadHandle<evt_desc_t> m_rawGuard{this, "RawGuard", LHCb::RawEventLocation::Default+"Guard"}; + DataObjectReadHandle<evt_desc_t> m_rawGuard{this, "RawGuard", "DAQ/RawDataGuard"}; public: using EventProcessor::EventProcessor; diff --git a/Online/GaudiOnline/components/ForceTAE.cpp b/Online/GaudiOnline/components/ForceTAE.cpp index fa977ea23..a4a280fdd 100644 --- a/Online/GaudiOnline/components/ForceTAE.cpp +++ b/Online/GaudiOnline/components/ForceTAE.cpp @@ -38,7 +38,7 @@ namespace Online { /// Property: TAE half window size Gaudi::Property<double> m_probability{this, "Probability", 0.0, ""}; /// Data guard location in TES - DataObjectReadHandle<evt_desc_t> m_rawGuard{this, "RawGuard", LHCb::RawEventLocation::Default+"Guard"}; + DataObjectReadHandle<evt_desc_t> m_rawGuard{this, "RawGuard", "DAQ/RawDataGuard"}; public: using EventProcessor::EventProcessor; diff --git a/Online/GaudiOnline/components/IOService.h b/Online/GaudiOnline/components/IOService.h index 94a17e610..450fa5025 100644 --- a/Online/GaudiOnline/components/IOService.h +++ b/Online/GaudiOnline/components/IOService.h @@ -17,7 +17,7 @@ /// Framework include files #include <GaudiKernel/Service.h> -#include <GaudiOnline/EventAccess.h> +#include <EventData/EventAccess.h> /// C/C++ include files diff --git a/Online/GaudiOnline/components/InputAlg.cpp b/Online/GaudiOnline/components/InputAlg.cpp index 98a8a434f..69e9962e7 100644 --- a/Online/GaudiOnline/components/InputAlg.cpp +++ b/Online/GaudiOnline/components/InputAlg.cpp @@ -56,45 +56,31 @@ StatusCode Online::InputAlg::stop() { return StatusCode::SUCCESS; } -/// Add error banks to the data service -Online::InputAlg::daq_error_t -Online::InputAlg::get_errors(const event_traits::record_t& record) const { - daq_error_t banks; - auto* event = record.tell40_event; - for(size_t i=0; i < event->num_bank_collections(); ++i) { - const auto* bc = event->bank_collection(i); - for(const auto* b=bc->begin(); b != bc->end(); b = bc->next(b)) { - if ( b->type() >= RawBank40::DaqErrorBase ) { - banks.emplace_back(b); - } - } - for(const auto* b=bc->special_begin(); b != bc->special_end(); b = bc->next(b)) { - if ( b->type() < b->LastType ) { - banks.emplace_back(b); - } - } - } - return banks; -} - - /// Execute single event StatusCode Online::InputAlg::process(EventContext const& /* ctxt */) const { + using namespace event_traits; EventAccess::event_t e(m_io->pop()); if ( e.second ) { - std::unique_ptr<LHCb::RawEvent> event; - if ( e.second->type() == event_traits::tell1::data_type ) { - event = create_event<event_traits::tell1>(e.second->at(e.first)); - } - else if ( e.second->type() == event_traits::tell40::data_type ) { - const auto& record = e.second->at(e.first); - event = create_event<event_traits::tell40>(record); - if ( m_declareData.value() ) { - m_daqError.put(move(get_errors(record))); + const auto record(e.second->at(e.first)); + auto typ = e.second->type(); + if ( m_declareEvt.value() ) { + if ( typ == tell1::data_type ) { + evt_data_t event = create_event<event_traits::tell1>(record); + m_rawData.put(move(event)); } + else if ( typ == tell40::data_type ) { + evt_data_t event = create_event<event_traits::tell40>(record); + m_rawData.put(move(event)); + } + else { + m_logger->error("+++ Algorithm failed [Invalid event type]."); + return StatusCode::FAILURE; + } + } + if ( typ == tell40::data_type && m_declareErrs.value() ) { + m_daqError.put(get_errors(record)); } if ( m_declareData.value() ) { - m_rawEvent.put(move(event)); m_rawGuard.put(move(e)); } return StatusCode::SUCCESS; diff --git a/Online/GaudiOnline/components/InputAlg.h b/Online/GaudiOnline/components/InputAlg.h index b4a99e369..a108c664c 100644 --- a/Online/GaudiOnline/components/InputAlg.h +++ b/Online/GaudiOnline/components/InputAlg.h @@ -33,26 +33,27 @@ namespace Online { protected: typedef std::vector<const RawBank40*> daq_error_t; - - Gaudi::Property<bool> m_declareData{this,"DeclareData", true, "Declare or drop data"}; - Gaudi::Property<bool> m_enableHalt{this, "EnableHalt", true, "Enable halt the event loop"}; - Gaudi::Property<std::string> m_ioService{this, "IOServiceName","Online::IOService/IOService","Name of IO service"}; + typedef EventProcessor::evt_data_t evt_data_t; - DataObjectWriteHandle<LHCb::RawEvent> m_rawEvent{this, "RawLocation", LHCb::RawEventLocation::Default}; - DataObjectWriteHandle<evt_desc_t> m_rawGuard{this, "RawGuard", LHCb::RawEventLocation::Default+"Guard"}; - DataObjectWriteHandle<daq_error_t> m_daqError{this, "DAQErrors", LHCb::RawEventLocation::Default+"DAQErrors"}; + Gaudi::Property<bool> m_declareData{this, "DeclareData", true, "Declare or drop data"}; + Gaudi::Property<bool> m_declareErrs{this, "DeclareErrors",false, "Declare error data"}; + Gaudi::Property<bool> m_declareEvt {this, "DeclareEvent", false, "Declare raw data"}; + Gaudi::Property<bool> m_enableHalt {this, "EnableHalt", true, "Enable halt the event loop"}; + Gaudi::Property<std::string> m_ioService {this, "IOServiceName","Online::IOService/IOService","Name of IO service"}; + + DataObjectWriteHandle<evt_data_t> m_rawData {this, "RawData", "DAQ/RawData"}; + DataObjectWriteHandle<evt_data_t> m_daqError {this, "DAQErrors", "DAQ/RawDataErrors"}; + DataObjectWriteHandle<evt_desc_t> m_rawGuard {this, "RawGuard", "DAQ/RawDataGuard"}; /// Reference to the I/O service SmartIF<IOService> m_io; /// Halt the algorithm and allow for debugging void halt() const; + /// Allow to escape halt mutable int m_halt; - /// Add error banks to the data service - daq_error_t get_errors(const event_traits::record_t& record) const; - public: using EventProcessor::EventProcessor; /// Initialize the algorithm diff --git a/Online/GaudiOnline/components/OnlineEventApp.cpp b/Online/GaudiOnline/components/OnlineEventApp.cpp index 16cb0324e..b16ab41ca 100644 --- a/Online/GaudiOnline/components/OnlineEventApp.cpp +++ b/Online/GaudiOnline/components/OnlineEventApp.cpp @@ -15,9 +15,9 @@ #include "OnlineEventApp.h" #include "IOService.h" -#include <GaudiOnline/MBMEventAccess.h> -#include <GaudiOnline/NetEventAccess.h> -#include <GaudiOnline/FileEventAccess.h> +#include <EventData/MBMEventAccess.h> +#include <EventData/NetEventAccess.h> +#include <EventData/FileEventAccess.h> #include <Gaudi/PluginService.h> #include <Gaudi/Interfaces/IQueueingEventProcessor.h> diff --git a/Online/GaudiOnline/components/OnlineEventApp.h b/Online/GaudiOnline/components/OnlineEventApp.h index e1dbcfc0d..c8d786071 100644 --- a/Online/GaudiOnline/components/OnlineEventApp.h +++ b/Online/GaudiOnline/components/OnlineEventApp.h @@ -17,13 +17,12 @@ #define GAUDIONLINE_ONLINEEVENTAPP_H /// Framework include files -#include "GaudiOnline/OnlineApplication.h" -#include "IOService.h" -#include <GaudiOnline/EventAccess.h> +#include <GaudiOnline/OnlineApplication.h> #include <GaudiKernel/IHiveWhiteBoard.h> #include <GaudiKernel/EventContext.h> #include <GaudiKernel/IMonitorSvc.h> -#include <GaudiKernel/StatusCode.h> +#include <EventData/EventAccess.h> +#include "IOService.h" /// C/C++ include files #include <memory> diff --git a/Online/GaudiOnline/components/OutputAlg.cpp b/Online/GaudiOnline/components/OutputAlg.cpp index 120e10fc7..dd4163f9d 100644 --- a/Online/GaudiOnline/components/OutputAlg.cpp +++ b/Online/GaudiOnline/components/OutputAlg.cpp @@ -18,8 +18,8 @@ #include <GaudiKernel/IIncidentSvc.h> #include <GaudiKernel/DataObjectHandle.h> #include <GaudiKernel/IIncidentListener.h> -#include <GaudiOnline/FileEventOutput.h> -#include <GaudiOnline/MBMEventOutput.h> +#include <EventData/FileEventOutput.h> +#include <EventData/MBMEventOutput.h> /// Online namespace declaration namespace Online { @@ -46,10 +46,16 @@ namespace Online { /// Property: Forced output trigger mask; if empty will not be applied Gaudi::Property<std::vector<int> > m_routingMask{this, "RoutingMask", {}, ""}; + + /// Property: Use raw event + bool m_useRawData {true}; + /// Property: Output MDF format (instead of PCIE40 MEPs) + bool m_output_mdf {true}; + /// Raw event location in TES - DataObjectReadHandle<LHCb::RawEvent> m_rawEvent{this, "RawLocation", LHCb::RawEventLocation::Default}; + DataObjectReadHandle<evt_data_t> m_rawData{ this, "RawData", "DAQ/RawData"}; /// Data guard location in TES - DataObjectReadHandle<evt_desc_t> m_rawGuard{this, "RawGuard", LHCb::RawEventLocation::Default+"Guard"}; + DataObjectReadHandle<evt_desc_t> m_rawGuard{this, "RawGuard", "DAQ/RawDataGuard"}; /// Reference to output writer std::shared_ptr<EventOutput> m_output; @@ -59,6 +65,10 @@ namespace Online { MBMEventOutput::mbm_config_t mbm; /// FILE output parameters FileEventOutput::file_config_t file; + + void output_mdf_pcie40(const pcie40::event_t& evt, + const std::vector<int>& routing_mask, + EventOutput& output) const; public: /// Default constructor @@ -81,6 +91,8 @@ namespace Online { } /// Framework include files +#include <PCIE40Data/pcie40.h> +#include <PCIE40Data/RawBank40.h> // C/C++ include files @@ -94,6 +106,9 @@ DECLARE_COMPONENT( OutputAlg ) OutputAlg::OutputAlg(const string& nam, ISvcLocator* loc) : extends::extends(nam, loc) { + declareProperty("UseRawData", m_useRawData); + declareProperty("OutputMDF", m_output_mdf); + declareProperty("MBM_allocationSize", mbm.allocation_size); declareProperty("MBM_burstPrintCount", mbm.burstPrintCount); declareProperty("MBM_transactionWaitTMO", mbm.transitionWaitTMO); @@ -193,14 +208,36 @@ StatusCode OutputAlg::stop() { /// Execute single event StatusCode OutputAlg::process(EventContext const& /* ctxt */) const { const EventAccess::event_t* event = m_rawGuard.get(); - const LHCb::RawEvent* evt = m_rawEvent.get(); - if ( event->second->type() == event_traits::tell1::data_type ) - output_mdf<event_traits::tell1>(*evt, m_routingMask.value(), *m_output); - else if ( event->second->type() == event_traits::tell1::burst_type ) - output_mdf<event_traits::tell1>(*evt, m_routingMask.value(), *m_output); - else if ( event->second->type() == event_traits::tell40::data_type ) - output_mdf<event_traits::tell40>(*evt, m_routingMask.value(), *m_output); - else - m_logger->except("+++ Invalid burst data type encountered: %ld",event->second->type()); + if ( m_output_mdf ) { + if ( event->second->type() == event_traits::tell1::data_type ) { + const auto* evt = m_rawData.get(); + output_mdf<event_traits::tell1>(*evt, m_routingMask.value(), *m_output); + } + else if ( event->second->type() == event_traits::tell1::burst_type ) { + const auto* evt = m_rawData.get(); + output_mdf<event_traits::tell1>(*evt, m_routingMask.value(), *m_output); + } + else if ( m_useRawData && event->second->type() == event_traits::tell40::data_type ) { + const auto* evt = m_rawData.get(); + output_mdf<event_traits::tell40>(*evt, m_routingMask.value(), *m_output); + } + else if ( event->second->type() == event_traits::tell40::data_type ) { + EventAccess::record_t rec = event->second->at(event->first); + const pcie40::event_t* evt = rec.tell40_event; + output_mdf<event_traits::tell40>(*evt, m_routingMask.value(), *m_output); + } + else { + m_logger->except("+++ Invalid burst data type encountered: %ld",event->second->type()); + } + } + else { + if ( !m_useRawData && event->second->type() == event_traits::tell40::data_type ) { + output_pcie40(event->second.get(), *m_output); + } + else { + m_logger->except("+++ Invalid PCIE40 output conversion requested!"); + } + } return StatusCode::SUCCESS; } + diff --git a/Online/GaudiOnline/components/Passthrough.cpp b/Online/GaudiOnline/components/Passthrough.cpp index 5393fb9a2..5f3023dff 100644 --- a/Online/GaudiOnline/components/Passthrough.cpp +++ b/Online/GaudiOnline/components/Passthrough.cpp @@ -14,9 +14,7 @@ //========================================================================== /// Framework include files -#include <GaudiKernel/DataObjectHandle.h> -#include <GaudiKernel/Algorithm.h> -#include <Event/RawEvent.h> +#include "EventProcessor.h" /// Online namespace declaration namespace Online { @@ -28,11 +26,10 @@ namespace Online { * @version 1.0 * @date 25/04/2019 */ - class Passthrough: public Gaudi::Algorithm { + class Passthrough : public EventProcessor { private: /// Property: Odin event type to be downscaled - std::vector<int> m_downScale; - + std::vector<int> m_downScale; /// Property: Odin trigger types to be filtered std::vector< int > m_triggerTypesToPass; /// Property: Odin calibration types to be downscaled @@ -56,37 +53,42 @@ namespace Online { unsigned int m_seed; /// Input data handle - DataObjectReadHandle<LHCb::RawEvent> m_rawEvent{this, "RawLocation", LHCb::RawEventLocation::Default}; + DataObjectReadHandle<EventAccess::event_t> m_rawGuard{this, "RawGuard", "DAQ/RawDataGuard"}; protected: - StatusCode _halt(int micro_seconds) const; + void _halt(int micro_seconds) const; + public: /// Standard constructor Passthrough( const std::string& name, ISvcLocator* pSvcLocator ); /// Default Destructor virtual ~Passthrough() = default; /// Initialization - StatusCode initialize() override { - return _halt(m_initDelay*1000); + virtual StatusCode initialize() override { + _halt(m_initDelay*1000); + return this->EventProcessor::initialize(); } /// Algorithm overload: Start the algorithm - StatusCode start() override; + virtual StatusCode start() override; /// Stop - StatusCode stop() override { - return _halt(m_stopDelay*1000); + virtual StatusCode stop() override { + _halt(m_stopDelay*1000); + return this->EventProcessor::stop(); } /// Finalization - StatusCode finalize() override { - return _halt(m_finiDelay*1000); + virtual StatusCode finalize() override { + _halt(m_finiDelay*1000); + return this->EventProcessor::finalize(); } /// Algorithm execution - StatusCode execute(EventContext const& evtCtx) const override; + virtual StatusCode process(EventContext const& evtCtx) const override; }; } /// Framework include files -#include "GaudiKernel/SmartDataPtr.h" #include "GaudiKernel/MsgStream.h" +#include "PCIE40Data/pcie40.h" +#include "PCIE40Data/sodin.h" #include "Tell1Data/MEP.h" #include "RTL/rtl.h" @@ -97,11 +99,11 @@ using namespace Online; DECLARE_COMPONENT( Passthrough ) -Passthrough::Passthrough( const std::string& name, ISvcLocator* pSvcLocator) -: Algorithm(name , pSvcLocator), m_triggerTypesToPass(), m_calibTypesToPass() +/// Initializing constructor +Passthrough::Passthrough( const std::string& name, ISvcLocator* pSvc) : EventProcessor(name , pSvc) { declareProperty("TriggerTypesToPass", m_triggerTypesToPass, - "Trigger types to pass if not calibration trigger inhibit"); + "Trigger types to pass if not calibration trigger inhibit. (Run 1/2 Only)"); declareProperty("CalibTypesToPass" , m_calibTypesToPass, "Calibration trigger inhibits"); @@ -121,85 +123,67 @@ Passthrough::Passthrough( const std::string& name, ISvcLocator* pSvcLocator) declareProperty("MicroDelayTime", m_muDelay=0); } -StatusCode Passthrough::_halt(int micro_seconds) const { +/// Pause function +void Passthrough::_halt(int micro_seconds) const { if ( micro_seconds ) ::lib_rtl_usleep(micro_seconds); - return StatusCode::SUCCESS; } /// Algorithm overload: Start the algorithm StatusCode Passthrough::start() { m_seed = InterfaceID::hash32((RTL::processName()+"@"+RTL::nodeName()).c_str()); ::srand(m_seed); - return _halt(m_startDelay*1000); + _halt(m_startDelay*1000); + return this->EventProcessor::start(); } -StatusCode Passthrough::execute(EventContext const& ctxt) const { +/// Event callback +StatusCode Passthrough::process(EventContext const& ctxt) const { double delay = m_delay*1000+m_muDelay; - auto raw = m_rawEvent.get(); + const auto* raw = m_rawGuard.get(); if ( !raw ) { MsgStream log(msgSvc(), name()); - log << MSG::ERROR << " ==> There is no RawEvent at: " << m_rawEvent << endmsg; - execState(ctxt).setFilterPassed(false); + log << MSG::ERROR << " ==> No raw data at: " << m_rawGuard << endmsg; return StatusCode::FAILURE; } /// If mothing is specified everything will be downscaled + bool downscale = false; if ( m_downScale.empty() && m_triggerTypesToPass.empty() && m_calibTypesToPass.empty() ) { - if ( m_rate < 1.0 ) { - double frac = double(::rand()) / double(RAND_MAX); - if ( m_rate < frac ) { - execState(ctxt).setFilterPassed(false); - return _halt(delay); - } - } - execState(ctxt).setFilterPassed(true); - return _halt(delay); + downscale = (m_rate < 1.0 && m_rate < (double(::rand()) / double(RAND_MAX))); } - - const auto odinBanks = raw->banks(LHCb::RawBank::ODIN); - if ( odinBanks.empty() ) { - execState(ctxt).setFilterPassed(false); - return _halt(delay); - } - - const RunInfo *odin = odinBanks[0]->begin<RunInfo>(); - int trgType = odin->triggerType; - - if ( !m_downScale.empty() ) { /// First downscale certain trigger types if required - if ( std::find(m_downScale.begin(),m_downScale.end(),trgType) != m_downScale.end() ) { - double frac = double(::rand()) / double(RAND_MAX); - if ( m_rate < frac ) { - execState(ctxt).setFilterPassed(false); - return _halt(delay); + else { + EventAccess::record_t record = raw->second->at(raw->first); + if ( raw->second->type() == event_traits::tell1::data_type ) { + const auto *odin = this->get_odin<event_traits::tell1>(record); + if ( !odin ) + downscale = true; + else { + if ( type_found(odin->triggerType, m_downScale) ) + downscale = (m_rate < 1.0 && m_rate < (double(::rand()) / double(RAND_MAX))); + /// Require a certain trigger type + if ( !downscale && !type_found(odin->triggerType, m_triggerTypesToPass) ) + downscale = true; + /// Require a certain calibration type + if ( !downscale && odin->triggerType == 7 && !type_found(odin->readoutType, m_calibTypesToPass) ) + downscale = true; } } - } - - // Check trigger type selection (may be ANDed with calibration type selection - if( !m_triggerTypesToPass.empty() ) { - if( std::find( m_triggerTypesToPass.begin(), m_triggerTypesToPass.end(), trgType) == - m_triggerTypesToPass.end() ) { - execState(ctxt).setFilterPassed(false); - return _halt(delay); - } - if( !m_calibTypesToPass.empty() && (odin->triggerType == 7)) { //calibration type check - if ( std::find( m_calibTypesToPass.begin(), m_calibTypesToPass.end(), odin->readoutType) == - m_calibTypesToPass.end() ) { - execState(ctxt).setFilterPassed(false); - return _halt(delay); - } - } - } - else if( !m_calibTypesToPass.empty() ) { - // Pure calibration type selection - if ( std::find( m_calibTypesToPass.begin(), m_calibTypesToPass.end(), odin->readoutType) == - m_calibTypesToPass.end() ) { - execState(ctxt).setFilterPassed(false); - return _halt(delay); + else if ( raw->second->type() == event_traits::tell40::data_type ) { + const auto *odin = this->get_odin<event_traits::tell40>(record); + if ( !odin ) + downscale = true; + else if ( !type_found(odin->event_type(), m_downScale) ) + downscale = true; + /// Require certain calibration types + if ( !downscale && !type_found(odin->calib_type(), m_calibTypesToPass) ) + downscale = true; } } - - execState(ctxt).setFilterPassed(true); - return _halt(delay); + if ( downscale ) + execState(ctxt).setFilterPassed(false); + else + execState(ctxt).setFilterPassed(true); + _halt(delay); + return StatusCode::SUCCESS; } diff --git a/Online/GaudiOnline/python/GaudiOnline/OnlineApplication.py b/Online/GaudiOnline/python/GaudiOnline/OnlineApplication.py index c7d6642a1..961e64665 100644 --- a/Online/GaudiOnline/python/GaudiOnline/OnlineApplication.py +++ b/Online/GaudiOnline/python/GaudiOnline/OnlineApplication.py @@ -139,6 +139,8 @@ class Application(object): log(MSG_INFO,'Setup event input for REGULAR processing') input = Configurables.Online__InputAlg('EventInput') input.DeclareData = True + input.DeclareEvent = True + input.DeclareErrors = False self.input = input return self.input diff --git a/Online/GaudiOnline/python/GaudiOnline/Passthrough.py b/Online/GaudiOnline/python/GaudiOnline/Passthrough.py index f57c40bcf..4584cc8fe 100644 --- a/Online/GaudiOnline/python/GaudiOnline/Passthrough.py +++ b/Online/GaudiOnline/python/GaudiOnline/Passthrough.py @@ -22,7 +22,8 @@ class Passthrough(Application): input = self.setup_event_input(TAE) self.input = input passThrough = Configurables.Online__Passthrough('Passthrough') - passThrough.RawLocation = '/Event/DAQ/RawEvent' + #passThrough = Configurables.Online__PassthroughPCIE40('Passthrough') + passThrough.RawGuard = '/Event/DAQ/RawDataGuard' passThrough.AcceptRate = acceptRate self.passThrough = passThrough sequence = Gaudi.GaudiSequencer('Output') diff --git a/Online/GaudiOnline/python/GaudiOnline/ReadDatafile.py b/Online/GaudiOnline/python/GaudiOnline/ReadDatafile.py index bddaf741b..2f63295f1 100644 --- a/Online/GaudiOnline/python/GaudiOnline/ReadDatafile.py +++ b/Online/GaudiOnline/python/GaudiOnline/ReadDatafile.py @@ -28,6 +28,7 @@ class ReadDatafile(Application): input = Configurables.Online__InputAlg('EventInput') input.DeclareData = True + input.DeclareEvent = True explorer = Configurables.StoreExplorerAlg('Explorer') explorer.Load = 1 explorer.PrintFreq = 1.0 @@ -35,7 +36,7 @@ class ReadDatafile(Application): ask = Configurables.Online__InteractiveAlg('DumpHandler') ask.Prompt = "Press <ENTER> to dump banks, q or Q to quit :" dump = Configurables.Online__RawEventTestDump('Dump') - dump.RawLocation = '/Event/DAQ/RawEvent' + dump.RawData = 'DAQ/RawData' dump.CheckData = 0 dump.DumpData = 1 dump.FullDump = 1 diff --git a/Online/GaudiOnline/python/GaudiOnline/configureEventConsumer.py b/Online/GaudiOnline/python/GaudiOnline/configureEventConsumer.py index 42b551dd2..eb9227931 100644 --- a/Online/GaudiOnline/python/GaudiOnline/configureEventConsumer.py +++ b/Online/GaudiOnline/python/GaudiOnline/configureEventConsumer.py @@ -9,7 +9,7 @@ def configureConsumer(appMgr, broker, raw, output=False): input = setupAlgorithm('Online__InputAlg', appMgr, broker, instanceName='EventInput', - RawLocation='/Event/DAQ/RawEvent', + RawData='/Event/DAQ/RawData', IOSvc='Online::IOService') application.setup_monitoring() application.setup_mbm_access('Input', True) diff --git a/Online/GaudiOnline/src/Configuration.cpp b/Online/GaudiOnline/src/Configuration.cpp index 369d700b3..b88b7aabc 100644 --- a/Online/GaudiOnline/src/Configuration.cpp +++ b/Online/GaudiOnline/src/Configuration.cpp @@ -14,8 +14,8 @@ //========================================================================== /// Framework include files -#include "GaudiOnline/Configuration.h" -#include "RTL/rtl.h" +#include <GaudiOnline/Configuration.h> +#include <RTL/rtl.h> /// C/C++ include files #include <thread> diff --git a/Online/GaudiOnline/src/OnlineApplication.cpp b/Online/GaudiOnline/src/OnlineApplication.cpp index 1ee91fbf6..0528cb670 100644 --- a/Online/GaudiOnline/src/OnlineApplication.cpp +++ b/Online/GaudiOnline/src/OnlineApplication.cpp @@ -14,7 +14,7 @@ //========================================================================== #define NO_LONGLONG_TYPEDEF -#include "dim/dis.hxx" +#include <dim/dis.hxx> #include <GaudiOnline/OnlineApplication.h> @@ -598,7 +598,7 @@ int OnlineApplication::unload() { setTargetState(ST_OFFLINE); declareState(ST_OFFLINE); ::lib_rtl_sleep(100); - ::exit(0); + ::_exit(0); return 1; } diff --git a/Online/GaudiOnline/src/QueuedFlowManager.cpp b/Online/GaudiOnline/src/QueuedFlowManager.cpp index 8e6951cc8..d797c163a 100644 --- a/Online/GaudiOnline/src/QueuedFlowManager.cpp +++ b/Online/GaudiOnline/src/QueuedFlowManager.cpp @@ -12,6 +12,8 @@ // // Author : Markus Frank //========================================================================== + +/// Framework include files #include <GaudiOnline/QueuedFlowManager.h> #include <thread> diff --git a/Online/GaudiOnlineTests/components/RawEventTestDump.cpp b/Online/GaudiOnlineTests/components/RawEventTestDump.cpp index 6f02fde15..5e30ebf14 100755 --- a/Online/GaudiOnlineTests/components/RawEventTestDump.cpp +++ b/Online/GaudiOnlineTests/components/RawEventTestDump.cpp @@ -16,7 +16,6 @@ // Include files from Gaudi #include <Gaudi/Algorithm.h> #include <GaudiKernel/DataObjectHandle.h> -#include <Event/RawEvent.h> #include <Tell1Data/Tell1Decoder.h> // C/C++ include files @@ -32,11 +31,15 @@ namespace Online { * @date 2005-10-13 */ class RawEventTestDump : public Gaudi::Algorithm { + + typedef Tell1Bank BankHeader; + typedef std::vector<std::pair<const BankHeader*, const void*> > evt_data_t; + Gaudi::Property<bool> m_full{ this, "FullDump", false, "FullDump: If true, full bank contents are dumped"}; Gaudi::Property<bool> m_dump{ this, "DumpData", false, "DumpData: If true, full bank contents are dumped"}; Gaudi::Property<bool> m_check{ this, "CheckData", false, "CheckData: If true, full bank contents are checked"}; Gaudi::Property<int> m_debug{ this, "Debug", 0, "Number of events where all dump flags should be considered true"}; - DataObjectReadHandle<LHCb::RawEvent> m_rawEvent{this, "RawLocation", LHCb::RawEventLocation::Default}; + DataObjectReadHandle<evt_data_t> m_rawData{this, "RawData", "DAQ/RawData"}; mutable std::atomic<long> m_numEvent; ///< Event counter public: @@ -50,23 +53,28 @@ namespace Online { /// Main execution callback StatusCode execute(EventContext const& /* ctxt */) const override { - auto raw = m_rawEvent.get(); MsgStream info(msgSvc(),name()); + const auto* raw = m_rawData.get(); + std::map<int, std::vector<const Tell1Bank*> > banks; bool dmp = m_numEvent<m_debug || m_dump; bool chk = m_numEvent<m_debug || m_check; bool ful = m_numEvent<m_debug || m_full; static int evt = 0; ++evt; info << MSG::INFO; - for(int j=0; j<Tell1Bank::LastType; ++j) { - auto b = raw->banks(LHCb::RawBank::BankType(j)); - int cnt, inc = (j == Tell1Bank::Rich) ? 64 : 32; + for ( const auto& dsc : *raw ) { + banks[dsc.first->type()].push_back(dsc.first); + } + for ( const auto& dsc : banks ) { + const auto& b = dsc.second; + int btyp = dsc.first; + int cnt, inc = (btyp == Tell1Bank::Rich) ? 64 : 32; const int *p; if ( b.size() > 0 ) { if ( dmp ) { info << "Evt No:" << std::left << std::setw(6) << evt - << " has " << b.size() << " bank(s) of type " << j - << " (" << Tell1Printout::bankType(j) << ") " << endmsg; + << " has " << b.size() << " bank(s) of type " << btyp + << " (" << Tell1Printout::bankType(btyp) << ") " << endmsg; } int k = 0; for(const auto* itB : b) { diff --git a/Online/OnlineBase/OnlineBase/RTL/Logger.h b/Online/OnlineBase/OnlineBase/RTL/Logger.h index 11290c1df..3afdd97d1 100644 --- a/Online/OnlineBase/OnlineBase/RTL/Logger.h +++ b/Online/OnlineBase/OnlineBase/RTL/Logger.h @@ -17,6 +17,7 @@ /// C/C++ include files #include <map> +#include <mutex> #include <string> #include <memory> #include <cstdarg> @@ -70,6 +71,8 @@ namespace RTL { }; public: + /// Device lock to protect against interleaved printouts + std::mutex* device_lock {nullptr}; /// Output format std::string format {"%TIME %LEVEL %-16SOURCE"}; /// The processes executable name @@ -225,6 +228,14 @@ namespace RTL { /// Format output string std::string format(const char* format, va_list& args) const; + /// Calls the display action with a given severity level + /** + * @arg severity [int,read-only] Display severity flag (see enum) + * @arg source [string,read-only] Originator name of the message + * @arg msg [string,read-only] Formatted message string + * @return Status code indicating success or failure + */ + size_t printmsg(int severity, const char* source, const char* msg) const; /// Always printout handling void always(const char* format, ...) const; /// Always printout handling diff --git a/Online/OnlineBase/src/RTL/Logger.cpp b/Online/OnlineBase/src/RTL/Logger.cpp index caa75f66d..679c820d7 100644 --- a/Online/OnlineBase/src/RTL/Logger.cpp +++ b/Online/OnlineBase/src/RTL/Logger.cpp @@ -41,7 +41,7 @@ namespace { } /// Default constructor -Logger::LogDevice::LogDevice() { +Logger::LogDevice::LogDevice() : device_lock(new std::mutex()) { char pathName[PATH_MAX] = ""; int len = ::readlink("/proc/self/exe",pathName,sizeof(pathName)-1); if ( len == -1 ) { @@ -58,6 +58,8 @@ Logger::LogDevice::LogDevice() { /// Default destructor Logger::LogDevice::~LogDevice() { + delete device_lock; + device_lock = nullptr; } /// Set global output device @@ -210,9 +212,11 @@ size_t Logger::LogDevice::formatHeader(char* buffer, size_t buff_len, int severi /// Calls the display action with a given severity level size_t Logger::LogDevice::printmsg(int severity, const char* source, const char* msg) const { char header[2048]; - size_t len = formatHeader(header, sizeof(header), severity, source); - len = ::fprintf(stdout, "%s %s\n", header, msg); - ::fflush(stdout); + size_t len = formatHeader(header, sizeof(header), severity, source); { + lock_guard<std::mutex> lock(*device_lock); + len = ::fprintf(stdout, "%s %s\n", header, msg); + ::fflush(stdout); + } return len+1; // '1' from fputc } @@ -235,9 +239,11 @@ size_t Logger::LogDevice::printout(int severity, const char* source, const char* /// Throw exception with message void Logger::LogDevice::exceptmsg(const char* source, const char* msg) const { char header[2048]; - formatHeader(header, sizeof(header), LIB_RTL_ERROR, source); - ::fprintf(stdout, "%s %s\n", header, msg); - ::fflush(stdout); + formatHeader(header, sizeof(header), LIB_RTL_ERROR, source); { + lock_guard<std::mutex> lock(*device_lock); + ::fprintf(stdout, "%s %s\n", header, msg); + ::fflush(stdout); + } throw runtime_error(header+string(" ")+msg); } @@ -347,6 +353,11 @@ string Logger::format(const char* fmt, va_list& args) const { return text; } +/// Calls the display action with a given severity level +size_t Logger::printmsg(int severity, const char* source, const char* msg) const { + return device->printmsg(severity, source, msg); +} + /// Calls the display action with a given severity level size_t Logger::printout(int severity, const char* fmt, va_list& args) const { return device->printout(severity, source.c_str(), fmt, args); diff --git a/Online/PCIE40Data/PCIE40Data/pcie40.h b/Online/PCIE40Data/PCIE40Data/pcie40.h index 46089556d..71ebd03a0 100644 --- a/Online/PCIE40Data/PCIE40Data/pcie40.h +++ b/Online/PCIE40Data/PCIE40Data/pcie40.h @@ -264,8 +264,10 @@ namespace Online { friend class event_collection_t; event_t() = default; public: - MAGIC_WORD - size_t slot; + unsigned long magic = MAGIC_PATTERN; + unsigned long pattern() const { return magic; } + void setPattern() { magic = MAGIC_PATTERN; } + size_t slot; union _flags { unsigned long raw; struct _detail { @@ -277,7 +279,7 @@ namespace Online { } flags; bank_collection_t banks[1]; - static constexpr size_t data_offset = DATA_OFFSET(sizeof(size_t)+sizeof(unsigned long)); + static constexpr size_t data_offset = sizeof(size_t)+2*sizeof(unsigned long); private: /// Disabled move constructor @@ -308,6 +310,7 @@ namespace Online { class event_collection_t { public: MAGIC_WORD + const mep_header_t* mep; size_t length; size_t capacity; event_t events[1]; @@ -331,6 +334,7 @@ namespace Online { size_t size() const { return length; } size_t num_events() const { return length; } size_t max_events() const { return capacity; } + const mep_header_t* mep_header() const { return mep; } const event_t* begin() const; const event_t* end() const; const event_t* next(const event_t* e) const; @@ -662,7 +666,7 @@ namespace Online { len += e->total_length(); return len; } - + } // namespace pcie40 } // namepace Online diff --git a/Online/PCIE40Data/PCIE40Data/pcie40decoder.h b/Online/PCIE40Data/PCIE40Data/pcie40decoder.h index b81a56bcf..d088ea28a 100644 --- a/Online/PCIE40Data/PCIE40Data/pcie40decoder.h +++ b/Online/PCIE40Data/PCIE40Data/pcie40decoder.h @@ -16,6 +16,7 @@ #include <PCIE40Data/pcie40.h> // C/C++ include files +#include <functional> #include <memory> /// Online namespace declaration @@ -46,16 +47,22 @@ namespace Online { */ class decoder_t final { public: + enum { PRINT = 3, ERROR = 5 }; typedef bool (*bank_selector)(unsigned char); typedef bool (*source_selector)(unsigned short); + typedef std::function<void(int, const char* source, const char* msg)> logger_t; + class implementation_t; + static void _prt(int lvl, const char* source, const char* msg); public: /// Debug flag - bool debug {false}; - + bool debug {false}; + implementation_t* implementation {nullptr}; public: /// Default constructor - decoder_t() = default; + decoder_t(); + /// Initializing constructor with printout object + decoder_t(logger_t& l); /// INHIBIT Move constructor decoder_t(decoder_t&& copy) = delete; /// INHIBIT Copy constructor @@ -65,7 +72,7 @@ namespace Online { /// INHIBIT Copy assignment decoder_t& operator=(const decoder_t& copy) = delete; /// Default destructor - ~decoder_t() = default; + ~decoder_t(); /// Initialize user data structure event_collection_t* initialize(std::unique_ptr<event_collection_t>& event_collection, size_t num_events) const; diff --git a/Online/PCIE40Data/src/pcie40decoder.cpp b/Online/PCIE40Data/src/pcie40decoder.cpp index 3afadbde0..0f09bfab7 100644 --- a/Online/PCIE40Data/src/pcie40decoder.cpp +++ b/Online/PCIE40Data/src/pcie40decoder.cpp @@ -30,31 +30,123 @@ using namespace Online::pcie40; namespace { - void _error(const char* ,...) {} - - void _error2(const char* fmt,...) { + void _error(const char* fmt,...) { char text[1024]; va_list args; va_start(args,fmt); - ::vsnprintf(text, sizeof(text),fmt,args); + ::vsnprintf(text, sizeof(text), fmt, args); va_end(args); text[sizeof(text)-1] = 0; ::write(fileno(stdout), text, strlen(text)); } + void _check(const event_collection_t& c) { + size_t num_bank_coll = 0; + size_t num_event = 0; + size_t num_bank = 0; + if ( c.pattern() != MAGIC_PATTERN ) { + _error("Bad magic pattern in event collection!\n"); + } + for(size_t j=0; j < c.capacity; ++j) { + const event_t* e = c.at(j); + if ( e->slot != j || e->pattern() != MAGIC_PATTERN ) { + _error("Bad magic pattern in event!\n"); + } + ++num_event; + for(size_t i=0; i<sizeof(params::collectionOffsets)/sizeof(params::collectionOffsets[0]); ++i) { + const auto* b = add_ptr<bank_collection_t>(e,params::collectionOffsets[i]); + if ( b->capacity != params::collectionCapacity[i] ) { + _error("Bad bank collection!\n"); + } + if ( b->pattern() != MAGIC_PATTERN ) { + _error("Bad magic pattern in bank collection!\n"); + } + ++num_bank_coll; + for(size_t k=0; k < b->capacity; ++k) { + const bank_t* bnk = b->at(k); + if ( bnk->magic() != bank_t::MagicPattern ) { + _error("Bad magic pattern in raw bank!\n"); + } + ++num_bank; + } + } + } + _error("Checked %ld event slots, %ld bank collections and %ld bank slots\n", + num_event, num_bank_coll, num_bank); + } + + void _print(const event_collection_t& c) { + size_t num_bank_coll = 0; + size_t num_event = 0; + size_t num_bank = 0; + _error("Dump PCIE40 event collection @%p capacity:%ld events magic:%p\n", &c, c.capacity, c.pattern()); + for(size_t j=0; j < c.capacity; ++j) { + const event_t* e = c.at(j); + if ( e->slot != j || e->pattern() != MAGIC_PATTERN ) { + _error("Bad magic pattern in event!\n"); + } + ++num_event; + for(size_t i=0; i<sizeof(params::collectionOffsets)/sizeof(params::collectionOffsets[0]); ++i) { + const auto* b = add_ptr<bank_collection_t>(e,params::collectionOffsets[i]); + if ( b->capacity != params::collectionCapacity[i] ) { + _error("Bad bank collection!\n"); + } + if ( b->pattern() != MAGIC_PATTERN ) { + _error("Bad magic pattern in bank collection!\n"); + } + if ( j == 0 ) { + _error("\t bank collection @%p capacity:%3ld banks:%3ld special:%3ld magic:%p offset:%ld\n", + b, b->capacity, b->length, b->specials, b->pattern(), params::collectionOffsets[i]); + } + ++num_bank_coll; + for(size_t k=0; k < b->capacity; ++k) { + const bank_t* bnk = b->at(k); + if ( bnk->magic() != bank_t::MagicPattern ) { + _error("Bad magic pattern in raw bank!\n"); + } + ++num_bank; + } + } + } + _error("Checked %ld event slots, %ld bank collections and %ld bank slots\n", + num_event, num_bank_coll, num_bank); + } + inline bool take_any(unsigned short) { return true; } +} + +class decoder_t::implementation_t { +public: + enum { PRINT = decoder_t::PRINT, ERROR = decoder_t::ERROR }; + decoder_t::logger_t log; + + implementation_t(decoder_t::logger_t& logger) : log(logger) { + } + + inline void print(int lvl, const char* fmt,...) { + if ( lvl > PRINT ) { + char text[1024]; + va_list args; + va_start(args,fmt); + ::vsnprintf(text, sizeof(text), fmt, args); + va_end(args); + text[sizeof(text)-1] = 0; + log(lvl, "pcie40decoder", text); + } + } + inline bank_t* allocate_regular_bank(event_t* e, size_t offset) { bank_collection_writer_t* c = add_ptr<bank_collection_writer_t>(e,offset); ++c->length; #ifdef PCIE40_ENABLE_CHECKS if ( __UNLIKELY(c->pattern() != MAGIC_PATTERN) ) { - _error("Bad magic pattern in bank collection!\n"); + this->print(ERROR, "Bad magic pattern in bank collection!\n"); } if ( __UNLIKELY(c->length + c->specials > c->capacity) ) { - _error("Bank allocation error: Too many banks!\n"); + this->print(ERROR, "Bank allocation error: Too many banks!\n"); } bank_t& b = c->banks[c->length-1]; if ( __UNLIKELY(b.magic() != b.MagicPattern) ) { - _error("Bad magic pattern in bank!\n"); + this->print(ERROR, "Bad magic pattern in bank!\n"); } return &b; #else @@ -67,14 +159,14 @@ namespace { ++c->specials; #ifdef PCIE40_ENABLE_CHECKS if ( c->pattern() != MAGIC_PATTERN ) { - _error("Bad magic pattern in bank collection!\n"); + this->print(ERROR, "+++ Bad magic pattern in bank collection!\n"); } if ( c->length + c->specials > c->capacity ) { - _error("Bank allocation error: Too many banks!\n"); + this->print(ERROR, "+++ Bank allocation error: Too many banks!\n"); } bank_t& b = c->banks[c->capacity - c->specials]; if ( b.magic() != b.MagicPattern ) { - _error("Bad magic pattern in bank!\n"); + this->print(ERROR, "Bad magic pattern in bank!\n"); } return &b; #else @@ -99,10 +191,14 @@ namespace { const uint8_t *typs = mfp->types(); const uint16_t *lens = mfp->sizes(); const frontend_data_t *curr = mfp->data(); - bool run = true; + //bool run = true; + if ( (const char*)typs > ((const char*)mfp)+6*sizeof(int) ) { - _error2("Inconsistent TYPES pointer\n"); - while(run) ::sleep(1); + this->print(ERROR, + "Inconsistent TYPES pointer. Drop MFP Source ID:%3d\n", + int(src_id)); + //while(run) ::sleep(1); + return 0; } for (size_t j=0, cnt=0, n=mfp->packingFactor(); cnt<n; ++cnt, ++typs, ++lens) { auto typx = *typs; @@ -111,24 +207,27 @@ namespace { bank_t* b = allocate_bank(e, src_id, typx); if ( nullptr == b ) { - _error2("ERROR +++ Ignore bank: Unknown bank type:%3d Source ID:%3d Size:%4d vsn:%d j:%ld cnt:%ld n:%ld\n", - int(typx), int(src_id), int(length), int(version), j, cnt, n); - while(run) ::sleep(1); + this->print(ERROR, + "+++ Ignore bank: Unknown bank type:%3d " + "Source ID:%3d Size:%4d vsn:%d j:%ld cnt:%ld n:%ld\n", + int(typx), int(src_id), int(length), int(version), j, cnt, n); + //while(run) ::sleep(1); + continue; } else { #ifdef PCIE40_ENABLE_CHECKS if ( __UNLIKELY(e->magic != MAGIC_PATTERN) ) { - _error("Data corruption in event!\n"); + this->print(ERROR, "Data corruption in event!\n"); } if ( __UNLIKELY(b->magic() != b->MagicPattern) ) { - _error("Data corruption in raw bank!\n"); + this->print(ERROR, "Data corruption in raw bank!\n"); } #endif const void* data = curr->data(); if ( debug ) { - ::printf("+++ Reading bank[%2ld] at %p len:%4d %p typ:%3d src:%3d vsn:%d\n", - cnt, (void*)data, int(length), (void*)((char*)data + length), - typx, src_id, version); + this->print(PRINT, "+++ Reading bank[%2ld] at %p len:%4d %p typ:%3d src:%3d vsn:%d\n", + cnt, (void*)data, int(length), (void*)((char*)data + length), + typx, src_id, version); } //b->setMagic(); b->setSize(length); @@ -136,12 +235,6 @@ namespace { b->setData(data); b->setType((RawBank40::BankType)typx); b->setVersion(version); -#if 0 - int* p1 = (int*)b->data(); - int* p2 = (int*)curr->data(); - for(size_t i=0; i<b->size()/sizeof(int); ++i) - p1[i] = p2[i]; -#endif ++num_bank; } curr = curr->next(length, align); @@ -149,87 +242,16 @@ namespace { } return num_bank; } - - void _check(const event_collection_t& c) { - size_t num_bank_coll = 0; - size_t num_event = 0; - size_t num_bank = 0; - if ( c.pattern() != MAGIC_PATTERN ) { - _error("Bad magic pattern in event collection!\n"); - } - for(size_t j=0; j < c.capacity; ++j) { - const event_t* e = c.at(j); - if ( e->slot != j || e->pattern() != MAGIC_PATTERN ) { - _error("Bad magic pattern in event!\n"); - } - ++num_event; - for(size_t i=0; i<sizeof(params::collectionOffsets)/sizeof(params::collectionOffsets[0]); ++i) { - const auto* b = add_ptr<bank_collection_t>(e,params::collectionOffsets[i]); - if ( b->capacity != params::collectionCapacity[i] ) { - _error("Bad bank collection!\n"); - } - if ( b->pattern() != MAGIC_PATTERN ) { - _error("Bad magic pattern in bank collection!\n"); - } - ++num_bank_coll; - for(size_t k=0; k < b->capacity; ++k) { - const bank_t* bnk = b->at(k); - if ( bnk->magic() != bank_t::MagicPattern ) { - _error("Bad magic pattern in raw bank!\n"); - } - ++num_bank; - } - } - } - _error("Checked %ld event slots, %ld bank collections and %ld bank slots\n", - num_event, num_bank_coll, num_bank); - } - - void _print(const event_collection_t& c) { - size_t num_bank_coll = 0; - size_t num_event = 0; - size_t num_bank = 0; - _error("Dump PCIE40 event collection @%p capacity:%ld events magic:%p\n", &c, c.capacity, c.pattern()); - for(size_t j=0; j < c.capacity; ++j) { - const event_t* e = c.at(j); - if ( e->slot != j || e->pattern() != MAGIC_PATTERN ) { - _error("Bad magic pattern in event!\n"); - } - ++num_event; - for(size_t i=0; i<sizeof(params::collectionOffsets)/sizeof(params::collectionOffsets[0]); ++i) { - const auto* b = add_ptr<bank_collection_t>(e,params::collectionOffsets[i]); - if ( b->capacity != params::collectionCapacity[i] ) { - _error("Bad bank collection!\n"); - } - if ( b->pattern() != MAGIC_PATTERN ) { - _error("Bad magic pattern in bank collection!\n"); - } - if ( j == 0 ) { - _error("\t bank collection @%p capacity:%3ld banks:%3ld special:%3ld magic:%p offset:%ld\n", - b, b->capacity, b->length, b->specials, b->pattern(), params::collectionOffsets[i]); - } - ++num_bank_coll; - for(size_t k=0; k < b->capacity; ++k) { - const bank_t* bnk = b->at(k); - if ( bnk->magic() != bank_t::MagicPattern ) { - _error("Bad magic pattern in raw bank!\n"); - } - ++num_bank; - } - } - } - _error("Checked %ld event slots, %ld bank collections and %ld bank slots\n", - num_event, num_bank_coll, num_bank); - } - + event_collection_t* _allocate(size_t num_events) { size_t len = sizeof(event_collection_t) + num_events*params::eventRecordLength; event_collection_writer_t* c; - void* ptr = ::malloc(len); + void* ptr = ::operator new(len); ::memset(ptr,0,len); c = (event_collection_writer_t*)ptr; c->length = 0; + c->mep = nullptr; c->capacity = num_events; c->setPattern(); for(size_t j=0; j<num_events; ++j) { @@ -254,6 +276,7 @@ namespace { void _initialize(event_collection_writer_t* ec) { ec->length = 0; + ec->mep = nullptr; for(size_t j=0; j < ec->capacity; ++j) { auto* e = ec->at(j); e->flags.raw = 0; @@ -265,8 +288,7 @@ namespace { } } } - inline bool take_any(unsigned short) { return true; } -} +}; void printer_t::print_summary(const std::unique_ptr<event_collection_t>& coll) const { if ( coll ) { @@ -284,22 +306,46 @@ void printer_t::check(const std::unique_ptr<event_collection_t>& coll) const { _error("Invalid event_collection_t instance passed. Cannot check!"); } +void decoder_t::_prt(int, const char* source, const char* msg) { + _error("%s %s", source, msg); +} + +/// Default constructor +decoder_t::decoder_t() { + logger_t log = decoder_t::_prt; + implementation = new implementation_t(log); +} + +/// Initializing constructor with printout object +decoder_t::decoder_t(logger_t& logger) { + implementation = new implementation_t(logger); +} + +/// Default destructor +decoder_t::~decoder_t() { + delete implementation; + implementation = nullptr; +} + +/// Initialize user data structure event_collection_t* decoder_t::initialize(std::unique_ptr<event_collection_t>& c, size_t num_events) const { if ( !c.get() || c->capacity < num_events ) { - if ( c.get() ) ::free(c.release()); - c.reset(_allocate(num_events)); + if ( c.get() ) ::operator delete(c.release()); + c.reset(implementation->_allocate(num_events)); return c.get(); } - _initialize((event_collection_writer_t*)c.get()); + implementation->_initialize((event_collection_writer_t*)c.get()); return c.get(); } +/// Decode MEP fragment void decoder_t::decode(std::unique_ptr<event_collection_t>& coll, const mep_header_t* mep) const { decode(coll, mep, take_any); } +/// Decode MEP fragment with predicate void decoder_t::decode(std::unique_ptr<event_collection_t>& ev_coll, const mep_header_t* mep, source_selector source_selector) const @@ -311,18 +357,21 @@ void decoder_t::decode(std::unique_ptr<event_collection_t>& ev_coll, if ( num_fragments > 0 ) { size_t packing = mep->multi_fragment(0)->packingFactor(); auto ec = (event_collection_writer_t*)initialize(ev_coll, packing); + ec->mep = mep; ec->length = packing; for(uint32_t i=0; i<num_fragments; ++i) { const multi_fragment_t *mfp = mep->multi_fragment(i); const multi_fragment_t::header_t& hdr = mfp->header; uint16_t src_id = hdr.source_id; if ( debug ) { - ::printf("+++ Reading mfp[%2d] at %p len:%6d %p magic:%04X pack:%3d eid:%8ld src:%3d vsn:%d align:%d\n", - i, (void*)mfp, int(hdr.size), - (void*)((char*)mfp + hdr.size), - int(hdr.magic), int(hdr.packing), long(hdr.event_id), - int(src_id), int(hdr.version), - int(hdr.alignment)); + implementation->print(PRINT, + "+++ Reading mfp[%2d] at %p len:%6d %p magic:%04X " + "pack:%3d eid:%8ld src:%3d vsn:%d align:%d\n", + i, (void*)mfp, int(hdr.size), + (void*)((char*)mfp + hdr.size), + int(hdr.magic), int(hdr.packing), long(hdr.event_id), + int(src_id), int(hdr.version), + int(hdr.alignment)); } #ifdef PCIE40_ENABLE_CHECKS if ( mfp->packingFactor() != packing ) { @@ -330,11 +379,13 @@ void decoder_t::decode(std::unique_ptr<event_collection_t>& ev_coll, } #endif if ( !source_selector || source_selector(src_id¶ms::sourceid_TOP5) ) { - num_banks += link_fragment(ec, mfp, debug); + num_banks += implementation->link_fragment(ec, mfp, debug); } } if ( num_err_packing > 0 ) { - _error("Got %ld fragments with inconsistent packing factor!\n", num_err_packing); + implementation->print(ERROR, + "+++ Got %ld fragments with inconsistent packing factor!\n", + num_err_packing); } return; } diff --git a/Online/SmiController/src/SmiController.cpp b/Online/SmiController/src/SmiController.cpp index a8bc7b043..a5768a76e 100644 --- a/Online/SmiController/src/SmiController.cpp +++ b/Online/SmiController/src/SmiController.cpp @@ -1287,7 +1287,9 @@ void SmiController::run() { if ( handle ) { Function fun(GETPROC(handle, "main")); if ( fun.function ) { - thread* thr = new thread([] () { IocSensor::instance().run(); }); + thread* thr = new thread([] () { + IocSensor::instance().run(); + }); if ( thr ) { m_log->info("Executing internal SMI server in thread."); const char* args[] = {"smiSM", "-u", "-t", "-d", config.smi_debug.c_str(), @@ -1296,7 +1298,9 @@ void SmiController::run() { config.smi_domain.c_str(), config.smi_file.c_str(), nullptr}; /// function will never return.... + ::lib_rtl_sleep(2500); (*fun.function)(sizeof(args)/sizeof(args[0])-1, (char**)args); + thr->join(); } } } -- GitLab From e202ff742507e1146de51d9c180e0dd60fb6f138 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Mon, 29 Mar 2021 10:28:41 +0200 Subject: [PATCH 10/17] Fox nightly build errors on dev3 --- Online/Dataflow/dict/dictionary.h | 8 ++++---- Online/RPC/RPC/GUI/MessageBox.h | 1 + Online/TestBeam/TestBeam/gui/MessageBox.h | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Online/Dataflow/dict/dictionary.h b/Online/Dataflow/dict/dictionary.h index a803aa2ff..4f764d9e6 100755 --- a/Online/Dataflow/dict/dictionary.h +++ b/Online/Dataflow/dict/dictionary.h @@ -53,22 +53,22 @@ namespace Online { }; struct PropertyResult { - string data; + std::string data; int status; PropertyResult() : status(0) {} - PropertyResult(const string& d, int s) : data(d), status(s) {} + PropertyResult(const std::string& d, int s) : data(d), status(s) {} PropertyResult(const PropertyResult& c) : data(c.data), status(c.status) {} ~PropertyResult() {} }; class DataflowComponentProperties { public: - static PropertyResult getProperty(DataflowComponent* action, const string& name) { + static PropertyResult getProperty(DataflowComponent* action, const std::string& name) { if ( action->hasProperty(name) ) { return PropertyResult(action->property(name).str(),1); } return PropertyResult("",0); } - static int setProperty(DataflowComponent* action, const string& name, const string& value) { + static int setProperty(DataflowComponent* action, const std::string& name, const std::string& value) { if ( action->hasProperty(name) ) { action->property(name).str(value); return 1; diff --git a/Online/RPC/RPC/GUI/MessageBox.h b/Online/RPC/RPC/GUI/MessageBox.h index f45ff0e07..d149b6da2 100644 --- a/Online/RPC/RPC/GUI/MessageBox.h +++ b/Online/RPC/RPC/GUI/MessageBox.h @@ -17,6 +17,7 @@ /// Framework include files #include "TGMsgBox.h" +#include "TGPicture.h" /// C++ include files diff --git a/Online/TestBeam/TestBeam/gui/MessageBox.h b/Online/TestBeam/TestBeam/gui/MessageBox.h index 964274e21..b8fb04920 100644 --- a/Online/TestBeam/TestBeam/gui/MessageBox.h +++ b/Online/TestBeam/TestBeam/gui/MessageBox.h @@ -17,6 +17,7 @@ /// Framework include files #include "TGMsgBox.h" +#include "TGPicture.h" /// C++ include files -- GitLab From e0c80b481512689d4fae91f68154f273f963b1f7 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Mon, 29 Mar 2021 10:50:55 +0200 Subject: [PATCH 11/17] Fix nightly build errors --- .../python/GaudiOnlineTests/MDFtests.py | 31 ++++++++++--------- .../tests/refs/go_create_mdf.ref | 7 ----- .../mdf.qms/mdf_03_read_mdf.qmt | 0 .../mdf.qms/mdf_04_create_mif.qmt | 0 .../mdf.qms/mdf_05_read_mif.qmt | 0 .../mdf.qms/mdf_08_create_tae.qmt | 0 .../mdf.qms/mdf_11_create_mep.qmt | 0 .../mdf.qms/mdf_12_read_mep.qmt | 0 8 files changed, 17 insertions(+), 21 deletions(-) rename Online/GaudiOnlineTests/tests/{qmtest => retired}/mdf.qms/mdf_03_read_mdf.qmt (100%) rename Online/GaudiOnlineTests/tests/{qmtest => retired}/mdf.qms/mdf_04_create_mif.qmt (100%) rename Online/GaudiOnlineTests/tests/{qmtest => retired}/mdf.qms/mdf_05_read_mif.qmt (100%) rename Online/GaudiOnlineTests/tests/{qmtest => retired}/mdf.qms/mdf_08_create_tae.qmt (100%) rename Online/GaudiOnlineTests/tests/{qmtest => retired}/mdf.qms/mdf_11_create_mep.qmt (100%) rename Online/GaudiOnlineTests/tests/{qmtest => retired}/mdf.qms/mdf_12_read_mep.qmt (100%) diff --git a/Online/GaudiOnlineTests/python/GaudiOnlineTests/MDFtests.py b/Online/GaudiOnlineTests/python/GaudiOnlineTests/MDFtests.py index 4be6e4f2c..077b63fcd 100755 --- a/Online/GaudiOnlineTests/python/GaudiOnlineTests/MDFtests.py +++ b/Online/GaudiOnlineTests/python/GaudiOnlineTests/MDFtests.py @@ -91,20 +91,23 @@ def setupApp(): return app #------------------------------------------------------------------------------------------------ -def mdfCheck(): +def mdfCheck(dump=True, explore=True): app = setupApp() - dmp = Configs.Online__RawEventTestDump('Dump') - dmp.CheckData = 1 - dmp.CheckData = 0 - dmp.DumpData = 0 - dmp.FullDump = 0 - dmp.OutputLevel = 3 - exp = CFG.StoreExplorerAlg('Explorer') - exp.Load = 1 - exp.PrintFreq = 0.00021 - exp.AccessForeign = True - exp.OutputLevel = 3 - app.TopAlg += [dmp,exp] + if dump: + dmp = Configs.Online__RawEventTestDump('Dump') + dmp.CheckData = 1 + dmp.CheckData = 0 + dmp.DumpData = 0 + dmp.FullDump = 0 + dmp.OutputLevel = 3 + app.TopAlg += [dmp] + if explore: + exp = CFG.StoreExplorerAlg('Explorer') + exp.Load = 1 + exp.PrintFreq = 0.00021 + exp.AccessForeign = True + exp.OutputLevel = 3 + app.TopAlg += [exp] return app #------------------------------------------------------------------------------------------------ @@ -153,7 +156,7 @@ def _createMDF(test_castor=None): app = ApplicationMgr() app.EvtSel = 'NONE' app.TopAlg = [Configs.Online__RawEventTestCreator('Creator')] - mdfCheck() + mdfCheck(dmp=False) # To create a MDF file using the standard Gaudi output stream: wr = CFG.OutputStream('Writer_0') wr.Output = "DATAFILE='PFN:root:file://mdfData_0.dat' SVC='LHCb::RawDataCnvSvc' OPT='REC'" diff --git a/Online/GaudiOnlineTests/tests/refs/go_create_mdf.ref b/Online/GaudiOnlineTests/tests/refs/go_create_mdf.ref index b55541d25..fec2f3ef2 100644 --- a/Online/GaudiOnlineTests/tests/refs/go_create_mdf.ref +++ b/Online/GaudiOnlineTests/tests/refs/go_create_mdf.ref @@ -23,16 +23,9 @@ ApplicationMgr INFO Application Manager Configured successfully ], "TopAlg": [ "Online::RawEventTestCreator/Creator", - "Online::RawEventTestDump/Dump", "StoreExplorerAlg/Explorer" ] }, - "Dump": { - "CheckData": false, - "DumpData": false, - "FullDump": false, - "OutputLevel": 3 - }, "EventDataSvc": { "EnableFaultHandler": true, "ForceLeaves": true, diff --git a/Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_03_read_mdf.qmt b/Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_03_read_mdf.qmt similarity index 100% rename from Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_03_read_mdf.qmt rename to Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_03_read_mdf.qmt diff --git a/Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_04_create_mif.qmt b/Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_04_create_mif.qmt similarity index 100% rename from Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_04_create_mif.qmt rename to Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_04_create_mif.qmt diff --git a/Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_05_read_mif.qmt b/Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_05_read_mif.qmt similarity index 100% rename from Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_05_read_mif.qmt rename to Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_05_read_mif.qmt diff --git a/Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_08_create_tae.qmt b/Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_08_create_tae.qmt similarity index 100% rename from Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_08_create_tae.qmt rename to Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_08_create_tae.qmt diff --git a/Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_11_create_mep.qmt b/Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_11_create_mep.qmt similarity index 100% rename from Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_11_create_mep.qmt rename to Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_11_create_mep.qmt diff --git a/Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_12_read_mep.qmt b/Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_12_read_mep.qmt similarity index 100% rename from Online/GaudiOnlineTests/tests/qmtest/mdf.qms/mdf_12_read_mep.qmt rename to Online/GaudiOnlineTests/tests/retired/mdf.qms/mdf_12_read_mep.qmt -- GitLab From a2a1def5faa8ba5152ccfc6f52569ebee8eb3e48 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Tue, 30 Mar 2021 09:34:46 +0200 Subject: [PATCH 12/17] Fix nightly build errors --- Online/EventBuilding/options/EB_BU_algo.opts | 6 +++--- Online/EventBuilding/options/EB_RU_algo.opts | 4 ++-- Online/EventBuilding/options/EB_Transport_properties.opts | 4 ++-- Online/EventBuilding/src/RU.cpp | 3 ++- Online/GaudiOnlineTests/python/GaudiOnlineTests/MDFtests.py | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Online/EventBuilding/options/EB_BU_algo.opts b/Online/EventBuilding/options/EB_BU_algo.opts index 59f599362..dff05b7be 100755 --- a/Online/EventBuilding/options/EB_BU_algo.opts +++ b/Online/EventBuilding/options/EB_BU_algo.opts @@ -1,7 +1,7 @@ -BU.MBM_name = { 'Input', 'Input', 'Input', 'Input', 'Input', 'Input' }; +BU.MBM_name = { 'Input', 'Input', 'Input', 'Input', 'Input', 'Input', 'Input', 'Input' }; BU.buffer_size = {}; -BU.buffer_type = { 2, 2, 2, 2, 2, 2 }; +BU.buffer_type = { 2, 2, 2, 2, 2, 2, 2, 2 }; BU.out_file_prefix = ""; BU.shmem_prefix = ""; BU.stop_timeout = 0; -BU.write_to_file = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }; +BU.write_to_file = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }; diff --git a/Online/EventBuilding/options/EB_RU_algo.opts b/Online/EventBuilding/options/EB_RU_algo.opts index 793a81403..05fb1ce0c 100755 --- a/Online/EventBuilding/options/EB_RU_algo.opts +++ b/Online/EventBuilding/options/EB_RU_algo.opts @@ -1,9 +1,9 @@ RU.MDF_filename = "/home/fpisani/mc_data/biger_file.mdf"; RU.PCIe40_ids = {}; -RU.PCIe40_names = { 'tdtel022_0', 'tdtel022_1', 'tdtel041_0', 'tdtel041_1', 'tdtel042_0', 'tdtel042_1', 'tdtel043_0', 'tdtel043_1', 'tdtel062_0', 'tdtel062_1', 'tdtel063_0', 'tdtel063_1' }; +RU.PCIe40_names = { 'tdtel071_0', 'tdtel071_1', 'tdtel072_0', 'tdtel072_1', 'tdtel081_0', 'tdtel081_1', 'tdtel082_0', 'tdtel082_1', 'tdtel091_0', 'tdtel091_1', 'tdtel092_0', 'tdtel092_1', 'tdtel101_0', 'tdtel101_1', 'tdtel102_0', 'tdtel102_1' }; RU.PCIe40_timeout = 30; RU.buffer_sizes = {}; -RU.buffer_type = { 3, 3, 3, 3, 3, 3 }; +RU.buffer_type = { 3, 3, 3, 3, 3, 3, 3, 3 }; RU.n_MFPs = 100; RU.n_fragment = 3000; RU.shmem_prefix = "$SHMEM_PREFIX"; diff --git a/Online/EventBuilding/options/EB_Transport_properties.opts b/Online/EventBuilding/options/EB_Transport_properties.opts index d365afbf6..ed1cd38ac 100755 --- a/Online/EventBuilding/options/EB_Transport_properties.opts +++ b/Online/EventBuilding/options/EB_Transport_properties.opts @@ -2,7 +2,7 @@ EB_transport.BU_ranks = {}; EB_transport.MPI_errors_return = FALSE; EB_transport.RU_ranks = {}; EB_transport.RUs_per_nic = {}; -EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.FV2976.json"; +EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.qq3067.json"; EB_transport.n_par_mess = 0; -EB_transport.n_sources_per_ru = { 1, 1, 3, 3, 2, 2 }; +EB_transport.n_sources_per_ru = { 2, 2, 2, 2, 2, 2, 2, 2 }; EB_transport.src_ids = {}; diff --git a/Online/EventBuilding/src/RU.cpp b/Online/EventBuilding/src/RU.cpp index e436c23f2..98f1dedeb 100644 --- a/Online/EventBuilding/src/RU.cpp +++ b/Online/EventBuilding/src/RU.cpp @@ -189,7 +189,7 @@ int EB::RU::start() int EB::RU::stop() { int ret_val = DF_SUCCESS; - logger.info << "stop" << std::flush; + logger.error << "stop" << std::flush; // TODO if start never finishes this lock may never be release probably a timeout is needed std::unique_lock<std::timed_mutex> start_lock(_start_lock, std::chrono::duration<int>(_stop_timeout)); _send_MEPs = false; @@ -217,6 +217,7 @@ int EB::RU::stop() int EB::RU::cancel() { // TODO implement this + logger.error << " cancel triggered" << std::flush; return DF_SUCCESS; } diff --git a/Online/GaudiOnlineTests/python/GaudiOnlineTests/MDFtests.py b/Online/GaudiOnlineTests/python/GaudiOnlineTests/MDFtests.py index 077b63fcd..2363a6c97 100755 --- a/Online/GaudiOnlineTests/python/GaudiOnlineTests/MDFtests.py +++ b/Online/GaudiOnlineTests/python/GaudiOnlineTests/MDFtests.py @@ -156,7 +156,7 @@ def _createMDF(test_castor=None): app = ApplicationMgr() app.EvtSel = 'NONE' app.TopAlg = [Configs.Online__RawEventTestCreator('Creator')] - mdfCheck(dmp=False) + mdfCheck(dump=False) # To create a MDF file using the standard Gaudi output stream: wr = CFG.OutputStream('Writer_0') wr.Output = "DATAFILE='PFN:root:file://mdfData_0.dat' SVC='LHCb::RawDataCnvSvc' OPT='REC'" -- GitLab From ebc475039d01090d7d36f884b0a1587c5c191128 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Wed, 31 Mar 2021 12:00:55 +0200 Subject: [PATCH 13/17] Fixes for event builder debugging --- Online/EventBuilding/options/EB_BU_algo.opts | 2 +- Online/EventBuilding/options/EB_RU_algo.opts | 4 +- .../options/EB_Transport_properties.opts | 4 +- Online/FarmConfig/job/Controller.sh | 6 +++ Online/OnlineBase/src/RTL/Logger.cpp | 22 +++++++- Online/PcSrv/CMakeLists.txt | 5 +- Online/PcSrv/PcSrv/TaskCheck.h | 3 +- Online/PcSrv/src/TaskCheck.cpp | 46 +++++++++------- Online/ROLogger/kafka/OutputListener.cpp | 52 ++++++++++++++----- 9 files changed, 102 insertions(+), 42 deletions(-) diff --git a/Online/EventBuilding/options/EB_BU_algo.opts b/Online/EventBuilding/options/EB_BU_algo.opts index dff05b7be..5d9bea577 100755 --- a/Online/EventBuilding/options/EB_BU_algo.opts +++ b/Online/EventBuilding/options/EB_BU_algo.opts @@ -3,5 +3,5 @@ BU.buffer_size = {}; BU.buffer_type = { 2, 2, 2, 2, 2, 2, 2, 2 }; BU.out_file_prefix = ""; BU.shmem_prefix = ""; -BU.stop_timeout = 0; +BU.stop_timeout = 30; BU.write_to_file = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }; diff --git a/Online/EventBuilding/options/EB_RU_algo.opts b/Online/EventBuilding/options/EB_RU_algo.opts index 05fb1ce0c..e7fd3dd19 100755 --- a/Online/EventBuilding/options/EB_RU_algo.opts +++ b/Online/EventBuilding/options/EB_RU_algo.opts @@ -1,10 +1,10 @@ RU.MDF_filename = "/home/fpisani/mc_data/biger_file.mdf"; RU.PCIe40_ids = {}; -RU.PCIe40_names = { 'tdtel071_0', 'tdtel071_1', 'tdtel072_0', 'tdtel072_1', 'tdtel081_0', 'tdtel081_1', 'tdtel082_0', 'tdtel082_1', 'tdtel091_0', 'tdtel091_1', 'tdtel092_0', 'tdtel092_1', 'tdtel101_0', 'tdtel101_1', 'tdtel102_0', 'tdtel102_1' }; +RU.PCIe40_names = { 'tdtel041_0', 'tdtel041_1', 'tdtel042_0', 'tdtel043_0', 'tdtel043_1', 'tdtel051_1', 'tdtel052_0', 'tdtel052_1', 'tdtel053_0', 'tdtel053_1', 'tdtel071_0', 'tdtel071_1', 'tdtel072_0', 'tdtel072_1', 'tdtel091_0', 'tdtel091_1', 'tdtel092_0', 'tdtel092_1' }; RU.PCIe40_timeout = 30; RU.buffer_sizes = {}; RU.buffer_type = { 3, 3, 3, 3, 3, 3, 3, 3 }; RU.n_MFPs = 100; RU.n_fragment = 3000; RU.shmem_prefix = "$SHMEM_PREFIX"; -RU.stop_timeout = 0; +RU.stop_timeout = 30; diff --git a/Online/EventBuilding/options/EB_Transport_properties.opts b/Online/EventBuilding/options/EB_Transport_properties.opts index ed1cd38ac..908c942e1 100755 --- a/Online/EventBuilding/options/EB_Transport_properties.opts +++ b/Online/EventBuilding/options/EB_Transport_properties.opts @@ -2,7 +2,7 @@ EB_transport.BU_ranks = {}; EB_transport.MPI_errors_return = FALSE; EB_transport.RU_ranks = {}; EB_transport.RUs_per_nic = {}; -EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.qq3067.json"; +EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.V23532.json"; EB_transport.n_par_mess = 0; -EB_transport.n_sources_per_ru = { 2, 2, 2, 2, 2, 2, 2, 2 }; +EB_transport.n_sources_per_ru = { 3, 2, 3, 2, 2, 2, 2, 2 }; EB_transport.src_ids = {}; diff --git a/Online/FarmConfig/job/Controller.sh b/Online/FarmConfig/job/Controller.sh index 548fde6fe..28305cd5b 100755 --- a/Online/FarmConfig/job/Controller.sh +++ b/Online/FarmConfig/job/Controller.sh @@ -20,6 +20,12 @@ echo "ERROR DIM_DNS_NODE: ${DIM_DNS_NODE}" # Check the existence of various arguments. # Otherwise use default values. # +if test -z "${LOGFIFO}"; then + export LOGFIFO=/run/fmc/logSrv.fifo; +fi; +if test "${LOGFIFO}" = "/run/fmc/logSrv.fifo" -a -e "/dev/shm/logs.dev"; then + export LOGFIFO=/dev/shm/logs.dev; +fi; if test -z "${TMS_DNS}"; then export TMS_DNS=${HOST_LONG}; fi; diff --git a/Online/OnlineBase/src/RTL/Logger.cpp b/Online/OnlineBase/src/RTL/Logger.cpp index 679c820d7..175b47352 100644 --- a/Online/OnlineBase/src/RTL/Logger.cpp +++ b/Online/OnlineBase/src/RTL/Logger.cpp @@ -131,30 +131,50 @@ pair<size_t,string> Logger::LogDevice::extract_format(const string& tag) { format = RTL::str_replace(format, tag, "s"); start = format.rfind('%',idx); for(end = idx + 1; format[end] && format[end]!='%';) ++end; - return make_pair(start,format.substr(start,end-start)); + return make_pair(idx,format.substr(start,end-start)); } return make_pair(string::npos,format); } /// Compile the format string void Logger::LogDevice::compileFormat(const string& fmt) { + string tmp; pair<size_t,string> item; if ( !fmt.empty() ) format = fmt; formatItems.clear(); + + // First order format statements according to their occurrence + tmp = format; while( (item=extract_format("TIME")).first != string::npos ) formatItems[item.first] = make_pair(TIME_FORMAT, item.second); + format = tmp; while( (item=extract_format("NODE")).first != string::npos ) formatItems[item.first] = make_pair(NODE_FORMAT, item.second); + format = tmp; while( (item=extract_format("LEVEL")).first != string::npos ) formatItems[item.first] = make_pair(LEVEL_FORMAT, item.second); + format = tmp; while( (item=extract_format("PROCESS")).first != string::npos ) formatItems[item.first] = make_pair(PROCESS_FORMAT, item.second); + format = tmp; while( (item=extract_format("UTGID")).first != string::npos ) formatItems[item.first] = make_pair(PROCESS_FORMAT, item.second); + format = tmp; while( (item=extract_format("SOURCE")).first != string::npos ) formatItems[item.first] = make_pair(SOURCE_FORMAT, item.second); + format = tmp; while( (item=extract_format("EXEC")).first != string::npos ) formatItems[item.first] = make_pair(EXEC_FORMAT, item.second); + + // Now reformat the formatting string + format = tmp; + while( (item=extract_format("TIME")).first != string::npos ); + while( (item=extract_format("NODE")).first != string::npos ); + while( (item=extract_format("LEVEL")).first != string::npos ); + while( (item=extract_format("PROCESS")).first != string::npos ); + while( (item=extract_format("UTGID")).first != string::npos ); + while( (item=extract_format("SOURCE")).first != string::npos ); + while( (item=extract_format("EXEC")).first != string::npos ); } /// Format header string according to precompiled format diff --git a/Online/PcSrv/CMakeLists.txt b/Online/PcSrv/CMakeLists.txt index 5e812a666..68c0524ee 100755 --- a/Online/PcSrv/CMakeLists.txt +++ b/Online/PcSrv/CMakeLists.txt @@ -19,6 +19,7 @@ gaudi_subdir(PcSrv v0r1) ################################################################################ gaudi_depends_on_subdirs(Online/dim Online/RPC + Online/HTTP Online/Parsers Online/OnlineBase) # @@ -38,9 +39,9 @@ include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) # --------------------------------------------------------------------------------------- gaudi_add_library(PcSrvLib src/*.cpp - INCLUDE_DIRS + INCLUDE_DIRS RPC HTTP PUBLIC_HEADERS PcSrv - LINK_LIBRARIES RPC Options Parsers Properties OnlineBase dim) + LINK_LIBRARIES RPC HTTP Options Parsers Properties OnlineBase dim) # Do not depend on ROOT target_compile_definitions(PcSrvLib PRIVATE -DDD4HEP_PARSERS_NO_ROOT=1) # Use boost::spirit for the properties diff --git a/Online/PcSrv/PcSrv/TaskCheck.h b/Online/PcSrv/PcSrv/TaskCheck.h index ac6dd3c06..d1101c823 100644 --- a/Online/PcSrv/PcSrv/TaskCheck.h +++ b/Online/PcSrv/PcSrv/TaskCheck.h @@ -89,6 +89,7 @@ namespace taskdb { std::string m_dns; std::string m_node; std::string m_tmName; + long m_tmDicDns = -1; int m_tmInfo = -1; bool m_inited = false; bool m_info_changed = false; @@ -112,7 +113,7 @@ namespace taskdb { public: /// Default constructor - TaskCheck(const std::string& dns, const std::string& node); + TaskCheck(const std::string& dns, const std::string& tms_dns, const std::string& node); /// Default destructor virtual ~TaskCheck(); /// Access the task container from the tmSrv service diff --git a/Online/PcSrv/src/TaskCheck.cpp b/Online/PcSrv/src/TaskCheck.cpp index 706363ff5..a2834bada 100644 --- a/Online/PcSrv/src/TaskCheck.cpp +++ b/Online/PcSrv/src/TaskCheck.cpp @@ -19,8 +19,9 @@ #include "CPP/IocSensor.h" #include "RPC/HttpRpcClient.h" #include "RPC/XMLRPC.h" -#include "RTL/rtl.h" +#include "RTL/Logger.h" #include "RTL/strdef.h" +#include "RTL/rtl.h" #include "dim/dic.h" #include "dim/dis.h" @@ -50,10 +51,11 @@ enum Commands { typedef void* pvoid; /// Default constructor -TaskCheck::TaskCheck(const string& dns, const string& node) { +TaskCheck::TaskCheck(const string& dns, const std::string& tms_dns, const string& node) { m_dns = dns; m_node = node; m_connectTime = system_clock::from_time_t(0); + m_tmDicDns = ::dic_add_dns(tms_dns.c_str(), ::dim_get_dns_port()); } /// Default destructor @@ -75,9 +77,10 @@ bool TaskCheck::setStrictMatching(bool new_value) { /// Initalization callback bool TaskCheck::initialize() { if ( !m_inited ) { - m_tmName = "/FMC/"+RTL::str_upper(m_node)+"/task_manager/"; - m_tmInfo = ::dic_info_service((m_tmName+"longList").c_str(), MONITORED, - 0, 0, 0, tmSrvInfoHandler, long(this), 0, 0); + m_tmName = "/FMC/"+RTL::str_upper(m_node)+"/task_manager/"; + m_tmInfo = ::dic_info_service_dns(m_tmDicDns, + (m_tmName+"longList").c_str(), MONITORED, + 0, 0, 0, tmSrvInfoHandler, long(this), 0, 0); TimeSensor::instance().add(this, 1, pvoid(TASKCHECK_LOAD_DB)); TimeSensor::instance().add(this, m_dbCheckUpdateTmo, pvoid(TASKCHECK_CHECK_DB)); TimeSensor::instance().add(this, 1, pvoid(TASKCHECK_CHECK_TM)); @@ -274,7 +277,7 @@ bool TaskCheck::start_task(const Task& task) { command = cmd.str(); for(const auto& r : m_replacements) command = RTL::str_replace(command,r.first,r.second); - int ret = ::dic_cmnd_service(svc.c_str(), (void*)command.c_str(), command.length()+1); + int ret = ::dic_cmnd_service_dns(m_tmDicDns, svc.c_str(), (void*)command.c_str(), command.length()+1); if ( ret == 1 ) { ::lib_rtl_output(LIB_RTL_INFO, "======= Successfully STARTED %s [%s].",task.utgid.c_str(),command.c_str()); } @@ -405,11 +408,11 @@ void TaskCheck::handleTimer(const Event& event) { } extern "C" int run_task_check(int argc, char** argv) { - string node, dns; - string port = "3500"; - string mount = "/TDBDATA/XMLRPC"; - string server; - string tm_dns; + string node, dns, server; + string port = "3500"; + string tm_dns = "ecstms01"; + string mount = "/TDBDATA/XMLRPC"; + string logger = ::getenv("LOGFIFO") ? ::getenv("LOGFIFO") : "/proc/self/1"; int print_level = LIB_RTL_INFO; RTL::CLI cli(argc, argv, [] (int, char**) { cout << " run_task_check -opt [-opt] \n" @@ -428,17 +431,21 @@ extern "C" int run_task_check(int argc, char** argv) { cli.getopt("server", 3, server); cli.getopt("mount", 3, mount); cli.getopt("tm_dns", 3, tm_dns); + cli.getopt("logger", 3, logger); cli.getopt("print", 3, print_level); - - TaskCheck chk(dns, node); - ::lib_rtl_set_log_level(print_level); - ::lib_rtl_install_printer(print_msg2, 0); - lib_rtl_output(LIB_RTL_ALWAYS,"-%s- Domain RPC service of type: TaskCheck started. DNS:%s TM:%s %s%s", - node.c_str(), dns.c_str(), tm_dns.c_str(), server.empty() ? "" : "Closest Server:", - server.empty() ? "" : server.c_str()); + { + RTL::Logger::log_args args(print_level); + RTL::Logger::install_rtl_printer(args.level); + RTL::Logger::getGlobalDevice()->compileFormat("%-36PROCESS %-8LEVEL %-20SOURCE"); + RTL::Logger::getGlobalDevice()->set_io_buffering(RTL::Logger::LINE_BUFFERING); + } + TaskCheck chk(dns, tm_dns, node); + ::lib_rtl_output(LIB_RTL_ALWAYS,"Domain RPC service of type: TaskCheck started. DNS:%s TM:%s %s%s", + node.c_str(), dns.c_str(), tm_dns.c_str(), server.empty() ? "" : "Closest Server:", + server.empty() ? "" : server.c_str()); if ( !server.empty() ) chk.servers.emplace_back(make_unique<HttpRpcClient>(server, mount, port)); - chk.servers.emplace_back(make_unique<HttpRpcClient>("slavetasks.service.consul.lhcb.cern.ch", mount, port)); chk.servers.emplace_back(make_unique<HttpRpcClient>("ecs03.lbdaq.cern.ch", mount, "3501")); + chk.servers.emplace_back(make_unique<HttpRpcClient>("slavetasks.service.consul.lhcb.cern.ch", mount, port)); chk.servers.emplace_back(make_unique<HttpRpcClient>("ecs03.lbdaq.cern.ch", mount, "3500")); chk.replaceString("<NODE>", node); chk.replaceString("<DIM_DNS>", dns); @@ -449,7 +456,6 @@ extern "C" int run_task_check(int argc, char** argv) { server = '/' + RTL::str_upper(RTL::nodeNameShort()) + '/' + RTL::processName(); ::dis_set_dns_node(dns.c_str()); ::dis_start_serving(server.c_str()); - //::dic_set_dns_node(tm_dns.c_str()); IocSensor::instance().run(); return 1; } diff --git a/Online/ROLogger/kafka/OutputListener.cpp b/Online/ROLogger/kafka/OutputListener.cpp index 9052b4007..d4b2b3612 100644 --- a/Online/ROLogger/kafka/OutputListener.cpp +++ b/Online/ROLogger/kafka/OutputListener.cpp @@ -138,6 +138,7 @@ void OutputListener::print_msg(const char* time_stamp, ::printf("\n"); } } +#include <unistd.h> /// Handler for all messages void OutputListener::handle_payload(const char* /* topic */, @@ -160,21 +161,39 @@ void OutputListener::handle_payload(const char* /* topic */, *(time_stamp+10) = ' '; *(time_stamp+19) = 0; char* message = mark_start(time_stamp+20, MESSAGE_TAG, m_tag_len); - char* end = mark_end(message); - size_t len = end-message-3; + char* msg_end = mark_end(message); + size_t len = msg_end-message-3; if ( message && len > plen ) { len = strlen(message); } - char* physical = mark_start(end, PHYSICAL_TAG, p_tag_len); - end = mark_end(physical); - char* host = mark_start(end, HOST_TAG, h_tag_len); - end = mark_end(host); - char* utgid = mark_start(end, UTGID_TAG, u_tag_len); - end = mark_end(utgid); - char* systag = mark_start(end, SYSTAG_TAG, s_tag_len); - end = mark_end(systag); - char* counter = mark_start(end, COUNTER_TAG, s_cnt_len); - end = mark_end(counter); + char* physical = mark_start(msg_end, PHYSICAL_TAG, p_tag_len); + char* phys_end = mark_end(physical); + char* host = mark_start(phys_end, HOST_TAG, h_tag_len); + char* host_end = mark_end(host); + char* utgid = mark_start(host_end, UTGID_TAG, u_tag_len); + char* utgid_end = mark_end(utgid); + char* systag = mark_start(utgid_end, SYSTAG_TAG, s_tag_len); + char* sys_end = mark_end(systag); + char* counter = mark_start(sys_end, COUNTER_TAG, s_cnt_len); + char* cnt_end = mark_end(counter); + +#if 0 + if ( message && message[0] == '{' ) { + bool wait = true; + ::printf("Havoc!!!!\n\n"); + while (wait) ::sleep(1); + } + if ( utgid && utgid[0] == '{' ) { + bool wait = true; + ::printf("Havoc!!!!\n\n"); + while (wait) ::sleep(1); + } + if ( systag && systag[0] == '{' ) { + bool wait = true; + ::printf("Havoc!!!!\n\n"); + while (wait) ::sleep(1); + } +#endif if ( !message ) { return; @@ -215,8 +234,15 @@ void OutputListener::handle_payload(const char* /* topic */, } if ( match_utgid && match_host ) { print_msg(time_stamp, message, systag, utgid, host, physical, counter); - return; } + if ( msg_end ) *msg_end = '\"'; + if ( phys_end ) *phys_end = '\"'; + if ( host_end ) *host_end = '\"'; + if ( utgid_end ) *utgid_end = '\"'; + if ( sys_end ) *sys_end = '\"'; + if ( cnt_end ) *cnt_end = '\"'; + if ( time_stamp ) *(time_stamp+10) = 'T'; + if ( time_stamp ) *(time_stamp+19) = ' '; } else { ::printf("%s %-8s '%s'\n", "PAYLOAD", "ERROR: Actual value is ", payload); -- GitLab From 1e5fdb5f3310556d873d697c8097aff5ceb8e4d6 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Thu, 8 Apr 2021 11:07:29 +0200 Subject: [PATCH 14/17] Improvement of fifo based output logging --- Online/Dataflow/src/Storage/StorageWriter.cpp | 3 +- Online/EventBuilding/options/EB_BU_algo.opts | 8 +- Online/EventBuilding/options/EB_RU_algo.opts | 6 +- .../options/EB_Transport_properties.opts | 4 +- .../EventBuilding/src/infiniband_net/sock.cpp | 19 +- Online/EventData/EventData/EventAccess.h | 8 +- Online/EventData/src/EventAccess.cpp | 27 +- Online/FarmConfig/job/EBPass.sh | 6 +- Online/OnlineBase/CMakeLists.txt | 4 +- Online/OnlineBase/OnlineBase/LOG/FifoLog.h | 6 +- Online/OnlineBase/src/LOG/FifoLog.cpp | 1002 ++++++++++++----- Online/ROLogger/kafka/OutputListener.cpp | 23 +- 12 files changed, 804 insertions(+), 312 deletions(-) diff --git a/Online/Dataflow/src/Storage/StorageWriter.cpp b/Online/Dataflow/src/Storage/StorageWriter.cpp index e5851dd8d..9a542480a 100644 --- a/Online/Dataflow/src/Storage/StorageWriter.cpp +++ b/Online/Dataflow/src/Storage/StorageWriter.cpp @@ -476,8 +476,7 @@ int StorageWriter::writeBuffer(const Buffer& buff) { error("writeBuffer: Exception while sending data: UNKNOWN Exception"); } ::lib_rtl_sleep(m_write_error_sleep); - process = (m_cancelled == 0); - process |= (::time(0) - m_cancelled < m_cancel_tmo); + process = (m_cancelled == 0) || (::time(0) - m_cancelled < m_cancel_tmo); process &= (--num_retries < 0); } break; diff --git a/Online/EventBuilding/options/EB_BU_algo.opts b/Online/EventBuilding/options/EB_BU_algo.opts index 5d9bea577..1fd2b0b01 100755 --- a/Online/EventBuilding/options/EB_BU_algo.opts +++ b/Online/EventBuilding/options/EB_BU_algo.opts @@ -1,7 +1,7 @@ -BU.MBM_name = { 'Input', 'Input', 'Input', 'Input', 'Input', 'Input', 'Input', 'Input' }; +BU.MBM_name = { 'Input', 'Input', 'Input', 'Input' }; BU.buffer_size = {}; -BU.buffer_type = { 2, 2, 2, 2, 2, 2, 2, 2 }; +BU.buffer_type = { 2, 2, 2, 2 }; BU.out_file_prefix = ""; BU.shmem_prefix = ""; -BU.stop_timeout = 30; -BU.write_to_file = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }; +BU.stop_timeout = 60; +BU.write_to_file = { FALSE, FALSE, FALSE, FALSE }; diff --git a/Online/EventBuilding/options/EB_RU_algo.opts b/Online/EventBuilding/options/EB_RU_algo.opts index e7fd3dd19..2f9cdb1b7 100755 --- a/Online/EventBuilding/options/EB_RU_algo.opts +++ b/Online/EventBuilding/options/EB_RU_algo.opts @@ -1,10 +1,10 @@ RU.MDF_filename = "/home/fpisani/mc_data/biger_file.mdf"; RU.PCIe40_ids = {}; -RU.PCIe40_names = { 'tdtel041_0', 'tdtel041_1', 'tdtel042_0', 'tdtel043_0', 'tdtel043_1', 'tdtel051_1', 'tdtel052_0', 'tdtel052_1', 'tdtel053_0', 'tdtel053_1', 'tdtel071_0', 'tdtel071_1', 'tdtel072_0', 'tdtel072_1', 'tdtel091_0', 'tdtel091_1', 'tdtel092_0', 'tdtel092_1' }; +RU.PCIe40_names = { 'tdtel041_0', 'tdtel041_1', 'tdtel042_0', 'tdtel043_0', 'tdtel043_1', 'tdtel071_0', 'tdtel071_1', 'tdtel072_0', 'tdtel072_1' }; RU.PCIe40_timeout = 30; RU.buffer_sizes = {}; -RU.buffer_type = { 3, 3, 3, 3, 3, 3, 3, 3 }; +RU.buffer_type = { 3, 3, 3, 3 }; RU.n_MFPs = 100; RU.n_fragment = 3000; RU.shmem_prefix = "$SHMEM_PREFIX"; -RU.stop_timeout = 30; +RU.stop_timeout = 60; diff --git a/Online/EventBuilding/options/EB_Transport_properties.opts b/Online/EventBuilding/options/EB_Transport_properties.opts index 908c942e1..25b1f8781 100755 --- a/Online/EventBuilding/options/EB_Transport_properties.opts +++ b/Online/EventBuilding/options/EB_Transport_properties.opts @@ -2,7 +2,7 @@ EB_transport.BU_ranks = {}; EB_transport.MPI_errors_return = FALSE; EB_transport.RU_ranks = {}; EB_transport.RUs_per_nic = {}; -EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.V23532.json"; +EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.J31513.json"; EB_transport.n_par_mess = 0; -EB_transport.n_sources_per_ru = { 3, 2, 3, 2, 2, 2, 2, 2 }; +EB_transport.n_sources_per_ru = { 3, 2, 2, 2 }; EB_transport.src_ids = {}; diff --git a/Online/EventBuilding/src/infiniband_net/sock.cpp b/Online/EventBuilding/src/infiniband_net/sock.cpp index 716a59d23..6ca6c083c 100644 --- a/Online/EventBuilding/src/infiniband_net/sock.cpp +++ b/Online/EventBuilding/src/infiniband_net/sock.cpp @@ -19,6 +19,23 @@ void Sock::recvQPs(const int rankid, const std::vector<Proc>& k, std::atomic<int { vector<Proc>& hosts = const_cast<vector<Proc>&>(k); int connfd = socket(AF_INET, SOCK_STREAM, 0); + // Preventing the OS from keeping the socket open after close() + struct linger sl; + sl.l_onoff = 1; /* non-zero value enables linger option in kernel */ + sl.l_linger = 0; /* timeout interval in seconds */ + if(setsockopt(connfd, SOL_SOCKET, SO_LINGER, &sl, sizeof(sl)) < 0){ + ret = -20; + return ; + } + + + + int reuse_addr = 1; + if(setsockopt(connfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr)) < 0){ + ret = -21; + return ; + } + sockaddr_in server; server.sin_family = AF_INET; server.sin_port = hosts.at(rankid).sockAddr.sin_port; @@ -77,4 +94,4 @@ int Sock::sendQP(const int rankid, Proc& rem) send(connfd, (char*) &tmp_qp_info, sizeof(QPInfo), 0); close(connfd); return 0; -} \ No newline at end of file +} diff --git a/Online/EventData/EventData/EventAccess.h b/Online/EventData/EventData/EventAccess.h index 278d9df23..d2dfd04a6 100644 --- a/Online/EventData/EventData/EventAccess.h +++ b/Online/EventData/EventData/EventAccess.h @@ -151,6 +151,10 @@ namespace Online { std::size_t eventsOut = 0; /// Monitoring item: Count of events which are currently buffered std::size_t eventsBuffered = 0; + /// Monitoring item: Count the events with no data banks + std::size_t eventsNoBanks = 0; + /// Monitoring item: Count the events with more banks than allowed + std::size_t eventsMaxBanks = 0; } monitor; /// Property: poll timeout to check if producers have delivered an event [milliseconds] @@ -162,10 +166,10 @@ namespace Online { bank_collection_t convertMDF(datapointer_t start, std::size_t len) const; /// The event is a MDF with multiple events, which must be decoded - event_collection_t convertMultiMDF(datapointer_t start, std::size_t len) const; + event_collection_t convertMultiMDF(datapointer_t start, std::size_t len); /// The event is a PCIE40 MEP structure with multiple events, which must be decoded - std::unique_ptr<pcie40::event_collection_t> convertPCIE40MEP(datapointer_t start, std::size_t len) const; + std::unique_ptr<pcie40::event_collection_t> convertPCIE40MEP(datapointer_t start, std::size_t len); public: /// Default constructors and destructors / inhibits diff --git a/Online/EventData/src/EventAccess.cpp b/Online/EventData/src/EventAccess.cpp index c1c1eea2e..7f74ee4bc 100644 --- a/Online/EventData/src/EventAccess.cpp +++ b/Online/EventData/src/EventAccess.cpp @@ -239,7 +239,7 @@ namespace { /// The event is a PCIE40 MEP structure with multiple events, which must be decoded std::unique_ptr<pcie40::event_collection_t> -EventAccess::convertPCIE40MEP(datapointer_t start, size_t len) const { +EventAccess::convertPCIE40MEP(datapointer_t start, size_t len) { struct _printer { RTL::Logger& logger; _printer(RTL::Logger& e) : logger(e) {} @@ -303,10 +303,12 @@ EventAccess::convertPCIE40MEP(datapointer_t start, size_t len) const { } } if ( num_bank == 0 ) { - m_logger->error("Event with ZERO banks encountered"); + ++monitor.eventsNoBanks; + m_logger->info("Event with ZERO banks encountered"); } else if ( num_bank > max_bank ) { - m_logger->error("Event with TOO MANY banks encountered"); + ++monitor.eventsMaxBanks; + m_logger->info("Event with TOO MANY banks encountered"); } } return events; @@ -318,7 +320,7 @@ EventAccess::convertPCIE40MEP(datapointer_t start, size_t len) const { /// The event is a MDF with multiple events, which must be decoded EventAccess::event_collection_t -EventAccess::convertMultiMDF(datapointer_t start, size_t len) const { +EventAccess::convertMultiMDF(datapointer_t start, size_t len) { event_collection_t events; datapointer_t begin = start, end = start + len; if ( end > start ) { @@ -349,15 +351,20 @@ EventAccess::convertMultiMDF(datapointer_t start, size_t len) const { ++num_banks; } if ( num_banks == 0 ) { + ++monitor.eventsNoBanks; err_msg = "Event with ZERO banks encountered"; } else if ( num_banks > max_banks ) { + ++monitor.eventsMaxBanks; err_msg = "Event with TOO MANY banks encountered"; stop = true; } } if ( err_msg || err_bank ) { - m_logger->error(" SKIPPING EVENT:"); + m_logger->error("SKIPPING EVENT: Buffer:%p Start:%p End:%p Size:(%d,%d,%d) HdrVsn:%u %s", + (void*)begin, (void*)start, (void*)evt_end, header->size0(), + header->size1(), header->size2(), header->headerVersion(), + stop ? "---> STOP decoding" : ""); if ( err_msg ) { m_logger->error(" %s",err_msg); } @@ -365,15 +372,9 @@ EventAccess::convertMultiMDF(datapointer_t start, size_t len) const { m_logger->error(" Bank: %p -> %s", (void*)err_bank, Tell1Printout::bankHeader(err_bank).c_str()); } - m_logger->error(" Start: %p", (void*)start); - m_logger->error(" End: %p", (void*)evt_end); - m_logger->error(" Size0: %d", header->size0()); - m_logger->error(" Size1: %d", header->size1()); - m_logger->error(" Size2: %d", header->size2()); - m_logger->error(" Hdr.Vsn: %u", header->headerVersion()); if ( stop ) { - m_logger->error(" ---> STOP decoding after %ld out of %ld bytes [%ld events]", - start-begin, end-begin, events.size()); + //m_logger->error(" ---> STOP decoding after %ld out of %ld bytes [%ld events]", + // start-begin, end-begin, events.size()); return events; } } diff --git a/Online/FarmConfig/job/EBPass.sh b/Online/FarmConfig/job/EBPass.sh index f220525a2..a6be5bff6 100755 --- a/Online/FarmConfig/job/EBPass.sh +++ b/Online/FarmConfig/job/EBPass.sh @@ -47,9 +47,9 @@ application.config.numEventThreads = 1 application.config.MBM_numConnections = 7 application.config.MBM_numEventThreads = 6 application.config.MBM_requests = [ - 'EvType=3;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=100.0', - 'EvType=2;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=100.0', - 'EvType=1;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=100.0' + 'EvType=3;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=20.0', + 'EvType=2;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=20.0', + 'EvType=1;TriggerMask=0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF;VetoMask=0,0,0,0;MaskType=ANY;UserType=ONE;Frequency=PERC;Perc=20.0' ] /EOF # diff --git a/Online/OnlineBase/CMakeLists.txt b/Online/OnlineBase/CMakeLists.txt index 51692de1b..6e788c0bb 100755 --- a/Online/OnlineBase/CMakeLists.txt +++ b/Online/OnlineBase/CMakeLists.txt @@ -50,12 +50,12 @@ gaudi_add_library(FifoLog src/LOG/FifoLog_preload.cpp src/LOG/FifoLog.cpp NO_PUBLIC_HEADERS - LINK_LIBRARIES -lrt) + LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt) # #=============================================================================== gaudi_add_python_module(_fifo_log src/LOG/FifoLog_module.cpp - LINK_LIBRARIES OnlineBase) + LINK_LIBRARIES OnlineBase ${CMAKE_DL_LIBS} -lrt) # # Need to cast out warnings created by Python.h target_compile_options(_fifo_log PRIVATE -Wno-register) diff --git a/Online/OnlineBase/OnlineBase/LOG/FifoLog.h b/Online/OnlineBase/OnlineBase/LOG/FifoLog.h index 76e9fcb08..f44809669 100644 --- a/Online/OnlineBase/OnlineBase/LOG/FifoLog.h +++ b/Online/OnlineBase/OnlineBase/LOG/FifoLog.h @@ -22,7 +22,7 @@ #include <memory> /// FIFLOLOG namespace declaration -namespace fiflolog { +namespace fifolog { /// Logger class capturing stdout and stderr. /** @@ -39,7 +39,7 @@ namespace fiflolog { /// Initializing constructor Logger(const std::string& fifo, const std::string& utgid, const std::string& tag); /// Default destructor - ~Logger() = default; + ~Logger(); /// Run the logger in a separate thread void run(); /// Stop processing and shutdown @@ -51,7 +51,7 @@ extern "C" { /// Initialize the logger unit void fifolog_initialize_logger(); /// Set fifo value (Only possible BEFORE startup (return=1), otherwise returns NULL) - int fifolog_set_fifo(const char* fifo); + int fifolog_set_fifo(const char* fifo); /// Set new utgid value void fifolog_set_utgid(const char* new_utgid); /// Set new tag value diff --git a/Online/OnlineBase/src/LOG/FifoLog.cpp b/Online/OnlineBase/src/LOG/FifoLog.cpp index b58b7279c..719c4c082 100644 --- a/Online/OnlineBase/src/LOG/FifoLog.cpp +++ b/Online/OnlineBase/src/LOG/FifoLog.cpp @@ -15,71 +15,259 @@ // //========================================================================== -#include "LOG/FifoLog.h" +#include "LOG/FifoLog.h" +#include <cstdarg> +#include <atomic> #include <thread> -#include <memory> #include <mutex> -#include <atomic> -#include <cerrno> -#include <cstdio> -#include <cstdlib> -#include <cstring> -#include <string> -#include <sstream> -#include <iostream> -#include <stdexcept> - -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/epoll.h> -#include <fcntl.h> -using namespace fiflolog; -using namespace std; +#define LOGGER_VA_LIST va_list -class Logger::Implementation { +class fifolog::Logger::Implementation { public: - typedef std::unique_ptr<std::thread> thread_t; + enum { STDOUT = 0, STDERR = 1 }; + static std::string utgid; static std::string systag; static std::string fifo_name; - std::string real_host; - std::string physical_host; - std::string stdout_buffer; - std::string stderr_buffer; - std::string output_trailer; + std::string real_host; + std::string physical_host; + std::string output_trailer; + std::string output[2]; + std::mutex output_mutex; std::atomic<unsigned long> msg_count; - std::mutex rebuild_lock; - thread_t runner; - int fifo_fd = -1; - int epoll_fd = -1; - int stdout_fd[2] = {-1, -1}; - int stderr_fd[2] = {-1, -1}; - bool done = false; - Implementation() = default; - ~Implementation() = default; + int fifo_fd = -1; + + /// Dump data buffer to file descriptor + void dump_buffer(int fd, const char* buf, int len); + + /// Build output record and dump record to output device + void flush_line(int stream_id); + + /// Append (unlocked) single character to output buffer + void append(int stream_id, char c) { + switch(c) { + case '\n': + flush_line(stream_id); + break; + default: + output[stream_id].push_back(c); + break; + } + } + + /// Append (locked) single character to output buffer + int push(int stream_id, char c) { + std::lock_guard<std::mutex> lock(output_mutex); + append(stream_id,c); + return c; + } + + /// Append (locked) opaque buffer to output buffer + int push(int stream_id, const void* text, size_t len) { + const char* p = (const char*)text; + std::lock_guard<std::mutex> lock(output_mutex); + for(const char* end=p+len; p<end; ++p) + this->append(stream_id, *p); + return len; + } + + /// Append (locked) string to output buffer + int push(int stream_id, const char* text) { + const char* p = text; + std::lock_guard<std::mutex> lock(output_mutex); + for(; *p; ++p) + this->append(stream_id, *p); + return p-text; + } + + /// Append (locked) formatted string to output buffer + int push(int stream_id, const char* format, LOGGER_VA_LIST args) { + char text[4096]; + int len = ::vsnprintf(text, sizeof(text), format, args); + text[sizeof(text)-1] = 0; + va_end(args); + this->push(stream_id, text); + return len; + } + + /// Append (locked) formatted string to output buffer + int push(int stream_id, const wchar_t* format, LOGGER_VA_LIST args) { + wchar_t text[4096]; + int len = ::vswprintf(text, sizeof(text), format, args); + text[sizeof(text)-1] = 0; + va_end(args); + this->push(stream_id, text, len*sizeof(wchar_t)); + return len; + } + +public: + + /// Default constructor + Implementation(); + + /// Default destructor + virtual ~Implementation(); + /// Object initialization - void init(const string& fifo, const string& utgid, const string& tag); + virtual void init(const std::string& fifo, const std::string& utgid, const std::string& tag); + /// Rebuild trailer - void rebuild_trailer(); - /// Read single data frame - void read_data(int fd, string& data); - /// Poll data from stdout/stderr pipes - void poll(); + virtual void rebuild_trailer(); + /// Stop processing and shutdown - void stop(); - /// Flush pending output buffers - void flush_buffer(string& data); + virtual void stop(); + + /// Run the instance + virtual void run(); }; -std::string Logger::Implementation::fifo_name; -std::string Logger::Implementation::systag; -std::string Logger::Implementation::utgid; +namespace fifolog { + + /// Class to capture all libc output routines to overload stdout/stderr + /** + * \author M.Frank + * \version 1.0 + */ + class FuncPtr { + public: + typedef ssize_t (*write_t) (int fd, const void *buf, size_t count); + typedef size_t (*putchar_t) (int c); + typedef int (*putc_t) (int c, FILE* stream); + typedef int (*puts_t) (const char *format); + + typedef size_t (*fputc_t) (int c, FILE *stream); + typedef size_t (*fputs_t) (const char *ptr, FILE *stream); + typedef size_t (*fwrite_t) (const void *ptr, size_t size, size_t nmemb, FILE *stream); + + typedef int (*printf_t) (const char *format, ...); + typedef int (*vprintf_t) (const char *format, LOGGER_VA_LIST args); + + typedef int (*wprintf_t) (const wchar_t *format, ...); + typedef int (*vwprintf_t) (const wchar_t *format, LOGGER_VA_LIST args); + + typedef int (*dprintf_t) (int fd, const char *format, ...); + typedef int (*vdprintf_t) (int fd, const char *format, LOGGER_VA_LIST args); + + typedef int (*fprintf_t) (FILE* stream, const char *format, ...); + typedef int (*vfprintf_t) (FILE* stream, const char *format, LOGGER_VA_LIST args); + typedef int (*vfwprintf_t)(FILE* stream, const wchar_t *format, LOGGER_VA_LIST args); + + typedef int (*printf_chk_t) (int flag, const char *format, ...); + typedef int (*vprintf_chk_t)(int flag, const char *format, LOGGER_VA_LIST args); + + typedef int (*fprintf_chk_t) (FILE *stream, int flag, const char *format, ...); + typedef int (*vfprintf_chk_t)(FILE *stream, int flag, const char *format, LOGGER_VA_LIST args); + + + public: + write_t real_write { nullptr }; + putchar_t real_putchar { nullptr }; + putc_t real_putc { nullptr }; + puts_t real_puts { nullptr }; + + fputc_t real_fputc { nullptr }; + fputs_t real_fputs { nullptr }; + fwrite_t real_fwrite { nullptr }; + + printf_t real_printf { nullptr }; + vprintf_t real_vprintf { nullptr }; + + wprintf_t real_wprintf { nullptr }; + vwprintf_t real_vwprintf { nullptr }; + + dprintf_t real_dprintf { nullptr }; + vdprintf_t real_vdprintf { nullptr }; + + fprintf_t real_fprintf { nullptr }; + vfprintf_t real_vfprintf { nullptr }; + vfwprintf_t real_vfwprintf{ nullptr }; + + printf_chk_t real_printf_chk { nullptr }; + vprintf_chk_t real_vprintf_chk { nullptr }; + fprintf_chk_t real_fprintf_chk { nullptr }; + vfprintf_chk_t real_vfprintf_chk { nullptr }; + + public: + /// Default constructor + FuncPtr(int); + /// Default destructor + ~FuncPtr() = default; + }; + + /// Logger class uniquely overloading output routines from libc + /** + * \author M.Frank + * \version 1.0 + */ + class LibCLogger : public fifolog::Logger::Implementation { + public: + /// Object initialization + virtual void init(const std::string& fifo, const std::string& utgid, const std::string& tag) override; + + /// Default constructor + LibCLogger(); + + /// Default destructor + virtual ~LibCLogger(); + }; + + /// Logger class overloading output routines from libc and polling on stdout/stderr + /** + * \author M.Frank + * \version 1.0 + */ + class PollLogger : public fifolog::Logger::Implementation { + protected: + typedef std::unique_ptr<std::thread> thread_t; + int epoll_fd = -1; + int std_fd[2] = {-1, -1}; + thread_t runner; + bool done = false; + + public: + /// Object initialization + virtual void init(const std::string& fifo, const std::string& utgid, const std::string& tag) override; + /// Poll data from stdout/stderr pipes + void poll(); + + /// Default constructor + PollLogger(); + + /// Default destructor + virtual ~PollLogger(); + /// Run the logger in a separate thread + void run() override; + /// Stop processing and shutdown + void stop() override; + }; +} + +#include <stdexcept> +#include <iostream> +#include <sstream> +#include <cstring> +#include <cstdarg> +#include <cstdio> + +#include <dlfcn.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/epoll.h> + +using namespace std; +using namespace fifolog; +typedef Logger::Implementation logger_imp; + +string logger_imp::fifo_name; +string logger_imp::systag; +string logger_imp::utgid; /// Anonymous namespace for helpers -namespace { +namespace { /// Translate errno into error string string error(int err) { @@ -88,12 +276,31 @@ namespace { return e; } - std::unique_ptr<Logger>& logger(bool create=true) { - static std::unique_ptr<Logger> log; - if ( create && !log.get() ) { - string tag = Logger::Implementation::systag; - string utgid = Logger::Implementation::utgid; - string fifo = Logger::Implementation::fifo_name; + template <typename FUNC_TYPE> FUNC_TYPE get_sym(const char* name) { + FUNC_TYPE fun = FUNC_TYPE( ::dlsym(RTLD_NEXT, name) ); + if ( nullptr == fun ) { + throw runtime_error("Failed to initialize logger function "+string(name)); + } + return fun; + } + + inline logger_imp& log() { + //static LibCLogger s_log; + static PollLogger s_log; + return s_log; + } + + inline FuncPtr& funcs() { + static FuncPtr s_funcs(0); + return s_funcs; + } + + unique_ptr<Logger>& logger(bool create=true) { + static unique_ptr<Logger> s_log; + if ( create && !s_log.get() ) { + string tag = logger_imp::systag; + string utgid = logger_imp::utgid; + string fifo = logger_imp::fifo_name; if ( utgid.empty() ) { utgid = ::getenv("UTGID") ? ::getenv("UTGID") : ""; } @@ -118,124 +325,119 @@ namespace { bool run = false; while(!run) ::sleep(1); } - log.reset(new Logger(fifo, utgid, tag)); + s_log.reset(new Logger(fifo, utgid, tag)); } - return log; + return s_log; } } +/// Default constructor +FuncPtr::FuncPtr(int) { +#define SYM(x) if ( FuncPtr::real_##x == nullptr ) \ + FuncPtr::real_##x = get_sym< FuncPtr::x##_t > ( #x ) + SYM(write); + SYM(putchar); + SYM(putc); + SYM(puts); + + SYM(fputc); + SYM(fputs); + SYM(fwrite); + + SYM(printf); + SYM(vprintf); + + SYM(wprintf); + SYM(vwprintf); + + SYM(dprintf); + SYM(vdprintf); + + SYM(fprintf); + SYM(vfprintf); + SYM(vfwprintf); +#undef SYM +#define SYM(x) if ( FuncPtr::real_##x == nullptr ) \ + FuncPtr::real_##x = get_sym< FuncPtr::x##_t > ( "__" #x ) + SYM(printf_chk); + SYM(vprintf_chk); + SYM(fprintf_chk); + SYM(vfprintf_chk); +#undef SYM +} + +/// Default constructor +logger_imp::Implementation() { + output[0].reserve(4096); + output[1].reserve(4096); + funcs(); +} + +/// Default destructor +logger_imp::~Implementation() { +} + /// Object initialization -void Logger::Implementation::init(const string& f, const string& u, const string& t) { +void logger_imp::init(const string& f, const string& u, const string& t) { char text[1024]; - int fd, ret = 0; struct stat statBuf; - string& fifo = Logger::Implementation::fifo_name; - string& utgid = Logger::Implementation::utgid; - string& tag = Logger::Implementation::systag; - - if ( !f.empty() ) fifo = f; - if ( !u.empty() ) utgid = u; - if ( !t.empty() ) tag = t; - this->msg_count = 0; - this->epoll_fd = ::epoll_create(10); - - // check if fifo is writable - if( ::access(fifo.c_str(),W_OK) == -1) { // write access to fifo OK - ::snprintf(text,sizeof(text),"+++ Failed to access output: %s [%s]\n", - fifo.c_str(), error(errno).c_str()); - throw runtime_error(text); - } - // get fifo information - if( ::stat(fifo.c_str(),&statBuf) == -1) { // fifo information got - ::snprintf(text,sizeof(text),"+++ Output: Canno stat device %s! [%s]\n", - fifo.c_str(), error(errno).c_str()); - throw runtime_error(text); - } - // check if fifo is a FIFO - if( !S_ISFIFO(statBuf.st_mode)) { // fifo is a FIFO - ::snprintf(text,sizeof(text),"+++ Output: %s is no fifo!\n", fifo.c_str()); - throw runtime_error(text); - } - // open fifo - this->fifo_fd = ::open(fifo.c_str(), O_RDWR|O_NONBLOCK|O_APPEND); - if( this->fifo_fd == -1 ) { /* fifo open() failed */ - ::snprintf(text,sizeof(text),"+++ Failed to open output: %s! [%s]\n", - fifo.c_str(), error(errno).c_str()); - throw runtime_error(text); - } - /* Now we are sure that another process has the FIFO open for reading. */ - /* We unset now the O_NONBLOCK bit to have blocking write (no-drop */ - /* behaviour). */ - int status = ::fcntl(this->fifo_fd, F_GETFL); - if ( status < 0 ) { - ::close(this->fifo_fd); - ::snprintf(text,sizeof(text),"+++ Cannot fcntl fifo path %s. [%s]", - fifo.c_str(), error(errno).c_str()); - throw runtime_error(text); - } - status &= ~O_NONBLOCK; /* unset O_NONBLOCK bit */ - if ( ::fcntl(this->fifo_fd, F_SETFL,status) == -1 ) { - ::close(this->fifo_fd); - ::snprintf(text,sizeof(text),"+++ Cannot set O_NONBLOCK bit of fifo %s. [%s]", - fifo.c_str(), error(errno).c_str()); - throw runtime_error(text); - } - /// - ret = ::pipe(this->stdout_fd); - if ( ret != 0 ) { - ::snprintf(text,sizeof(text),"+++ Failed to create stdout pipe for fifo: %s. [%s]\n", - fifo.c_str(), error(errno).c_str()); - ::close(this->fifo_fd); - throw runtime_error(text); - } - fd = ::fileno(stdout); - ret = ::dup2(this->stdout_fd[1],fd); - if ( ret == -1 ) { - ::snprintf(text,sizeof(text),"+++ Failed to dup stdout for fifo: %s. [%s]\n", - fifo.c_str(), error(errno).c_str()); - ::close(this->fifo_fd); - throw runtime_error(text); - } - /// - ret = ::pipe(this->stderr_fd); - if ( ret != 0 ) { - ::snprintf(text,sizeof(text),"+++ Failed to create stderr pipe for fifo: %s. [%s]\n", - fifo.c_str(), error(errno).c_str()); - ::close(this->fifo_fd); - throw runtime_error(text); - } - fd = ::fileno(stderr); - ret = ::dup2(this->stderr_fd[1],fd); - if ( ret == -1 ) { - ::snprintf(text,sizeof(text),"+++ Failed to dup stderr for fifo: %s. [%s]\n", - fifo.c_str(), error(errno).c_str()); - ::close(this->fifo_fd); - throw runtime_error(text); + if ( this->fifo_fd < 0 ) { + string& fifo = Logger::Implementation::fifo_name; + if ( !f.empty() ) fifo = f; + + if ( !fifo.empty() ) { + string& utgid = Logger::Implementation::utgid; + string& tag = Logger::Implementation::systag; + + if ( !u.empty() ) utgid = u; + if ( !t.empty() ) tag = t; + + this->msg_count = 0; + + // check if fifo is writable + if( ::access(fifo.c_str(),W_OK) == -1) { // write access to fifo OK + ::snprintf(text,sizeof(text),"+++ Failed to access output: %s [%s]\n", + fifo.c_str(), error(errno).c_str()); + throw runtime_error(text); + } + // get fifo information + if( ::stat(fifo.c_str(),&statBuf) == -1) { // fifo information got + ::snprintf(text,sizeof(text),"+++ Output: Canno stat device %s! [%s]\n", + fifo.c_str(), error(errno).c_str()); + throw runtime_error(text); + } + // check if fifo is a FIFO + if( !S_ISFIFO(statBuf.st_mode)) { // fifo is a FIFO + ::snprintf(text,sizeof(text),"+++ Output: %s is no fifo!\n", fifo.c_str()); + throw runtime_error(text); + } + // open fifo + this->fifo_fd = ::open(fifo.c_str(), O_RDWR|O_NONBLOCK|O_APPEND); + if( this->fifo_fd == -1 ) { /* fifo open() failed */ + ::snprintf(text,sizeof(text),"+++ Failed to open output: %s! [%s]\n", + fifo.c_str(), error(errno).c_str()); + throw runtime_error(text); + } + // Now we are sure that another process has the FIFO open for reading. + // We unset now the O_NONBLOCK bit to have blocking write (no-drop behaviour). + int status = ::fcntl(this->fifo_fd, F_GETFL); + if ( status < 0 ) { + ::close(this->fifo_fd); + ::snprintf(text,sizeof(text),"+++ Cannot fcntl fifo path %s. [%s]", + fifo.c_str(), error(errno).c_str()); + throw runtime_error(text); + } + status &= ~O_NONBLOCK; /* unset O_NONBLOCK bit */ + if ( ::fcntl(this->fifo_fd, F_SETFL,status) == -1 ) { + ::close(this->fifo_fd); + ::snprintf(text,sizeof(text),"+++ Cannot set O_NONBLOCK bit of fifo %s. [%s]", + fifo.c_str(), error(errno).c_str()); + throw runtime_error(text); + } + } } /// - struct epoll_event ev; - ev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET; - /// - ev.data.fd = this->stdout_fd[0]; - ::fcntl(this->stdout_fd[0], F_SETFL, O_NONBLOCK); - ret = ::epoll_ctl(this->epoll_fd, EPOLL_CTL_ADD, this->stdout_fd[0], &ev); - if ( ret != 0 ) { - ::snprintf(text,sizeof(text),"+++ Failed to add FD %d to epoll structure for fifo: %s. [%s]\n", - this->stdout_fd[0], fifo.c_str(), error(errno).c_str()); - ::close(this->fifo_fd); - throw runtime_error(text); - } - ev.data.fd = this->stderr_fd[0]; - ::fcntl(this->stderr_fd[0], F_SETFL, O_NONBLOCK); - ret = ::epoll_ctl(this->epoll_fd, EPOLL_CTL_ADD, this->stderr_fd[0], &ev); - if ( ret != 0 ) { - ::snprintf(text,sizeof(text),"+++ Failed to add FD %d to epoll structure for fifo: %s. [%s]\n", - this->stdout_fd[0], fifo.c_str(), error(errno).c_str()); - ::close(this->epoll_fd); - ::close(this->fifo_fd); - throw runtime_error(text); - } char host[128]; ::gethostname(host,sizeof(host)); this->physical_host = host; @@ -250,148 +452,262 @@ void Logger::Implementation::init(const string& f, const string& u, const string this->rebuild_trailer(); } +/// Run the instance +void logger_imp::run() { +} + +/// Stop processing and shutdown +void logger_imp::stop() { + ::setvbuf(stdout, nullptr, _IONBF, 0); + ::setvbuf(stderr, nullptr, _IONBF, 0); + this->flush_line(STDOUT); + this->flush_line(STDERR); + if ( this->fifo_fd >= 0 ) { + ::syncfs(this->fifo_fd); + ::close(this->fifo_fd); + } + this->fifo_fd = 0; +} + /// Rebuild trailer -void Logger::Implementation::rebuild_trailer() { - std::stringstream str; - std::lock_guard<std::mutex> lock(this->rebuild_lock); - str << ::getpid(); - this->output_trailer = "\",\"physical_host\":\""; - this->output_trailer += this->physical_host; - this->output_trailer += "\",\"host\":\""; - this->output_trailer += this->real_host; - this->output_trailer += "\",\"pid\":\""; - this->output_trailer += str.str(); - this->output_trailer += "\",\"utgid\":\""; - this->output_trailer += Logger::Implementation::utgid; - this->output_trailer += "\",\"systag\":\""; - this->output_trailer += Logger::Implementation::systag; - this->output_trailer += "\"}\n"; -} - -void Logger::Implementation::flush_buffer(string& data) { - if ( !data.empty() ) { - struct tm tim; - char time_str[256]; - time_t now = ::time(0); - struct timespec delay = {0,1000000}; /* 0.001 s */ - string output_buffer; - ::localtime_r(&now, &tim); - ::strftime(time_str,sizeof(time_str),"{\"@timestamp\":\"%Y-%m-%dT%H:%M:%S.000000%z\",\"message\":\"",&tim); - output_buffer.reserve(512); - output_buffer = time_str; - output_buffer += data; - output_buffer += this->output_trailer; - ++this->msg_count; - - int tryC = 0, numRetry = 100; - int len = output_buffer.length(); - for ( tryC=0; tryC < numRetry; tryC++ ) { - int written = write(this->fifo_fd, output_buffer.c_str(), len); - if ( written > 0 ) - len -= written; - else if ( written == -1 ) - break; - else if ( errno != EAGAIN ) - break; - - if ( 0 == len ) break; - nanosleep(&delay,NULL); - delay.tv_sec *= 2; - delay.tv_nsec *= 2; - if(delay.tv_nsec>999999999){ - delay.tv_sec+=1; - delay.tv_nsec-=1000000000; - } +void logger_imp::rebuild_trailer() { + stringstream str; + str << "\",\"physical_host\":\"" << this->physical_host + << "\",\"host\":\"" << this->real_host + << "\",\"pid\":\"" << ::getpid() + << "\",\"utgid\":\"" << logger_imp::utgid + << "\",\"systag\":\"" << logger_imp::systag + << "\"}\n"; + { + lock_guard<mutex> lock(this->output_mutex); + this->output_trailer = str.str(); + } +} + +/// Dump data buffer to file descriptor +void logger_imp::dump_buffer(int fd, const char* buf, int len) { + struct timespec delay = {0,1000000}; /* 0.001 s */ + int tryC = 0, numRetry = 100, done=0; + for ( tryC=0; tryC < numRetry; tryC++ ) { + int written = funcs().real_write(fd, buf+done, len-done); + if ( written > 0 ) + done += written; + else if ( written == -1 ) + break; + else if ( errno != EAGAIN ) + break; + + if ( done == len ) break; + nanosleep(&delay,NULL); + delay.tv_sec *= 2; + delay.tv_nsec *= 2; + if(delay.tv_nsec>999999999){ + delay.tv_sec+=1; + delay.tv_nsec-=1000000000; } } } -/// Read single data frame -void Logger::Implementation::read_data(int fd, string& data) { - char text[512]; - ssize_t nbyt = ::read(fd, text, sizeof(text)-2); - if ( nbyt <= 0 ) { +/// Build output record and dump record to output device +void logger_imp::flush_line(int stream_id) { + string& data = output[stream_id]; + if ( this->fifo_fd >= 0 ) { + if ( !data.empty() ) { + struct tm tim; + char time_str[256]; + time_t now = ::time(0); + string output_buffer; + ::localtime_r(&now, &tim); + ::strftime(time_str,sizeof(time_str),"{\"@timestamp\":\"%Y-%m-%dT%H:%M:%S.000000%z\",\"message\":\"",&tim); + output_buffer.reserve(200+data.length()); + output_buffer = time_str; + output_buffer += data; + output_buffer += this->output_trailer; + data = ""; + ++this->msg_count; + dump_buffer(this->fifo_fd, output_buffer.c_str(), output_buffer.length()); + } return; } - text[nbyt] = 0; - for(char* p = text; *p; ++p) { - switch(*p) { - case '\0': - case '\n': { - if ( !data.empty() ) { - flush_buffer(data); - data = ""; - data.reserve(512); - } - break; + data += '\n'; + if ( stream_id == STDOUT ) { + dump_buffer(STDOUT_FILENO, data.c_str(), data.length()); + data = ""; + return; + } + dump_buffer(STDERR_FILENO, data.c_str(), data.length()); + data = ""; +} + +/// Default constructor +LibCLogger::LibCLogger() { +} + +/// Default destructor +LibCLogger::~LibCLogger() { +} + +/// Object initialization +void LibCLogger::init(const string& f, const string& u, const string& t) { + if ( this->fifo_fd < 0 ) { + this->logger_imp::init(f, u, t); + char text[1024]; + string& fifo = Logger::Implementation::fifo_name; + int fd = ::fileno(stdout); + int ret = ::dup2(this->fifo_fd, fd); + if ( ret == -1 ) { + ::snprintf(text,sizeof(text),"+++ Failed to dup stdout for fifo: %s. [%s]\n", + fifo.c_str(), error(errno).c_str()); + ::close(this->fifo_fd); + throw runtime_error(text); } - default: - data += *p; - break; + fd = ::fileno(stderr); + ret = ::dup2(this->fifo_fd, fd); + if ( ret == -1 ) { + ::snprintf(text,sizeof(text),"+++ Failed to dup stderr for fifo: %s. [%s]\n", + fifo.c_str(), error(errno).c_str()); + ::close(this->fifo_fd); + throw runtime_error(text); + } + this->push(STDOUT,"LIBC logger initialized!!!\n"); + } +} + +/// Default constructor +PollLogger::PollLogger() { +} + +/// Default destructor +PollLogger::~PollLogger() { + this->done = true; + if ( this->runner.get() ) { + try { + this->runner->join(); + this->runner.reset(); + } + catch(...) { + } + } +} + +/// Object initialization +void PollLogger::init(const string& f, const string& u, const string& t) { + if ( this->fifo_fd < 0 ) { + this->logger_imp::init(f, u, t); + char text[1024]; + string& fifo = Logger::Implementation::fifo_name; + int fd, ret; + /// + ret = ::pipe(this->std_fd); + if ( ret != 0 ) { + ::snprintf(text,sizeof(text),"+++ Failed to create stdout pipe for fifo: %s. [%s]\n", + fifo.c_str(), error(errno).c_str()); + ::close(this->fifo_fd); + this->fifo_fd = -1; + throw runtime_error(text); + } + fd = ::fileno(stdout); + ret = ::dup2(this->std_fd[1],fd); + if ( ret == -1 ) { + ::snprintf(text,sizeof(text),"+++ Failed to dup stdout for fifo: %s. [%s]\n", + fifo.c_str(), error(errno).c_str()); + ::close(this->fifo_fd); + this->fifo_fd = -1; + throw runtime_error(text); + } + fd = ::fileno(stderr); + ret = ::dup2(this->std_fd[1],fd); + if ( ret == -1 ) { + ::snprintf(text,sizeof(text),"+++ Failed to dup stderr for fifo: %s. [%s]\n", + fifo.c_str(), error(errno).c_str()); + ::close(this->fifo_fd); + this->fifo_fd = -1; + throw runtime_error(text); } + /// + struct epoll_event ev; + this->epoll_fd = ::epoll_create(10); + ev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP | EPOLLET; + /// + ev.data.fd = this->std_fd[0]; + ::fcntl(this->std_fd[0], F_SETFL, O_NONBLOCK); + ret = ::epoll_ctl(this->epoll_fd, EPOLL_CTL_ADD, this->std_fd[0], &ev); + if ( ret != 0 ) { + ::snprintf(text,sizeof(text),"+++ Failed to add FD %d to epoll structure for fifo: %s. [%s]\n", + this->std_fd[0], fifo.c_str(), error(errno).c_str()); + ::close(this->epoll_fd); + ::close(this->fifo_fd); + throw runtime_error(text); + } + //this->push(STDOUT,"POLL logger initialized!!!\n"); } } +/// Run the logger in a separate thread +void PollLogger::run() { + if ( !this->runner.get() ) { + this->runner = make_unique<thread>([this]() { this->poll(); }); + } +} + +/// Stop processing and shutdown +void PollLogger::stop() { + this->done = true; + this->runner->join(); + this->Logger::Implementation::stop(); +} + /// Poll data from stdout/stderr pipes -void Logger::Implementation::poll() { +void PollLogger::poll() { + int count = 0; + // this->push(STDOUT, "POLL thread is starting now....\n"); while ( 1 ) { struct epoll_event ep; int nc = ::epoll_wait(this->epoll_fd, &ep, 1, 100); if ( nc > 0 ) { - for( int i=0; i < nc; ++i ) { - if ( ep.events&EPOLLIN ) { - if ( ep.data.fd == this->stdout_fd[0] ) - this->read_data(ep.data.fd, this->stdout_buffer); - else if ( ep.data.fd == this->stderr_fd[0] ) - this->read_data(ep.data.fd, this->stderr_buffer); - else - this->read_data(ep.data.fd, this->stdout_buffer); + if ( ep.events&EPOLLIN ) { + int fd = ep.data.fd; + char text[512]; + ssize_t nbyt = ::read(fd, text, sizeof(text)-2); + if ( nbyt <= 0 ) { + return; } + text[nbyt] = 0; + this->push(STDOUT, text, nbyt); } } - if ( this->done ) { + if ( count > 5 ) break; - } + else if ( this->done ) + ++count; } -} - -/// Stop processing and shutdown -void Logger::Implementation::stop() { - ::setvbuf(stdout, nullptr, _IONBF, 0); - ::setvbuf(stderr, nullptr, _IONBF, 0); - this->done = true; - this->runner->join(); - this->flush_buffer(this->stdout_buffer); - this->flush_buffer(this->stderr_buffer); - if ( this->fifo_fd ) { - ::syncfs(this->fifo_fd); - ::close(this->fifo_fd); - } - this->fifo_fd = 0; + // this->push(STDOUT, "POLL thread is exiting now....\n"); } /// Initializing constructor Logger::Logger(const string& fifo_name, const string& utgid, const string& tag) { - this->imp = make_unique<Implementation>(); + this->imp.reset(&log()); this->imp->init(fifo_name, utgid, tag); } +/// Default destructor +Logger::~Logger() { + if ( this->imp.get() ) this->imp.release(); +} + /// Run the logger in a separate thread void Logger::run() { - if ( !this->imp->runner.get() ) { - this->imp->runner = make_unique<thread>([this]() { this->imp->poll(); }); - } + if ( this->imp.get() ) this->imp->run(); } /// Stop processing and shutdown void Logger::stop() { - this->imp->stop(); + if ( this->imp.get() ) this->imp->stop(); } /// Initialize the logger unit extern "C" void fifolog_initialize_logger() { - auto& log = logger(); - log->run(); + logger(true)->run(); } /// Set new utgid value @@ -406,14 +722,14 @@ extern "C" void fifolog_set_utgid(const char* new_utgid) { ::snprintf(text,sizeof(text),"P%06d",::getpid()); utgid = text; } - Logger::Implementation::utgid = new_utgid ? new_utgid : text; + logger_imp::utgid = new_utgid ? new_utgid : text; if ( log.get() ) log->imp->rebuild_trailer(); } /// Set new tag value extern "C" void fifolog_set_tag(const char* new_tag) { auto& log = logger(false); - Logger::Implementation::systag = new_tag ? new_tag : "SYSTEM"; + logger_imp::systag = new_tag ? new_tag : "SYSTEM"; if ( log.get() ) log->imp->rebuild_trailer(); } @@ -421,7 +737,7 @@ extern "C" void fifolog_set_tag(const char* new_tag) { extern "C" int fifolog_set_fifo(const char* fifo) { auto& log = logger(false); if ( fifo && !log.get() ) { - Logger::Implementation::fifo_name = fifo; + logger_imp::fifo_name = fifo; return 1; } ::fprintf(stderr,"Failed to set output fifo: %s [%s] logger %s initialized.\n", @@ -434,8 +750,156 @@ extern "C" int fifolog_set_fifo(const char* fifo) { extern "C" void fifolog_finalize_logger() { auto& log = logger(false); if ( log.get() ) { - log->imp->stop(); + log->stop(); log.reset(); ::fprintf(stderr, "\nFinalizing dim logger....\n"); } } + +extern "C" int fputc(int c, FILE *stream) { + if ( logger(false).get() ) { + if ( stream == stdout ) + return log().push(logger_imp::STDOUT, c); + else if ( stream == stderr ) + return log().push(logger_imp::STDERR, c); + } + return funcs().real_fputc(c, stream); +} + +extern "C" int putc(int c, FILE *stream) { + return ::fputc(c, stream); +} + +extern "C" int putchar(int c) { + return ::fputc(c, stdout); +} + +extern "C" int fputs(const char *str, FILE *stream) { + if ( logger(false).get() ) { + if ( stream == stdout ) + return log().push(logger_imp::STDOUT, str); + else if ( stream == stderr ) + return log().push(logger_imp::STDERR, str); + } + return funcs().real_fputs(str, stream); +} + +extern "C" int puts(const char* str) { + return ::fputs(str, stdout); +} + +extern "C" ssize_t write(int fd, const void *buf, size_t count) { + if ( logger(false).get() ) { + switch(fd) { + case STDOUT_FILENO: return log().push(logger_imp::STDOUT, buf, count); + case STDERR_FILENO: return log().push(logger_imp::STDERR, buf, count); + default: break; + } + } + return funcs().real_write(fd, buf, count); +} + +extern "C" size_t fwrite(const void *str, size_t size, size_t nmemb, FILE *stream) { + if ( logger(false).get() ) { + if ( stream == stdout ) + return log().push(logger_imp::STDOUT, str, size*nmemb); + else if ( stream == stderr ) + return log().push(logger_imp::STDERR, str, size*nmemb); + } + return funcs().real_fwrite(str, size, nmemb, stream); +} + +extern "C" int vprintf(const char *format, LOGGER_VA_LIST args) { + return logger(false).get() + ? log().push(logger_imp::STDOUT, format, args) + : funcs().real_vprintf(format, args); +} + +extern "C" int vwprintf(const wchar_t *format, LOGGER_VA_LIST args) { + return logger(false).get() + ? log().push(logger_imp::STDOUT, format, args) + : funcs().real_vwprintf(format, args); +} + +extern "C" int vdprintf(int fd, const char *format, LOGGER_VA_LIST args) { + if ( logger(false).get() ) { + switch(fd) { + case STDOUT_FILENO: return log().push(logger_imp::STDOUT, format, args); + case STDERR_FILENO: return log().push(logger_imp::STDERR, format, args); + default: break; + } + } + return funcs().real_vdprintf(fd, format, args); +} + +extern "C" int vfprintf(FILE* stream, const char *format, LOGGER_VA_LIST args) { + if ( logger(false).get() ) { + if ( stream == stdout ) + return log().push(logger_imp::STDOUT, format, args); + else if ( stream == stderr ) + return log().push(logger_imp::STDERR, format, args); + } + return funcs().real_vfprintf(stream, format, args); +} + +extern "C" int __vfprintf_chk(FILE* stream, int flag, const char *format, LOGGER_VA_LIST args) { + if ( logger(false).get() ) { + if ( stream == stdout ) + return log().push(logger_imp::STDOUT, format, args); + else if ( stream == stderr ) + return log().push(logger_imp::STDERR, format, args); + } + return funcs().real_vfprintf_chk(stream, flag, format, args); +} + +extern "C" int __vprintf_chk(int flag, const char *format, LOGGER_VA_LIST args) { + return __vfprintf_chk(stdout, flag, format, args); +} + +extern "C" int printf(const char *format, ...) { + LOGGER_VA_LIST args; + va_start(args, format); + int ret = ::vprintf(format, args); + va_end(args); + return ret; +} + +extern "C" int wprintf(const wchar_t *format, ...) { + LOGGER_VA_LIST args; + va_start(args, format); + int ret = ::vwprintf(format, args); + va_end(args); + return ret; +} + +extern "C" int dprintf(int fd, const char *format, ...) { + LOGGER_VA_LIST args; + va_start(args, format); + int ret = ::vdprintf(fd, format, args); + va_end(args); + return ret; +} + +extern "C" int fprintf(FILE* stream, const char *format, ...) { + LOGGER_VA_LIST args; + va_start(args, format); + int ret = ::vfprintf(stream, format, args); + va_end(args); + return ret; +} + +extern "C" int __printf_chk(int flag, const char *format, ...) { + LOGGER_VA_LIST args; + va_start(args, format); + int ret = __vprintf_chk(flag, format, args); + va_end(args); + return ret; +} + +extern "C" int __fprintf_chk(FILE* stream, int flag, const char *format, ...) { + LOGGER_VA_LIST args; + va_start(args, format); + int ret = __vfprintf_chk(stream, flag, format, args); + va_end(args); + return ret; +} diff --git a/Online/ROLogger/kafka/OutputListener.cpp b/Online/ROLogger/kafka/OutputListener.cpp index d4b2b3612..7500b4346 100644 --- a/Online/ROLogger/kafka/OutputListener.cpp +++ b/Online/ROLogger/kafka/OutputListener.cpp @@ -121,21 +121,28 @@ void OutputListener::print_msg(const char* time_stamp, break; } } + size_t len = 0; + char text[1024]; + text[0] = 0; if ( !simple_msg ) { - if ( time_stamp ) ::printf("%s ",time_stamp); - if ( host ) ::printf("%-8s ",host); - if ( print_counter && counter ) ::printf("%8s ",counter); - ::printf("%-6s ", tag); + len += ::snprintf(text+len,sizeof(text)-len,"%s %-9s", + time_stamp ? time_stamp : "", + host ? host : ""); + if ( counter ) + len += ::snprintf(text+len,sizeof(text)-len,"%9s%-7s",counter,tag); + else + len += ::snprintf(text+len,sizeof(text)-len,"%-7s",tag); } - if ( utgid ) ::printf("%-36s ",utgid); - if ( message ) ::printf("%s ",message); - + len += ::snprintf(text+len,sizeof(text)-len,"%-25s%s\n", + utgid ? utgid : "", + message ? message : ""); if ( have_colors ) { graphics::white(); graphics::plain(); graphics::bg_black(); } - ::printf("\n"); + ::fputs(text,stdout); + ::fflush(stdout); } } #include <unistd.h> -- GitLab From 06ce301cc7984c617a9cea714b46ae2e9dcfb2a3 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Fri, 9 Apr 2021 18:12:58 +0200 Subject: [PATCH 15/17] Add monitoring to storage servers --- Online/Dataflow/src/Storage/StorageWriter.cpp | 13 +- .../options/EB_Transport_properties.opts | 3 +- .../python/GaudiOnline/Passthrough.py | 1 - Online/ROLogger/kafka/OutputListener.cpp | 5 +- .../SmiController/SmiController.h | 36 +++-- Online/SmiController/scripts/MBMDistBox.sh | 1 + Online/SmiController/scripts/SNDMulti.sh | 1 + Online/SmiController/scripts/SNDSingle.sh | 2 +- Online/SmiController/scripts/TestFileProd.sh | 9 ++ .../scripts/TestStorageReader.sh | 3 +- .../scripts/TestStorageWriter.sh | 3 +- Online/SmiController/scripts/configure.sh | 32 ++-- Online/SmiController/src/SmiController.cpp | 49 ++++--- Online/Storage/CMakeLists.txt | 7 +- Online/Storage/Storage/fdb_dbase.h | 43 ++++++ Online/Storage/Storage/fdb_server.h | 16 +- Online/Storage/src/server/fdb_SQLite.cpp | 10 +- Online/Storage/src/server/fdb_SQLite_bind.cpp | 137 ------------------ .../Storage/src/server/fdb_SQLite_direct.cpp | 0 Online/Storage/src/server/fdb_db_server.cpp | 91 ++++++++++-- Online/Storage/src/server/fdb_fs_server.cpp | 103 +++++++++++-- 21 files changed, 331 insertions(+), 234 deletions(-) delete mode 100644 Online/Storage/src/server/fdb_SQLite_bind.cpp delete mode 100644 Online/Storage/src/server/fdb_SQLite_direct.cpp diff --git a/Online/Dataflow/src/Storage/StorageWriter.cpp b/Online/Dataflow/src/Storage/StorageWriter.cpp index 9a542480a..ec97f8b65 100644 --- a/Online/Dataflow/src/Storage/StorageWriter.cpp +++ b/Online/Dataflow/src/Storage/StorageWriter.cpp @@ -279,17 +279,18 @@ int StorageWriter::save_pcie40_as_mdf(Buffer& buff, const uint8_t* start, long l /// Save MDF frame or MDF burst int StorageWriter::save_mdf_buffer(Buffer& buff, const uint8_t* start, long len) { - /// Auto detect data type: now check for MDF data type - for( const uint8_t* end = start + len; start < end; ) { + for( const uint8_t *begin=start, *end = start + len; start < end; ) { auto* header = (EventHeader*)start; + if ( !header->is_mdf() ) { + warning("save_mdf: Encountered invalid MDF header: (%d %d %d). Skip %ld bytes of data.", + header->size0(), header->size1(), header->size2(), start-begin); + return DF_SUCCESS; + } auto* hdr = header->subHeader().H1; long length = header->size0(); long run = hdr->runNumber(); - if ( start+length > end ) { - break; - } - else if ( 0 == m_curr_run ) { + if ( 0 == m_curr_run ) { /// First event in this buffer: store the current run number m_curr_run = run; m_curr_orbit = hdr->orbitNumber(); diff --git a/Online/EventBuilding/options/EB_Transport_properties.opts b/Online/EventBuilding/options/EB_Transport_properties.opts index 6cfdb061a..3d06991a2 100755 --- a/Online/EventBuilding/options/EB_Transport_properties.opts +++ b/Online/EventBuilding/options/EB_Transport_properties.opts @@ -2,6 +2,7 @@ EB_transport.BU_ranks = {}; EB_transport.MPI_errors_return = FALSE; EB_transport.RU_ranks = {}; EB_transport.RUs_per_nic = {}; -EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.J31513.json"; +EB_transport.ib_config_file = "/home/lgranado/ebuilder/Online/tmp/PVSS.n18450.json"; EB_transport.n_par_mess = 0; EB_transport.n_sources_per_ru = { 3, 2, 2, 2 }; +EB_transport.src_ids = {}; diff --git a/Online/GaudiOnline/python/GaudiOnline/Passthrough.py b/Online/GaudiOnline/python/GaudiOnline/Passthrough.py index 4584cc8fe..907b738ed 100644 --- a/Online/GaudiOnline/python/GaudiOnline/Passthrough.py +++ b/Online/GaudiOnline/python/GaudiOnline/Passthrough.py @@ -22,7 +22,6 @@ class Passthrough(Application): input = self.setup_event_input(TAE) self.input = input passThrough = Configurables.Online__Passthrough('Passthrough') - #passThrough = Configurables.Online__PassthroughPCIE40('Passthrough') passThrough.RawGuard = '/Event/DAQ/RawDataGuard' passThrough.AcceptRate = acceptRate self.passThrough = passThrough diff --git a/Online/ROLogger/kafka/OutputListener.cpp b/Online/ROLogger/kafka/OutputListener.cpp index 7500b4346..1eea5d071 100644 --- a/Online/ROLogger/kafka/OutputListener.cpp +++ b/Online/ROLogger/kafka/OutputListener.cpp @@ -133,9 +133,8 @@ void OutputListener::print_msg(const char* time_stamp, else len += ::snprintf(text+len,sizeof(text)-len,"%-7s",tag); } - len += ::snprintf(text+len,sizeof(text)-len,"%-25s%s\n", - utgid ? utgid : "", - message ? message : ""); + len += ::snprintf(text+len,sizeof(text)-len,"%-34s%s\n", + utgid ? utgid : "", message ? message : ""); if ( have_colors ) { graphics::white(); graphics::plain(); diff --git a/Online/SmiController/SmiController/SmiController.h b/Online/SmiController/SmiController/SmiController.h index 149f4bcec..95e4771a1 100644 --- a/Online/SmiController/SmiController/SmiController.h +++ b/Online/SmiController/SmiController/SmiController.h @@ -178,32 +178,36 @@ namespace FiniteStateMachine { /// Variable to publish the instance information std::string m_instance_info; - long m_tms_dic_dns_ID = 0; - long m_smi_dic_dns_ID = 0; - long m_smi_dis_dns_ID = 0; - long m_local_dic_dns_ID = 0; - long m_local_dis_dns_ID = 0; + long m_tms_dic_dns_ID = 0; + long m_smi_dic_dns_ID = 0; + long m_smi_dis_dns_ID = 0; + long m_local_dic_dns_ID = 0; + long m_local_dis_dns_ID = 0; /// Pointer to the dim service receiving commands - int m_command_ID = 0; + int m_command_ID = 0; /// Pointer to the secondary dim service receiving commands - int m_userCmd_ID = 0; - /// Pointer to the dim service serving the FSM status - int m_status_ID = 0; - int m_state_ID = 0; + int m_userCmd_ID = 0; + /// Pointer to the dim service serving the FSM state + int m_status_ID = 0; + /// Pointer to the dim service serving the FSM state + int m_state_ID = 0; /// Pointer to the dim service serving the FSM sub status information - int m_sub_status_ID = 0; + int m_sub_status_ID = 0; /// Pointer to the dim service publishing the instance information - int m_fsm_tags_ID = 0; + int m_fsm_tags_ID = 0; /// Pointer to the dim service publishing the task information - int m_fsm_tasks_ID = 0; + int m_fsm_tasks_ID = 0; /// Pointer to dim client with maximum instance tag - int m_num_worker_ID = 0; + int m_num_worker_ID = 0; /// Pointer to dim client with node state - int m_node_state_ID = 0; + int m_node_state_ID = 0; /// Maximal number of active threads on the node - int m_num_worker_threads = 1; + int m_num_worker_threads = 1; + /// Variable to check initialization + bool m_inited = false; + /// Basic controller configuration: chains initialize() and start_smi() void configure(); /// Controller configuration diff --git a/Online/SmiController/scripts/MBMDistBox.sh b/Online/SmiController/scripts/MBMDistBox.sh index ec1c05e34..2b7d65a24 100755 --- a/Online/SmiController/scripts/MBMDistBox.sh +++ b/Online/SmiController/scripts/MBMDistBox.sh @@ -8,4 +8,5 @@ # Date: 20/05/2013 # # ========================================================================= +# `dataflow_task Class0` `dataflow_default_options ${TASK_TYPE}` diff --git a/Online/SmiController/scripts/SNDMulti.sh b/Online/SmiController/scripts/SNDMulti.sh index 6d1cb2f46..391e499e7 100755 --- a/Online/SmiController/scripts/SNDMulti.sh +++ b/Online/SmiController/scripts/SNDMulti.sh @@ -8,4 +8,5 @@ # Date: 20/05/2013 # # ========================================================================= +# `dataflow_task Class2` `dataflow_default_options ${TASK_TYPE}`; diff --git a/Online/SmiController/scripts/SNDSingle.sh b/Online/SmiController/scripts/SNDSingle.sh index 7f96a3fc6..f2eec598a 100755 --- a/Online/SmiController/scripts/SNDSingle.sh +++ b/Online/SmiController/scripts/SNDSingle.sh @@ -8,5 +8,5 @@ # Date: 20/05/2013 # # ========================================================================= +# `dataflow_task Class2` `dataflow_default_options ${TASK_TYPE}` - diff --git a/Online/SmiController/scripts/TestFileProd.sh b/Online/SmiController/scripts/TestFileProd.sh index bbdf2fc63..93da36a77 100644 --- a/Online/SmiController/scripts/TestFileProd.sh +++ b/Online/SmiController/scripts/TestFileProd.sh @@ -1,4 +1,13 @@ #!/bin/bash +# ========================================================================= +# +# Generic farm task startup script +# +# Author M.Frank +# Version: 1.0 +# Date: 20/05/2013 +# +# ========================================================================= # export LOGFIFO=/run/fmc/logSrv.fifo; `dataflow_task Class2` `dataflow_default_options ${TASK_TYPE}` diff --git a/Online/SmiController/scripts/TestStorageReader.sh b/Online/SmiController/scripts/TestStorageReader.sh index a12662bb2..83c7de473 100755 --- a/Online/SmiController/scripts/TestStorageReader.sh +++ b/Online/SmiController/scripts/TestStorageReader.sh @@ -8,7 +8,6 @@ # Date: 20/05/2013 # # ========================================================================= -export INFO_OPTIONS=/group/online/dataflow/options/LHCb/MONITORING/OnlineEnv.opts; -echo "ERROR `dataflow_task Class1` `dataflow_default_options ${TASK_TYPE}`"; +# `dataflow_task Class1` `dataflow_default_options ${TASK_TYPE}`; diff --git a/Online/SmiController/scripts/TestStorageWriter.sh b/Online/SmiController/scripts/TestStorageWriter.sh index a12662bb2..83c7de473 100755 --- a/Online/SmiController/scripts/TestStorageWriter.sh +++ b/Online/SmiController/scripts/TestStorageWriter.sh @@ -8,7 +8,6 @@ # Date: 20/05/2013 # # ========================================================================= -export INFO_OPTIONS=/group/online/dataflow/options/LHCb/MONITORING/OnlineEnv.opts; -echo "ERROR `dataflow_task Class1` `dataflow_default_options ${TASK_TYPE}`"; +# `dataflow_task Class1` `dataflow_default_options ${TASK_TYPE}`; diff --git a/Online/SmiController/scripts/configure.sh b/Online/SmiController/scripts/configure.sh index 198d93ffc..b71326ef3 100755 --- a/Online/SmiController/scripts/configure.sh +++ b/Online/SmiController/scripts/configure.sh @@ -13,23 +13,25 @@ export HOST=`echo ${DIM_DNS_HOST} | tr a-z A-Z`; export PREAMBLE_OPTS=`pwd`/../options/Empty.opts; # # -export ONLINETASKS=/group/online/dataflow/templates; -export NON_DYNAMIC_OPTS=/group/online/dataflow/options/${PARTITION_NAME}; +HOST_TYPE=`hostname -s | tr a-z A-Z`; +if test "`echo ${HOST_TYPE} | cut -b 1-3`" = "MON"; then + export NON_DYNAMIC_OPTS=/group/online/dataflow/options/${PARTITION_NAME}/MONITORING; +elif test "`echo ${HOST_TYPE} | cut -b 3-4`" = "EB"; then + export NON_DYNAMIC_OPTS=/group/online/dataflow/options/${PARTITION_NAME}; +else + export NON_DYNAMIC_OPTS=/group/online/dataflow/options/${PARTITION_NAME}; +fi; +# +# export DYNAMIC_OPTS=${NON_DYNAMIC_OPTS}; +export PYTHONPATH=${NON_DYNAMIC_OPTS}:${PYTHONPATH}; +export INFO_OPTIONS=${NON_DYNAMIC_OPTS}/OnlineEnv.opts; +# +export ONLINETASKS=/group/online/dataflow/templates; export DATAINTERFACE=`python /group/online/dataflow/scripts/getDataInterface.py`; -export INFO_OPTIONS=${DYNAMIC_OPTS}/${PARTITION_NAME}_Info.opts; -export OPTS=/group/online/dataflow/templates/options -export msg_svc=MessageSvc -export msg_svc=LHCb::FmcMessageSvc -export gaudi_task="GaudiOnlineExe.exe libGaudiOnline.so OnlineTask -msgsvc=$msg_svc " -export Class0_task="$gaudi_task -tasktype=LHCb::Class0Task " -export Class1_task="$gaudi_task -tasktype=LHCb::Class1Task -main=$OPTS/Main.opts " -export Class2_task="$gaudi_task -tasktype=LHCb::Class2Task -main=$OPTS/Main.opts " -export Checkpoint_task="GaudiCheckpoint.exe libGaudiOnline.so OnlineTask -msgsvc=$msg_svc -tasktype=LHCb::Class1Task -main=$OPTS/Main.opts " -## export DATAFLOW_task="gentest.exe libDataflow.so dataflow_run_task -msg=Dataflow_FmcLogger -mon=Dataflow_DIMMonitoring"; export DATAFLOW_task="gentest.exe libDataflow.so dataflow_run_task -msg=fifo -mon=Dataflow_DIMMonitoring"; # -export PYTHONPATH=${DYNAMIC_OPTS}/MONITORING:${PYTHONPATH}; +# # dataflow_specialized_options() { @@ -39,12 +41,14 @@ dataflow_specialized_options() echo "-opts=/group/online/dataflow/options/${PARTITION_NAME}/MONITORING/${UTGID}.opts"; fi; } +# dataflow_default_options() { echo "-opts=/group/online/dataflow/options/${PARTITION_NAME}/MONITORING/${UTGID}.opts"; } +# dataflow_task() { #echo "exec -a ${UTGID} gentest.exe libDataflow.so dataflow_run_task -msg=Dataflow_FmcLogger -mon=Dataflow_DIMMonitoring -class=$1"; - echo "exec -a ${UTGID} gentest.exe libDataflow.so dataflow_run_task -msg=fifo -mon=Dataflow_DIMMonitoring -class=$1"; + echo "exec -a ${UTGID} gentest.exe libDataflow.so dataflow_run_task -msg=fifo -mon=Dataflow_DIMMonitoring -class=$1"; } diff --git a/Online/SmiController/src/SmiController.cpp b/Online/SmiController/src/SmiController.cpp index a5768a76e..c04dd6391 100644 --- a/Online/SmiController/src/SmiController.cpp +++ b/Online/SmiController/src/SmiController.cpp @@ -85,10 +85,12 @@ public: public: /// Initializing constructor SmiControllerObject(SmiController* ctrl, const std::string& nam) - : SmiObject(ctrl->config.smi_dns.c_str(), ctrl->config.smiDomain().c_str(), nam.c_str()), - controller(ctrl) - { - } + : SmiObject(ctrl->config.smiDomain().c_str(), nam.c_str()), controller(ctrl) + { } + /// Initializing constructor + SmiControllerObject(SmiController* ctrl, const std::string& dns, const std::string& nam) + : SmiObject(dns.c_str(), ctrl->config.smiDomain().c_str(), nam.c_str()), controller(ctrl) + { } /// Default destructor virtual ~SmiControllerObject() = default; virtual void smiStateChangeHandler() override final {} @@ -767,6 +769,14 @@ SmiController::SmiController(const config_t& cfg) m_log.reset(new RTL::Logger(RTL::Logger::LogDevice::getGlobalDevice(), "Controller", cfg.output_level)); m_num_worker_threads = config.num_workers; m_node_state = State::UNKNOWN; + + m_local_dic_dns_ID = ::dic_add_dns(config.dns.c_str(), ::dim_get_dns_port()); + m_tms_dic_dns_ID = ::dic_add_dns(config.tms_dns.c_str(), ::dim_get_dns_port()); + m_smi_dic_dns_ID = ::dic_add_dns(config.smi_dns.c_str(), ::dim_get_dns_port()); + m_local_dis_dns_ID = 0;//::dis_add_dns(config.dns.c_str(), ::dim_get_dns_port()); + m_smi_dis_dns_ID = ::dis_add_dns(config.smi_dns.c_str(), ::dim_get_dns_port()); + + //::dis_start_serving_dns(m_local_dis_dns_ID, config.name.c_str()); } /// Default destructor @@ -801,12 +811,6 @@ void SmiController::initialize() { m_monitor.partitionID = -1; m_monitor.pad = 0; - m_local_dic_dns_ID = ::dic_add_dns(config.dns.c_str(), ::dim_get_dns_port()); - m_tms_dic_dns_ID = ::dic_add_dns(config.tms_dns.c_str(), ::dim_get_dns_port()); - m_smi_dic_dns_ID = ::dic_add_dns(config.smi_dns.c_str(), ::dim_get_dns_port()); - m_local_dis_dns_ID = 0;//::dis_add_dns(config.dns.c_str(), ::dim_get_dns_port()); - m_smi_dis_dns_ID = ::dis_add_dns(config.smi_dns.c_str(), ::dim_get_dns_port()); - m_command_ID = ::dis_add_cmnd_dns( m_local_dis_dns_ID, config.name.c_str(), "C", feed_transition, (long)this); @@ -842,18 +846,20 @@ void SmiController::initialize() { (long)this,0,0); } string slice = config.standalone ? string("Manager") : config.smiDomain() + "_Manager"; - m_taskset = make_unique<TaskSet>(this, slice.c_str()); + m_taskset = make_unique<TaskSet>(this, config.smi_dns, slice.c_str()); if ( config.standalone ) { string node_state = RTL::str_upper("SMI/"+config.smi_domain+"/PROCESSINGNODE"); bool print = config.output_level <= LIB_RTL_INFO; m_self = make_unique<CtrlProxy> (this, "Controller"); - m_nodeProxy = make_unique<NodeProxy> (this, "ProcessingNode"); + m_nodeProxy = make_unique<NodeProxy> (this, config.smi_dns, "ProcessingNode"); m_defTask = make_unique<DfTaskProxy>(this, "DefTask"); m_vipTask = make_unique<DfTaskProxy>(this, "VipTask"); m_node_state_ID = ::dic_info_service_dns(m_local_dic_dns_ID, node_state.c_str(), - MONITORED,0,0,0,node_state_handler,(long)this,0,0); + MONITORED, 0, 0, 0, + node_state_handler, + (long)this, 0, 0); print ? m_self->setPrintOn() : m_self->setPrintOff(); print ? m_defTask->setPrintOn() : m_defTask->setPrintOff(); print ? m_vipTask->setPrintOn() : m_vipTask->setPrintOff(); @@ -862,8 +868,8 @@ void SmiController::initialize() { m_vipTask->setState(State::OFFLINE); } ::dis_start_serving_dns(m_local_dis_dns_ID, config.name.c_str()); - //IocSensor::instance().send(this,CONTROLLER_REMOVE_TASK,new string("DEFTASK")); - //IocSensor::instance().send(this,CONTROLLER_REMOVE_VIPTASK,new string("VIPTASK")); + this_thread::sleep_for(chrono::milliseconds(200)); + m_inited = true; } //============================================================================== @@ -920,7 +926,7 @@ void SmiController::load_tasks() { } } m_log->debug("Sleep 2 seconds after ADDTASKS."); - ::lib_rtl_sleep(2000); + this_thread::sleep_for(chrono::milliseconds(2000)); IocSensor::instance().send(this, CONTROLLER_SETSTATE, nullptr); } @@ -1033,7 +1039,7 @@ bool SmiController::attach_tasks(std::map<std::string, SmiTask*>&& tasks) { } } - ::lib_rtl_sleep(200); + this_thread::sleep_for(chrono::milliseconds(200)); for( const auto& task : tasks) { const auto& nam = task.second->utgid; m_log->info("Adding dependent task: %s", nam.c_str()); @@ -1053,7 +1059,7 @@ bool SmiController::attach_tasks(std::map<std::string, SmiTask*>&& tasks) { proxy->task->add_fmc_args("-DDIM_DNS_HOST="+RTL::str_upper(RTL::nodeNameShort())); } ::dis_start_serving_dns(m_local_dis_dns_ID, config.name.c_str()); - ::lib_rtl_sleep(200); + this_thread::sleep_for(chrono::milliseconds(200)); return true; } @@ -1133,7 +1139,7 @@ void SmiController::handle(const CPP::Event& event) { if ( !config.smi_utgid.empty() ) { TaskManager::instance(RTL::nodeNameShort(), m_tms_dic_dns_ID).kill(config.smi_utgid,SIGKILL); } - ::lib_rtl_sleep(1000); + this_thread::sleep_for(chrono::milliseconds(1000)); _exit(0); return; @@ -1297,8 +1303,11 @@ void SmiController::run() { "-dns", config.smi_dns.c_str(), config.smi_domain.c_str(), config.smi_file.c_str(), nullptr}; + /// Wait with server start until controller is initialized + while ( !this->m_inited ) + this_thread::sleep_for(chrono::milliseconds(100)); + this_thread::sleep_for(chrono::milliseconds(1000)); /// function will never return.... - ::lib_rtl_sleep(2500); (*fun.function)(sizeof(args)/sizeof(args[0])-1, (char**)args); thr->join(); } diff --git a/Online/Storage/CMakeLists.txt b/Online/Storage/CMakeLists.txt index f2496c2cc..c8151ec63 100644 --- a/Online/Storage/CMakeLists.txt +++ b/Online/Storage/CMakeLists.txt @@ -16,7 +16,8 @@ gaudi_subdir(Storage v0r1) ################################################################################ # gaudi_depends_on_subdirs(Online/OnlineBase - Online/HTTP) + Online/HTTP + Online/dim) # find_package(SQLite3 REQUIRED) # @@ -32,9 +33,9 @@ gaudi_add_library(StorageClient src/client/*.cpp target_compile_definitions(StorageClient PRIVATE -DSTORAGECLIENT=1) # gaudi_add_library(StorageServer src/server/*.cpp - INCLUDE_DIRS Boost HTTP SQLite3 + INCLUDE_DIRS Boost HTTP SQLite3 dim NO_PUBLIC_HEADERS - LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt z Boost HTTP SQLite3 StorageClient) + LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt z dim Boost HTTP SQLite3 StorageClient) # target_compile_definitions(StorageServer PRIVATE -DSTORAGECLIENT=1) # diff --git a/Online/Storage/Storage/fdb_dbase.h b/Online/Storage/Storage/fdb_dbase.h index f4c2415d7..c21bad757 100644 --- a/Online/Storage/Storage/fdb_dbase.h +++ b/Online/Storage/Storage/fdb_dbase.h @@ -186,6 +186,49 @@ namespace Online { virtual boost::system::error_code update_object_state(const std::string& object_name, const std::string& state); }; + + + /// Monitor object to publish values + /** + * + * \author M.Frank + * \version 1.0 + * \date 02.02.2021 + */ + class fdb_dbase_monitor_t { + public: + struct Data { + int num_get_success {0}; + int num_get_errors {0}; + int num_get_not_found {0}; + int num_get_unauthorized {0}; + + int num_del_success {0}; + int num_del_errors {0}; + int num_del_not_found {0}; + int num_del_unauthorized {0}; + + int num_put_success {0}; + int num_put_errors {0}; + int num_put_bad_request {0}; + int num_put_unauthorized {0}; + + int num_upda_success {0}; + int num_upda_errors {0}; + int num_upda_bad_request {0}; + } data; + + std::vector<int> services; + + void add(int svc) { services.emplace_back(svc); } + + public: + /// Standard constructor + fdb_dbase_monitor_t(); + /// Default destructor + ~fdb_dbase_monitor_t(); + }; + } // End namespace storage } // End namespace Online #endif // ONLINE_STORAGE_FDB_DBASE_H diff --git a/Online/Storage/Storage/fdb_server.h b/Online/Storage/Storage/fdb_server.h index 4df72257b..64714b397 100644 --- a/Online/Storage/Storage/fdb_server.h +++ b/Online/Storage/Storage/fdb_server.h @@ -35,12 +35,22 @@ namespace http { */ template <typename T> class basic_http_server<T>::handler_t : public HttpRequestHandler { + public: - typedef typename T::traits traits; - typedef typename traits::dbase_t dbase_t; + typedef typename T::traits traits; + typedef typename traits::dbase_t dbase_t; + typedef typename traits::monitor_t monitor_t; + public: - std::unique_ptr<dbase_t> dbase; + + /// Reference to the database instance + std::unique_ptr<dbase_t> dbase; + + /// Reference to the monitoring instance + std::unique_ptr<monitor_t> monitor; + public: + /// Standard constructor explicit handler_t() = default; /// Standard destructor diff --git a/Online/Storage/src/server/fdb_SQLite.cpp b/Online/Storage/src/server/fdb_SQLite.cpp index 3cfee40e0..41da23c57 100644 --- a/Online/Storage/src/server/fdb_SQLite.cpp +++ b/Online/Storage/src/server/fdb_SQLite.cpp @@ -15,6 +15,7 @@ // Framework include files #include "fdb_SQLite.h" +#include <RTL/strdef.h> #include <RTL/rtl.h> // C/C++ files @@ -172,20 +173,25 @@ SQLite_handler_t::set (const std::string& object_name, int value) { return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); } +#include <dim/dis.h> #include <Storage/fdb_server.h> + class Online::storage::db::traits { public: - typedef fdb_dbase_t dbase_t; + typedef fdb_dbase_t dbase_t; + typedef fdb_dbase_monitor_t monitor_t; }; extern "C" int fdb_sqlite_server(int argc, char** argv) { + std::string srv = "/"+RTL::str_upper(RTL::nodeNameShort())+"/"+RTL::processName(); Online::storage::SrvRun<Online::storage::db> s; s.create(argc, argv); auto* sql = new Online::storage::fdb_dbase_t(s.server); sql->_debug = s.application_debug; sql->_engine.reset(new SQLite_handler_t(s.dbase, s.application_debug)); s.ptr->implementation->dbase.reset(sql); + s.ptr->implementation->monitor.reset(new fdb_dbase_monitor_t()); + ::dis_start_serving(srv.c_str()); s.start(); return 0; } - diff --git a/Online/Storage/src/server/fdb_SQLite_bind.cpp b/Online/Storage/src/server/fdb_SQLite_bind.cpp deleted file mode 100644 index 0c136cbaa..000000000 --- a/Online/Storage/src/server/fdb_SQLite_bind.cpp +++ /dev/null @@ -1,137 +0,0 @@ -//========================================================================== -// LHCb Online software suite -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see OnlineSys/LICENSE. -// -//-------------------------------------------------------------------------- -// -// Package : RPC -// -// Author : Markus Frank -//========================================================================== -#if 0 - -// Framework include files -#include "fdb_SQLite.h" -#include <RTL/rtl.h> - -// C/C++ files -using namespace boost; - -namespace { - - class handler_t : public Online::storage::fdb_SQLite::handler_t { - public: - - /// Standard constructor - handler_t(const std::string& p, int dbg) - : Online::storage::fdb_SQLite::handler_t(dbg), path(p) - { - this->init(path); - } - - /// Default destructor - virtual ~handler_t() { - this->fini(); - } - - /// Check the existence of a given object in the database - virtual system::error_code query_file(const std::string& object_name, File& file, int state) override { - this->query_record.reset(); - this->query_record.bind(1, object_name); - this->query_record.bind(2, state); - int ret = this->query_record.execute(); - while ( ret == SQLITE_ROW ) { - file.name = query_record.get<std::string>(0); - file.state = query_record.get<std::string>(1); - file.size = query_record.get<std::string>(2); - file.date = query_record.get<std::string>(3); - file.host = query_record.get<std::string>(4); - return system::error_code(system::errc::success, system::system_category()); - } - return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); - } - - /// Add a new object to the database - virtual system::error_code add (const std::string& object_name, - const std::string& date, - std::size_t length, - const std::string& host) override { - this->insert_record.reset(); - this->insert_record.bind(1, object_name); - this->insert_record.bind(2, STATE_OPEN); - this->insert_record.bind(3, length); - this->insert_record.bind(4, date); - this->insert_record.bind(5, host); - this->database.begin(); - int ret = this->insert_record.execute(); - this->insert_record.reset(); - this->database.commit(); - if ( ret == SQLITE_DONE ) { - return system::error_code(system::errc::success, system::system_category()); - } - else if ( ret == SQLITE_CONSTRAINT_PRIMARYKEY ) { - return system::error_code(system::errc::file_exists, system::system_category()); - } - else if ( ret == SQLITE_CONSTRAINT_FOREIGNKEY ) { - return system::error_code(system::errc::file_exists, system::system_category()); - } - else if ( ret != SQLITE_OK ) { - return system::error_code(system::errc::file_exists, system::system_category()); - } - return system::error_code(system::errc::success, system::system_category()); - } - - /// Remove an object from the database - virtual system::error_code del (const std::string& object_name) override { - this->delete_record.reset(); - this->delete_record.bind(1, object_name); - this->database.begin(); - int ret = this->delete_record.execute(); - this->delete_record.reset(); - this->database.commit(); - if ( ret == SQLITE_OK ) - return system::error_code(system::errc::success, system::system_category()); - else if ( ret == SQLITE_DONE ) - return system::error_code(system::errc::success, system::system_category()); - return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); - } - - /// lock database record - virtual system::error_code set (const std::string& object_name, int value) override { - this->lock_record.reset(); - this->lock_record.bind(1, value); - this->lock_record.bind(2, object_name); - this->database.begin(); - int ret = this->lock_record.execute(); - this->lock_record.reset(); - this->database.commit(); - if ( ret == SQLITE_DONE ) - return system::error_code(system::errc::success, system::system_category()); - else if ( ret == SQLITE_OK ) - return system::error_code(system::errc::success, system::system_category()); - return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); - } - }; -} - -#include <Storage/fdb_server.h> -class Online::storage::db::traits { -public: - typedef fdb_dbase_t dbase_t; -}; - -extern "C" int fdb_sqlite_bind_server(int argc, char** argv) { - Online::storage::SrvRun<Online::storage::db> s; - s.create(argc, argv); - auto* sql = new Online::storage::fdb_SQLite(s.server); - sql->debug = s.application_debug; - sql->engine.reset(new handler_t(s.dbase, s.application_debug)); - s.ptr->implementation->dbase.reset(sql); - s.start(); - return 0; -} -#endif diff --git a/Online/Storage/src/server/fdb_SQLite_direct.cpp b/Online/Storage/src/server/fdb_SQLite_direct.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/Online/Storage/src/server/fdb_db_server.cpp b/Online/Storage/src/server/fdb_db_server.cpp index 4e6dc0a29..33643942a 100644 --- a/Online/Storage/src/server/fdb_db_server.cpp +++ b/Online/Storage/src/server/fdb_db_server.cpp @@ -18,12 +18,16 @@ #include <Storage/fdb_dbase.h> #include <Storage/fdb_server.h> #include <Storage/communication.h> +#include <RTL/strdef.h> +#include <RTL/rtl.h> +#include <dim/dis.h> // C/C++ include files class Online::storage::db::traits { public: - typedef fdb_dbase_t dbase_t; + typedef fdb_dbase_t dbase_t; + typedef fdb_dbase_monitor_t monitor_t; }; using namespace std; @@ -43,6 +47,51 @@ static inline string object_name(const string& obj, string opt="") { return obj; } +/// Standard constructor +fdb_dbase_monitor_t::fdb_dbase_monitor_t() { + std::string nam = "/"+RTL::str_upper(RTL::nodeNameShort())+"/"+RTL::processName(); + add( ::dis_add_service((nam+"/DATA").c_str(),"C",&data,sizeof(data),0,0) ); + add( ::dis_add_service((nam+"/GET").c_str(),"L", + &data.num_get_success,sizeof(data.num_get_success),0,0) ); + add( ::dis_add_service((nam+"/GET_errors").c_str(),"L", + &data.num_get_errors,sizeof(data.num_get_errors),0,0) ); + add( ::dis_add_service((nam+"/GET_not_found").c_str(),"L", + &data.num_get_not_found,sizeof(data.num_get_not_found),0,0) ); + add( ::dis_add_service((nam+"/GET_unauthorized").c_str(),"L", + &data.num_get_unauthorized,sizeof(data.num_get_unauthorized),0,0) ); + + add( ::dis_add_service((nam+"/DEL").c_str(),"L", + &data.num_del_success,sizeof(data.num_del_success),0,0) ); + add( ::dis_add_service((nam+"/DEL_errors").c_str(),"L", + &data.num_del_errors,sizeof(data.num_del_errors),0,0) ); + add( ::dis_add_service((nam+"/DEL_not_found").c_str(),"L", + &data.num_del_not_found,sizeof(data.num_del_not_found),0,0) ); + add( ::dis_add_service((nam+"/DEL_unauthorized").c_str(),"L", + &data.num_del_unauthorized,sizeof(data.num_del_unauthorized),0,0) ); + + add( ::dis_add_service((nam+"/PUT").c_str(),"L", + &data.num_put_success,sizeof(data.num_put_success),0,0) ); + add( ::dis_add_service((nam+"/PUT_errors").c_str(),"L", + &data.num_put_errors,sizeof(data.num_put_errors),0,0) ); + add( ::dis_add_service((nam+"/PUT_bad_request").c_str(),"L", + &data.num_put_bad_request,sizeof(data.num_put_bad_request),0,0) ); + add( ::dis_add_service((nam+"/PUT_unauthorized").c_str(),"L", + &data.num_put_unauthorized,sizeof(data.num_put_unauthorized),0,0) ); + + add( ::dis_add_service((nam+"/UPDA").c_str(),"L", + &data.num_upda_success,sizeof(data.num_upda_success),0,0) ); + add( ::dis_add_service((nam+"/UPDA_errors").c_str(),"L", + &data.num_upda_errors,sizeof(data.num_upda_errors),0,0) ); + add( ::dis_add_service((nam+"/UPDA_bad_request").c_str(),"L", + &data.num_upda_bad_request,sizeof(data.num_upda_bad_request),0,0) ); +} + +/// Default destructor +fdb_dbase_monitor_t::~fdb_dbase_monitor_t() { + for( auto svc : services ) ::dis_remove_service(svc); +} + + /// Standard destructor template <> http::basic_http_server<db>::handler_t::~handler_t() { } @@ -57,19 +106,25 @@ http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t dbase_t::lock_t lock(dbase.get()); ec = dbase->query_object(req.uri, access_name, date, length); } - if ( ec == boost::system::errc::no_such_file_or_directory ) + if ( ec == boost::system::errc::no_such_file_or_directory ) { rep = reply_t::stock_reply(reply_t::not_found); - else if ( ec == boost::system::errc::permission_denied ) + ++monitor->data.num_get_not_found; + } + else if ( ec == boost::system::errc::permission_denied ) { rep = reply_t::stock_reply(reply_t::unauthorized); - else if ( !error_code_ok(ec, this->debug) ) + ++monitor->data.num_get_unauthorized; + } + else if ( !error_code_ok(ec, this->debug) ) { rep = reply_t::stock_reply(reply_t::not_found); - + ++monitor->data.num_get_not_found; + } if ( !error_code_ok(ec, this->debug) ) { header_t h(http::constants::error_cause,"Failed to get "+req.uri+" ["+ec.message()+"]"); ::lib_rtl_output(LIB_RTL_ERROR,"GET: %s %-20s = %s", reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); rep.headers.emplace_back(move(h)); + ++monitor->data.num_get_errors; } else { bool mb = length > 3*MByte; @@ -78,6 +133,7 @@ http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t ::lib_rtl_output(LIB_RTL_INFO,"GET: '%s' %.1f %cB [%s]", access_name.c_str(), double(length)/(mb ? MByte : kByte), mb ? 'M' : 'k', req.remote_address().to_string().c_str()); + ++monitor->data.num_get_success; } return write; } @@ -92,19 +148,25 @@ http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, repl dbase_t::lock_t lock(dbase.get()); ec = dbase->delete_object(obj, access_name, date, length); } - if ( ec == boost::system::errc::no_such_file_or_directory ) + if ( ec == boost::system::errc::no_such_file_or_directory ) { rep = reply_t::stock_reply(reply_t::not_found); - else if ( ec == boost::system::errc::permission_denied ) + ++monitor->data.num_del_not_found; + } + else if ( ec == boost::system::errc::permission_denied ) { rep = reply_t::stock_reply(reply_t::unauthorized); - else if ( !error_code_ok(ec) ) + ++monitor->data.num_del_unauthorized; + } + else if ( !error_code_ok(ec) ) { rep = reply_t::stock_reply(reply_t::not_found); - + ++monitor->data.num_del_not_found; + } if ( !error_code_ok(ec, this->debug) ) { header_t h(http::constants::error_cause,"Failed to delete "+req.uri+" ["+ec.message()+"]"); ::lib_rtl_output(LIB_RTL_ERROR,"DELETE: %s %-20s = %s", reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); rep.headers.emplace_back(move(h)); + ++monitor->data.num_del_errors; } else { bool mb = length > 3*MByte; @@ -113,6 +175,7 @@ http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, repl ::lib_rtl_output(LIB_RTL_INFO,"DELETE:'%s' %.1f %cB [%s]", obj.c_str(), double(length)/(mb ? MByte : kByte), mb ? 'M' : 'k', req.remote_address().to_string().c_str()); + ++monitor->data.num_del_success; } return write; } @@ -126,6 +189,7 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t rep = reply_t::stock_reply(reply_t::bad_request); ::lib_rtl_output(LIB_RTL_ERROR,"PUT: bad_request %-20s = %s", h.name.c_str(), h.value.c_str()); + ++monitor->data.num_put_bad_request; rep.headers.emplace_back(move(h)); } else if ( (hdr_len=req.header(http::constants::content_length)) == nullptr ) { @@ -133,6 +197,7 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t rep = reply_t::stock_reply(reply_t::bad_request); ::lib_rtl_output(LIB_RTL_ERROR,"PUT: bad_request %-20s = %s", h.name.c_str(), h.value.c_str()); + ++monitor->data.num_put_bad_request; rep.headers.emplace_back(move(h)); } else { @@ -149,6 +214,7 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t ::lib_rtl_output(LIB_RTL_ERROR,"PUT: %s %-20s = %s", reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); + ++monitor->data.num_put_unauthorized; rep.headers.emplace_back(move(h)); } else if ( !error_code_ok(ec, this->debug) ) { @@ -158,6 +224,7 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t ::lib_rtl_output(LIB_RTL_ERROR,"PUT: %s %-20s = %s", reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); + ++monitor->data.num_put_bad_request; rep.headers.emplace_back(move(h)); } else { @@ -171,8 +238,11 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t ::lib_rtl_output(LIB_RTL_INFO,"PUT: '%s' %.1f %cB [%s]", req.uri.c_str(), double(len)/(mb ? MByte : kByte), mb ? 'M' : 'k', req.remote_address().to_string().c_str()); + ++monitor->data.num_put_success; + return write; } } + ++monitor->data.num_put_errors; return write; } @@ -185,6 +255,7 @@ http::basic_http_server<db>::handler_t::handle_update(const request_t& req, repl rep = reply_t::stock_reply(reply_t::bad_request); ::lib_rtl_output(LIB_RTL_ERROR,"UPDATE: bad_request %-20s = %s", h.name.c_str(), h.value.c_str()); + ++monitor->data.num_upda_bad_request; rep.headers.emplace_back(move(h)); } else { @@ -199,9 +270,11 @@ http::basic_http_server<db>::handler_t::handle_update(const request_t& req, repl ::lib_rtl_output(LIB_RTL_ERROR,"UPDATE: %s %-20s = %s", reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); + ++monitor->data.num_upda_errors; rep.headers.emplace_back(move(h)); } else { + ++monitor->data.num_upda_success; rep = reply_t::stock_reply(reply_t::ok); rep.content.clear(); rep.headers.clear(); diff --git a/Online/Storage/src/server/fdb_fs_server.cpp b/Online/Storage/src/server/fdb_fs_server.cpp index eb5a0e6b4..d07012fac 100644 --- a/Online/Storage/src/server/fdb_fs_server.cpp +++ b/Online/Storage/src/server/fdb_fs_server.cpp @@ -15,14 +15,17 @@ // Framework include files #include <HTTP/HttpReply.h> -#include <Storage/fdb_server.h> #include <Storage/client.h> +#include <Storage/fdb_server.h> #include <boost/filesystem.hpp> +#include <RTL/strdef.h> +#include <dim/dis.h> // C/C++ include files #include <cstring> #include <unistd.h> +// Put private stuff in anonymous namespace namespace { /// Database object to check fs @@ -44,7 +47,36 @@ namespace { { return file_dir + object_name; } }; - + /// Monitor object to publish values + /** + * + * \author M.Frank + * \version 1.0 + * \date 02.02.2021 + */ + struct fs_monitor { + public: + struct mon_data { + int numGET {0}; + int numPUT {0}; + int numDEL {0}; + int numGET_not_found {0}; + int numDEL_not_found {0}; + int numPUT_error {0}; + long bytesGET {0}; + long bytesPUT {0}; + long bytesDEL {0}; + } data; + + std::vector<int> services; + + void add(int svc) { services.emplace_back(svc); } + public: + /// Standard constructor + fs_monitor(); + /// Default destructor + ~fs_monitor(); + }; /// File I/O object /** @@ -132,11 +164,35 @@ namespace { class Online::storage::fs::traits { public: - typedef fs_db dbase_t; + typedef fs_db dbase_t; + typedef fs_monitor monitor_t; }; using namespace Online::storage; +/// Standard constructor +fs_monitor::fs_monitor() { + std::string nam = "/"+RTL::str_upper(RTL::nodeNameShort())+"/"+RTL::processName(); + add( ::dis_add_service((nam+"/DATA").c_str(),"C",&data,sizeof(data),0,0) ); + add( ::dis_add_service((nam+"/GET").c_str(),"L",&data.numGET,sizeof(data.numGET),0,0) ); + add( ::dis_add_service((nam+"/PUT").c_str(),"L",&data.numPUT,sizeof(data.numPUT),0,0) ); + add( ::dis_add_service((nam+"/DEL").c_str(),"L",&data.numDEL,sizeof(data.numDEL),0,0) ); + add( ::dis_add_service((nam+"/GET_bytes").c_str(),"L",&data.bytesGET,sizeof(data.bytesGET),0,0) ); + add( ::dis_add_service((nam+"/PUT_bytes").c_str(),"L",&data.bytesPUT,sizeof(data.bytesPUT),0,0) ); + add( ::dis_add_service((nam+"/DEL_bytes").c_str(),"L",&data.bytesDEL,sizeof(data.bytesDEL),0,0) ); + add( ::dis_add_service((nam+"/PUT_error").c_str(),"L", + &data.numPUT_error,sizeof(data.numPUT_error),0,0) ); + add( ::dis_add_service((nam+"/GET_not_found").c_str(),"L", + &data.numGET_not_found,sizeof(data.numGET_not_found),0,0) ); + add( ::dis_add_service((nam+"/DEL_not_found").c_str(),"L", + &data.numDEL_not_found,sizeof(data.numDEL_not_found),0,0) ); +} + +/// Default destructor +fs_monitor::~fs_monitor() { + for( auto svc : services ) ::dis_remove_service(svc); +} + /// Standard destructor template <> http::basic_http_server<fs>::handler_t::~handler_t() { } @@ -153,6 +209,7 @@ http::basic_http_server<fs>::handler_t::handle_get(const request_t& req, reply_t if ( -1 == ret_stat ) { rep = reply_t::stock_reply(reply_t::not_found); rep.headers.emplace_back(constants::error_cause,"File '"+fname+"' does not exist"); + ++monitor->data.numGET_not_found; return write; } rep = reply_t::stock_reply(reply_t::ok); @@ -172,6 +229,7 @@ http::basic_http_server<fs>::handler_t::handle_get(const request_t& req, reply_t if ( !error_code_ok(ec, this->debug) ) { rep = reply_t::stock_reply(reply_t::not_found); rep.headers.emplace_back(constants::error_cause,"File '"+fname+"' does not exist"); + ++monitor->data.numGET_not_found; } return write; } @@ -188,12 +246,12 @@ http::basic_http_server<fs>::handler_t::handle_get(const request_t& req, reply_t ctxt->st_data += rd; } else { - ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read data '%s' [%s] only got %ld out of %ld bytes", + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read '%s' [%s] only got %ld out of %ld bytes", req.method.c_str(), req.uri.c_str(), ::strerror(errno), rd, len); } if ( ctxt->st_data == ctxt->st_size ) { - ::lib_rtl_output(LIB_RTL_INFO, "+++ %s: Prepared last chunk '%s' %.1f MB", + ::lib_rtl_output(LIB_RTL_INFO, "+++ %s: Last chunk '%s' %.1f MB", req.method.c_str(), req.uri.c_str(), double(ctxt->st_size)/(1024e0*1024e0)); } return write; @@ -207,9 +265,11 @@ http::basic_http_server<fs>::handler_t::handle_get(const request_t& req, reply_t req.method.c_str(), ctxt->st_size, net, mb/std::max(1e-6, double(net)/1e3), wrt, mb/std::max(1e-6, double(wrt)/1e3)); + ++monitor->data.numGET; + monitor->data.bytesGET += ctxt->st_data; return none; } - ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read data '%s' size:%ld / %ld %s [Inconsistemt context]", + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read '%s' size:%ld / %ld %s [Inconsistemt context]", req.method.c_str(), req.uri.c_str(), rep.bytes_sent, rep.bytes_total, rep.stock_status(rep.status).c_str()); rep.context.reset(); @@ -229,6 +289,7 @@ http::basic_http_server<fs>::handler_t::handle_delete(const request_t& req, repl if ( -1 == ret_stat ) { rep = reply_t::stock_reply(reply_t::not_found); rep.headers.emplace_back(constants::error_cause,"File '"+fname+"' does not exist"); + ++monitor->data.numDEL_not_found; return write; } rep = reply_t::stock_reply(reply_t::ok); @@ -249,6 +310,7 @@ http::basic_http_server<fs>::handler_t::handle_delete(const request_t& req, repl if ( !error_code_ok(ec, this->debug) ) { rep = reply_t::stock_reply(reply_t::not_found); rep.headers.emplace_back(constants::error_cause,"File '"+fname+"' does not exist"); + ++monitor->data.numDEL_not_found; } return write; } @@ -265,7 +327,7 @@ http::basic_http_server<fs>::handler_t::handle_delete(const request_t& req, repl ctxt->st_data += rd; } else { - ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read data '%s' [%s] only got %ld out of %ld bytes", + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read '%s' [%s] only got %ld out of %ld bytes", req.method.c_str(), req.uri.c_str(), ::strerror(errno), rd, len); } if ( ctxt->st_data == ctxt->st_size ) { @@ -274,7 +336,7 @@ http::basic_http_server<fs>::handler_t::handle_delete(const request_t& req, repl ec = ctxt->unlink(fname.c_str()); if ( !error_code_ok(ec, this->debug) ) { } - ::lib_rtl_output(LIB_RTL_INFO, "+++ %s: Prepared last chunk '%s' %.1f MB", + ::lib_rtl_output(LIB_RTL_INFO, "+++ %s: Last chunk '%s' %.1f MB", req.method.c_str(), req.uri.c_str(), double(ctxt->st_size)/(1024e0*1024e0)); } return write; @@ -288,9 +350,11 @@ http::basic_http_server<fs>::handler_t::handle_delete(const request_t& req, repl req.method.c_str(), ctxt->st_size, net, mb/std::max(1e-6, double(net)/1e3), wrt, mb/std::max(1e-6, double(wrt)/1e3)); + ++monitor->data.numDEL; + monitor->data.bytesDEL += ctxt->st_data; return none; } - ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read data '%s' size:%ld / %ld %s [Inconsistemt context]", + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read '%s' size:%ld / %ld %s [Inconsistemt context]", req.method.c_str(), req.uri.c_str(), rep.bytes_sent, rep.bytes_total, rep.stock_status(rep.status).c_str()); rep.context.reset(); @@ -312,16 +376,19 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t if ( 0 == ret_stat ) { rep = reply_t::stock_reply(reply_t::conflict); rep.headers.emplace_back(constants::error_cause,"Target already exists"); + ++monitor->data.numPUT_error; return write; } else if ( (hdr_date=req.header(constants::date)) == nullptr ) { rep = reply_t::stock_reply(reply_t::bad_request); rep.headers.emplace_back(constants::error_cause,"Missing date header [Protocol Violation]"); + ++monitor->data.numPUT_error; return write; } else if ( (hdr_len=req.header(constants::content_length)) == nullptr ) { rep = reply_t::stock_reply(reply_t::bad_request); rep.headers.emplace_back(constants::error_cause,"Missing content length header [Protocol Violation]"); + ++monitor->data.numPUT_error; return write; } boost::filesystem::path p = boost::filesystem::path(fname).parent_path(); @@ -346,6 +413,7 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t else rep = reply_t::stock_reply(reply_t::bad_request); rep.headers.emplace_back(constants::error_cause,err); + ++monitor->data.numPUT_error; return write; } } @@ -365,6 +433,7 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t if ( !error_code_ok(ec, this->debug) ) { rep = reply_t::stock_reply(reply_t::forbidden); rep.headers.emplace_back(constants::error_cause, "Failed to open file "+fname+" ["+ec.message()+"]"); + ++monitor->data.numPUT_error; } if ( req.content.empty() ) { return write; @@ -372,7 +441,6 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t // This should not happen: The client must first receive the continue! ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Received non-empty data on request to write " "'%s' [Protocol Violation]", req.method.c_str(), fname.c_str()); - //req.content.clear(); return write; } else if ( ctxt && ctxt->st_data < ctxt->st_size && req.content.empty() ) { @@ -384,12 +452,12 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t long wrt = ctxt->write(len, &req.content.at(0)); ctxt->st_data += wrt; if ( wrt != len ) { - ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to write data chunk '%s' " + ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to write '%s' " "[%s] only wrote %ld out of %ld bytes", req.method.c_str(), req.uri.c_str(), ::strerror(errno), wrt, len); + ++monitor->data.numPUT_error; } } - //req.content.clear(); return read; } else if ( ctxt && ctxt->st_data >= ctxt->st_size && rep.status != reply_t::created ) { @@ -397,12 +465,15 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t long net = std::chrono::duration_cast<std::chrono::milliseconds>(req.netio-null).count(); long wrt = std::chrono::duration_cast<std::chrono::milliseconds>(req.handling-null).count(); double mb = double(ctxt->st_size)/(1024e0*1024e0); - ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ %s: Wrote data '%s' %.0f %cB", req.method.c_str(), + ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ %s: Wrote '%s' %.0f %cB", req.method.c_str(), req.uri.c_str(), mb > 10e0 ? mb : mb*1024e0, mb > 10e0 ? 'M' : 'k'); - ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ %s: %ld bytes netio: %ld ms %.1f MB/s wrt: %ld ms %.1f MB/s", + ::lib_rtl_output(LIB_RTL_ALWAYS, "+++ %s: %ld bytes netio: %ld ms %.1f MB/s wrt: %ld ms %.1f MB/s", req.method.c_str(), ctxt->st_size, net, mb/std::max(1e-6, double(net)/1e3), wrt, mb/std::max(1e-6, double(wrt)/1e3)); + ++monitor->data.numPUT; + monitor->data.bytesPUT += ctxt->st_size; + rep.context.reset(); rep = reply_t::stock_reply(reply_t::created); rep.headers.clear(); @@ -422,6 +493,7 @@ http::basic_http_server<fs>::handler_t::handle_put(const request_t& req, reply_t return write; } } + ++monitor->data.numPUT_error; ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: FAILED to update '%s' to state WRITTEN!", req.method.c_str(), req.uri.c_str()); return write; @@ -457,9 +529,12 @@ namespace http { } extern "C" int fdb_fs_file_server(int argc, char** argv) { + std::string srv = "/"+RTL::str_upper(RTL::nodeNameShort())+"/"+RTL::processName(); SrvRun<fs> s; s.create(argc, argv); s.ptr->implementation->dbase.reset(new fs_db(s.server, s.file_dir)); + s.ptr->implementation->monitor.reset(new fs_monitor()); + ::dis_start_serving(srv.c_str()); s.start(); return 0; } -- GitLab From 9ba15756ebf154af18e2d510a5cdbb09623b5615 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Wed, 14 Apr 2021 19:14:24 +0200 Subject: [PATCH 16/17] Fix to fifo logger. Fix storage file server --- Online/Dataflow/src/framework/DiskReader.cpp | 16 ++- Online/FarmConfig/job/Controller.sh | 3 +- Online/HTTP/HTTP/HttpServer.h | 19 ++- Online/HTTP/src/HttpServer.cpp | 5 + Online/OnlineBase/CMakeLists.txt | 9 ++ Online/OnlineBase/src/LOG/FifoLog.cpp | 113 +++++++++++------- Online/OnlineBase/src/RTL/Logger.cpp | 24 +++- Online/OnlineKernel/CMakeLists.txt | 6 - Online/OnlineKernel/main/checkpoint.cpp | 21 ---- Online/OnlineKernel/main/gentest.cpp | 52 -------- Online/OnlineKernel/main/mbm_remove.cpp | 28 ----- Online/OnlineKernel/main/wt.cpp | 31 ----- Online/PCIE40Data/src/pcie40decoder.cpp | 29 ++++- Online/ROLogger/kafka/OutputListener.cpp | 19 ++- Online/ROLogger/kafka/OutputListener.h | 1 + Online/ROLogger/kafka/OutputLogger.cpp | 6 + .../SmiController/scripts/EventProcessor.py | 3 +- .../SmiController/scripts/EventProcessor.sh | 3 +- Online/SmiController/scripts/MBMMonMulti.sh | 1 + Online/SmiController/scripts/MBMMonSingle.sh | 1 + Online/SmiController/scripts/RCVMon.sh | 1 + Online/SmiController/scripts/TestMEPProd.sh | 9 ++ Online/SmiController/scripts/configure.sh | 7 +- Online/SmiController/scripts/runDummyTask.sh | 2 +- Online/SmiController/scripts/runTask.sh | 8 +- Online/Storage/CMakeLists.txt | 9 +- Online/Storage/src/server/fdb_db_server.cpp | 55 +++++---- Online/Storage/src/server/fdb_dbase.cpp | 28 ++--- Online/Storage/src/server/fdb_fs_server.cpp | 54 +++++++-- Online/Tell1Data/src/RawFile.cpp | 6 +- Online/TestBeam/job/Controller.sh | 4 +- Online/TestBeam/job/runTask.sh | 6 +- 32 files changed, 317 insertions(+), 262 deletions(-) delete mode 100644 Online/OnlineKernel/main/checkpoint.cpp delete mode 100755 Online/OnlineKernel/main/gentest.cpp delete mode 100755 Online/OnlineKernel/main/mbm_remove.cpp delete mode 100755 Online/OnlineKernel/main/wt.cpp diff --git a/Online/Dataflow/src/framework/DiskReader.cpp b/Online/Dataflow/src/framework/DiskReader.cpp index 8fc1e2685..c61a97b76 100644 --- a/Online/Dataflow/src/framework/DiskReader.cpp +++ b/Online/Dataflow/src/framework/DiskReader.cpp @@ -482,12 +482,24 @@ DiskReader::load_event_data(RawFile::Allocator& allocator, RawFile& file) { return { size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE }; } mdf_hdr = (EventHeader*)data_ptr; - if ( mdf_hdr->recordSize() + data_size > alloc_size ) { + if ( !mdf_hdr->is_mdf() ) { + warning("Corrupted file found: %s at position %ld. Skip %ld bytes.", + file.cname(), position, long(file.data_size())-file.position()); + file.reset(true); + return { size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE }; + } + else if ( mdf_hdr->recordSize() + data_size > alloc_size ) { file.position(position); return { size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE }; } status = file.read(data_ptr + peek, mdf_hdr->recordSize() - peek); - if ( status < mdf_hdr->recordSize() - peek ) { + if ( status < 0 ) { + warning("Corrupted file found: %s at position %ld. Skip %ld bytes.", + file.cname(), position, long(file.data_size())-file.position()); + file.reset(true); + return { size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE }; + } + else if ( status < (mdf_hdr->recordSize() - peek) ) { file.reset(true); return { size_t(data_size), num_evts, RawFile::MDF_INPUT_TYPE }; } diff --git a/Online/FarmConfig/job/Controller.sh b/Online/FarmConfig/job/Controller.sh index 28305cd5b..4e89e04a7 100755 --- a/Online/FarmConfig/job/Controller.sh +++ b/Online/FarmConfig/job/Controller.sh @@ -10,7 +10,7 @@ # ========================================================================= HOST=`hostname -s | tr a-z A-Z`; HOST_LONG=`hostname -f | tr a-z A-Z`; -echo "ERROR DIM_DNS_NODE: ${DIM_DNS_NODE}" +# echo "ERROR DIM_DNS_NODE: ${DIM_DNS_NODE}" # #if test "${HOST}" = "N3080501"; then # export SMI_DNS=devpvsscc7; @@ -42,6 +42,7 @@ if test -z "${DIM_DNS_NODE}"; then export DIM_DNS_NODE=${HOST_LONG}; fi; # +# exec -a ${UTGID} `which gentest.exe` libSmiController.so smi_controller \ -print=4 \ -logger=fifo \ diff --git a/Online/HTTP/HTTP/HttpServer.h b/Online/HTTP/HTTP/HttpServer.h index 196877edf..b54383d2d 100644 --- a/Online/HTTP/HTTP/HttpServer.h +++ b/Online/HTTP/HTTP/HttpServer.h @@ -281,9 +281,10 @@ namespace http { typedef std::vector<std::shared_ptr<std::thread> > Threads; enum continue_action { none, write, read, close }; - - typedef HttpRequest request_t; - typedef HttpReply reply_t; + + typedef std::atomic<long> counter_t; + typedef HttpRequest request_t; + typedef HttpReply reply_t; /// Object Lock to ensure we have no race conditions when editing the call-map std::mutex lock; @@ -299,10 +300,18 @@ namespace http { HttpConnectionManager manager; /// The next socket to be accepted. boost::asio::ip::tcp::socket socket; + /// Number of currently active connections + counter_t num_connections {0}; + /// Number of ever opened connections + counter_t num_connections_opened {0}; + /// Number of ever closed connections + counter_t num_connections_closed {0}; + /// Number of ever stopped connections + counter_t num_connections_stopped {0}; /// Default buffer size of the connection - size_t buffer_size = 16*1024; + size_t buffer_size {16*1024}; /// Enable debugging if necessary - int debug = 0; + int debug {0}; protected: /// Perform an asynchronous accept operation. diff --git a/Online/HTTP/src/HttpServer.cpp b/Online/HTTP/src/HttpServer.cpp index 45c464f6e..89109effd 100644 --- a/Online/HTTP/src/HttpServer.cpp +++ b/Online/HTTP/src/HttpServer.cpp @@ -55,10 +55,14 @@ HttpConnection::HttpConnection(asio::ip::tcp::socket s, request.start = system_clock::now(); request.netio = std::chrono::time_point<system_clock>(system_clock::duration::zero()); request.handling = std::chrono::time_point<system_clock>(system_clock::duration::zero()); + ++handler.num_connections_opened; + ++handler.num_connections; } /// Default destructor HttpConnection::~HttpConnection() { + ++handler.num_connections_closed; + --handler.num_connections; if ( handler.debug ) { std::cout << "HttpConnection: DESTRUCT." << std::endl << std::flush; } @@ -94,6 +98,7 @@ void HttpConnection::stop() { if ( socket.is_open() ) { system::error_code ec; socket.close(ec); + ++handler.num_connections_stopped; if ( ec ) { std::cout << "HttpConnection: STOP: " << ec.message() << std::endl << std::flush; } diff --git a/Online/OnlineBase/CMakeLists.txt b/Online/OnlineBase/CMakeLists.txt index 6e788c0bb..5d8ce0fb5 100755 --- a/Online/OnlineBase/CMakeLists.txt +++ b/Online/OnlineBase/CMakeLists.txt @@ -59,6 +59,15 @@ gaudi_add_python_module(_fifo_log # # Need to cast out warnings created by Python.h target_compile_options(_fifo_log PRIVATE -Wno-register) +#=============================================================================== +gaudi_add_executable(gentest main/gentest.cpp LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt) +gaudi_add_executable(genRunner main/genRunner.cpp LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt) +gaudi_add_executable(genPython main/genPython.cpp LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt ${PYTHON_LIBRARIES} ) +gaudi_add_executable(mbm_remove main/mbm_remove.cpp LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt) +gaudi_add_executable(checkpoint main/checkpoint.cpp LINK_LIBRARIES OnlineBase ${CMAKE_DL_LIBS} -lrt) +# +gaudi_add_executable(onlinekernel_test main/wt.cpp LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt) + #=============================================================================== # gaudi_install_python_modules() diff --git a/Online/OnlineBase/src/LOG/FifoLog.cpp b/Online/OnlineBase/src/LOG/FifoLog.cpp index 719c4c082..2556d3ccd 100644 --- a/Online/OnlineBase/src/LOG/FifoLog.cpp +++ b/Online/OnlineBase/src/LOG/FifoLog.cpp @@ -48,6 +48,8 @@ public: /// Append (unlocked) single character to output buffer void append(int stream_id, char c) { switch(c) { + case '\0': + case '\r': case '\n': flush_line(stream_id); break; @@ -96,7 +98,7 @@ public: int push(int stream_id, const wchar_t* format, LOGGER_VA_LIST args) { wchar_t text[4096]; int len = ::vswprintf(text, sizeof(text), format, args); - text[sizeof(text)-1] = 0; + text[sizeof(text)/sizeof(wchar_t)-1] = 0; va_end(args); this->push(stream_id, text, len*sizeof(wchar_t)); return len; @@ -263,7 +265,7 @@ using namespace fifolog; typedef Logger::Implementation logger_imp; string logger_imp::fifo_name; -string logger_imp::systag; +string logger_imp::systag = "SYSTEM"; string logger_imp::utgid; /// Anonymous namespace for helpers @@ -285,8 +287,8 @@ namespace { } inline logger_imp& log() { - //static LibCLogger s_log; - static PollLogger s_log; + static LibCLogger s_log; + //static PollLogger s_log; return s_log; } @@ -315,8 +317,8 @@ namespace { if ( fifo.empty() ) { fifo = ::getenv("LOGFIFO") ? ::getenv("LOGFIFO") : ""; } - if ( tag.empty() ) { - tag = ::getenv("PARTITION_NAME") ? ::getenv("PARTITION_NAME") : ""; + if ( tag.empty() || tag == "SYSTEM" ) { + tag = ::getenv("PARTITION_NAME") ? ::getenv("PARTITION_NAME") : tag; } if ( tag.empty() ) { tag = "SYSTEM"; @@ -569,7 +571,7 @@ void LibCLogger::init(const string& f, const string& u, const string& t) { ::close(this->fifo_fd); throw runtime_error(text); } - this->push(STDOUT,"LIBC logger initialized!!!\n"); + //this->push(STDOUT,"LIBC logger initialized!!!\n"); } } @@ -729,7 +731,7 @@ extern "C" void fifolog_set_utgid(const char* new_utgid) { /// Set new tag value extern "C" void fifolog_set_tag(const char* new_tag) { auto& log = logger(false); - logger_imp::systag = new_tag ? new_tag : "SYSTEM"; + logger_imp::systag = new_tag && ::strlen(new_tag)>0 ? new_tag : "SYSTEM"; if ( log.get() ) log->imp->rebuild_trailer(); } @@ -740,6 +742,10 @@ extern "C" int fifolog_set_fifo(const char* fifo) { logger_imp::fifo_name = fifo; return 1; } + else if ( log.get() ) { + log->imp->rebuild_trailer(); + return 1; + } ::fprintf(stderr,"Failed to set output fifo: %s [%s] logger %s initialized.\n", fifo, ::strerror(errno), log.get() ? "already" : "NOT"); errno = ENOENT; @@ -756,7 +762,7 @@ extern "C" void fifolog_finalize_logger() { } } -extern "C" int fputc(int c, FILE *stream) { +extern "C" int local__fputc(int c, FILE *stream) { if ( logger(false).get() ) { if ( stream == stdout ) return log().push(logger_imp::STDOUT, c); @@ -766,15 +772,15 @@ extern "C" int fputc(int c, FILE *stream) { return funcs().real_fputc(c, stream); } -extern "C" int putc(int c, FILE *stream) { +extern "C" int local__putc(int c, FILE *stream) { return ::fputc(c, stream); } -extern "C" int putchar(int c) { +extern "C" int local__putchar(int c) { return ::fputc(c, stdout); } -extern "C" int fputs(const char *str, FILE *stream) { +extern "C" int local__fputs(const char *str, FILE *stream) { if ( logger(false).get() ) { if ( stream == stdout ) return log().push(logger_imp::STDOUT, str); @@ -784,11 +790,11 @@ extern "C" int fputs(const char *str, FILE *stream) { return funcs().real_fputs(str, stream); } -extern "C" int puts(const char* str) { +extern "C" int local__puts(const char* str) { return ::fputs(str, stdout); } -extern "C" ssize_t write(int fd, const void *buf, size_t count) { +extern "C" ssize_t local__write(int fd, const void *buf, size_t count) { if ( logger(false).get() ) { switch(fd) { case STDOUT_FILENO: return log().push(logger_imp::STDOUT, buf, count); @@ -799,7 +805,7 @@ extern "C" ssize_t write(int fd, const void *buf, size_t count) { return funcs().real_write(fd, buf, count); } -extern "C" size_t fwrite(const void *str, size_t size, size_t nmemb, FILE *stream) { +extern "C" size_t local__fwrite(const void *str, size_t size, size_t nmemb, FILE *stream) { if ( logger(false).get() ) { if ( stream == stdout ) return log().push(logger_imp::STDOUT, str, size*nmemb); @@ -809,19 +815,19 @@ extern "C" size_t fwrite(const void *str, size_t size, size_t nmemb, FILE *strea return funcs().real_fwrite(str, size, nmemb, stream); } -extern "C" int vprintf(const char *format, LOGGER_VA_LIST args) { +extern "C" int local__vprintf(const char *format, LOGGER_VA_LIST args) { return logger(false).get() ? log().push(logger_imp::STDOUT, format, args) : funcs().real_vprintf(format, args); } -extern "C" int vwprintf(const wchar_t *format, LOGGER_VA_LIST args) { +extern "C" int local__vwprintf(const wchar_t *format, LOGGER_VA_LIST args) { return logger(false).get() ? log().push(logger_imp::STDOUT, format, args) : funcs().real_vwprintf(format, args); } -extern "C" int vdprintf(int fd, const char *format, LOGGER_VA_LIST args) { +extern "C" int local__vdprintf(int fd, const char *format, LOGGER_VA_LIST args) { if ( logger(false).get() ) { switch(fd) { case STDOUT_FILENO: return log().push(logger_imp::STDOUT, format, args); @@ -832,7 +838,7 @@ extern "C" int vdprintf(int fd, const char *format, LOGGER_VA_LIST args) { return funcs().real_vdprintf(fd, format, args); } -extern "C" int vfprintf(FILE* stream, const char *format, LOGGER_VA_LIST args) { +extern "C" int local__vfprintf(FILE* stream, const char *format, LOGGER_VA_LIST args) { if ( logger(false).get() ) { if ( stream == stdout ) return log().push(logger_imp::STDOUT, format, args); @@ -842,21 +848,7 @@ extern "C" int vfprintf(FILE* stream, const char *format, LOGGER_VA_LIST args) return funcs().real_vfprintf(stream, format, args); } -extern "C" int __vfprintf_chk(FILE* stream, int flag, const char *format, LOGGER_VA_LIST args) { - if ( logger(false).get() ) { - if ( stream == stdout ) - return log().push(logger_imp::STDOUT, format, args); - else if ( stream == stderr ) - return log().push(logger_imp::STDERR, format, args); - } - return funcs().real_vfprintf_chk(stream, flag, format, args); -} - -extern "C" int __vprintf_chk(int flag, const char *format, LOGGER_VA_LIST args) { - return __vfprintf_chk(stdout, flag, format, args); -} - -extern "C" int printf(const char *format, ...) { +extern "C" int local__printf(const char *format, ...) { LOGGER_VA_LIST args; va_start(args, format); int ret = ::vprintf(format, args); @@ -864,7 +856,7 @@ extern "C" int printf(const char *format, ...) { return ret; } -extern "C" int wprintf(const wchar_t *format, ...) { +extern "C" int local__wprintf(const wchar_t *format, ...) { LOGGER_VA_LIST args; va_start(args, format); int ret = ::vwprintf(format, args); @@ -872,7 +864,7 @@ extern "C" int wprintf(const wchar_t *format, ...) { return ret; } -extern "C" int dprintf(int fd, const char *format, ...) { +extern "C" int local__dprintf(int fd, const char *format, ...) { LOGGER_VA_LIST args; va_start(args, format); int ret = ::vdprintf(fd, format, args); @@ -880,7 +872,7 @@ extern "C" int dprintf(int fd, const char *format, ...) { return ret; } -extern "C" int fprintf(FILE* stream, const char *format, ...) { +extern "C" int local__fprintf(FILE* stream, const char *format, ...) { LOGGER_VA_LIST args; va_start(args, format); int ret = ::vfprintf(stream, format, args); @@ -888,18 +880,57 @@ extern "C" int fprintf(FILE* stream, const char *format, ...) { return ret; } -extern "C" int __printf_chk(int flag, const char *format, ...) { + +extern "C" int local__vfprintf_chk(FILE* stream, int flag, const char *format, LOGGER_VA_LIST args) { + if ( logger(false).get() ) { + if ( stream == stdout ) + return log().push(logger_imp::STDOUT, format, args); + else if ( stream == stderr ) + return log().push(logger_imp::STDERR, format, args); + } + return funcs().real_vfprintf_chk(stream, flag, format, args); +} + +extern "C" int local__vprintf_chk(int flag, const char *format, LOGGER_VA_LIST args) { + return local__vfprintf_chk(stdout, flag, format, args); +} + +extern "C" int local__printf_chk(int flag, const char *format, ...) { LOGGER_VA_LIST args; va_start(args, format); - int ret = __vprintf_chk(flag, format, args); + int ret = local__vprintf_chk(flag, format, args); va_end(args); return ret; } -extern "C" int __fprintf_chk(FILE* stream, int flag, const char *format, ...) { +extern "C" int local__fprintf_chk(FILE* stream, int flag, const char *format, ...) { LOGGER_VA_LIST args; va_start(args, format); - int ret = __vfprintf_chk(stream, flag, format, args); + int ret = local__vfprintf_chk(stream, flag, format, args); va_end(args); return ret; } + + +__asm__ (".global fputc; .type fputc,@function; fputc = local__fputc"); +//__asm__ (".global putc; .type putc,@function; putc = local__ putc"); +//__asm__ (".global putchar; .type putchar,@function; putchar = local__ putchar"); +__asm__ (".global fputs; .type fputs,@function; fputs = local__fputs"); +__asm__ (".global write; .type write,@function; write = local__write"); +__asm__ (".global fputs; .type fputs,@function; fputs = local__fputs"); +__asm__ (".global puts; .type puts,@function; puts = local__puts"); +__asm__ (".global fwrite; .type fwrite,@function; fwrite = local__fwrite"); + +__asm__ (".global vprintf; .type vprintf,@function; vprintf = local__vprintf"); +__asm__ (".global vwprintf; .type vwprintf,@function; vwprintf = local__vwprintf"); +__asm__ (".global vdprintf; .type vdprintf,@function; vdprintf = local__vdprintf"); +__asm__ (".global vfprintf; .type vfprintf,@function; vfprintf = local__vfprintf"); +__asm__ (".global printf; .type printf,@function; printf = local__printf"); +__asm__ (".global wprintf; .type wprintf,@function; wprintf = local__wprintf"); +__asm__ (".global dprintf; .type dprintf,@function; dprintf = local__dprintf"); +__asm__ (".global fprintf; .type fprintf,@function; fprintf = local__fprintf"); +__asm__ (".global vfprintf_chk; .type vfprintf_chk,@function; vfprintf_chk = local__vfprintf_chk"); +__asm__ (".global __vfprintf_chk; .type __vfprintf_chk,@function; __vfprintf_chk = local__vfprintf_chk"); +__asm__ (".global __printf_chk; .type __printf_chk,@function; __printf_chk = local__printf_chk"); +__asm__ (".global __fprintf_chk; .type __fprintf_chk,@function; __fprintf_chk = local__fprintf_chk"); +__asm__ (".global __vfprintf_chk; .type __vfprintf_chk,@function; __vfprintf_chk = local__vfprintf_chk"); diff --git a/Online/OnlineBase/src/RTL/Logger.cpp b/Online/OnlineBase/src/RTL/Logger.cpp index 175b47352..99d40ed0c 100644 --- a/Online/OnlineBase/src/RTL/Logger.cpp +++ b/Online/OnlineBase/src/RTL/Logger.cpp @@ -231,13 +231,24 @@ size_t Logger::LogDevice::formatHeader(char* buffer, size_t buff_len, int severi /// Calls the display action with a given severity level size_t Logger::LogDevice::printmsg(int severity, const char* source, const char* msg) const { - char header[2048]; - size_t len = formatHeader(header, sizeof(header), severity, source); { - lock_guard<std::mutex> lock(*device_lock); - len = ::fprintf(stdout, "%s %s\n", header, msg); - ::fflush(stdout); + char text[4096], header[2048]; + size_t len1 = formatHeader(header, sizeof(header), severity, source); + size_t len2 = ::strlen(msg); + if ( len1+len2+3 < sizeof(text) ) { + ::memcpy(text, header, len1); + text[len1] = ' '; + ::memcpy(text+len1+1, msg, len2); + size_t len = len1+len2+1; + if ( msg[len2-1] != '\n' && msg[len2-2] != '\n' ) { + text[len] = '\n'; + ++len; + } + { + lock_guard<std::mutex> lock(*device_lock); + return ::write(STDOUT_FILENO, text, len); + } } - return len+1; // '1' from fputc + return 0; // '1' from fputc } /// Calls the display action with a given severity level @@ -326,6 +337,7 @@ void Logger::install_fifolog(const char* fifo) { void Logger::install_fifolog(const char* fifo, const log_args& args) { if ( fifo && fifo[0] ) { if ( 0 == ::fifolog_set_fifo(fifo) ) ::exit(1); + ::fifolog_set_utgid(RTL::processName().c_str()); ::fifolog_initialize_logger(); } if ( args.debug ) diff --git a/Online/OnlineKernel/CMakeLists.txt b/Online/OnlineKernel/CMakeLists.txt index fa40ee047..78d9c995b 100644 --- a/Online/OnlineKernel/CMakeLists.txt +++ b/Online/OnlineKernel/CMakeLists.txt @@ -35,12 +35,6 @@ gaudi_add_dictionary(OnlineKernel dict/dictionary.h dict/dictionary.xml INCLUDE_DIRS PythonLibs LINK_LIBRARIES OnlineKernel PythonLibs) # -gaudi_add_executable(gentest main/gentest.cpp LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt) -gaudi_add_executable(checkpoint main/checkpoint.cpp LINK_LIBRARIES OnlineBase ${CMAKE_DL_LIBS} -lrt) -gaudi_add_executable(mbm_remove main/mbm_remove.cpp LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt) -# -gaudi_add_executable(onlinekernel_test main/wt.cpp LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt) -# # Disable generation of ConfUserDB (must be done before gaudi_install_python_modules) set_directory_properties(PROPERTIES CONFIGURABLE_USER_MODULES None) # diff --git a/Online/OnlineKernel/main/checkpoint.cpp b/Online/OnlineKernel/main/checkpoint.cpp deleted file mode 100644 index a9d494bd5..000000000 --- a/Online/OnlineKernel/main/checkpoint.cpp +++ /dev/null @@ -1,21 +0,0 @@ -//========================================================================== -// LHCb Online software suite -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see OnlineSys/LICENSE. -// -//-------------------------------------------------------------------------- -// -// Author : Markus Frank -//========================================================================== -#define main checkpointing_main -#include "gentest.cpp" -#undef main -extern void CheckpointRestoreWrapper__init_instance(int argc, char** argv); - -int main (int argc, char** argv) { - CheckpointRestoreWrapper__init_instance(argc, argv); - return checkpointing_main(argc,argv); -} diff --git a/Online/OnlineKernel/main/gentest.cpp b/Online/OnlineKernel/main/gentest.cpp deleted file mode 100755 index 99988aab4..000000000 --- a/Online/OnlineKernel/main/gentest.cpp +++ /dev/null @@ -1,52 +0,0 @@ -//========================================================================== -// LHCb Online software suite -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see OnlineSys/LICENSE. -// -//-------------------------------------------------------------------------- -// -// Author : Markus Frank -//========================================================================== -#include "RTL/DllAccess.h" -#include <iostream> -#include <cerrno> - -/// Generic main program to start any process -/** - * Generic main program to start any process - * by loading a library and executing a - * function within - * - * \author M.Frank - * \version 1.0 - */ -int main (int argc, char** argv) { - if ( argc >= 3 ) { - void* handle = LOAD_LIB( argv[1] ); - if ( handle ) { - Function fun(GETPROC(handle, argv[2])); - if ( fun.function ) { - return (*fun.function)(argc-2, &argv[2]); - } - // The required function is not in the loaded image. - // Try to load it directly from the executable - Function f1(GETPROC(0, argv[2])); - if ( f1.function ) { - std::cout << "[WARNING] Executing function " << argv[2] - << " from exe rather than image " << std::endl; - return (*f1.function)(argc-2, &argv[2]); - } - std::cout << "[ERROR] Failed to access test procedure: '" << argv[2] << "'" << std::endl; - std::cout << "[ERROR] Error: " << DLERROR << std::endl; - return EINVAL; - } - std::cout << "[ERROR] Failed to load test library: '" << argv[1] << "'" << std::endl; - std::cout << "[ERROR] Error: " << DLERROR << std::endl; - return EINVAL; - } - std::cout << "[ERROR] usage: gentest.exe <library-name> <function-name> -arg [-arg]" << std::endl; - return EINVAL; -} diff --git a/Online/OnlineKernel/main/mbm_remove.cpp b/Online/OnlineKernel/main/mbm_remove.cpp deleted file mode 100755 index bbc209c55..000000000 --- a/Online/OnlineKernel/main/mbm_remove.cpp +++ /dev/null @@ -1,28 +0,0 @@ -//========================================================================== -// LHCb Online software suite -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see OnlineSys/LICENSE. -// -//-------------------------------------------------------------------------- -// -// Author : Markus Frank -//========================================================================== -#include "RTL/DllAccess.h" -#include <iostream> - -int main (int argc, char** argv) { - void* handle = LOAD_LIB2( "OnlineKernel" ); - if ( 0 != handle ) { - Function fun(GETPROC(handle,"mbm_remove")); - if ( fun.function ) { - return (*fun.function)(argc, argv); - } - std::cout << "Failed to access test procedure!" << std::endl; - } - std::cout << "Failed to load test library!" << std::endl; - std::cout << "Error: " << DLERROR << std::endl; - return 0; -} diff --git a/Online/OnlineKernel/main/wt.cpp b/Online/OnlineKernel/main/wt.cpp deleted file mode 100755 index e6a77bf30..000000000 --- a/Online/OnlineKernel/main/wt.cpp +++ /dev/null @@ -1,31 +0,0 @@ -//========================================================================== -// LHCb Online software suite -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see OnlineSys/LICENSE. -// -//-------------------------------------------------------------------------- -// -// Author : Markus Frank -//========================================================================== -#include "RTL/DllAccess.h" -#include <iostream> - -using OnlineBase::FuncPtrCast; - -int main (int argc, char** argv) { - void* handle = LOAD_LIB2("OnlineKernel"); - if ( 0 != handle ) { - typedef int (*func_t)(int, char**); - func_t fun = FuncPtrCast<func_t>(GETPROC(handle, argv[1])); - if ( fun ) { - return (*fun)(argc-1, &argv[1]); - } - std::cout << "Failed to access test procedure!" << std::endl; - } - std::cout << "Failed to load test library!" << std::endl; - std::cout << "Error: " << DLERROR << std::endl; - return 0; -} diff --git a/Online/PCIE40Data/src/pcie40decoder.cpp b/Online/PCIE40Data/src/pcie40decoder.cpp index 0f09bfab7..899a9beb2 100644 --- a/Online/PCIE40Data/src/pcie40decoder.cpp +++ b/Online/PCIE40Data/src/pcie40decoder.cpp @@ -355,14 +355,38 @@ void decoder_t::decode(std::unique_ptr<event_collection_t>& ev_coll, size_t num_err_packing = 0; size_t num_fragments = mep->num_source; if ( num_fragments > 0 ) { + const multi_fragment_t *last_mfp = nullptr; size_t packing = mep->multi_fragment(0)->packingFactor(); auto ec = (event_collection_writer_t*)initialize(ev_coll, packing); ec->mep = mep; ec->length = packing; for(uint32_t i=0; i<num_fragments; ++i) { - const multi_fragment_t *mfp = mep->multi_fragment(i); - const multi_fragment_t::header_t& hdr = mfp->header; + const auto* mfp = mep->multi_fragment(i); + const auto& hdr = mfp->header; uint16_t src_id = hdr.source_id; + if ( !mfp->is_valid() ) { + implementation->print(ERROR, + "+++ SKIP CORRUPTED MFP[%2d] at %p len:%6d %p magic:%04X " + "pack:%3d eid:%8ld src:%3d vsn:%d align:%d\n", + i, (void*)mfp, int(hdr.size), + (void*)((char*)mfp + hdr.size), + int(hdr.magic), int(hdr.packing), long(hdr.event_id), + int(src_id), int(hdr.version), + int(hdr.alignment)); + if ( last_mfp ) { + const auto& lhdr = last_mfp->header; + uint16_t lsrc_id = lhdr.source_id; + implementation->print(ERROR, + "+++ LAST GOOD MFP[%2d] at %p len:%6d %p magic:%04X " + "pack:%3d eid:%8ld src:%3d vsn:%d align:%d\n", + i, (void*)last_mfp, int(lhdr.size), + (void*)((char*)last_mfp + lhdr.size), + int(lhdr.magic), int(lhdr.packing), long(lhdr.event_id), + int(lsrc_id), int(lhdr.version), + int(lhdr.alignment)); + } + continue; + } if ( debug ) { implementation->print(PRINT, "+++ Reading mfp[%2d] at %p len:%6d %p magic:%04X " @@ -381,6 +405,7 @@ void decoder_t::decode(std::unique_ptr<event_collection_t>& ev_coll, if ( !source_selector || source_selector(src_id¶ms::sourceid_TOP5) ) { num_banks += implementation->link_fragment(ec, mfp, debug); } + last_mfp = mfp; } if ( num_err_packing > 0 ) { implementation->print(ERROR, diff --git a/Online/ROLogger/kafka/OutputListener.cpp b/Online/ROLogger/kafka/OutputListener.cpp index 1eea5d071..bea09ee24 100644 --- a/Online/ROLogger/kafka/OutputListener.cpp +++ b/Online/ROLogger/kafka/OutputListener.cpp @@ -129,12 +129,12 @@ void OutputListener::print_msg(const char* time_stamp, time_stamp ? time_stamp : "", host ? host : ""); if ( counter ) - len += ::snprintf(text+len,sizeof(text)-len,"%9s%-7s",counter,tag); + len += ::snprintf(text+len,sizeof(text)-len,"%-9s%-7s",counter,tag); else len += ::snprintf(text+len,sizeof(text)-len,"%-7s",tag); } len += ::snprintf(text+len,sizeof(text)-len,"%-34s%s\n", - utgid ? utgid : "", message ? message : ""); + utgid ? utgid : "", message ? message : ""); if ( have_colors ) { graphics::white(); graphics::plain(); @@ -164,8 +164,15 @@ void OutputListener::handle_payload(const char* /* topic */, int match = *(long*)payload == PAYLOAD_MATCH; if ( match ) { + std::string raw_msg; *(time_stamp+10) = ' '; *(time_stamp+19) = 0; + if ( print_raw ) { + raw_msg.clear(); + raw_msg.reserve(plen+1); + raw_msg.insert(raw_msg.end(), payload, payload+plen); + raw_msg.push_back('\n'); + } char* message = mark_start(time_stamp+20, MESSAGE_TAG, m_tag_len); char* msg_end = mark_end(message); size_t len = msg_end-message-3; @@ -239,7 +246,13 @@ void OutputListener::handle_payload(const char* /* topic */, } } if ( match_utgid && match_host ) { - print_msg(time_stamp, message, systag, utgid, host, physical, counter); + if ( print_raw ) { + ::fwrite(raw_msg.c_str(), 1, raw_msg.length(), stdout); + ::fflush(stdout); + } + else { + print_msg(time_stamp, message, systag, utgid, host, physical, counter); + } } if ( msg_end ) *msg_end = '\"'; if ( phys_end ) *phys_end = '\"'; diff --git a/Online/ROLogger/kafka/OutputListener.h b/Online/ROLogger/kafka/OutputListener.h index cb9c1fcc3..6d0e33346 100644 --- a/Online/ROLogger/kafka/OutputListener.h +++ b/Online/ROLogger/kafka/OutputListener.h @@ -43,6 +43,7 @@ namespace kafka { Matches node_match; Matches utgid_match; Matches message_veto; + bool print_raw = false; bool print_stats = false; bool print_counter = false; bool simple_msg = false; diff --git a/Online/ROLogger/kafka/OutputLogger.cpp b/Online/ROLogger/kafka/OutputLogger.cpp index 848241601..c1a5ae161 100644 --- a/Online/ROLogger/kafka/OutputLogger.cpp +++ b/Online/ROLogger/kafka/OutputLogger.cpp @@ -51,6 +51,7 @@ namespace { " -b <broker> Set DIM message broker. \n" " -O <level> Set RTL output level (1...4). \n" " -P Print statistics \n" + " -R Print RAW messages \n" " -m <reg-ex> Add node matching regular expression. \n" " -V <reg-ex> Veto messages matching regular expression.\n"); return 0; @@ -69,6 +70,7 @@ extern "C" int run_output_logger (int argc, char **argv) { bool print_help = false; bool print_stats = false; bool print_counter = false; + bool print_raw = false; bool simple_msg = false; bool have_colors = false; size_t rows = 0, cols = 0; @@ -105,6 +107,9 @@ extern "C" int run_output_logger (int argc, char **argv) { case 'O': output_level = ::atol(argv[++i]); break; + case 'R': + print_raw = true; + break; case 'V': value = argv[++i]; ::lib_rtl_output(LIB_RTL_ALWAYS,"+++ Adding message veto: %s\n",value.c_str()); @@ -162,6 +167,7 @@ extern "C" int run_output_logger (int argc, char **argv) { listener.message_veto = std::move(message_veto); listener.node_match = std::move(node_matches); listener.utgid_match = std::move(utgid_matches); + listener.print_raw = print_raw; listener.print_stats = print_stats; listener.print_counter = print_counter; listener.have_colors = have_colors; diff --git a/Online/SmiController/scripts/EventProcessor.py b/Online/SmiController/scripts/EventProcessor.py index a8e3bbb57..bee5242bd 100644 --- a/Online/SmiController/scripts/EventProcessor.py +++ b/Online/SmiController/scripts/EventProcessor.py @@ -22,7 +22,8 @@ application = GaudiOnline.Passthrough(outputLevel=OnlineEnvBase.OutputLevel, partitionID=OnlineEnvBase.PartitionID, classType=GaudiOnline.Class1) application.setup_fifolog() -application.log(GaudiOnline.MSG_INFO,'+++ OnlineEnv: %s Level:%d',OnlineEnvBase.__file__,OnlineEnvBase.OutputLevel) +application.log(GaudiOnline.MSG_INFO, '+++ OnlineEnv: %s Level:%d',OnlineEnvBase.__file__,OnlineEnvBase.OutputLevel) +application.log(GaudiOnline.MSG_ERROR,'+++ OnlineEnv: %s Level:%d',OnlineEnvBase.__file__,OnlineEnvBase.OutputLevel) application.setup_mbm_access('Events', True) writer = None writer = application.setup_mbm_output('EventOutput') diff --git a/Online/SmiController/scripts/EventProcessor.sh b/Online/SmiController/scripts/EventProcessor.sh index 5a78fb01d..deb6226a2 100644 --- a/Online/SmiController/scripts/EventProcessor.sh +++ b/Online/SmiController/scripts/EventProcessor.sh @@ -8,4 +8,5 @@ # Date: 20/05/2013 # # ========================================================================= -exec -a ${UTGID} python `which gaudirun.py` EventProcessor.py --application=OnlineEvents +# +exec -a ${UTGID} genPython.exe `which gaudirun.py` EventProcessor.py --application=OnlineEvents; diff --git a/Online/SmiController/scripts/MBMMonMulti.sh b/Online/SmiController/scripts/MBMMonMulti.sh index ec1c05e34..2b7d65a24 100755 --- a/Online/SmiController/scripts/MBMMonMulti.sh +++ b/Online/SmiController/scripts/MBMMonMulti.sh @@ -8,4 +8,5 @@ # Date: 20/05/2013 # # ========================================================================= +# `dataflow_task Class0` `dataflow_default_options ${TASK_TYPE}` diff --git a/Online/SmiController/scripts/MBMMonSingle.sh b/Online/SmiController/scripts/MBMMonSingle.sh index 71f6ece82..56ccd112c 100755 --- a/Online/SmiController/scripts/MBMMonSingle.sh +++ b/Online/SmiController/scripts/MBMMonSingle.sh @@ -8,5 +8,6 @@ # Date: 20/05/2013 # # ========================================================================= +# `dataflow_task Class0` `dataflow_default_options ${TASK_TYPE}` diff --git a/Online/SmiController/scripts/RCVMon.sh b/Online/SmiController/scripts/RCVMon.sh index c3e616d0a..ad3d05210 100755 --- a/Online/SmiController/scripts/RCVMon.sh +++ b/Online/SmiController/scripts/RCVMon.sh @@ -8,4 +8,5 @@ # Date: 20/05/2013 # # ========================================================================= +# `dataflow_task Class1` `dataflow_default_options ${TASK_TYPE}` diff --git a/Online/SmiController/scripts/TestMEPProd.sh b/Online/SmiController/scripts/TestMEPProd.sh index 48b19a903..5875196c4 100644 --- a/Online/SmiController/scripts/TestMEPProd.sh +++ b/Online/SmiController/scripts/TestMEPProd.sh @@ -1,3 +1,12 @@ #!/bin/bash +# ========================================================================= # +# Generic farm task startup script +# +# Author M.Frank +# Version: 1.0 +# Date: 20/05/2013 +# +# ========================================================================= +# `dataflow_task Class2` `dataflow_default_options ${TASK_TYPE}` diff --git a/Online/SmiController/scripts/configure.sh b/Online/SmiController/scripts/configure.sh index b71326ef3..bdaebb756 100755 --- a/Online/SmiController/scripts/configure.sh +++ b/Online/SmiController/scripts/configure.sh @@ -33,6 +33,11 @@ export DATAFLOW_task="gentest.exe libDataflow.so dataflow_run_task -msg=fifo -mo # # # +dataflow_task_setup() +{ + echo "echo bla > /dev/null;"; +} +# dataflow_specialized_options() { if test -n "${1}"; then @@ -50,5 +55,5 @@ dataflow_default_options() dataflow_task() { #echo "exec -a ${UTGID} gentest.exe libDataflow.so dataflow_run_task -msg=Dataflow_FmcLogger -mon=Dataflow_DIMMonitoring -class=$1"; - echo "exec -a ${UTGID} gentest.exe libDataflow.so dataflow_run_task -msg=fifo -mon=Dataflow_DIMMonitoring -class=$1"; + echo "exec -a ${UTGID} genRunner.exe libDataflow.so dataflow_run_task -msg=fifo -mon=Dataflow_DIMMonitoring -class=$1"; } diff --git a/Online/SmiController/scripts/runDummyTask.sh b/Online/SmiController/scripts/runDummyTask.sh index c38ced154..6a6f4e748 100755 --- a/Online/SmiController/scripts/runDummyTask.sh +++ b/Online/SmiController/scripts/runDummyTask.sh @@ -38,6 +38,6 @@ else fi; echo "Warning: ${DIM_DNS_NODE} -- ${DIM_DNS_HOST}" cd ${SMICONTROLLERROOT}/scripts; -python ${SMICONTROLLERROOT}/scripts/DummyTask.py -utgid ${UTGID} -partition 103 -print ${OUTPUT_LEVEL} +exec -a ${UTGID} genPython.exe ${SMICONTROLLERROOT}/scripts/DummyTask.py -utgid ${UTGID} -partition 103 -print ${OUTPUT_LEVEL} # echo "Going asleep....." diff --git a/Online/SmiController/scripts/runTask.sh b/Online/SmiController/scripts/runTask.sh index b025961e4..029b7f499 100755 --- a/Online/SmiController/scripts/runTask.sh +++ b/Online/SmiController/scripts/runTask.sh @@ -25,8 +25,8 @@ cd ${SMICONTROLLERROOT}/scripts; # if test -z "${FARMCONFIGROOT}";then export PARTITION=$PARTITION_NAME; - echo "ERROR FARMCONFIGROOT: ${FARMCONFIGROOT}"; - echo "UTGID:${UTGID} Partition: $PARTITION_NAME $PARTITION Task type:${TASK_TYPE} Log fifo:${LOGFIFO}"; + #echo "ERROR FARMCONFIGROOT: ${FARMCONFIGROOT}"; + #echo "UTGID:${UTGID} Partition: $PARTITION_NAME $PARTITION Task type:${TASK_TYPE} Log fifo:${LOGFIFO}"; else echo "Skip execution of setup.${CMTCONFIG}.vars" > /dev/null; #echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}"; @@ -39,11 +39,11 @@ fi; #echo "[ERROR] ${UTGID} Current directory: `pwd`"; # if test -f ./${TASK_TYPE}.sh; then - #echo "[ERROR] ${UTGID} Running specialized task"; + # echo "[ERROR] ${UTGID} Running specialized task"; . ./configure.sh; . ./${TASK_TYPE}.sh $*; elif test -n "`echo ${UTGID} | grep TestEvent`"; then - #echo "[ERROR] ${UTGID} Running event processing task"; + # echo "[ERROR] ${UTGID} Running event processing task"; . ./configure.sh; . ./EventProcessor.sh $*; else diff --git a/Online/Storage/CMakeLists.txt b/Online/Storage/CMakeLists.txt index c8151ec63..9d47debc3 100644 --- a/Online/Storage/CMakeLists.txt +++ b/Online/Storage/CMakeLists.txt @@ -23,6 +23,8 @@ find_package(SQLite3 REQUIRED) # find_package(Boost REQUIRED COMPONENTS system filesystem) # +find_package(MySQL) # REQUIRED) +# include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) # gaudi_add_library(StorageClient src/client/*.cpp @@ -33,11 +35,14 @@ gaudi_add_library(StorageClient src/client/*.cpp target_compile_definitions(StorageClient PRIVATE -DSTORAGECLIENT=1) # gaudi_add_library(StorageServer src/server/*.cpp - INCLUDE_DIRS Boost HTTP SQLite3 dim + INCLUDE_DIRS Boost HTTP SQLite3 MySQL dim NO_PUBLIC_HEADERS - LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt z dim Boost HTTP SQLite3 StorageClient) + LINK_LIBRARIES ${CMAKE_DL_LIBS} -lrt z dim SQLite3 Boost HTTP StorageClient) # target_compile_definitions(StorageServer PRIVATE -DSTORAGECLIENT=1) +if (MYSQL_FOUND) + target_compile_definitions(StorageServer PRIVATE -DSTORAGE_HAVE_MYSQL=1) +endif() # # --------------------------------------------------------------------------------------- # Testing diff --git a/Online/Storage/src/server/fdb_db_server.cpp b/Online/Storage/src/server/fdb_db_server.cpp index 33643942a..438d9d4d4 100644 --- a/Online/Storage/src/server/fdb_db_server.cpp +++ b/Online/Storage/src/server/fdb_db_server.cpp @@ -120,8 +120,8 @@ http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t } if ( !error_code_ok(ec, this->debug) ) { header_t h(http::constants::error_cause,"Failed to get "+req.uri+" ["+ec.message()+"]"); - ::lib_rtl_output(LIB_RTL_ERROR,"GET: %s %-20s = %s", - reply_t::stock_status(rep.status).c_str(), + ::lib_rtl_output(LIB_RTL_ERROR,"+++ %s: %s %-20s = %s", + req.method.c_str(), reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); rep.headers.emplace_back(move(h)); ++monitor->data.num_get_errors; @@ -130,8 +130,9 @@ http::basic_http_server<db>::handler_t::handle_get(const request_t& req, reply_t bool mb = length > 3*MByte; rep = reply_t::stock_reply(reply_t::temp_redirect); rep.headers.emplace_back(http::constants::location,access_name); - ::lib_rtl_output(LIB_RTL_INFO,"GET: '%s' %.1f %cB [%s]", - access_name.c_str(), double(length)/(mb ? MByte : kByte), mb ? 'M' : 'k', + ::lib_rtl_output(LIB_RTL_INFO,"+++ %s: '%s' %.1f %cB [%s]", + req.method.c_str(), access_name.c_str(), + double(length)/(mb ? MByte : kByte), mb ? 'M' : 'k', req.remote_address().to_string().c_str()); ++monitor->data.num_get_success; } @@ -162,8 +163,8 @@ http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, repl } if ( !error_code_ok(ec, this->debug) ) { header_t h(http::constants::error_cause,"Failed to delete "+req.uri+" ["+ec.message()+"]"); - ::lib_rtl_output(LIB_RTL_ERROR,"DELETE: %s %-20s = %s", - reply_t::stock_status(rep.status).c_str(), + ::lib_rtl_output(LIB_RTL_ERROR,"+++ %s: %s %-20s = %s", + req.method.c_str(), reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); rep.headers.emplace_back(move(h)); ++monitor->data.num_del_errors; @@ -172,8 +173,9 @@ http::basic_http_server<db>::handler_t::handle_delete(const request_t& req, repl bool mb = length > 3*MByte; rep = reply_t::stock_reply(reply_t::temp_redirect); rep.headers.emplace_back(http::constants::location,access_name); - ::lib_rtl_output(LIB_RTL_INFO,"DELETE:'%s' %.1f %cB [%s]", - obj.c_str(), double(length)/(mb ? MByte : kByte), mb ? 'M' : 'k', + ::lib_rtl_output(LIB_RTL_INFO,"+++ %s: '%s' %.1f %cB [%s]", + req.method.c_str(), obj.c_str(), + double(length)/(mb ? MByte : kByte), mb ? 'M' : 'k', req.remote_address().to_string().c_str()); ++monitor->data.num_del_success; } @@ -187,16 +189,16 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t if ( (hdr_date=req.header(http::constants::date)) == nullptr ) { header_t h(http::constants::error_cause,"Missing date header"); rep = reply_t::stock_reply(reply_t::bad_request); - ::lib_rtl_output(LIB_RTL_ERROR,"PUT: bad_request %-20s = %s", - h.name.c_str(), h.value.c_str()); + ::lib_rtl_output(LIB_RTL_ERROR,"+++ %s: bad_request %-20s = %s", + req.method.c_str(), h.name.c_str(), h.value.c_str()); ++monitor->data.num_put_bad_request; rep.headers.emplace_back(move(h)); } else if ( (hdr_len=req.header(http::constants::content_length)) == nullptr ) { header_t h(http::constants::error_cause,"Missing content length header"); rep = reply_t::stock_reply(reply_t::bad_request); - ::lib_rtl_output(LIB_RTL_ERROR,"PUT: bad_request %-20s = %s", - h.name.c_str(), h.value.c_str()); + ::lib_rtl_output(LIB_RTL_ERROR,"+++ %s: bad_request %-20s = %s", + req.method.c_str(), h.name.c_str(), h.value.c_str()); ++monitor->data.num_put_bad_request; rep.headers.emplace_back(move(h)); } @@ -211,8 +213,8 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t if ( ec == boost::system::errc::permission_denied ) { header_t h(http::constants::error_cause,"Failed to add "+req.uri+" "+ec.message()); rep = reply_t::stock_reply(reply_t::unauthorized); - ::lib_rtl_output(LIB_RTL_ERROR,"PUT: %s %-20s = %s", - reply_t::stock_status(rep.status).c_str(), + ::lib_rtl_output(LIB_RTL_ERROR,"+++ %s: %s %-20s = %s", + req.method.c_str(), reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); ++monitor->data.num_put_unauthorized; rep.headers.emplace_back(move(h)); @@ -221,23 +223,30 @@ http::basic_http_server<db>::handler_t::handle_put(const request_t& req, reply_t header_t h(http::constants::error_cause, "Failed to add object "+req.uri+" in dbase: "+ec.message()); rep = reply_t::stock_reply(reply_t::bad_request); - ::lib_rtl_output(LIB_RTL_ERROR,"PUT: %s %-20s = %s", - reply_t::stock_status(rep.status).c_str(), + ::lib_rtl_output(LIB_RTL_ERROR,"+++ %s: %s %-20s = %s", + req.method.c_str(), reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); ++monitor->data.num_put_bad_request; rep.headers.emplace_back(move(h)); } else { bool mb = len > 3*MByte; + std::string remote = "UNKNOWN-ERROR"; + try { + remote = req.remote_address().to_string(); + } + catch (...) { + } rep = reply_t::stock_reply(reply_t::temp_redirect); rep.content.clear(); rep.headers.clear(); rep.headers.emplace_back(http::constants::location,access_name); rep.headers.emplace_back(http::constants::data_length,len); rep.headers.emplace_back(http::constants::date,date); - ::lib_rtl_output(LIB_RTL_INFO,"PUT: '%s' %.1f %cB [%s]", - req.uri.c_str(), double(len)/(mb ? MByte : kByte), mb ? 'M' : 'k', - req.remote_address().to_string().c_str()); + ::lib_rtl_output(LIB_RTL_INFO,"+++ %s: '%s' %.1f %cB [%s]", + req.method.c_str(), req.uri.c_str(), + double(len)/(mb ? MByte : kByte), mb ? 'M' : 'k', + remote.c_str()); ++monitor->data.num_put_success; return write; } @@ -253,8 +262,8 @@ http::basic_http_server<db>::handler_t::handle_update(const request_t& req, repl if ( (hdr_state=req.header(http::constants::state)) == nullptr ) { header_t h(http::constants::error_cause,"Missing state header"); rep = reply_t::stock_reply(reply_t::bad_request); - ::lib_rtl_output(LIB_RTL_ERROR,"UPDATE: bad_request %-20s = %s", - h.name.c_str(), h.value.c_str()); + ::lib_rtl_output(LIB_RTL_ERROR,"+++ %s: bad_request %-20s = %s", + req.method.c_str(), h.name.c_str(), h.value.c_str()); ++monitor->data.num_upda_bad_request; rep.headers.emplace_back(move(h)); } @@ -267,8 +276,8 @@ http::basic_http_server<db>::handler_t::handle_update(const request_t& req, repl header_t h(http::constants::error_cause, "Failed to update object "+req.uri+" in dbase: "+ec.message()); rep = reply_t::stock_reply(reply_t::bad_request); - ::lib_rtl_output(LIB_RTL_ERROR,"UPDATE: %s %-20s = %s", - reply_t::stock_status(rep.status).c_str(), + ::lib_rtl_output(LIB_RTL_ERROR,"+++ %s: %s %-20s = %s", + req.method.c_str(), reply_t::stock_status(rep.status).c_str(), h.name.c_str(), h.value.c_str()); ++monitor->data.num_upda_errors; rep.headers.emplace_back(move(h)); diff --git a/Online/Storage/src/server/fdb_dbase.cpp b/Online/Storage/src/server/fdb_dbase.cpp index 83e6ad294..81b563917 100644 --- a/Online/Storage/src/server/fdb_dbase.cpp +++ b/Online/Storage/src/server/fdb_dbase.cpp @@ -49,10 +49,10 @@ fdb_dbase_t::handler_t::query(std::string& object, host = file.host; length = ::atol(file.size.c_str()); date = file.date; - ::lib_rtl_output(_prt(this), "Query '%s'", object.c_str()); + ::lib_rtl_output(_prt(this), "+++ Query '%s'", object.c_str()); return ec; } - ::lib_rtl_output(LIB_RTL_ALWAYS,"Query: file '%s' NOT FOUND!", object.c_str()); + ::lib_rtl_output(LIB_RTL_ERROR,"+++ Query: file '%s' NOT FOUND!", object.c_str()); return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); } @@ -71,12 +71,12 @@ fdb_dbase_t::handler_t::next( std::string& object, date = file.date; ec = this->set(object, handler_t::STATE_READ); if ( ec == system::errc::success ) { - ::lib_rtl_output(_prt(this), "Next '%s'", object.c_str()); + ::lib_rtl_output(_prt(this), "+++ Next '%s'", object.c_str()); return system::error_code(system::errc::success, system::system_category()); } return system::error_code(system::errc::protocol_error, system::system_category()); } - ::lib_rtl_output(LIB_RTL_ALWAYS,"Query: file '%s' NOT FOUND!", object.c_str()); + ::lib_rtl_output(LIB_RTL_ERROR,"+++ Query: file '%s' NOT FOUND!", object.c_str()); return system::error_code(system::errc::no_such_file_or_directory, system::system_category()); } @@ -116,10 +116,10 @@ system::error_code fdb_dbase_t::query_object(const std::string& object, auto ec = this->_engine->query(obj, host, date, length); if ( ec == system::errc::success ) { access = this->network_file(host, obj); - ::lib_rtl_output(_prt(this), "Lookup '%s'", obj.c_str()); + ::lib_rtl_output(_prt(this), "+++ Lookup '%s'", obj.c_str()); return ec; } - ::lib_rtl_output(LIB_RTL_ALWAYS,"FAILED to lookup object: '%s' [%s]", + ::lib_rtl_output(LIB_RTL_ERROR,"+++ FAILED lookup: '%s' [%s]", object.c_str(), ec.message().c_str()); return ec; } @@ -136,11 +136,11 @@ system::error_code fdb_dbase_t::delete_next( const std::string& object, ec = this->_engine->del(obj); access = this->network_file(host, obj); if ( ec == system::errc::success ) { - ::lib_rtl_output(_prt(this), "Lookup '%s'", obj.c_str()); + ::lib_rtl_output(_prt(this), "+++ Lookup '%s'", obj.c_str()); return ec; } } - ::lib_rtl_output(LIB_RTL_ERROR,"FAILED to lookup sequence object: '%s' [%s]", + ::lib_rtl_output(LIB_RTL_ERROR,"+++ FAILED sequence lookup: '%s' [%s]", object.c_str(), ec.message().c_str()); return ec; } @@ -157,11 +157,11 @@ system::error_code fdb_dbase_t::delete_object(const std::string& object, ec = this->_engine->del(obj); access = this->network_file(host, obj); if ( ec == system::errc::success ) { - ::lib_rtl_output(_prt(this), "Remove '%s'", obj.c_str()); + ::lib_rtl_output(_prt(this), "+++ Remove '%s'", obj.c_str()); return ec; } } - ::lib_rtl_output(_prt(this), "FAILED to remove: '%s' [%s]", + ::lib_rtl_output(_prt(this), "+++ FAILED remove: '%s' [%s]", object.c_str(), ec.message().c_str()); return ec; } @@ -178,12 +178,12 @@ fdb_dbase_t::add_object(const std::string& object, auto ec = this->_engine->add(obj, date, length, host); if ( ec == system::errc::success ) { access = this->network_file(host, obj); - ::lib_rtl_output(_prt(this), "Add '%s' %s %s", object.c_str(), + ::lib_rtl_output(_prt(this), "+++ Add '%s' %s %s", object.c_str(), this->_debug > 1 ? "access:" : "", this->_debug > 1 ? access.c_str() : ""); return ec; } - ::lib_rtl_output(LIB_RTL_ERROR,"FAILED to add: '%s' access: %s [%s]", + ::lib_rtl_output(LIB_RTL_ERROR,"+++ FAILED add: '%s' access: %s [%s]", object.c_str(), access.c_str(), ec.message().c_str()); return ec; } @@ -208,10 +208,10 @@ fdb_dbase_t::update_object_state(const std::string& object, const std::string& s } if ( ec == system::errc::success ) { ::lib_rtl_output(this->_debug > 1 ? LIB_RTL_ALWAYS : LIB_RTL_DEBUG, - "Update '%s' NEW state: %s", object.c_str(), state.c_str()); + "+++ Update '%s' state: %s", object.c_str(), state.c_str()); return ec; } - ::lib_rtl_output(LIB_RTL_ERROR,"FAILED update '%s' to state: %s [%s]", + ::lib_rtl_output(LIB_RTL_ERROR,"+++ FAILED update '%s' state: %s [%s]", object.c_str(), state.c_str(), ec.message().c_str()); return ec; } diff --git a/Online/Storage/src/server/fdb_fs_server.cpp b/Online/Storage/src/server/fdb_fs_server.cpp index d07012fac..bf8905ad7 100644 --- a/Online/Storage/src/server/fdb_fs_server.cpp +++ b/Online/Storage/src/server/fdb_fs_server.cpp @@ -56,7 +56,9 @@ namespace { */ struct fs_monitor { public: + typedef http::basic_http_server<Online::storage::fs>::handler_t handler_t; struct mon_data { + typedef std::pair<long, std::atomic<long>* > counter_t; int numGET {0}; int numPUT {0}; int numDEL {0}; @@ -66,14 +68,19 @@ namespace { long bytesGET {0}; long bytesPUT {0}; long bytesDEL {0}; + counter_t num_connections {0,nullptr}; + counter_t num_connections_opened {0,nullptr}; + counter_t num_connections_closed {0,nullptr}; + counter_t num_connections_stopped {0,nullptr}; } data; - std::vector<int> services; + handler_t& handler; + std::vector<int> services; void add(int svc) { services.emplace_back(svc); } public: /// Standard constructor - fs_monitor(); + fs_monitor(handler_t& hdlr); /// Default destructor ~fs_monitor(); }; @@ -160,6 +167,21 @@ namespace { return boost::system::error_code(errno, boost::system::system_category()); } }; + + /// Feed data to DIS when updating state + void counter_handler(void* tag, void** buff, int* size, int* /* first */) { + typedef std::pair<long, std::atomic<long>* > counter_t; + static long defaults = 0; + counter_t* h = *(counter_t**)tag; + if ( h ) { + h->first = h->second->load(std::memory_order_relaxed); + *buff = &h->first; + *size = sizeof(h->first); + return; + } + *buff = &defaults; + *size = sizeof(defaults); + } } class Online::storage::fs::traits { @@ -171,12 +193,26 @@ public: using namespace Online::storage; /// Standard constructor -fs_monitor::fs_monitor() { +fs_monitor::fs_monitor(handler_t& hdlr) : handler(hdlr) +{ std::string nam = "/"+RTL::str_upper(RTL::nodeNameShort())+"/"+RTL::processName(); + data.num_connections.second = &handler.num_connections; + data.num_connections_opened.second = &handler.num_connections_opened; + data.num_connections_closed.second = &handler.num_connections_closed; + data.num_connections_stopped.second = &handler.num_connections_stopped; + + add( ::dis_add_service((nam+"/Connections_active").c_str(), "L", 0, 0, + counter_handler, (long)&data.num_connections) ); + add( ::dis_add_service((nam+"/Connections_opened").c_str(), "L", 0, 0, + counter_handler, (long)&data.num_connections_opened) ); + add( ::dis_add_service((nam+"/Connections_closed").c_str(), "L", 0, 0, + counter_handler, (long)&data.num_connections_closed) ); + add( ::dis_add_service((nam+"/Connections_stopped").c_str(), "L", 0, 0, + counter_handler, (long)&data.num_connections_stopped) ); add( ::dis_add_service((nam+"/DATA").c_str(),"C",&data,sizeof(data),0,0) ); - add( ::dis_add_service((nam+"/GET").c_str(),"L",&data.numGET,sizeof(data.numGET),0,0) ); - add( ::dis_add_service((nam+"/PUT").c_str(),"L",&data.numPUT,sizeof(data.numPUT),0,0) ); - add( ::dis_add_service((nam+"/DEL").c_str(),"L",&data.numDEL,sizeof(data.numDEL),0,0) ); + add( ::dis_add_service((nam+"/GET").c_str(),"L",&data.numGET,sizeof(data.numGET), 0, 0) ); + add( ::dis_add_service((nam+"/PUT").c_str(),"L",&data.numPUT,sizeof(data.numPUT), 0, 0) ); + add( ::dis_add_service((nam+"/DEL").c_str(),"L",&data.numDEL,sizeof(data.numDEL), 0, 0) ); add( ::dis_add_service((nam+"/GET_bytes").c_str(),"L",&data.bytesGET,sizeof(data.bytesGET),0,0) ); add( ::dis_add_service((nam+"/PUT_bytes").c_str(),"L",&data.bytesPUT,sizeof(data.bytesPUT),0,0) ); add( ::dis_add_service((nam+"/DEL_bytes").c_str(),"L",&data.bytesDEL,sizeof(data.bytesDEL),0,0) ); @@ -352,13 +388,13 @@ http::basic_http_server<fs>::handler_t::handle_delete(const request_t& req, repl wrt, mb/std::max(1e-6, double(wrt)/1e3)); ++monitor->data.numDEL; monitor->data.bytesDEL += ctxt->st_data; - return none; + return close; } ::lib_rtl_output(LIB_RTL_ERROR, "+++ %s: Failed to read '%s' size:%ld / %ld %s [Inconsistemt context]", req.method.c_str(), req.uri.c_str(), rep.bytes_sent, rep.bytes_total, rep.stock_status(rep.status).c_str()); rep.context.reset(); - return none; + return close; } /// Specific handler for PUT requests @@ -533,7 +569,7 @@ extern "C" int fdb_fs_file_server(int argc, char** argv) { SrvRun<fs> s; s.create(argc, argv); s.ptr->implementation->dbase.reset(new fs_db(s.server, s.file_dir)); - s.ptr->implementation->monitor.reset(new fs_monitor()); + s.ptr->implementation->monitor.reset(new fs_monitor(*s.ptr->implementation)); ::dis_start_serving(srv.c_str()); s.start(); return 0; diff --git a/Online/Tell1Data/src/RawFile.cpp b/Online/Tell1Data/src/RawFile.cpp index 2327f422a..5c8f8db83 100644 --- a/Online/Tell1Data/src/RawFile.cpp +++ b/Online/Tell1Data/src/RawFile.cpp @@ -225,7 +225,11 @@ long RawFile::write(const void* data, size_t len) { long RawFile::read(void* pointer, int len) { unsigned char* p = (unsigned char*)pointer; - if ( m_begin ) { + if ( len < 0 ) { + errno = EINVAL; + return -1; + } + else if ( m_begin ) { if ( m_ptr + len <= m_end ) { ::memcpy(p, m_ptr, len); m_ptr += len; diff --git a/Online/TestBeam/job/Controller.sh b/Online/TestBeam/job/Controller.sh index fe0409e30..568878b59 100755 --- a/Online/TestBeam/job/Controller.sh +++ b/Online/TestBeam/job/Controller.sh @@ -10,7 +10,7 @@ # ========================================================================= HOST=`hostname -s | tr a-z A-Z`; HOST_LONG=`hostname -f | tr a-z A-Z`; -echo "ERROR DIM_DNS_NODE: ${DIM_DNS_NODE}" +# echo "ERROR DIM_DNS_NODE: ${DIM_DNS_NODE}" # # Check the existence of various arguments. # Otherwise use default values. @@ -31,7 +31,7 @@ if test -z "${DIM_DNS_NODE}"; then export DIM_DNS_NODE=${HOST_LONG}; fi; # -exec -a ${UTGID} `which gentest.exe` libSmiController.so smi_controller \ +exec -a ${UTGID} `which genRunner.exe` libSmiController.so smi_controller \ -print=4 \ -logger=fifo \ -part=${PARTITION_NAME} \ diff --git a/Online/TestBeam/job/runTask.sh b/Online/TestBeam/job/runTask.sh index d11364a06..c5fef55ed 100755 --- a/Online/TestBeam/job/runTask.sh +++ b/Online/TestBeam/job/runTask.sh @@ -9,8 +9,6 @@ # # ========================================================================= # -##export DIM_DNS_NODE=`hostname -s`; -# export SUBFARM=`echo ${DIM_DNS_NODE} | tr a-z A-Z`; export STATIC_OPTS=${FARMCONFIGROOT}/options; if test -z "${DATAINTERFACE}"; then @@ -23,11 +21,9 @@ export INFO_OPTIONS=${OPTIONS_DIR}/OnlineEnv.opts; export MBM_SETUP_OPTIONS=${OPTIONS_DIR}/MBMSetup.opts; export DATAFLOW_task="gentest.exe libDataflow.so dataflow_run_task -msg=fifo -mon=Dataflow_DIMMonitoring -print=${OUTPUT_LEVEL}"; # -##echo `pwd`; -# if test -f ./${TASK_TYPE}.sh; then - echo "RunTask: TASK_TYPE: ${TASK_TYPE} ./${TASK_TYPE}.sh" + #echo "RunTask: TASK_TYPE: ${TASK_TYPE} ./${TASK_TYPE}.sh" . ./${TASK_TYPE}.sh $*; elif test -f ./${PARTITION_NAME}${TASK_TYPE}.sh; then -- GitLab From d115506eca562d88fe924e7df08fb4932dc36afe Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Thu, 15 Apr 2021 15:42:06 +0200 Subject: [PATCH 17/17] Move basic main programs from OnlineKernel to OnlineBase --- Online/OnlineBase/main/checkpoint.cpp | 21 ++++++++ Online/OnlineBase/main/genPython.cpp | 75 +++++++++++++++++++++++++++ Online/OnlineBase/main/genRunner.cpp | 72 +++++++++++++++++++++++++ Online/OnlineBase/main/gentest.cpp | 52 +++++++++++++++++++ Online/OnlineBase/main/mbm_remove.cpp | 28 ++++++++++ Online/OnlineBase/main/wt.cpp | 31 +++++++++++ 6 files changed, 279 insertions(+) create mode 100644 Online/OnlineBase/main/checkpoint.cpp create mode 100644 Online/OnlineBase/main/genPython.cpp create mode 100644 Online/OnlineBase/main/genRunner.cpp create mode 100755 Online/OnlineBase/main/gentest.cpp create mode 100755 Online/OnlineBase/main/mbm_remove.cpp create mode 100755 Online/OnlineBase/main/wt.cpp diff --git a/Online/OnlineBase/main/checkpoint.cpp b/Online/OnlineBase/main/checkpoint.cpp new file mode 100644 index 000000000..a9d494bd5 --- /dev/null +++ b/Online/OnlineBase/main/checkpoint.cpp @@ -0,0 +1,21 @@ +//========================================================================== +// LHCb Online software suite +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see OnlineSys/LICENSE. +// +//-------------------------------------------------------------------------- +// +// Author : Markus Frank +//========================================================================== +#define main checkpointing_main +#include "gentest.cpp" +#undef main +extern void CheckpointRestoreWrapper__init_instance(int argc, char** argv); + +int main (int argc, char** argv) { + CheckpointRestoreWrapper__init_instance(argc, argv); + return checkpointing_main(argc,argv); +} diff --git a/Online/OnlineBase/main/genPython.cpp b/Online/OnlineBase/main/genPython.cpp new file mode 100644 index 000000000..59bde542c --- /dev/null +++ b/Online/OnlineBase/main/genPython.cpp @@ -0,0 +1,75 @@ +//========================================================================== +// LHCb Online software suite +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see OnlineSys/LICENSE. +// +//-------------------------------------------------------------------------- +// +// Author : Markus Frank +//========================================================================== +#if defined(__clang__) || defined(__CLING__) +#pragma clang diagnostic ignored "-Wregister" +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wregister" +#endif + +/// Framework include files +#include "../src/LOG/FifoLog.cpp" + +/// C/C++ include files +#include <iostream> +#include <cerrno> + +// Iniitalize the logger unit +__attribute__((constructor)) void s__fifolog_initialize_logger() { + fifolog_initialize_logger(); +} + +/// Shutdown the loggetr unit +__attribute__((destructor)) void s__fifolog_finalize_logger() { + ::usleep(3000); + fifolog_finalize_logger(); +} + +/// Framework include files +#include <RTL/DllAccess.h> + +// ----------------------------------------------------------------------------- +// Python hacks to avoid warnings if outside dictionaries ..... +// ----------------------------------------------------------------------------- +// --> /usr/include/python2.7/pyconfig.h:1161:0: warning: "_POSIX_C_SOURCE" redefined [enabled by default] +#ifdef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif /* _POSIX_C_SOURCE */ +// --> /usr/include/python2.7/pyconfig.h:1183:0: warning: "_XOPEN_SOURCE" redefined [enabled by default] +#ifdef _XOPEN_SOURCE +#undef _XOPEN_SOURCE +#endif /* _XOPEN_SOURCE */ +#include "Python.h" + +/// Start the interpreter in normal mode without hacks like 'python.exe' does. +int main( int argc, char** argv ) { +#if PY_VERSION_HEX < 0x03000000 + return ::Py_Main(argc, argv); +#else + std::vector<wstring> wargs; + std::vector<const wchar_t*> wargv; + for(int i=0; i<argc;++i) { + std::wstring wstr; + if ( argv[i] ) { + const size_t size = ::strlen(argv[i]); + if (size > 0) { + wstr.resize(size+1); + std::mbstowcs(&wstr[0], argv[i], size); + wstr[size] = 0; + } + } + wargs.push_back(wstr); + } + for( auto& s : wargs ) wargv.push_back(s.c_str()); + return ::Py_Main(argc, (wchar_t**)&wargv[0]); +#endif +} diff --git a/Online/OnlineBase/main/genRunner.cpp b/Online/OnlineBase/main/genRunner.cpp new file mode 100644 index 000000000..99ff457b6 --- /dev/null +++ b/Online/OnlineBase/main/genRunner.cpp @@ -0,0 +1,72 @@ +//========================================================================== +// LHCb Online software suite +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see OnlineSys/LICENSE. +// +//-------------------------------------------------------------------------- +// +// Author : Markus Frank +//========================================================================== + +/// Framework include files +#include "../src/LOG/FifoLog.cpp" + +/// C/C++ include files +#include <unistd.h> +#include <iostream> +#include <cerrno> + +// Iniitalize the logger unit +__attribute__((constructor)) void s__fifolog_initialize_logger() { + fifolog_initialize_logger(); +} + +/// Shutdown the loggetr unit +__attribute__((destructor)) void s__fifolog_finalize_logger() { + ::usleep(3000); + fifolog_finalize_logger(); +} + + +/// Framework include files +#include <RTL/DllAccess.h> + +/// Generic main program to start any process +/** + * Generic main program to start any process + * by loading a library and executing a + * function within + * + * \author M.Frank + * \version 1.0 + */ +int main (int argc, char** argv) { + if ( argc >= 3 ) { + void* handle = LOAD_LIB( argv[1] ); + if ( handle ) { + Function fun(GETPROC(handle, argv[2])); + if ( fun.function ) { + return (*fun.function)(argc-2, &argv[2]); + } + // The required function is not in the loaded image. + // Try to load it directly from the executable + Function f1(GETPROC(0, argv[2])); + if ( f1.function ) { + std::cout << "[WARNING] Executing function " << argv[2] + << " from exe rather than image " << std::endl; + return (*f1.function)(argc-2, &argv[2]); + } + std::cout << "[ERROR] Failed to access test procedure: '" << argv[2] << "'" << std::endl; + std::cout << "[ERROR] Error: " << DLERROR << std::endl; + return EINVAL; + } + std::cout << "[ERROR] Failed to load test library: '" << argv[1] << "'" << std::endl; + std::cout << "[ERROR] Error: " << DLERROR << std::endl; + return EINVAL; + } + std::cout << "[ERROR] usage: gentest.exe <library-name> <function-name> -arg [-arg]" << std::endl; + return EINVAL; +} diff --git a/Online/OnlineBase/main/gentest.cpp b/Online/OnlineBase/main/gentest.cpp new file mode 100755 index 000000000..99988aab4 --- /dev/null +++ b/Online/OnlineBase/main/gentest.cpp @@ -0,0 +1,52 @@ +//========================================================================== +// LHCb Online software suite +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see OnlineSys/LICENSE. +// +//-------------------------------------------------------------------------- +// +// Author : Markus Frank +//========================================================================== +#include "RTL/DllAccess.h" +#include <iostream> +#include <cerrno> + +/// Generic main program to start any process +/** + * Generic main program to start any process + * by loading a library and executing a + * function within + * + * \author M.Frank + * \version 1.0 + */ +int main (int argc, char** argv) { + if ( argc >= 3 ) { + void* handle = LOAD_LIB( argv[1] ); + if ( handle ) { + Function fun(GETPROC(handle, argv[2])); + if ( fun.function ) { + return (*fun.function)(argc-2, &argv[2]); + } + // The required function is not in the loaded image. + // Try to load it directly from the executable + Function f1(GETPROC(0, argv[2])); + if ( f1.function ) { + std::cout << "[WARNING] Executing function " << argv[2] + << " from exe rather than image " << std::endl; + return (*f1.function)(argc-2, &argv[2]); + } + std::cout << "[ERROR] Failed to access test procedure: '" << argv[2] << "'" << std::endl; + std::cout << "[ERROR] Error: " << DLERROR << std::endl; + return EINVAL; + } + std::cout << "[ERROR] Failed to load test library: '" << argv[1] << "'" << std::endl; + std::cout << "[ERROR] Error: " << DLERROR << std::endl; + return EINVAL; + } + std::cout << "[ERROR] usage: gentest.exe <library-name> <function-name> -arg [-arg]" << std::endl; + return EINVAL; +} diff --git a/Online/OnlineBase/main/mbm_remove.cpp b/Online/OnlineBase/main/mbm_remove.cpp new file mode 100755 index 000000000..bbc209c55 --- /dev/null +++ b/Online/OnlineBase/main/mbm_remove.cpp @@ -0,0 +1,28 @@ +//========================================================================== +// LHCb Online software suite +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see OnlineSys/LICENSE. +// +//-------------------------------------------------------------------------- +// +// Author : Markus Frank +//========================================================================== +#include "RTL/DllAccess.h" +#include <iostream> + +int main (int argc, char** argv) { + void* handle = LOAD_LIB2( "OnlineKernel" ); + if ( 0 != handle ) { + Function fun(GETPROC(handle,"mbm_remove")); + if ( fun.function ) { + return (*fun.function)(argc, argv); + } + std::cout << "Failed to access test procedure!" << std::endl; + } + std::cout << "Failed to load test library!" << std::endl; + std::cout << "Error: " << DLERROR << std::endl; + return 0; +} diff --git a/Online/OnlineBase/main/wt.cpp b/Online/OnlineBase/main/wt.cpp new file mode 100755 index 000000000..e6a77bf30 --- /dev/null +++ b/Online/OnlineBase/main/wt.cpp @@ -0,0 +1,31 @@ +//========================================================================== +// LHCb Online software suite +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see OnlineSys/LICENSE. +// +//-------------------------------------------------------------------------- +// +// Author : Markus Frank +//========================================================================== +#include "RTL/DllAccess.h" +#include <iostream> + +using OnlineBase::FuncPtrCast; + +int main (int argc, char** argv) { + void* handle = LOAD_LIB2("OnlineKernel"); + if ( 0 != handle ) { + typedef int (*func_t)(int, char**); + func_t fun = FuncPtrCast<func_t>(GETPROC(handle, argv[1])); + if ( fun ) { + return (*fun)(argc-1, &argv[1]); + } + std::cout << "Failed to access test procedure!" << std::endl; + } + std::cout << "Failed to load test library!" << std::endl; + std::cout << "Error: " << DLERROR << std::endl; + return 0; +} -- GitLab