@@ -154,6 +154,7 @@ class Readout
154154 std::string cfgLogbookApiToken;
155155 int cfgLogbookUpdateInterval;
156156 std::string cfgTimeframeServerUrl;
157+ int cfgVerbose = 0 ;
157158
158159 // runtime entities
159160 std::vector<std::unique_ptr<Consumer>> dataConsumers;
@@ -226,6 +227,59 @@ void Readout::publishLogbookStats()
226227
227228int Readout::init (int argc, char * argv[])
228229{
230+ int doMemLock = 0 ; // when set, ensure all allocated memory is locked in ram
231+ std::string readoutExe = " " ; // when set, use specified executable
232+ std::string readoutConfig = " " ; // when set, use specified executable
233+
234+ // cache of logs - delay startup messages
235+ std::vector<std::pair<AliceO2::InfoLogger::InfoLogger::InfoLoggerMessageOption, std::string>> initLogs;
236+
237+ // load configuration defaults
238+ ConfigFile cfgDefaults;
239+ const std::string cfgDefaultsPath = " file:/etc/o2.d/readout-defaults.cfg" ; // path to default configuration file
240+ const std::string cfgDefaultsEntryPoint = " readout" ; // entry point for default configuration variables (e.g. section named [readout])
241+ try {
242+ cfgDefaults.load (cfgDefaultsPath.c_str ());
243+ initLogs.push_back ({LogInfoDevel, " Defaults loaded from " + cfgDefaultsPath});
244+ cfgDefaults.getOptionalValue <int >(cfgDefaultsEntryPoint + " .memLock" , doMemLock, doMemLock);
245+ cfgDefaults.getOptionalValue <std::string>(cfgDefaultsEntryPoint + " .readoutExe" , readoutExe, readoutExe);
246+ cfgDefaults.getOptionalValue <std::string>(cfgDefaultsEntryPoint + " .readoutConfig" , readoutConfig, readoutConfig);
247+ cfgDefaults.getOptionalValue <int >(cfgDefaultsEntryPoint + " .verbose" , cfgVerbose, cfgVerbose);
248+ }
249+ catch (...) {
250+ // initLogs.push_back({LogWarningSupport_(3100), std::string("Error loading defaults")});
251+ }
252+
253+ // redirect executable (if different from self!)
254+ if (readoutExe.length () && readoutExe!=argv[0 ]) {
255+ std::vector<char *> argv2;
256+ argv2.push_back ((char *)readoutExe.c_str ());
257+ if (readoutConfig.length ()) {
258+ argv2.push_back ((char *)readoutConfig.c_str ());
259+ }
260+ for (int i=argv2.size (); i<argc; i++) {
261+ argv2.push_back (argv[i]);
262+ }
263+ printf (" Launching " );
264+ for (auto const &a : argv2) {
265+ printf (" %s " ,a);
266+ }
267+ printf (" \n " );
268+ argv2.push_back (NULL );
269+ execv (readoutExe.c_str (), &argv2[0 ]);
270+ printf (" Failed to execute : %s\n " ,strerror (errno));
271+ exit (1 );
272+ }
273+
274+ // before anything, ensure all memory used by readout is kept in RAM
275+ if (doMemLock) {
276+ if (mlockall (MCL_CURRENT | MCL_FUTURE) == 0 ) {
277+ initLogs.push_back ({LogInfoDevel, " Memory locked" });
278+ } else {
279+ initLogs.push_back ({LogWarningSupport_ (3230 ), " Failed to lock memory" });
280+ }
281+ }
282+
229283 if (argc < 2 ) {
230284 printf (" Please provide path to configuration file\n " );
231285 return -1 ;
@@ -245,49 +299,56 @@ int Readout::init(int argc, char* argv[])
245299
246300 // log startup and options
247301 theLog.log (LogInfoSupport_ (3001 ), " Readout " READOUT_VERSION " - process starting, pid %d" , getpid ());
248- theLog.log (LogInfoDevel, " Optional built features enabled:" );
249- #ifdef WITH_READOUTCARD
250- theLog.log (LogInfoDevel, " READOUTCARD : yes" );
251- #else
252- theLog.log (LogInfoDevel, " READOUTCARD : no" );
253- #endif
254- #ifdef WITH_CONFIG
255- theLog.log (LogInfoDevel, " CONFIG : yes" );
256- #else
257- theLog.log (LogInfoDevel, " CONFIG : no" );
258- #endif
259- #ifdef WITH_FAIRMQ
260- theLog.log (LogInfoDevel, " FAIRMQ : yes" );
261- // redirect FMQ logs to infologger
262- setFMQLogsToInfoLogger (&theLog);
263- #else
264- theLog.log (LogInfoDevel, " FAIRMQ : no" );
265- #endif
266- #ifdef WITH_NUMA
267- theLog.log (LogInfoDevel, " NUMA : yes" );
268- #else
269- theLog.log (LogInfoDevel, " NUMA : no" );
270- #endif
271- #ifdef WITH_RDMA
272- theLog.log (LogInfoDevel, " RDMA : yes" );
273- #else
274- theLog.log (LogInfoDevel, " RDMA : no" );
275- #endif
276- #ifdef WITH_OCC
277- theLog.log (LogInfoDevel, " OCC : yes" );
278- #else
279- theLog.log (LogInfoDevel, " OCC : no" );
280- #endif
281- #ifdef WITH_LOGBOOK
282- theLog.log (LogInfoDevel, " LOGBOOK : yes" );
283- #else
284- theLog.log (LogInfoDevel, " LOGBOOK : no" );
285- #endif
286- #ifdef WITH_ZMQ
287- theLog.log (LogInfoDevel, " ZMQ : yes" );
288- #else
289- theLog.log (LogInfoDevel, " ZMQ : no" );
290- #endif
302+ if (cfgVerbose) {
303+ theLog.log (LogInfoDevel, " Optional built features enabled:" );
304+ #ifdef WITH_READOUTCARD
305+ theLog.log (LogInfoDevel, " READOUTCARD : yes" );
306+ #else
307+ theLog.log (LogInfoDevel, " READOUTCARD : no" );
308+ #endif
309+ #ifdef WITH_CONFIG
310+ theLog.log (LogInfoDevel, " CONFIG : yes" );
311+ #else
312+ theLog.log (LogInfoDevel, " CONFIG : no" );
313+ #endif
314+ #ifdef WITH_FAIRMQ
315+ theLog.log (LogInfoDevel, " FAIRMQ : yes" );
316+ // redirect FMQ logs to infologger
317+ setFMQLogsToInfoLogger (&theLog);
318+ #else
319+ theLog.log (LogInfoDevel, " FAIRMQ : no" );
320+ #endif
321+ #ifdef WITH_NUMA
322+ theLog.log (LogInfoDevel, " NUMA : yes" );
323+ #else
324+ theLog.log (LogInfoDevel, " NUMA : no" );
325+ #endif
326+ #ifdef WITH_RDMA
327+ theLog.log (LogInfoDevel, " RDMA : yes" );
328+ #else
329+ theLog.log (LogInfoDevel, " RDMA : no" );
330+ #endif
331+ #ifdef WITH_OCC
332+ theLog.log (LogInfoDevel, " OCC : yes" );
333+ #else
334+ theLog.log (LogInfoDevel, " OCC : no" );
335+ #endif
336+ #ifdef WITH_LOGBOOK
337+ theLog.log (LogInfoDevel, " LOGBOOK : yes" );
338+ #else
339+ theLog.log (LogInfoDevel, " LOGBOOK : no" );
340+ #endif
341+ #ifdef WITH_ZMQ
342+ theLog.log (LogInfoDevel, " ZMQ : yes" );
343+ #else
344+ theLog.log (LogInfoDevel, " ZMQ : no" );
345+ #endif
346+ }
347+
348+ // report cached logs
349+ for (auto const &l : initLogs) {
350+ theLog.log (l.first , " %s" , l.second .c_str ());
351+ }
291352
292353 return 0 ;
293354}
@@ -1250,12 +1311,8 @@ class ReadoutOCCStateMachine : public RuntimeControlledObject
12501311// the main program loop
12511312int main (int argc, char * argv[])
12521313{
1253- // before anything, ensure all memory used by readout is kept in RAM
1254- bool memLockSuccess = false ;
1255- if (mlockall (MCL_CURRENT | MCL_FUTURE) == 0 ) {
1256- memLockSuccess = true ;
1257- }
1258-
1314+ // printf("Starting %s - %d\n",argv[0], (int)getpid());
1315+
12591316 // check environment settings
12601317
12611318 // OCC control port. If set, use OCClib to handle Readout states.
@@ -1285,11 +1342,6 @@ int main(int argc, char* argv[])
12851342 return err;
12861343 }
12871344
1288- // report memlock status
1289- if (!memLockSuccess) {
1290- theLog.log (LogWarningSupport_ (3230 ), " Failed to lock readout memory" );
1291- }
1292-
12931345 if (occMode) {
12941346#ifdef WITH_OCC
12951347 theLog.log (LogInfoDevel, " Readout entering OCC state machine" );
0 commit comments