ROOT  6.06/09
Reference Guide
TProofServ.cxx
Go to the documentation of this file.
1 // @(#)root/proof:$Id$
2 // Author: Fons Rademakers 16/02/97
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TProofServ //
15 // //
16 // TProofServ is the PROOF server. It can act either as the master //
17 // server or as a slave server, depending on its startup arguments. It //
18 // receives and handles message coming from the client or from the //
19 // master server. //
20 // //
21 //////////////////////////////////////////////////////////////////////////
22 
23 #include "RConfigure.h"
24 #include "RConfig.h"
25 #include "Riostream.h"
26 
27 #ifdef WIN32
28  #include <process.h>
29  #include <io.h>
30  #include "snprintf.h"
31  typedef long off_t;
32 #endif
33 #include <errno.h>
34 #include <time.h>
35 #include <fcntl.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #ifndef WIN32
39 #include <sys/wait.h>
40 #endif
41 #include <cstdlib>
42 
43 // To handle exceptions
44 #include <exception>
45 #include <new>
46 
47 using namespace std;
48 
49 #if (defined(__FreeBSD__) && (__FreeBSD__ < 4)) || \
50  (defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_10_3) || \
51  (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3)))
52 #include <sys/file.h>
53 #define lockf(fd, op, sz) flock((fd), (op))
54 #ifndef F_LOCK
55 #define F_LOCK (LOCK_EX | LOCK_NB)
56 #endif
57 #ifndef F_ULOCK
58 #define F_ULOCK LOCK_UN
59 #endif
60 #endif
61 
62 #include "TProofServ.h"
63 #include "TDSetProxy.h"
64 #include "TEnv.h"
65 #include "TError.h"
66 #include "TEventList.h"
67 #include "TEntryList.h"
68 #include "TException.h"
69 #include "TFile.h"
70 #include "THashList.h"
71 #include "TInterpreter.h"
72 #include "TKey.h"
73 #include "TMessage.h"
74 #include "TVirtualPerfStats.h"
75 #include "TProofDebug.h"
76 #include "TProof.h"
77 #include "TVirtualProofPlayer.h"
78 #include "TProofQueryResult.h"
79 #include "TQueryResultManager.h"
80 #include "TRegexp.h"
81 #include "TROOT.h"
82 #include "TSocket.h"
83 #include "TStopwatch.h"
84 #include "TSystem.h"
85 #include "TTimeStamp.h"
86 #include "TUrl.h"
87 #include "TPluginManager.h"
88 #include "TObjString.h"
89 #include "compiledata.h"
90 #include "TProofResourcesStatic.h"
91 #include "TProofNodeInfo.h"
92 #include "TFileInfo.h"
93 #include "TMutex.h"
94 #include "TClass.h"
95 #include "TSQLServer.h"
96 #include "TSQLResult.h"
97 #include "TSQLRow.h"
98 #include "TPRegexp.h"
99 #include "TParameter.h"
100 #include "TMap.h"
101 #include "TSortedList.h"
102 #include "TParameter.h"
103 #include "TFileCollection.h"
104 #include "TLockFile.h"
105 #include "TDataSetManagerFile.h"
106 #include "TProofProgressStatus.h"
107 #include "TServerSocket.h"
108 #include "TMonitor.h"
109 #include "TFunction.h"
110 #include "TMethodArg.h"
111 #include "TMethodCall.h"
112 #include "TProofOutputFile.h"
113 #include "TSelector.h"
114 
115 // global proofserv handle
116 TProofServ *gProofServ = 0;
117 
118 // debug hook
119 static volatile Int_t gProofServDebug = 1;
120 
121 // Syslog control
124 TString TProofServ::fgSysLogEntity("undef:default");
125 
126 // File where to log: default stderr
128 
129 // Integrate with crash reporter.
130 #ifdef __APPLE__
131 extern "C" {
132 static const char *__crashreporter_info__ = 0;
133 asm(".desc ___crashreporter_info__, 0x10");
134 }
135 #endif
136 
137 // To control allowed actions while processing
139 
140 // Last message and entry before exceptions
141 TString TProofServ::fgLastMsg("<undef>");
143 
144 // Memory controllers
149 
150 //----- Termination signal handler ---------------------------------------------
151 ////////////////////////////////////////////////////////////////////////////////
152 
153 class TProofServTerminationHandler : public TSignalHandler {
154  TProofServ *fServ;
155 public:
156  TProofServTerminationHandler(TProofServ *s)
157  : TSignalHandler(kSigTermination, kFALSE) { fServ = s; }
158  Bool_t Notify();
159 };
160 
161 ////////////////////////////////////////////////////////////////////////////////
162 /// Handle this interrupt
163 
165 {
166  Printf("Received SIGTERM: terminating");
167  fServ->HandleTermination();
168  return kTRUE;
169 }
170 
171 //----- Interrupt signal handler -----------------------------------------------
172 ////////////////////////////////////////////////////////////////////////////////
173 
174 class TProofServInterruptHandler : public TSignalHandler {
175  TProofServ *fServ;
176 public:
177  TProofServInterruptHandler(TProofServ *s)
178  : TSignalHandler(kSigUrgent, kFALSE) { fServ = s; }
179  Bool_t Notify();
180 };
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 /// Handle this interrupt
184 
186 {
187  fServ->HandleUrgentData();
188  if (TROOT::Initialized()) {
189  Throw(GetSignal());
190  }
191  return kTRUE;
192 }
193 
194 //----- SigPipe signal handler -------------------------------------------------
195 ////////////////////////////////////////////////////////////////////////////////
196 
197 class TProofServSigPipeHandler : public TSignalHandler {
198  TProofServ *fServ;
199 public:
200  TProofServSigPipeHandler(TProofServ *s) : TSignalHandler(kSigPipe, kFALSE)
201  { fServ = s; }
202  Bool_t Notify();
203 };
204 
205 ////////////////////////////////////////////////////////////////////////////////
206 /// Handle this signal
207 
209 {
210  fServ->HandleSigPipe();
211  return kTRUE;
212 }
213 
214 //----- Input handler for messages from parent or master -----------------------
215 ////////////////////////////////////////////////////////////////////////////////
216 
217 class TProofServInputHandler : public TFileHandler {
218  TProofServ *fServ;
219 public:
220  TProofServInputHandler(TProofServ *s, Int_t fd) : TFileHandler(fd, 1)
221  { fServ = s; }
222  Bool_t Notify();
223  Bool_t ReadNotify() { return Notify(); }
224 };
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// Handle this input
228 
230 {
231  fServ->HandleSocketInput();
232  return kTRUE;
233 }
234 
235 TString TProofServLogHandler::fgPfx = ""; // Default prefix to be prepended to messages
236 Int_t TProofServLogHandler::fgCmdRtn = 0; // Return code of the command execution (available only
237  // after closing the pipe)
238 ////////////////////////////////////////////////////////////////////////////////
239 /// Execute 'cmd' in a pipe and handle output messages from the related file
240 
242  TSocket *s, const char *pfx)
243  : TFileHandler(-1, 1), fSocket(s), fPfx(pfx)
244 {
246  fgCmdRtn = 0;
247  fFile = 0;
248  if (s && cmd) {
249  fFile = gSystem->OpenPipe(cmd, "r");
250  if (fFile) {
251  SetFd(fileno(fFile));
252  // Notify what already in the file
253  Notify();
254  // Used in the destructor
256  } else {
257  fSocket = 0;
258  Error("TProofServLogHandler", "executing command in pipe");
259  fgCmdRtn = -1;
260  }
261  } else {
262  Error("TProofServLogHandler",
263  "undefined command (%p) or socket (%p)", (int *)cmd, s);
264  }
265 }
266 ////////////////////////////////////////////////////////////////////////////////
267 /// Handle available message from the open file 'f'
268 
270  : TFileHandler(-1, 1), fSocket(s), fPfx(pfx)
271 {
273  fgCmdRtn = 0;
274  fFile = 0;
275  if (s && f) {
276  fFile = f;
277  SetFd(fileno(fFile));
278  // Notify what already in the file
279  Notify();
280  } else {
281  Error("TProofServLogHandler", "undefined file (%p) or socket (%p)", f, s);
282  }
283 }
284 ////////////////////////////////////////////////////////////////////////////////
285 /// Handle available message in the open file
286 
288 {
289  if (TestBit(kFileIsPipe) && fFile) {
290  Int_t rc = gSystem->ClosePipe(fFile);
291 #ifdef WIN32
292  fgCmdRtn = rc;
293 #else
294  fgCmdRtn = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
295 #endif
296  }
297  fFile = 0;
298  fSocket = 0;
300 }
301 ////////////////////////////////////////////////////////////////////////////////
302 /// Handle available message in the open file
303 
305 {
306  if (IsValid()) {
308  // Read buffer
309  char line[4096];
310  char *plf = 0;
311  while (fgets(line, sizeof(line), fFile)) {
312  if ((plf = strchr(line, '\n')))
313  *plf = 0;
314  // Create log string
315  TString log;
316  if (fPfx.Length() > 0) {
317  // Prepend prefix specific to this instance
318  log.Form("%s: %s", fPfx.Data(), line);
319  } else if (fgPfx.Length() > 0) {
320  // Prepend default prefix
321  log.Form("%s: %s", fgPfx.Data(), line);
322  } else {
323  // Nothing to prepend
324  log = line;
325  }
326  // Send the message one level up
328  m << log;
329  fSocket->Send(m);
330  }
331  }
332  return kTRUE;
333 }
334 ////////////////////////////////////////////////////////////////////////////////
335 /// Static method to set the default prefix
336 
338 {
339  fgPfx = pfx;
340 }
341 ////////////////////////////////////////////////////////////////////////////////
342 /// Static method to get the return code from the execution of a command via
343 /// the pipe. This is always 0 when the log handler is not used with a pipe
344 
346 {
347  return fgCmdRtn;
348 }
349 
350 ////////////////////////////////////////////////////////////////////////////////
351 /// Init a guard for executing a command in a pipe
352 
354  const char *pfx, Bool_t on)
355 {
356  fExecHandler = 0;
357  if (cmd && on) {
358  fExecHandler = new TProofServLogHandler(cmd, s, pfx);
359  if (fExecHandler->IsValid()) {
361  } else {
362  Error("TProofServLogHandlerGuard","invalid handler");
363  }
364  } else {
365  if (on)
366  Error("TProofServLogHandlerGuard","undefined command");
367  }
368 }
369 
370 ////////////////////////////////////////////////////////////////////////////////
371 /// Init a guard for executing a command in a pipe
372 
374  const char *pfx, Bool_t on)
375 {
376  fExecHandler = 0;
377  if (f && on) {
378  fExecHandler = new TProofServLogHandler(f, s, pfx);
379  if (fExecHandler->IsValid()) {
381  } else {
382  Error("TProofServLogHandlerGuard","invalid handler");
383  }
384  } else {
385  if (on)
386  Error("TProofServLogHandlerGuard","undefined file");
387  }
388 }
389 
390 ////////////////////////////////////////////////////////////////////////////////
391 /// Close a guard for executing a command in a pipe
392 
394 {
395  if (fExecHandler && fExecHandler->IsValid()) {
398  }
399 }
400 
401 //--- Special timer to control delayed shutdowns ----------------------------//
402 ////////////////////////////////////////////////////////////////////////////////
403 /// Construtor
404 
406  : TTimer(delay, kFALSE), fProofServ(p)
407 {
408  fTimeout = gEnv->GetValue("ProofServ.ShutdownTimeout", 20);
409  // Backward compaitibility: until 5.32 the variable was called ProofServ.ShutdonwTimeout
410  fTimeout = gEnv->GetValue("ProofServ.ShutdonwTimeout", fTimeout);
411 }
412 
413 ////////////////////////////////////////////////////////////////////////////////
414 /// Handle expiration of the shutdown timer. In the case of low activity the
415 /// process will be aborted.
416 
418 {
419  if (gDebug > 0)
420  printf("TShutdownTimer::Notify: checking activity on the input socket\n");
421 
422  // Check activity on the socket
423  TSocket *xs = 0;
424  if (fProofServ && (xs = fProofServ->GetSocket())) {
425  TTimeStamp now;
426  TTimeStamp ts = xs->GetLastUsage();
427  Long_t dt = (Long_t)(now.GetSec() - ts.GetSec()) * 1000 +
428  (Long_t)(now.GetNanoSec() - ts.GetNanoSec()) / 1000000 ;
429  if (dt > fTimeout * 60000) {
430  printf("TShutdownTimer::Notify: input socket: %p: did not show any activity"
431  " during the last %d mins: aborting\n", xs, fTimeout);
432  // At this point we lost our controller: we need to abort to avoid
433  // hidden timeouts or loops
434  gSystem->Abort();
435  } else {
436  if (gDebug > 0)
437  printf("TShutdownTimer::Notify: input socket: %p: show activity"
438  " %ld secs ago\n", xs, dt / 60000);
439  }
440  }
441  // Needed for the next shot
442  Reset();
443  return kTRUE;
444 }
445 
446 //--- Synchronous timer used to reap children processes change of state ------//
447 ////////////////////////////////////////////////////////////////////////////////
448 /// Destructor
449 
451 {
452  if (fChildren) {
454  delete fChildren;
455  fChildren = 0;
456  }
457 }
458 
459 ////////////////////////////////////////////////////////////////////////////////
460 /// Add an entry for 'pid' in the internal list
461 
463 {
464  if (pid > 0) {
465  if (!fChildren)
466  fChildren = new TList;
467  TString spid;
468  spid.Form("%d", pid);
469  fChildren->Add(new TParameter<Int_t>(spid.Data(), pid));
470  TurnOn();
471  }
472 }
473 
474 ////////////////////////////////////////////////////////////////////////////////
475 /// Check if any of the registered children has changed its state.
476 /// Unregister those that are gone.
477 
479 {
480  if (fChildren) {
481  TIter nxp(fChildren);
482  TParameter<Int_t> *p = 0;
483  while ((p = (TParameter<Int_t> *)nxp())) {
484  int status;
485 #ifndef WIN32
486  pid_t pid;
487  do {
488  pid = waitpid(p->GetVal(), &status, WNOHANG);
489  } while (pid < 0 && errno == EINTR);
490 #else
491  intptr_t pid;
492  pid = _cwait(&status, (intptr_t)p->GetVal(), 0);
493 #endif
494  if (pid > 0 && pid == p->GetVal()) {
495  // Remove from the list
496  fChildren->Remove(p);
497  delete p;
498  }
499  }
500  }
501 
502  // Stop the timer if no children
503  if (!fChildren || fChildren->GetSize() <= 0) {
504  Stop();
505  } else {
506  // Needed for the next shot
507  Reset();
508  }
509  return kTRUE;
510 }
511 
512 //--- Special timer to terminate idle sessions ----------------------------//
513 ////////////////////////////////////////////////////////////////////////////////
514 /// Handle expiration of the idle timer. The session will just be terminated.
515 
517 {
518  Info ("Notify", "session idle for more then %lld secs: terminating", Long64_t(fTime)/1000);
519 
520  if (fProofServ) {
521  // Set the status to timed-out
522  Int_t uss_rc = -1;
523  if ((uss_rc = fProofServ->UpdateSessionStatus(4)) != 0)
524  Warning("Notify", "problems updating session status (errno: %d)", -uss_rc);
525  // Send a terminate request
526  TString msg;
527  if (fProofServ->GetProtocol() < 29) {
528  msg.Form("\n//\n// PROOF session at %s (%s) terminated because idle for more than %lld secs\n"
529  "// Please IGNORE any error message possibly displayed below\n//",
531  } else {
532  msg.Form("\n//\n// PROOF session at %s (%s) terminated because idle for more than %lld secs\n//",
534  }
536  fProofServ->Terminate(0);
537  Reset();
538  Stop();
539  } else {
540  Warning("Notify", "fProofServ undefined!");
541  Start(-1, kTRUE);
542  }
543  return kTRUE;
544 }
545 
547 
548 // Hook to the constructor. This is needed to avoid using the plugin manager
549 // which may create problems in multi-threaded environments.
550 extern "C" {
551  TApplication *GetTProofServ(Int_t *argc, char **argv, FILE *flog)
552  { return new TProofServ(argc, argv, flog); }
553 }
554 
555 ////////////////////////////////////////////////////////////////////////////////
556 /// Main constructor. Create an application environment. The TProofServ
557 /// environment provides an eventloop via inheritance of TApplication.
558 /// Actual server creation work is done in CreateServer() to allow
559 /// overloading.
560 
561 TProofServ::TProofServ(Int_t *argc, char **argv, FILE *flog)
562  : TApplication("proofserv", argc, argv, 0, -1)
563 {
564  // If test and tty, we are done
565  Bool_t xtest = (argc && *argc == 1) ? kTRUE : kFALSE;
566  if (xtest) {
567  Printf("proofserv: command line testing: OK");
568  exit(0);
569  }
570 
571  // Read session specific rootrc file
572  TString rcfile = gSystem->Getenv("ROOTRCFILE") ? gSystem->Getenv("ROOTRCFILE")
573  : "session.rootrc";
574  if (!gSystem->AccessPathName(rcfile, kReadPermission))
575  gEnv->ReadFile(rcfile, kEnvChange);
576 
577  // Upper limit on Virtual Memory (in kB)
578  fgVirtMemMax = gEnv->GetValue("Proof.VirtMemMax",-1);
579  if (fgVirtMemMax < 0 && gSystem->Getenv("PROOF_VIRTMEMMAX")) {
580  Long_t mmx = strtol(gSystem->Getenv("PROOF_VIRTMEMMAX"), 0, 10);
581  if (mmx < kMaxLong && mmx > 0)
582  fgVirtMemMax = mmx * 1024;
583  }
584  // Old variable for backward compatibility
585  if (fgVirtMemMax < 0 && gSystem->Getenv("ROOTPROOFASHARD")) {
586  Long_t mmx = strtol(gSystem->Getenv("ROOTPROOFASHARD"), 0, 10);
587  if (mmx < kMaxLong && mmx > 0)
588  fgVirtMemMax = mmx * 1024;
589  }
590  // Upper limit on Resident Memory (in kB)
591  fgResMemMax = gEnv->GetValue("Proof.ResMemMax",-1);
592  if (fgResMemMax < 0 && gSystem->Getenv("PROOF_RESMEMMAX")) {
593  Long_t mmx = strtol(gSystem->Getenv("PROOF_RESMEMMAX"), 0, 10);
594  if (mmx < kMaxLong && mmx > 0)
595  fgResMemMax = mmx * 1024;
596  }
597  // Thresholds for warnings and stop processing
598  fgMemStop = gEnv->GetValue("Proof.MemStop", 0.95);
599  fgMemHWM = gEnv->GetValue("Proof.MemHWM", 0.80);
600  if (fgVirtMemMax > 0 || fgResMemMax > 0) {
601  if ((fgMemStop < 0.) || (fgMemStop > 1.)) {
602  Warning("TProofServ", "requested memory fraction threshold to stop processing"
603  " (MemStop) out of range [0,1] - ignoring");
604  fgMemStop = 0.95;
605  }
606  if ((fgMemHWM < 0.) || (fgMemHWM > fgMemStop)) {
607  Warning("TProofServ", "requested memory fraction threshold for warning and finer monitoring"
608  " (MemHWM) out of range [0,MemStop] - ignoring");
609  fgMemHWM = 0.80;
610  }
611  }
612 
613  // Wait (loop) to allow debugger to connect
614  Bool_t test = (argc && *argc >= 4 && !strcmp(argv[3], "test")) ? kTRUE : kFALSE;
615  if ((gEnv->GetValue("Proof.GdbHook",0) == 3 && !test) ||
616  (gEnv->GetValue("Proof.GdbHook",0) == 4 && test)) {
617  while (gProofServDebug)
618  ;
619  }
620 
621  // Test instance
622  if (argc && *argc >= 4)
623  if (!strcmp(argv[3], "test"))
624  fService = "prooftest";
625 
626  // crude check on number of arguments
627  if (argc && *argc < 2) {
628  Error("TProofServ", "Must have at least 1 arguments (see proofd).");
629  exit(1);
630  }
631 
632  // Set global to this instance
633  gProofServ = this;
634 
635  // Log control flags
637 
638  // Abort on higher than kSysError's and set error handler
640  SetErrorHandlerFile(stderr);
642 
643  fNcmd = 0;
644  fGroupPriority = 100;
645  fInterrupt = kFALSE;
646  fProtocol = 0;
647  fOrdinal = gEnv->GetValue("ProofServ.Ordinal", "-1");
648  fGroupId = -1;
649  fGroupSize = 0;
650  fRealTime = 0.0;
651  fCpuTime = 0.0;
652  fProof = 0;
653  fPlayer = 0;
654  fSocket = 0;
655  fEnabledPackages = new TList;
657 
658  fTotSessions = -1;
659  fActSessions = -1;
660  fEffSessions = -1.;
661 
663 
664  fLogFile = flog;
665  fLogFileDes = -1;
666 
667  fArchivePath = "";
668  // Init lockers
669  fPackageLock = 0;
670  fCacheLock = 0;
671  fQueryLock = 0;
672 
673  fQMgr = 0;
674  fQMtx = new TMutex(kTRUE);
675  fWaitingQueries = new TList;
676  fIdle = kTRUE;
677  fQuerySeqNum = -1;
678 
679  fQueuedMsg = new TList;
680 
682 
683  fShutdownTimer = 0;
684  fReaperTimer = 0;
685  fIdleTOTimer = 0;
686 
687  fDataSetManager = 0; // Initialized in Setup()
688  fDataSetStgRepo = 0; // Initialized in Setup()
689 
690  fInputHandler = 0;
691 
692  // Quotas disabled by default
693  fMaxQueries = -1;
694  fMaxBoxSize = -1;
695  fHWMBoxSize = -1;
696 
697  // Submerger quantities
698  fMergingSocket = 0;
699  fMergingMonitor = 0;
700  fMergedWorkers = 0;
701 
702  // Bit to flg high-memory footprint
704 
705  // Max message size
706  fMsgSizeHWM = gEnv->GetValue("ProofServ.MsgSizeHWM", 1000000);
707 
708  // Message compression
709  fCompressMsg = gEnv->GetValue("ProofServ.CompressMessage", 0);
710 
711  gProofDebugLevel = gEnv->GetValue("Proof.DebugLevel",0);
713 
714  gProofDebugMask = (TProofDebug::EProofDebugMask) gEnv->GetValue("Proof.DebugMask",~0);
715  if (gProofDebugLevel > 0)
716  Info("TProofServ", "DebugLevel %d Mask 0x%x", gProofDebugLevel, gProofDebugMask);
717 
718  // Max log file size
719  fLogFileMaxSize = -1;
720  TString logmx = gEnv->GetValue("ProofServ.LogFileMaxSize", "");
721  if (!logmx.IsNull()) {
722  Long64_t xf = 1;
723  if (!logmx.IsDigit()) {
724  if (logmx.EndsWith("K")) {
725  xf = 1024;
726  logmx.Remove(TString::kTrailing, 'K');
727  } else if (logmx.EndsWith("M")) {
728  xf = 1024*1024;
729  logmx.Remove(TString::kTrailing, 'M');
730  } if (logmx.EndsWith("G")) {
731  xf = 1024*1024*1024;
732  logmx.Remove(TString::kTrailing, 'G');
733  }
734  }
735  if (logmx.IsDigit()) {
736  fLogFileMaxSize = logmx.Atoi() * xf;
737  if (fLogFileMaxSize > 0)
738  Info("TProofServ", "keeping the log file size within %lld bytes", fLogFileMaxSize);
739  } else {
740  logmx = gEnv->GetValue("ProofServ.LogFileMaxSize", "");
741  Warning("TProofServ", "bad formatted log file size limit ignored: '%s'", logmx.Data());
742  }
743  }
744 
745  // Parse options
746  GetOptions(argc, argv);
747 
748  // Default prefix in the form '<role>-<ordinal>'
749  fPrefix = (IsMaster() ? "Mst-" : "Wrk-");
750  if (test) fPrefix = "Test";
751  if (fOrdinal != "-1")
752  fPrefix += fOrdinal;
754 
755  // Syslog control
756  TString slog = gEnv->GetValue("ProofServ.LogToSysLog", "");
757  if (!(slog.IsNull())) {
758  if (slog.IsDigit()) {
759  fgLogToSysLog = slog.Atoi();
760  } else {
761  char c = (slog[0] == 'M' || slog[0] == 'm') ? 'm' : 'a';
762  c = (slog[0] == 'W' || slog[0] == 'w') ? 'w' : c;
763  Bool_t dosyslog = ((c == 'm' && IsMaster()) ||
764  (c == 'w' && !IsMaster()) || c == 'a') ? kTRUE : kFALSE;
765  if (dosyslog) {
766  slog.Remove(0,1);
767  if (slog.IsDigit()) fgLogToSysLog = slog.Atoi();
768  if (fgLogToSysLog <= 0)
769  Warning("TProofServ", "request for syslog logging ineffective!");
770  }
771  }
772  }
773  // Initialize proper service if required
774  if (fgLogToSysLog > 0) {
775  fgSysLogService = (IsMaster()) ? "proofm" : "proofw";
776  if (fOrdinal != "-1") fgSysLogService += TString::Format("-%s", fOrdinal.Data());
778  }
779 
780  // Enable optimized sending of streamer infos to use embedded backward/forward
781  // compatibility support between different ROOT versions and different versions of
782  // users classes
783  Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
784  if (enableSchemaEvolution) {
786  } else {
787  Info("TProofServ", "automatic schema evolution in TMessage explicitly disabled");
788  }
789 }
790 
791 ////////////////////////////////////////////////////////////////////////////////
792 /// Finalize the server setup. If master, create the TProof instance to talk
793 /// to the worker or submaster nodes.
794 /// Return 0 on success, -1 on error
795 
797 {
798  // Get socket to be used (setup in proofd)
799  TString opensock = gSystem->Getenv("ROOTOPENSOCK");
800  if (opensock.Length() <= 0)
801  opensock = gEnv->GetValue("ProofServ.OpenSock", "-1");
802  Int_t sock = opensock.Atoi();
803  if (sock <= 0) {
804  Fatal("CreateServer", "Invalid socket descriptor number (%d)", sock);
805  return -1;
806  }
807  fSocket = new TSocket(sock);
808 
809  // Set compression level, if any
811 
812  // debug hooks
813  if (IsMaster()) {
814  // wait (loop) in master to allow debugger to connect
815  if (gEnv->GetValue("Proof.GdbHook",0) == 1) {
816  while (gProofServDebug)
817  ;
818  }
819  } else {
820  // wait (loop) in slave to allow debugger to connect
821  if (gEnv->GetValue("Proof.GdbHook",0) == 2) {
822  while (gProofServDebug)
823  ;
824  }
825  }
826 
827  if (gProofDebugLevel > 0)
828  Info("CreateServer", "Service %s ConfDir %s IsMaster %d\n",
830 
831  if (Setup() != 0) {
832  // Setup failure
833  LogToMaster();
834  SendLogFile();
835  Terminate(0);
836  return -1;
837  }
838 
839  // Set the default prefix in the form '<role>-<ordinal>' (it was already done
840  // in the constructor, but for standard PROOF the ordinal number is only set in
841  // Setup(), so we need to do it again here)
842  TString pfx = (IsMaster() ? "Mst-" : "Wrk-");
843  pfx += GetOrdinal();
845 
846  if (!fLogFile) {
847  RedirectOutput();
848  // If for some reason we failed setting a redirection file for the logs
849  // we cannot continue
850  if (!fLogFile || (fLogFileDes = fileno(fLogFile)) < 0) {
851  LogToMaster();
852  SendLogFile(-98);
853  Terminate(0);
854  return -1;
855  }
856  } else {
857  // Use the file already open by pmain
858  if ((fLogFileDes = fileno(fLogFile)) < 0) {
859  LogToMaster();
860  SendLogFile(-98);
861  Terminate(0);
862  return -1;
863  }
864  }
865 
866  // Send message of the day to the client
867  if (IsMaster()) {
868  if (CatMotd() == -1) {
869  LogToMaster();
870  SendLogFile(-99);
871  Terminate(0);
872  return -1;
873  }
874  }
875 
876  // Everybody expects std::iostream to be available, so load it...
877  ProcessLine("#include <iostream>", kTRUE);
878  ProcessLine("#include <string>",kTRUE); // for std::string std::iostream.
879 
880  // The following libs are also useful to have, make sure they are loaded...
881  //gROOT->LoadClass("TMinuit", "Minuit");
882  //gROOT->LoadClass("TPostScript", "Postscript");
883 
884  // Load user functions
885  const char *logon;
886  logon = gEnv->GetValue("Proof.Load", (char *)0);
887  if (logon) {
888  char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
889  if (mac)
890  ProcessLine(TString::Format(".L %s", logon), kTRUE);
891  delete [] mac;
892  }
893 
894  // Execute logon macro
895  logon = gEnv->GetValue("Proof.Logon", (char *)0);
896  if (logon && !NoLogOpt()) {
897  char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
898  if (mac)
899  ProcessFile(logon);
900  delete [] mac;
901  }
902 
903  // Save current interpreter context
904  gInterpreter->SaveContext();
905  gInterpreter->SaveGlobalsContext();
906 
907  // Install interrupt and message input handlers
908  gSystem->AddSignalHandler(new TProofServTerminationHandler(this));
909  gSystem->AddSignalHandler(new TProofServInterruptHandler(this));
910  fInputHandler = new TProofServInputHandler(this, sock);
912 
913  // if master, start slave servers
914  if (IsMaster()) {
915  TString master = "proof://__master__";
917  if (a.IsValid()) {
918  master += ":";
919  master += a.GetPort();
920  }
921 
922  // Get plugin manager to load appropriate TProof from
923  TPluginManager *pm = gROOT->GetPluginManager();
924  if (!pm) {
925  Error("CreateServer", "no plugin manager found");
926  SendLogFile(-99);
927  Terminate(0);
928  return -1;
929  }
930 
931  // Find the appropriate handler
932  TPluginHandler *h = pm->FindHandler("TProof", fConfFile);
933  if (!h) {
934  Error("CreateServer", "no plugin found for TProof with a"
935  " config file of '%s'", fConfFile.Data());
936  SendLogFile(-99);
937  Terminate(0);
938  return -1;
939  }
940 
941  // load the plugin
942  if (h->LoadPlugin() == -1) {
943  Error("CreateServer", "plugin for TProof could not be loaded");
944  SendLogFile(-99);
945  Terminate(0);
946  return -1;
947  }
948 
949  // make instance of TProof
950  fProof = reinterpret_cast<TProof*>(h->ExecPlugin(5, master.Data(),
951  fConfFile.Data(),
952  GetConfDir(),
953  fLogLevel, 0));
954  if (!fProof || !fProof->IsValid()) {
955  Error("CreateServer", "plugin for TProof could not be executed");
957  SendLogFile(-99);
958  Terminate(0);
959  return -1;
960  }
961  // Find out if we are a master in direct contact only with workers
963 
964  SendLogFile();
965  }
966 
967  // Setup the shutdown timer
968  if (!fShutdownTimer) {
969  // Check activity on socket every 5 mins
970  fShutdownTimer = new TShutdownTimer(this, 300000);
972  }
973 
974  // Check if schema evolution is effective: clients running versions <=17 do not
975  // support that: send a warning message
976  if (fProtocol <= 17) {
977  TString msg;
978  msg.Form("Warning: client version is too old: automatic schema evolution is ineffective.\n"
979  " This may generate compatibility problems between streamed objects.\n"
980  " The advise is to move to ROOT >= 5.21/02 .");
981  SendAsynMessage(msg.Data());
982  }
983 
984  // Setup the idle timer
985  if (IsMaster() && !fIdleTOTimer) {
986  // Check activity on socket every 5 mins
987  Int_t idle_to = gEnv->GetValue("ProofServ.IdleTimeout", -1);
988  if (idle_to > 0) {
989  fIdleTOTimer = new TIdleTOTimer(this, idle_to * 1000);
990  fIdleTOTimer->Start(-1, kTRUE);
991  if (gProofDebugLevel > 0)
992  Info("CreateServer", " idle timer started (%d secs)", idle_to);
993  } else if (gProofDebugLevel > 0) {
994  Info("CreateServer", " idle timer not started (no idle timeout requested)");
995  }
996  }
997 
998  // Done
999  return 0;
1000 }
1001 
1002 ////////////////////////////////////////////////////////////////////////////////
1003 /// Cleanup. Not really necessary since after this dtor there is no
1004 /// live anyway.
1005 
1007 {
1009  SafeDelete(fQMtx);
1018  close(fLogFileDes);
1019 }
1020 
1021 ////////////////////////////////////////////////////////////////////////////////
1022 /// Print message of the day (in the file pointed by the env PROOFMOTD
1023 /// or from fConfDir/etc/proof/motd). The motd is not shown more than
1024 /// once a day. If the file pointed by env PROOFNOPROOF exists (or the
1025 /// file fConfDir/etc/proof/noproof exists), show its contents and close
1026 /// the connection.
1027 
1029 {
1030  TString lastname;
1031  FILE *motd;
1032  Bool_t show = kFALSE;
1033 
1034  // If we are disabled just print the message and close the connection
1035  TString motdname(GetConfDir());
1036  // The env variable PROOFNOPROOF allows to put the file in an alternative
1037  // location not overwritten by a new installation
1038  if (gSystem->Getenv("PROOFNOPROOF")) {
1039  motdname = gSystem->Getenv("PROOFNOPROOF");
1040  } else {
1041  motdname += "/etc/proof/noproof";
1042  }
1043  if ((motd = fopen(motdname, "r"))) {
1044  Int_t c;
1045  printf("\n");
1046  while ((c = getc(motd)) != EOF)
1047  putchar(c);
1048  fclose(motd);
1049  printf("\n");
1050 
1051  return -1;
1052  }
1053 
1054  // get last modification time of the file ~/proof/.prooflast
1055  lastname = TString(GetWorkDir()) + "/.prooflast";
1056  char *last = gSystem->ExpandPathName(lastname.Data());
1057  Long64_t size;
1058  Long_t id, flags, modtime, lasttime = 0;
1059  if (gSystem->GetPathInfo(last, &id, &size, &flags, &lasttime) == 1)
1060  lasttime = 0;
1061 
1062  // show motd at least once per day
1063  if (time(0) - lasttime > (time_t)86400)
1064  show = kTRUE;
1065 
1066  // The env variable PROOFMOTD allows to put the file in an alternative
1067  // location not overwritten by a new installation
1068  if (gSystem->Getenv("PROOFMOTD")) {
1069  motdname = gSystem->Getenv("PROOFMOTD");
1070  } else {
1071  motdname = GetConfDir();
1072  motdname += "/etc/proof/motd";
1073  }
1074  if (gSystem->GetPathInfo(motdname, &id, &size, &flags, &modtime) == 0) {
1075  if (modtime > lasttime || show) {
1076  if ((motd = fopen(motdname, "r"))) {
1077  Int_t c;
1078  printf("\n");
1079  while ((c = getc(motd)) != EOF)
1080  putchar(c);
1081  fclose(motd);
1082  printf("\n");
1083  }
1084  }
1085  }
1086 
1087  if (lasttime)
1088  gSystem->Unlink(last);
1089  Int_t fd = creat(last, 0600);
1090  if (fd >= 0) close(fd);
1091  delete [] last;
1092 
1093  return 0;
1094 }
1095 
1096 ////////////////////////////////////////////////////////////////////////////////
1097 /// Get object with name "name;cycle" (e.g. "aap;2") from master or client.
1098 /// This method is called by TDirectory::Get() in case the object can not
1099 /// be found locally.
1100 
1101 TObject *TProofServ::Get(const char *namecycle)
1102 {
1103  if (fSocket->Send(namecycle, kPROOF_GETOBJECT) < 0) {
1104  Error("Get", "problems sending request");
1105  return (TObject *)0;
1106  }
1107 
1108  TObject *idcur = 0;
1109 
1110  Bool_t notdone = kTRUE;
1111  while (notdone) {
1112  TMessage *mess = 0;
1113  if (fSocket->Recv(mess) < 0)
1114  return 0;
1115  Int_t what = mess->What();
1116  if (what == kMESS_OBJECT) {
1117  idcur = mess->ReadObject(mess->GetClass());
1118  notdone = kFALSE;
1119  } else {
1120  Int_t xrc = HandleSocketInput(mess, kFALSE);
1121  if (xrc == -1) {
1122  Error("Get", "command %d cannot be executed while processing", what);
1123  } else if (xrc == -2) {
1124  Error("Get", "unknown command %d ! Protocol error?", what);
1125  }
1126  }
1127  delete mess;
1128  }
1129 
1130  return idcur;
1131 }
1132 
1133 ////////////////////////////////////////////////////////////////////////////////
1134 /// Reset the compute time
1135 
1137 {
1138  fCompute.Stop();
1139  if (fPlayer) {
1141  if (status) status->SetLearnTime(fCompute.RealTime());
1142  Info("RestartComputeTime", "compute time restarted after %f secs (%d entries)",
1144  }
1146 }
1147 
1148 ////////////////////////////////////////////////////////////////////////////////
1149 /// Get next range of entries to be processed on this server.
1150 
1152 {
1153  Long64_t bytesRead = 0;
1154 
1155  if (gPerfStats) bytesRead = gPerfStats->GetBytesRead();
1156 
1157  if (fCompute.Counter() > 0)
1158  fCompute.Stop();
1159 
1161  Double_t cputime = fCompute.CpuTime();
1162  Double_t realtime = fCompute.RealTime();
1163 
1164  if (fProtocol > 18) {
1165  req << fLatency.RealTime();
1166  TProofProgressStatus *status = 0;
1167  if (fPlayer) {
1169  status = fPlayer->GetProgressStatus();
1170  } else {
1171  Error("GetNextPacket", "no progress status object");
1172  return 0;
1173  }
1174  // the CPU and wallclock proc times are kept in the TProofServ and here
1175  // added to the status object in the fPlayer.
1176  if (status->GetEntries() > 0) {
1177  PDB(kLoop, 2) status->Print(GetOrdinal());
1178  status->IncProcTime(realtime);
1179  status->IncCPUTime(cputime);
1180  }
1181  // Flag cases with problems in opening files
1182  if (totalEntries < 0) status->SetBit(TProofProgressStatus::kFileNotOpen);
1183  // Add to the message
1184  req << status;
1185  // Send tree cache information
1186  Long64_t cacheSize = (fPlayer) ? fPlayer->GetCacheSize() : -1;
1187  Int_t learnent = (fPlayer) ? fPlayer->GetLearnEntries() : -1;
1188  req << cacheSize << learnent;
1189 
1190  // Sent over the number of entries in the file, used by packetizer do not relying
1191  // on initial validation. Also, -1 means that the file could not be open, which is
1192  // used to flag files as missing
1193  req << totalEntries;
1194 
1195  // Send the time spent in saving the partial result to file
1196  if (fProtocol > 34) req << fSaveOutput.RealTime();
1197 
1198  PDB(kLoop, 1) {
1199  PDB(kLoop, 2) status->Print();
1200  Info("GetNextPacket","cacheSize: %lld, learnent: %d", cacheSize, learnent);
1201  }
1202  // Reset the status bits
1203  status->ResetBit(TProofProgressStatus::kFileNotOpen);
1204  status->ResetBit(TProofProgressStatus::kFileCorrupted);
1205  status = 0; // status is owned by the player.
1206  } else {
1207  req << fLatency.RealTime() << realtime << cputime
1208  << bytesRead << totalEntries;
1209  if (fPlayer)
1210  req << fPlayer->GetEventsProcessed();
1211  }
1212 
1213  fLatency.Start();
1214  Int_t rc = fSocket->Send(req);
1215  if (rc <= 0) {
1216  Error("GetNextPacket","Send() failed, returned %d", rc);
1217  return 0;
1218  }
1219 
1220  // Save the current output
1221  if (fPlayer) {
1222  fSaveOutput.Start();
1223  if (fPlayer->SavePartialResults(kFALSE) < 0)
1224  Warning("GetNextPacket", "problems saving partial results");
1225  fSaveOutput.Stop();
1226  }
1227 
1228  TDSetElement *e = 0;
1229  Bool_t notdone = kTRUE;
1230  while (notdone) {
1231 
1232  TMessage *mess;
1233  if ((rc = fSocket->Recv(mess)) <= 0) {
1234  fLatency.Stop();
1235  Error("GetNextPacket","Recv() failed, returned %d", rc);
1236  return 0;
1237  }
1238 
1239  Int_t xrc = 0;
1240  TString file, dir, obj;
1241 
1242  Int_t what = mess->What();
1243 
1244  switch (what) {
1245  case kPROOF_GETPACKET:
1246 
1247  fLatency.Stop();
1248  (*mess) >> e;
1249  if (e != 0) {
1250  fCompute.Start();
1251  PDB(kLoop, 2) Info("GetNextPacket", "'%s' '%s' '%s' %lld %lld",
1252  e->GetFileName(), e->GetDirectory(),
1253  e->GetObjName(), e->GetFirst(),e->GetNum());
1254  } else {
1255  PDB(kLoop, 2) Info("GetNextPacket", "Done");
1256  }
1257  notdone = kFALSE;
1258  break;
1259 
1260  case kPROOF_STOPPROCESS:
1261  // if a kPROOF_STOPPROCESS message is returned to kPROOF_GETPACKET
1262  // GetNextPacket() will return 0 and the TPacketizer and hence
1263  // TEventIter will be stopped
1264  fLatency.Stop();
1265  PDB(kLoop, 2) Info("GetNextPacket:kPROOF_STOPPROCESS","received");
1266  break;
1267 
1268  default:
1269  xrc = HandleSocketInput(mess, kFALSE);
1270  if (xrc == -1) {
1271  Error("GetNextPacket", "command %d cannot be executed while processing", what);
1272  } else if (xrc == -2) {
1273  Error("GetNextPacket", "unknown command %d ! Protocol error?", what);
1274  }
1275  break;
1276  }
1277 
1278  delete mess;
1279 
1280  }
1281 
1282  // Done
1283  return e;
1284 }
1285 
1286 ////////////////////////////////////////////////////////////////////////////////
1287 /// Get and handle command line options. Fixed format:
1288 /// "proofserv"|"proofslave" <confdir>
1289 
1290 void TProofServ::GetOptions(Int_t *argc, char **argv)
1291 {
1292  Bool_t xtest = (argc && *argc > 3 && !strcmp(argv[3], "test")) ? kTRUE : kFALSE;
1293 
1294  // If test and tty
1295  if (xtest && !(isatty(0) == 0 || isatty(1) == 0)) {
1296  Printf("proofserv: command line testing: OK");
1297  exit(0);
1298  }
1299 
1300  if (!argc || (argc && *argc <= 1)) {
1301  Fatal("GetOptions", "Must be started from proofd with arguments");
1302  exit(1);
1303  }
1304 
1305  if (!strcmp(argv[1], "proofserv")) {
1306  fMasterServ = kTRUE;
1307  fEndMaster = kTRUE;
1308  } else if (!strcmp(argv[1], "proofslave")) {
1309  fMasterServ = kFALSE;
1310  fEndMaster = kFALSE;
1311  } else {
1312  Fatal("GetOptions", "Must be started as 'proofserv' or 'proofslave'");
1313  exit(1);
1314  }
1315 
1316  fService = argv[1];
1317 
1318  // Confdir
1319  if (!(gSystem->Getenv("ROOTCONFDIR"))) {
1320  Fatal("GetOptions", "ROOTCONFDIR shell variable not set");
1321  exit(1);
1322  }
1323  fConfDir = gSystem->Getenv("ROOTCONFDIR");
1324 }
1325 
1326 ////////////////////////////////////////////////////////////////////////////////
1327 /// Handle input coming from the client or from the master server.
1328 
1330 {
1331  // The idle timeout guard: stops the timer and restarts when we return from here
1333 
1334  Bool_t all = (fgRecursive > 0) ? kFALSE : kTRUE;
1335  fgRecursive++;
1336 
1337  TMessage *mess;
1338  Int_t rc = 0;
1339  TString exmsg;
1340 
1341  // Check log file length (before the action, so we have the chance to keep the
1342  // latest logs)
1343  TruncateLogFile();
1344 
1345  try {
1346 
1347  // Get message
1348  if (fSocket->Recv(mess) <= 0 || !mess) {
1349  // Pending: do something more intelligent here
1350  // but at least get a message in the log file
1351  Error("HandleSocketInput", "retrieving message from input socket");
1352  Terminate(0);
1353  return;
1354  }
1355  Int_t what = mess->What();
1356  PDB(kCollect, 1)
1357  Info("HandleSocketInput", "got type %d from '%s'", what, fSocket->GetTitle());
1358 
1359  fNcmd++;
1360 
1361  if (fProof) fProof->SetActive();
1362 
1363  Bool_t doit = kTRUE;
1364 
1365  while (doit) {
1366 
1367  // Process the message
1368  rc = HandleSocketInput(mess, all);
1369  if (rc < 0) {
1370  TString emsg;
1371  if (rc == -1) {
1372  emsg.Form("HandleSocketInput: command %d cannot be executed while processing", what);
1373  } else if (rc == -3) {
1374  emsg.Form("HandleSocketInput: message %d undefined! Protocol error?", what);
1375  } else {
1376  emsg.Form("HandleSocketInput: unknown command %d! Protocol error?", what);
1377  }
1378  SendAsynMessage(emsg.Data());
1379  } else if (rc == 2) {
1380  // Add to the queue
1381  fQueuedMsg->Add(mess);
1382  PDB(kGlobal, 1)
1383  Info("HandleSocketInput", "message of type %d enqueued; sz: %d",
1384  what, fQueuedMsg->GetSize());
1385  mess = 0;
1386  }
1387 
1388  // Still something to do?
1389  doit = 0;
1390  if (fgRecursive == 1 && fQueuedMsg->GetSize() > 0) {
1391  // Add to the queue
1392  PDB(kCollect, 1)
1393  Info("HandleSocketInput", "processing enqueued message of type %d; left: %d",
1394  what, fQueuedMsg->GetSize());
1395  all = 1;
1396  SafeDelete(mess);
1397  mess = (TMessage *) fQueuedMsg->First();
1398  if (mess) fQueuedMsg->Remove(mess);
1399  doit = 1;
1400  }
1401  }
1402 
1403  } catch (std::bad_alloc &) {
1404  // Memory allocation problem:
1405  exmsg.Form("caught exception 'bad_alloc' (memory leak?) %s %lld",
1407  } catch (std::exception &exc) {
1408  // Standard exception caught
1409  exmsg.Form("caught standard exception '%s' %s %lld",
1410  exc.what(), fgLastMsg.Data(), fgLastEntry);
1411  } catch (int i) {
1412  // Other exception caught
1413  exmsg.Form("caught exception throwing %d %s %lld",
1414  i, fgLastMsg.Data(), fgLastEntry);
1415  } catch (const char *str) {
1416  // Other exception caught
1417  exmsg.Form("caught exception throwing '%s' %s %lld",
1418  str, fgLastMsg.Data(), fgLastEntry);
1419  } catch (...) {
1420  // Caught other exception
1421  exmsg.Form("caught exception <unknown> %s %lld",
1423  }
1424 
1425  // Terminate on exception
1426  if (!exmsg.IsNull()) {
1427  // Save info in the log file too
1428  Error("HandleSocketInput", "%s", exmsg.Data());
1429  // Try to warn the user
1430  SendAsynMessage(TString::Format("%s: %s", GetOrdinal(), exmsg.Data()));
1431  // Terminate
1432  Terminate(0);
1433  }
1434 
1435  // Terminate also if a high memory footprint was detected before the related
1436  // exception was thrwon
1438  // Save info in the log file too
1439  exmsg.Form("high-memory footprint detected during Process(...) - terminating");
1440  Error("HandleSocketInput", "%s", exmsg.Data());
1441  // Try to warn the user
1442  SendAsynMessage(TString::Format("%s: %s", GetOrdinal(), exmsg.Data()));
1443  // Terminate
1444  Terminate(0);
1445  }
1446 
1447  fgRecursive--;
1448 
1449  if (fProof) {
1450  // If something wrong went on during processing and we do not have
1451  // any worker anymore, we shutdown this session
1452  Bool_t masterOnly = gEnv->GetValue("Proof.MasterOnly", kFALSE);
1453  Bool_t dynamicStartup = gEnv->GetValue("Proof.DynamicStartup", kFALSE);
1455  if (rc == 0 && ngwrks == 0 && !masterOnly && !dynamicStartup) {
1456  SendAsynMessage(" *** No workers left: cannot continue! Terminating ... *** ");
1457  Terminate(0);
1458  }
1460  // Reset PROOF to running state
1462  }
1463 
1464  // Cleanup
1465  SafeDelete(mess);
1466 }
1467 
1468 ////////////////////////////////////////////////////////////////////////////////
1469 /// Process input coming from the client or from the master server.
1470 /// If 'all' is kFALSE, process only those messages that can be handled
1471 /// during query processing.
1472 /// Returns -1 if the message could not be processed, <-1 if something went
1473 /// wrong. Returns 1 if the action may have changed the parallel state.
1474 /// Returns 2 if the message has to be enqueued.
1475 /// Returns 0 otherwise
1476 
1478 {
1479  static TStopwatch timer;
1480  char str[2048];
1481  Bool_t aborted = kFALSE;
1482 
1483  if (!mess) return -3;
1484 
1485  Int_t what = mess->What();
1486  PDB(kCollect, 1)
1487  Info("HandleSocketInput", "processing message type %d from '%s'",
1488  what, fSocket->GetTitle());
1489 
1490  timer.Start();
1491 
1492  Int_t rc = 0, lirc = 0;
1493  TString slb;
1494  TString *pslb = (fgLogToSysLog > 0) ? &slb : (TString *)0;
1495 
1496  switch (what) {
1497 
1498  case kMESS_CINT:
1499  if (all) {
1500  mess->ReadString(str, sizeof(str));
1501  // Make sure that the relevant files are available
1502  TString fn;
1503 
1504  Bool_t hasfn = TProof::GetFileInCmd(str, fn);
1505 
1506  if (IsParallel() && fProof && !fProof->UseDynamicStartup()) {
1507  fProof->SendCommand(str);
1508  } else {
1509  PDB(kGlobal, 1)
1510  Info("HandleSocketInput:kMESS_CINT", "processing: %s...", str);
1511  TString ocwd;
1512  if (hasfn) {
1513  fCacheLock->Lock();
1514  ocwd = gSystem->WorkingDirectory();
1516  }
1517  ProcessLine(str);
1518  if (hasfn) {
1519  gSystem->ChangeDirectory(ocwd);
1520  fCacheLock->Unlock();
1521  }
1522  }
1523 
1524  LogToMaster();
1525  } else {
1526  rc = -1;
1527  }
1528  SendLogFile();
1529  if (pslb) slb = str;
1530  break;
1531 
1532  case kMESS_STRING:
1533  if (all) {
1534  mess->ReadString(str, sizeof(str));
1535  } else {
1536  rc = -1;
1537  }
1538  break;
1539 
1540  case kMESS_OBJECT:
1541  if (all) {
1542  mess->ReadObject(mess->GetClass());
1543  } else {
1544  rc = -1;
1545  }
1546  break;
1547 
1548  case kPROOF_GROUPVIEW:
1549  if (all) {
1550  mess->ReadString(str, sizeof(str));
1551  // coverity[secure_coding]
1552  sscanf(str, "%d %d", &fGroupId, &fGroupSize);
1553  } else {
1554  rc = -1;
1555  }
1556  break;
1557 
1558  case kPROOF_LOGLEVEL:
1559  { UInt_t mask;
1560  mess->ReadString(str, sizeof(str));
1561  sscanf(str, "%d %u", &fLogLevel, &mask);
1562  Bool_t levelchanged = (fLogLevel != gProofDebugLevel) ? kTRUE : kFALSE;
1565  if (levelchanged)
1566  Info("HandleSocketInput:kPROOF_LOGLEVEL", "debug level set to %d (mask: 0x%x)",
1568  if (IsMaster())
1569  fProof->SetLogLevel(fLogLevel, mask);
1570  }
1571  break;
1572 
1573  case kPROOF_PING:
1574  { if (IsMaster())
1575  fProof->Ping();
1576  // do nothing (ping is already acknowledged)
1577  }
1578  break;
1579 
1580  case kPROOF_PRINT:
1581  mess->ReadString(str, sizeof(str));
1582  Print(str);
1583  LogToMaster();
1584  SendLogFile();
1585  break;
1586 
1587  case kPROOF_RESET:
1588  if (all) {
1589  mess->ReadString(str, sizeof(str));
1590  Reset(str);
1591  } else {
1592  rc = -1;
1593  }
1594  break;
1595 
1596  case kPROOF_STATUS:
1597  Warning("HandleSocketInput:kPROOF_STATUS",
1598  "kPROOF_STATUS message is obsolete");
1600  Warning("HandleSocketInput:kPROOF_STATUS", "problem sending of request");
1601  break;
1602 
1603  case kPROOF_GETSTATS:
1604  SendStatistics();
1605  break;
1606 
1607  case kPROOF_GETPARALLEL:
1608  SendParallel();
1609  break;
1610 
1611  case kPROOF_STOP:
1612  if (all) {
1613  if (IsMaster()) {
1614  TString ord;
1615  *mess >> ord;
1616  PDB(kGlobal, 1)
1617  Info("HandleSocketInput:kPROOF_STOP", "request for worker %s", ord.Data());
1618  if (fProof) fProof->TerminateWorker(ord);
1619  } else {
1620  PDB(kGlobal, 1)
1621  Info("HandleSocketInput:kPROOF_STOP", "got request to terminate");
1622  Terminate(0);
1623  }
1624  } else {
1625  rc = -1;
1626  }
1627  break;
1628 
1629  case kPROOF_STOPPROCESS:
1630  if (all) {
1631  // this message makes only sense when the query is being processed,
1632  // however the message can also be received if the user pressed
1633  // ctrl-c, so ignore it!
1634  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_STOPPROCESS","enter");
1635  } else {
1636  Long_t timeout = -1;
1637  (*mess) >> aborted;
1638  if (fProtocol > 9)
1639  (*mess) >> timeout;
1640  PDB(kGlobal, 1)
1641  Info("HandleSocketInput:kPROOF_STOPPROCESS",
1642  "recursive mode: enter %d, %ld", aborted, timeout);
1643  if (fProof)
1644  // On the master: propagate further
1645  fProof->StopProcess(aborted, timeout);
1646  else
1647  // Worker: actually stop processing
1648  if (fPlayer)
1649  fPlayer->StopProcess(aborted, timeout);
1650  }
1651  break;
1652 
1653  case kPROOF_PROCESS:
1654  {
1656  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_PROCESS","enter");
1657  HandleProcess(mess, pslb);
1658  // The log file is send either in HandleProcess or HandleSubmergers.
1659  // The reason is that the order of various messages depend on the
1660  // processing mode (sync/async) and/or merging mode
1661  }
1662  break;
1663 
1664  case kPROOF_SENDOUTPUT:
1665  {
1666  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_SENDOUTPUT",
1667  "worker was asked to send output to master");
1668  Int_t sorc = 0;
1669  if (SendResults(fSocket, fPlayer->GetOutputList()) != 0) {
1670  Error("HandleSocketInput:kPROOF_SENDOUTPUT", "problems sending output list");
1671  sorc = 1;
1672  }
1673  // Signal the master that we are idle
1675  SetIdle(kTRUE);
1676  DeletePlayer();
1677  SendLogFile(sorc);
1678  }
1679  break;
1680 
1681  case kPROOF_QUERYLIST:
1682  {
1683  HandleQueryList(mess);
1684  // Notify
1685  SendLogFile();
1686  }
1687  break;
1688 
1689  case kPROOF_REMOVE:
1690  {
1691  HandleRemove(mess, pslb);
1692  // Notify
1693  SendLogFile();
1694  }
1695  break;
1696 
1697  case kPROOF_RETRIEVE:
1698  {
1699  HandleRetrieve(mess, pslb);
1700  // Notify
1701  SendLogFile();
1702  }
1703  break;
1704 
1705  case kPROOF_ARCHIVE:
1706  {
1707  HandleArchive(mess, pslb);
1708  // Notify
1709  SendLogFile();
1710  }
1711  break;
1712 
1713  case kPROOF_MAXQUERIES:
1714  { PDB(kGlobal, 1)
1715  Info("HandleSocketInput:kPROOF_MAXQUERIES", "Enter");
1717  m << fMaxQueries;
1718  fSocket->Send(m);
1719  // Notify
1720  SendLogFile();
1721  }
1722  break;
1723 
1724  case kPROOF_CLEANUPSESSION:
1725  if (all) {
1726  PDB(kGlobal, 1)
1727  Info("HandleSocketInput:kPROOF_CLEANUPSESSION", "Enter");
1728  TString stag;
1729  (*mess) >> stag;
1730  if (fQMgr && fQMgr->CleanupSession(stag) == 0) {
1731  Printf("Session %s cleaned up", stag.Data());
1732  } else {
1733  Printf("Could not cleanup session %s", stag.Data());
1734  }
1735  } else {
1736  rc = -1;
1737  }
1738  // Notify
1739  SendLogFile();
1740  break;
1741 
1742  case kPROOF_GETENTRIES:
1743  { PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETENTRIES", "Enter");
1744  Bool_t isTree;
1745  TString filename;
1746  TString dir;
1747  TString objname("undef");
1748  Long64_t entries = -1;
1749 
1750  if (all) {
1751  (*mess) >> isTree >> filename >> dir >> objname;
1752  PDB(kGlobal, 2) Info("HandleSocketInput:kPROOF_GETENTRIES",
1753  "Report size of object %s (%s) in dir %s in file %s",
1754  objname.Data(), isTree ? "T" : "O",
1755  dir.Data(), filename.Data());
1756  entries = TDSet::GetEntries(isTree, filename, dir, objname);
1757  PDB(kGlobal, 2) Info("HandleSocketInput:kPROOF_GETENTRIES",
1758  "Found %lld %s", entries, isTree ? "entries" : "objects");
1759  } else {
1760  rc = -1;
1761  }
1763  answ << entries << objname;
1764  SendLogFile(); // in case of error messages
1765  fSocket->Send(answ);
1766  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETENTRIES", "Done");
1767  }
1768  break;
1769 
1770  case kPROOF_CHECKFILE:
1771  if (!all && fProtocol <= 19) {
1772  // Come back later
1773  rc = 2;
1774  } else {
1775  // Handle file checking request
1776  HandleCheckFile(mess, pslb);
1777  }
1778  break;
1779 
1780  case kPROOF_SENDFILE:
1781  if (!all && fProtocol <= 19) {
1782  // Come back later
1783  rc = 2;
1784  } else {
1785  mess->ReadString(str, sizeof(str));
1786  Long_t size;
1787  Int_t bin, fw = 1;
1788  char name[1024];
1789  if (fProtocol > 5) {
1790  sscanf(str, "%1023s %d %ld %d", name, &bin, &size, &fw);
1791  } else {
1792  sscanf(str, "%1023s %d %ld", name, &bin, &size);
1793  }
1794  TString fnam(name);
1795  Bool_t copytocache = kTRUE;
1796  if (fnam.BeginsWith("cache:")) {
1797  fnam.ReplaceAll("cache:", TString::Format("%s/", fCacheDir.Data()));
1798  copytocache = kFALSE;
1799  }
1800 
1801  Int_t rfrc = 0;
1802  if (size > 0) {
1803  rfrc = ReceiveFile(fnam, bin ? kTRUE : kFALSE, size);
1804  } else {
1805  // Take it from the cache
1806  if (!fnam.BeginsWith(fCacheDir.Data())) {
1807  fnam.Insert(0, TString::Format("%s/", fCacheDir.Data()));
1808  }
1809  }
1810  if (rfrc == 0) {
1811  // copy file to cache if not a PAR file
1812  if (copytocache && size > 0 &&
1813  strncmp(fPackageDir, name, fPackageDir.Length()))
1814  gSystem->Exec(TString::Format("%s %s %s", kCP, fnam.Data(), fCacheDir.Data()));
1815 
1816  if (IsMaster() && fw == 1) {
1818  if (bin)
1819  opt |= TProof::kBinary;
1820  PDB(kGlobal, 1)
1821  Info("HandleSocketInput","forwarding file: %s", fnam.Data());
1822  if (fProof->SendFile(fnam, opt, (copytocache ? "cache" : "")) < 0) {
1823  Error("HandleSocketInput", "forwarding file: %s", fnam.Data());
1824  }
1825  }
1826  if (fProtocol > 19) fSocket->Send(kPROOF_SENDFILE);
1827  } else {
1828  // There was an error
1829  SendLogFile(1);
1830  }
1831  }
1832  break;
1833 
1834  case kPROOF_LOGFILE:
1835  {
1836  Int_t start, end;
1837  (*mess) >> start >> end;
1838  PDB(kGlobal, 1)
1839  Info("HandleSocketInput:kPROOF_LOGFILE",
1840  "Logfile request - byte range: %d - %d", start, end);
1841 
1842  LogToMaster();
1843  SendLogFile(0, start, end);
1844  }
1845  break;
1846 
1847  case kPROOF_PARALLEL:
1848  if (all) {
1849  if (IsMaster()) {
1850  Int_t nodes;
1851  Bool_t random = kFALSE;
1852  (*mess) >> nodes;
1853  if ((mess->BufferSize() > mess->Length()))
1854  (*mess) >> random;
1855  if (fProof) fProof->SetParallel(nodes, random);
1856  rc = 1;
1857  }
1858  } else {
1859  rc = -1;
1860  }
1861  // Notify
1862  SendLogFile();
1863  break;
1864 
1865  case kPROOF_CACHE:
1866  if (!all && fProtocol <= 19) {
1867  // Come back later
1868  rc = 2;
1869  } else {
1871  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_CACHE","enter");
1872  Int_t hcrc = HandleCache(mess, pslb);
1873  // Notify
1874  SendLogFile(hcrc);
1875  }
1876  break;
1877 
1878  case kPROOF_WORKERLISTS:
1879  { Int_t wlrc = -1;
1880  if (all) {
1881  if (IsMaster())
1882  wlrc = HandleWorkerLists(mess);
1883  else
1884  Warning("HandleSocketInput:kPROOF_WORKERLISTS",
1885  "Action meaning-less on worker nodes: protocol error?");
1886  } else {
1887  rc = -1;
1888  }
1889  // Notify
1890  SendLogFile(wlrc);
1891  }
1892  break;
1893 
1894  case kPROOF_GETSLAVEINFO:
1895  if (all) {
1896  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETSLAVEINFO", "Enter");
1897  if (IsMaster()) {
1898 
1899  Bool_t ok = kTRUE;
1900  // if the session does not have workers and is in the dynamic mode
1901  if (fProof->UseDynamicStartup()) {
1902  ok = kFALSE;
1903  // get the a list of workers and start them
1904  Int_t pc = 0;
1905  TList* workerList = new TList();
1906  EQueryAction retVal = GetWorkers(workerList, pc);
1907  if (retVal != TProofServ::kQueryStop && retVal != TProofServ::kQueryEnqueued) {
1908  if (Int_t ret = fProof->AddWorkers(workerList) < 0) {
1909  Error("HandleSocketInput:kPROOF_GETSLAVEINFO",
1910  "adding a list of worker nodes returned: %d", ret);
1911  }
1912  } else {
1913  Error("HandleSocketInput:kPROOF_GETSLAVEINFO",
1914  "getting list of worker nodes returned: %d", retVal);
1915  }
1916  ok = kTRUE;
1917  }
1918  if (ok) {
1919  TList *info = fProof->GetListOfSlaveInfos();
1921  answ << info;
1922  fSocket->Send(answ);
1923  // stop the workers
1925  }
1926  } else {
1928  TList *info = new TList;
1929  TSlaveInfo *wi = new TSlaveInfo(GetOrdinal(), TUrl(gSystem->HostName()).GetHostFQDN(), 0, "", GetDataDir());
1930  SysInfo_t si;
1931  gSystem->GetSysInfo(&si);
1932  wi->SetSysInfo(si);
1933  info->Add(wi);
1934  answ << (TList *)info;
1935  fSocket->Send(answ);
1936  info->SetOwner(kTRUE);
1937  delete info;
1938  }
1939 
1940  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETSLAVEINFO", "Done");
1941  } else {
1943  answ << (TList *)0;
1944  fSocket->Send(answ);
1945  rc = -1;
1946  }
1947  break;
1948 
1949  case kPROOF_GETTREEHEADER:
1950  if (all) {
1951  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETTREEHEADER", "Enter");
1952 
1954  if (p) {
1955  p->HandleGetTreeHeader(mess);
1956  delete p;
1957  } else {
1958  Error("HandleSocketInput:kPROOF_GETTREEHEADER", "could not create TProofPlayer instance!");
1959  }
1960 
1961  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETTREEHEADER", "Done");
1962  } else {
1964  answ << TString("Failed") << (TObject *)0;
1965  fSocket->Send(answ);
1966  rc = -1;
1967  }
1968  break;
1969 
1970  case kPROOF_GETOUTPUTLIST:
1971  { PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETOUTPUTLIST", "Enter");
1972  TList* outputList = 0;
1973  if (IsMaster()) {
1974  outputList = fProof->GetOutputList();
1975  if (!outputList)
1976  outputList = new TList();
1977  } else {
1978  outputList = new TList();
1979  if (fProof->GetPlayer()) {
1980  TList *olist = fProof->GetPlayer()->GetOutputList();
1981  TIter next(olist);
1982  TObject *o;
1983  while ( (o = next()) ) {
1984  outputList->Add(new TNamed(o->GetName(), ""));
1985  }
1986  }
1987  }
1988  outputList->SetOwner();
1990  answ << outputList;
1991  fSocket->Send(answ);
1992  delete outputList;
1993  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETOUTPUTLIST", "Done");
1994  }
1995  break;
1996 
1997  case kPROOF_VALIDATE_DSET:
1998  if (all) {
1999  PDB(kGlobal, 1)
2000  Info("HandleSocketInput:kPROOF_VALIDATE_DSET", "Enter");
2001 
2002  TDSet* dset = 0;
2003  (*mess) >> dset;
2004 
2005  if (IsMaster()) fProof->ValidateDSet(dset);
2006  else dset->Validate();
2007 
2009  answ << dset;
2010  fSocket->Send(answ);
2011  delete dset;
2012  PDB(kGlobal, 1)
2013  Info("HandleSocketInput:kPROOF_VALIDATE_DSET", "Done");
2014  } else {
2015  rc = -1;
2016  }
2017  // Notify
2018  SendLogFile();
2019  break;
2020 
2021  case kPROOF_DATA_READY:
2022  if (all) {
2023  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_DATA_READY", "Enter");
2025  if (IsMaster()) {
2026  Long64_t totalbytes = 0, bytesready = 0;
2027  Bool_t dataready = fProof->IsDataReady(totalbytes, bytesready);
2028  answ << dataready << totalbytes << bytesready;
2029  } else {
2030  Error("HandleSocketInput:kPROOF_DATA_READY",
2031  "This message should not be sent to slaves");
2032  answ << kFALSE << Long64_t(0) << Long64_t(0);
2033  }
2034  fSocket->Send(answ);
2035  PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_DATA_READY", "Done");
2036  } else {
2038  answ << kFALSE << Long64_t(0) << Long64_t(0);
2039  fSocket->Send(answ);
2040  rc = -1;
2041  }
2042  // Notify
2043  SendLogFile();
2044  break;
2045 
2046  case kPROOF_DATASETS:
2047  { Int_t dsrc = -1;
2048  if (fProtocol > 16) {
2049  dsrc = HandleDataSets(mess, pslb);
2050  } else {
2051  Error("HandleSocketInput", "old client: no or incompatible dataset support");
2052  }
2053  SendLogFile(dsrc);
2054  }
2055  break;
2056 
2057  case kPROOF_SUBMERGER:
2058  { HandleSubmerger(mess);
2059  }
2060  break;
2061 
2062  case kPROOF_LIB_INC_PATH:
2063  if (all) {
2064  lirc = HandleLibIncPath(mess);
2065  } else {
2066  rc = -1;
2067  }
2068  // Notify the client
2069  if (lirc > 0) SendLogFile();
2070  break;
2071 
2072  case kPROOF_REALTIMELOG:
2073  { Bool_t on;
2074  (*mess) >> on;
2075  PDB(kGlobal, 1)
2076  Info("HandleSocketInput:kPROOF_REALTIMELOG",
2077  "setting real-time logging %s", (on ? "ON" : "OFF"));
2078  fRealTimeLog = on;
2079  // Forward the request to lower levels
2080  if (IsMaster())
2081  fProof->SetRealTimeLog(on);
2082  }
2083  break;
2084 
2085  case kPROOF_FORK:
2086  if (all) {
2087  HandleFork(mess);
2088  LogToMaster();
2089  } else {
2090  rc = -1;
2091  }
2092  SendLogFile();
2093  break;
2094 
2095  case kPROOF_STARTPROCESS:
2096  if (all) {
2097  // This message resumes the session; should not come during processing.
2098 
2099  if (WaitingQueries() == 0) {
2100  Error("HandleSocketInput", "no queries enqueued");
2101  break;
2102  }
2103 
2104  // Similar to handle process
2105  // get the list of workers and start them
2106  TList *workerList = (fProof->UseDynamicStartup()) ? new TList : (TList *)0;
2107  Int_t pc = 0;
2108  EQueryAction retVal = GetWorkers(workerList, pc, kTRUE);
2109 
2110  if (retVal == TProofServ::kQueryOK) {
2111  Int_t ret = 0;
2112  if (workerList && (ret = fProof->AddWorkers(workerList)) < 0) {
2113  Error("HandleSocketInput", "adding a list of worker nodes returned: %d", ret);
2114  } else {
2115  ProcessNext(pslb);
2116  // Set idle
2117  SetIdle(kTRUE);
2118  // Signal the client that we are idle
2120  Bool_t waiting = (WaitingQueries() > 0) ? kTRUE : kFALSE;
2121  m << waiting;
2122  fSocket->Send(m);
2123  }
2124  } else {
2125  if (retVal == TProofServ::kQueryStop) {
2126  Error("HandleSocketInput", "error getting list of worker nodes");
2127  } else if (retVal != TProofServ::kQueryEnqueued) {
2128  Warning("HandleSocketInput", "query was re-queued!");
2129  } else {
2130  Error("HandleSocketInput", "unexpected answer: %d", retVal);
2131  break;
2132  }
2133  }
2134 
2135  }
2136  break;
2137 
2138  case kPROOF_GOASYNC:
2139  { // The client requested to switch to asynchronous mode:
2140  // communicate the sequential number of the running query for later
2141  // identification, if any
2142  if (!IsIdle() && fPlayer) {
2143  // Get query currently being processed
2146  m << pq->GetSeqNum() << kFALSE;
2147  fSocket->Send(m);
2148  } else {
2149  // Idle or undefined: nothing to do; ignore
2150  SendAsynMessage("Processing request to go asynchronous:"
2151  " idle or undefined player - ignoring");
2152  }
2153  }
2154  break;
2155 
2156  case kPROOF_ECHO:
2157  { // Echo request: an object has been sent along. If the object is a
2158  // string, it is simply echoed back to the client from the master
2159  // and each worker. Elsewhere, the output of TObject::Print() is
2160  // sent. Received object is disposed after usage.
2161 
2162  TObject *obj = mess->ReadObject(0x0); // class type ignored
2163 
2164  if (IsMaster()) {
2165  // We are on master
2166  // dbTODO: forward on dynamic startup when wrks are up
2167  if (IsParallel() && fProof && !fProof->UseDynamicStartup()) {
2168  fProof->Echo(obj); // forward to lower layer
2169  }
2170  }
2171 
2172  TMessage rmsg(kPROOF_MESSAGE);
2173  TString smsg;
2174 
2175  if (obj->InheritsFrom(TObjString::Class())) {
2176  // It's a string: echo it
2177  smsg.Form("Echo response from %s:%s: %s",
2178  gSystem->HostName(), GetOrdinal(),
2179  ((TObjString *)obj)->String().Data());
2180  }
2181  else {
2182  // Not a string: collect Print() output and send it
2183 
2184  // Output to tempfile
2185  TString tmpfn = "echo-out-";
2186  FILE *tf = gSystem->TempFileName(tmpfn, fDataDir);
2187  if (!tf || (gSystem->RedirectOutput(tmpfn.Data()) == -1)) {
2188  Error("HandleSocketInput", "Can't redirect output");
2189  if (tf) {
2190  fclose(tf);
2191  gSystem->Unlink(tmpfn);
2192  }
2193  rc = -1;
2194  delete obj;
2195  break;
2196  }
2197  //cout << obj->ClassName() << endl;
2198  obj->Print();
2199  gSystem->RedirectOutput(0x0); // restore
2200  fclose(tf);
2201 
2202  // Read file back and send it via message
2203  smsg.Form("*** Echo response from %s:%s ***\n",
2204  gSystem->HostName(), GetOrdinal());
2205  TMacro *fr = new TMacro();
2206  fr->ReadFile(tmpfn);
2207  TIter nextLine(fr->GetListOfLines());
2208  TObjString *line;
2209  while (( line = (TObjString *)nextLine() )) {
2210  smsg.Append( line->String() );
2211  }
2212 
2213  // Close the reader (TMacro) and remove file
2214  delete fr;
2215  gSystem->Unlink(tmpfn);
2216  }
2217 
2218  // Send message and dispose object
2219  rmsg << smsg;
2220  GetSocket()->Send(rmsg);
2221  delete obj;
2222  }
2223  break;
2224 
2225  default:
2226  Error("HandleSocketInput", "unknown command %d", what);
2227  rc = -2;
2228  break;
2229  }
2230 
2231  fRealTime += (Float_t)timer.RealTime();
2232  fCpuTime += (Float_t)timer.CpuTime();
2233 
2234  if (!(slb.IsNull()) || fgLogToSysLog > 1) {
2235  TString s;
2236  s.Form("%s %d %.3f %.3f %s", fgSysLogEntity.Data(),
2237  what, timer.RealTime(), timer.CpuTime(), slb.Data());
2238  gSystem->Syslog(kLogNotice, s.Data());
2239  }
2240 
2241  // Done
2242  return rc;
2243 }
2244 
2245 ////////////////////////////////////////////////////////////////////////////////
2246 /// Accept and merge results from a set of workers
2247 
2249 {
2250  TMessage *mess = new TMessage();
2251  Int_t mergedWorkers = 0;
2252 
2253  PDB(kSubmerger, 1) Info("AcceptResults", "enter");
2254 
2255  // Overall result of this procedure
2256  Bool_t result = kTRUE;
2257 
2258  fMergingMonitor = new TMonitor();
2260 
2261  Int_t numworkers = 0;
2262  while (fMergingMonitor->GetActive() > 0 && mergedWorkers < connections) {
2263 
2264  TSocket *s = fMergingMonitor->Select();
2265  if (!s) {
2266  Info("AcceptResults", "interrupt!");
2267  result = kFALSE;
2268  break;
2269  }
2270 
2271  if (s == fMergingSocket) {
2272  // New incoming connection
2273  TSocket *sw = fMergingSocket->Accept();
2274  if (sw && sw != (TSocket *)(-1)) {
2275  fMergingMonitor->Add(sw);
2276 
2277  PDB(kSubmerger, 2)
2278  Info("AcceptResults", "connection from a worker accepted on merger %s ",
2279  fOrdinal.Data());
2280  // All assigned workers are connected
2281  if (++numworkers >= connections)
2283  } else {
2284  PDB(kSubmerger, 1)
2285  Info("AcceptResults", "spurious signal found of merging socket");
2286  }
2287  } else {
2288  if (s->Recv(mess) < 0) {
2289  Error("AcceptResults", "problems receiving message");
2290  continue;
2291  }
2292  PDB(kSubmerger, 2)
2293  Info("AcceptResults", "message received: %d ", (mess ? mess->What() : 0));
2294  if (!mess) {
2295  Error("AcceptResults", "message received: %p ", mess);
2296  continue;
2297  }
2298  Int_t type = 0;
2299 
2300  // Read output objec(s) from the received message
2301  while ((mess->BufferSize() > mess->Length())) {
2302  (*mess) >> type;
2303 
2304  PDB(kSubmerger, 2) Info("AcceptResults", " type %d ", type);
2305  if (type == 2) {
2306  mergedWorkers++;
2307  PDB(kSubmerger, 2)
2308  Info("AcceptResults",
2309  "a new worker has been mergerd. Total merged workers: %d",
2310  mergedWorkers);
2311  }
2312  TObject *o = mess->ReadObject(TObject::Class());
2313  if (mergerPlayer->AddOutputObject(o) == 1) {
2314  // Remove the object if it has been merged
2315  PDB(kSubmerger, 2) Info("AcceptResults", "removing %p (has been merged)", o);
2316  SafeDelete(o);
2317  } else
2318  PDB(kSubmerger, 2) Info("AcceptResults", "%p not merged yet", o);
2319  }
2320  }
2321  }
2323 
2325  Int_t size = sockets->GetSize();
2326  for (Int_t i =0; i< size; ++i){
2327  ((TSocket*)(sockets->At(i)))->Close();
2328  PDB(kSubmerger, 2) Info("AcceptResults", "closing socket");
2329  delete ((TSocket*)(sockets->At(i)));
2330  }
2331 
2334 
2335  PDB(kSubmerger, 2) Info("AcceptResults", "exit: %d", result);
2336  return result;
2337 }
2338 
2339 ////////////////////////////////////////////////////////////////////////////////
2340 /// Handle Out-Of-Band data sent by the master or client.
2341 
2343 {
2344  char oob_byte;
2345  Int_t n, nch, wasted = 0;
2346 
2347  const Int_t kBufSize = 1024;
2348  char waste[kBufSize];
2349 
2350  // Real-time notification of messages
2352 
2353  PDB(kGlobal, 5)
2354  Info("HandleUrgentData", "handling oob...");
2355 
2356  // Receive the OOB byte
2357  while ((n = fSocket->RecvRaw(&oob_byte, 1, kOob)) < 0) {
2358  if (n == -2) { // EWOULDBLOCK
2359  //
2360  // The OOB data has not yet arrived: flush the input stream
2361  //
2362  // In some systems (Solaris) regular recv() does not return upon
2363  // receipt of the oob byte, which makes the below call to recv()
2364  // block indefinitely if there are no other data in the queue.
2365  // FIONREAD ioctl can be used to check if there are actually any
2366  // data to be flushed. If not, wait for a while for the oob byte
2367  // to arrive and try to read it again.
2368  //
2370  if (nch == 0) {
2371  gSystem->Sleep(1000);
2372  continue;
2373  }
2374 
2375  if (nch > kBufSize) nch = kBufSize;
2376  n = fSocket->RecvRaw(waste, nch);
2377  if (n <= 0) {
2378  Error("HandleUrgentData", "error receiving waste");
2379  break;
2380  }
2381  wasted = 1;
2382  } else {
2383  Error("HandleUrgentData", "error receiving OOB");
2384  return;
2385  }
2386  }
2387 
2388  PDB(kGlobal, 5)
2389  Info("HandleUrgentData", "got OOB byte: %d\n", oob_byte);
2390 
2391  if (fProof) fProof->SetActive();
2392 
2393  switch (oob_byte) {
2394 
2396  Info("HandleUrgentData", "*** Hard Interrupt");
2397 
2398  // If master server, propagate interrupt to slaves
2399  if (IsMaster())
2401 
2402  // Flush input socket
2403  while (1) {
2404  Int_t atmark;
2405 
2406  fSocket->GetOption(kAtMark, atmark);
2407 
2408  if (atmark) {
2409  // Send the OOB byte back so that the client knows where
2410  // to stop flushing its input stream of obsolete messages
2411  n = fSocket->SendRaw(&oob_byte, 1, kOob);
2412  if (n <= 0)
2413  Error("HandleUrgentData", "error sending OOB");
2414  break;
2415  }
2416 
2417  // find out number of bytes to read before atmark
2419  if (nch == 0) {
2420  gSystem->Sleep(1000);
2421  continue;
2422  }
2423 
2424  if (nch > kBufSize) nch = kBufSize;
2425  n = fSocket->RecvRaw(waste, nch);
2426  if (n <= 0) {
2427  Error("HandleUrgentData", "error receiving waste (2)");
2428  break;
2429  }
2430  }
2431 
2432  SendLogFile();
2433 
2434  break;
2435 
2437  Info("HandleUrgentData", "Soft Interrupt");
2438 
2439  // If master server, propagate interrupt to slaves
2440  if (IsMaster())
2442 
2443  if (wasted) {
2444  Error("HandleUrgentData", "soft interrupt flushed stream");
2445  break;
2446  }
2447 
2448  Interrupt();
2449 
2450  SendLogFile();
2451 
2452  break;
2453 
2455  Info("HandleUrgentData", "Shutdown Interrupt");
2456 
2457  // If master server, propagate interrupt to slaves
2458  if (IsMaster())
2460 
2461  Terminate(0);
2462 
2463  break;
2464 
2465  default:
2466  Error("HandleUrgentData", "unexpected OOB byte");
2467  break;
2468  }
2469 
2470  if (fProof) fProof->SetActive(kFALSE);
2471 }
2472 
2473 ////////////////////////////////////////////////////////////////////////////////
2474 /// Called when the client is not alive anymore (i.e. when kKeepAlive
2475 /// has failed).
2476 
2478 {
2479  // Real-time notification of messages
2481 
2482  if (IsMaster()) {
2483  // Check if we are here because client is closed. Try to ping client,
2484  // if that works it we are here because some slave died
2485  if (fSocket->Send(kPROOF_PING | kMESS_ACK) < 0) {
2486  Info("HandleSigPipe", "keepAlive probe failed");
2487  // Tell slaves we are going to close since there is no client anymore
2488 
2489  fProof->SetActive();
2492  Terminate(0);
2493  }
2494  } else {
2495  Info("HandleSigPipe", "keepAlive probe failed");
2496  Terminate(0); // will not return from here....
2497  }
2498 }
2499 
2500 ////////////////////////////////////////////////////////////////////////////////
2501 /// True if in parallel mode.
2502 
2504 {
2505  if (IsMaster() && fProof)
2506  return fProof->IsParallel() || fProof->UseDynamicStartup() ;
2507 
2508  // false in case we are a slave
2509  return kFALSE;
2510 }
2511 
2512 ////////////////////////////////////////////////////////////////////////////////
2513 /// Print status of slave server.
2514 
2515 void TProofServ::Print(Option_t *option) const
2516 {
2517  if (IsMaster() && fProof)
2518  fProof->Print(option);
2519  else
2520  Printf("This is worker %s", gSystem->HostName());
2521 }
2522 
2523 ////////////////////////////////////////////////////////////////////////////////
2524 /// Redirect stdout to a log file. This log file will be flushed to the
2525 /// client or master after each command.
2526 
2527 void TProofServ::RedirectOutput(const char *dir, const char *mode)
2528 {
2529  char logfile[512];
2530 
2531  TString sdir = (dir && strlen(dir) > 0) ? dir : fSessionDir.Data();
2532  if (IsMaster()) {
2533  snprintf(logfile, 512, "%s/master-%s.log", sdir.Data(), fOrdinal.Data());
2534  } else {
2535  snprintf(logfile, 512, "%s/worker-%s.log", sdir.Data(), fOrdinal.Data());
2536  }
2537 
2538  if ((freopen(logfile, mode, stdout)) == 0)
2539  SysError("RedirectOutput", "could not freopen stdout (%s)", logfile);
2540 
2541  if ((dup2(fileno(stdout), fileno(stderr))) < 0)
2542  SysError("RedirectOutput", "could not redirect stderr");
2543 
2544  if ((fLogFile = fopen(logfile, "r")) == 0)
2545  SysError("RedirectOutput", "could not open logfile '%s'", logfile);
2546 
2547  // from this point on stdout and stderr are properly redirected
2548  if (fProtocol < 4 && fWorkDir != TString::Format("~/%s", kPROOF_WorkDir)) {
2549  Warning("RedirectOutput", "no way to tell master (or client) where"
2550  " to upload packages");
2551  }
2552 }
2553 
2554 ////////////////////////////////////////////////////////////////////////////////
2555 /// Reset PROOF environment to be ready for execution of next command.
2556 
2557 void TProofServ::Reset(const char *dir)
2558 {
2559  // First go to new directory. Check first that we got a reasonable path;
2560  // in PROOF-Lite it may not be the case
2561  TString dd(dir);
2562  if (!dd.BeginsWith("proofserv")) {
2563  Int_t ic = dd.Index(":");
2564  if (ic != kNPOS)
2565  dd.Replace(0, ic, "proofserv");
2566  }
2567  gDirectory->cd(dd.Data());
2568 
2569  // Clear interpreter environment.
2570  gROOT->Reset();
2571 
2572  // Make sure current directory is empty (don't delete anything when
2573  // we happen to be in the ROOT memory only directory!?)
2574  if (gDirectory != gROOT) {
2575  gDirectory->Delete();
2576  }
2577 
2578  if (IsMaster()) fProof->SendCurrentState();
2579 }
2580 
2581 ////////////////////////////////////////////////////////////////////////////////
2582 /// Receive a file, either sent by a client or a master server.
2583 /// If bin is true it is a binary file, other wise it is an ASCII
2584 /// file and we need to check for Windows \r tokens. Returns -1 in
2585 /// case of error, 0 otherwise.
2586 
2587 Int_t TProofServ::ReceiveFile(const char *file, Bool_t bin, Long64_t size)
2588 {
2589  if (size <= 0) return 0;
2590 
2591  // open file, overwrite already existing file
2592  Int_t fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
2593  if (fd < 0) {
2594  SysError("ReceiveFile", "error opening file %s", file);
2595  return -1;
2596  }
2597 
2598  const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
2599  char buf[kMAXBUF], cpy[kMAXBUF];
2600 
2601  Int_t left, r;
2602  Long64_t filesize = 0;
2603 
2604  while (filesize < size) {
2605  left = Int_t(size - filesize);
2606  if (left > kMAXBUF)
2607  left = kMAXBUF;
2608  r = fSocket->RecvRaw(&buf, left);
2609  if (r > 0) {
2610  char *p = buf;
2611 
2612  filesize += r;
2613  while (r) {
2614  Int_t w;
2615 
2616  if (!bin) {
2617  Int_t k = 0, i = 0, j = 0;
2618  char *q;
2619  while (i < r) {
2620  if (p[i] == '\r') {
2621  i++;
2622  k++;
2623  }
2624  cpy[j++] = buf[i++];
2625  }
2626  q = cpy;
2627  r -= k;
2628  w = write(fd, q, r);
2629  } else {
2630  w = write(fd, p, r);
2631  }
2632 
2633  if (w < 0) {
2634  SysError("ReceiveFile", "error writing to file %s", file);
2635  close(fd);
2636  return -1;
2637  }
2638  r -= w;
2639  p += w;
2640  }
2641  } else if (r < 0) {
2642  Error("ReceiveFile", "error during receiving file %s", file);
2643  close(fd);
2644  return -1;
2645  }
2646  }
2647 
2648  close(fd);
2649 
2650  if (chmod(file, 0644) != 0)
2651  Warning("ReceiveFile", "error setting mode 0644 on file %s", file);
2652 
2653  return 0;
2654 }
2655 
2656 ////////////////////////////////////////////////////////////////////////////////
2657 /// Main server eventloop.
2658 
2660 {
2661  // Setup the server
2662  if (CreateServer() == 0) {
2663 
2664  // Run the main event loop
2665  TApplication::Run(retrn);
2666  }
2667 }
2668 
2669 ////////////////////////////////////////////////////////////////////////////////
2670 /// Send log file to master.
2671 /// If start > -1 send only bytes in the range from start to end,
2672 /// if end <= start send everything from start.
2673 
2674 void TProofServ::SendLogFile(Int_t status, Int_t start, Int_t end)
2675 {
2676  // Determine the number of bytes left to be read from the log file.
2677  fflush(stdout);
2678 
2679  // On workers we do not send the logs to masters (to avoid duplication of
2680  // text) unless asked explicitly, e.g. after an Exec(...) request.
2681  if (!IsMaster()) {
2682  if (!fSendLogToMaster) {
2683  FlushLogFile();
2684  } else {
2685  // Decide case by case
2687  }
2688  }
2689 
2690  off_t ltot=0, lnow=0;
2691  Int_t left = -1;
2692  Bool_t adhoc = kFALSE;
2693 
2694  if (fLogFileDes > -1) {
2695  ltot = lseek(fileno(stdout), (off_t) 0, SEEK_END);
2696  lnow = lseek(fLogFileDes, (off_t) 0, SEEK_CUR);
2697 
2698  if (ltot >= 0 && lnow >= 0) {
2699  if (start > -1) {
2700  lseek(fLogFileDes, (off_t) start, SEEK_SET);
2701  if (end <= start || end > ltot)
2702  end = ltot;
2703  left = (Int_t)(end - start);
2704  if (end < ltot)
2705  left++;
2706  adhoc = kTRUE;
2707  } else {
2708  left = (Int_t)(ltot - lnow);
2709  }
2710  }
2711  }
2712 
2713  if (left > 0) {
2714  if (fSocket->Send(left, kPROOF_LOGFILE) < 0) {
2715  SysError("SendLogFile", "error sending kPROOF_LOGFILE");
2716  return;
2717  }
2718 
2719  const Int_t kMAXBUF = 32768; //16384 //65536;
2720  char buf[kMAXBUF];
2721  Int_t wanted = (left > kMAXBUF) ? kMAXBUF : left;
2722  Int_t len;
2723  do {
2724  while ((len = read(fLogFileDes, buf, wanted)) < 0 &&
2725  TSystem::GetErrno() == EINTR)
2727 
2728  if (len < 0) {
2729  SysError("SendLogFile", "error reading log file");
2730  break;
2731  }
2732 
2733  if (end == ltot && len == wanted)
2734  buf[len-1] = '\n';
2735 
2736  if (fSocket->SendRaw(buf, len) < 0) {
2737  SysError("SendLogFile", "error sending log file");
2738  break;
2739  }
2740 
2741  // Update counters
2742  left -= len;
2743  wanted = (left > kMAXBUF) ? kMAXBUF : left;
2744 
2745  } while (len > 0 && left > 0);
2746  }
2747 
2748  // Restore initial position if partial send
2749  if (adhoc && lnow >=0 )
2750  lseek(fLogFileDes, lnow, SEEK_SET);
2751 
2752  TMessage mess(kPROOF_LOGDONE);
2753  if (IsMaster())
2754  mess << status << (fProof ? fProof->GetParallel() : 0);
2755  else
2756  mess << status << (Int_t) 1;
2757 
2758  if (fSocket->Send(mess) < 0) {
2759  SysError("SendLogFile", "error sending kPROOF_LOGDONE");
2760  return;
2761  }
2762 
2763  PDB(kGlobal, 1) Info("SendLogFile", "kPROOF_LOGDONE sent");
2764 }
2765 
2766 ////////////////////////////////////////////////////////////////////////////////
2767 /// Send statistics of slave server to master or client.
2768 
2770 {
2771  Long64_t bytesread = TFile::GetFileBytesRead();
2772  Float_t cputime = fCpuTime, realtime = fRealTime;
2773  if (IsMaster()) {
2774  bytesread = fProof->GetBytesRead();
2775  cputime = fProof->GetCpuTime();
2776  }
2777 
2778  TMessage mess(kPROOF_GETSTATS);
2779  TString workdir = gSystem->WorkingDirectory(); // expect TString on other side
2780  mess << bytesread << realtime << cputime << workdir;
2781  if (fProtocol >= 4) mess << TString(gProofServ->GetWorkDir());
2782  mess << TString(gProofServ->GetImage());
2783  fSocket->Send(mess);
2784 }
2785 
2786 ////////////////////////////////////////////////////////////////////////////////
2787 /// Send number of parallel nodes to master or client.
2788 
2790 {
2791  Int_t nparallel = 0;
2792  if (IsMaster()) {
2793  PDB(kGlobal, 2)
2794  Info("SendParallel", "Will invoke AskParallel()");
2795  fProof->AskParallel();
2796  PDB(kGlobal, 2)
2797  Info("SendParallel", "Will invoke GetParallel()");
2798  nparallel = fProof->GetParallel();
2799  } else {
2800  nparallel = 1;
2801  }
2802 
2804  mess << nparallel << async;
2805  fSocket->Send(mess);
2806 }
2807 
2808 ////////////////////////////////////////////////////////////////////////////////
2809 /// Removes link to package in working directory,
2810 /// removes entry from include path,
2811 /// removes entry from enabled package list,
2812 /// does not currently remove entry from interpreter include path.
2813 /// Returns -1 in case of error, 0 otherwise.
2814 
2815 Int_t TProofServ::UnloadPackage(const char *package)
2816 {
2817  TPair *pack = (TPair *) fEnabledPackages->FindObject(package);
2818  if (pack) {
2819 
2820  // Remove entry from include path
2821  TString aclicincpath = gSystem->GetIncludePath();
2822  TString cintincpath = gInterpreter->GetIncludePath();
2823  // remove interpreter part of gSystem->GetIncludePath()
2824  aclicincpath.Remove(aclicincpath.Length() - cintincpath.Length() - 1);
2825  // remove package's include path
2826  aclicincpath.ReplaceAll(TString(" -I") + package, "");
2827  gSystem->SetIncludePath(aclicincpath);
2828 
2829  //TODO reset interpreter include path
2830 
2831  // remove entry from enabled packages list
2832  delete fEnabledPackages->Remove(pack);
2833  PDB(kPackage, 1)
2834  Info("UnloadPackage",
2835  "package %s successfully unloaded", package);
2836  }
2837 
2838  // Cleanup the link, if there
2839  if (!gSystem->AccessPathName(package))
2840  if (gSystem->Unlink(package) != 0)
2841  Warning("UnloadPackage", "unable to remove symlink to %s", package);
2842 
2843  // We are done
2844  return 0;
2845 }
2846 
2847 ////////////////////////////////////////////////////////////////////////////////
2848 /// Unloads all enabled packages. Returns -1 in case of error, 0 otherwise.
2849 
2851 {
2852  // Iterate over packages and remove each package
2853  TIter nextpackage(fEnabledPackages);
2854  while (TPair *pck = dynamic_cast<TPair *>(nextpackage()))
2855  if (UnloadPackage(pck->GetName()) != 0)
2856  return -1;
2857 
2858  PDB(kPackage, 1)
2859  Info("UnloadPackages",
2860  "packages successfully unloaded");
2861 
2862  return 0;
2863 }
2864 
2865 ////////////////////////////////////////////////////////////////////////////////
2866 /// Print the ProofServ logo on standard output.
2867 /// Return 0 on success, -1 on failure
2868 
2870 {
2871  char str[512];
2872 
2873  if (IsMaster()) {
2874  snprintf(str, 512, "**** Welcome to the PROOF server @ %s ****", gSystem->HostName());
2875  } else {
2876  snprintf(str, 512, "**** PROOF slave server @ %s started ****", gSystem->HostName());
2877  }
2878 
2879  if (fSocket->Send(str) != 1+static_cast<Int_t>(strlen(str))) {
2880  Error("Setup", "failed to send proof server startup message");
2881  return -1;
2882  }
2883 
2884  // exchange protocol level between client and master and between
2885  // master and slave
2886  Int_t what;
2887  if (fSocket->Recv(fProtocol, what) != 2*sizeof(Int_t)) {
2888  Error("Setup", "failed to receive remote proof protocol");
2889  return -1;
2890  }
2891  if (fSocket->Send(kPROOF_Protocol, kROOTD_PROTOCOL) != 2*sizeof(Int_t)) {
2892  Error("Setup", "failed to send local proof protocol");
2893  return -1;
2894  }
2895 
2896  // If old version, setup authentication related stuff
2897  if (fProtocol < 5) {
2898  TString wconf;
2899  if (OldAuthSetup(wconf) != 0) {
2900  Error("Setup", "OldAuthSetup: failed to setup authentication");
2901  return -1;
2902  }
2903  if (IsMaster()) {
2904  fConfFile = wconf;
2905  fWorkDir.Form("~/%s", kPROOF_WorkDir);
2906  } else {
2907  if (fProtocol < 4) {
2908  fWorkDir.Form("~/%s", kPROOF_WorkDir);
2909  } else {
2910  fWorkDir = wconf;
2911  if (fWorkDir.IsNull()) fWorkDir.Form("~/%s", kPROOF_WorkDir);
2912  }
2913  }
2914  } else {
2915 
2916  // Receive some useful information
2917  TMessage *mess;
2918  if ((fSocket->Recv(mess) <= 0) || !mess) {
2919  Error("Setup", "failed to receive ordinal and config info");
2920  return -1;
2921  }
2922  if (IsMaster()) {
2923  (*mess) >> fUser >> fOrdinal >> fConfFile;
2924  fWorkDir = gEnv->GetValue("ProofServ.Sandbox", TString::Format("~/%s", kPROOF_WorkDir));
2925  } else {
2926  (*mess) >> fUser >> fOrdinal >> fWorkDir;
2927  if (fWorkDir.IsNull())
2928  fWorkDir = gEnv->GetValue("ProofServ.Sandbox", TString::Format("~/%s", kPROOF_WorkDir));
2929  }
2930  // Set the correct prefix
2931  if (fOrdinal != "-1")
2932  fPrefix += fOrdinal;
2934  delete mess;
2935  }
2936 
2937  if (IsMaster()) {
2938 
2939  // strip off any prooftype directives
2940  TString conffile = fConfFile;
2941  conffile.Remove(0, 1 + conffile.Index(":"));
2942 
2943  // parse config file to find working directory
2944  TProofResourcesStatic resources(fConfDir, conffile);
2945  if (resources.IsValid()) {
2946  if (resources.GetMaster()) {
2947  TString tmpWorkDir = resources.GetMaster()->GetWorkDir();
2948  if (tmpWorkDir != "")
2949  fWorkDir = tmpWorkDir;
2950  }
2951  } else {
2952  Info("Setup", "invalid config file %s (missing or unreadable",
2953  resources.GetFileName().Data());
2954  }
2955  }
2956 
2957  // Set $HOME and $PATH. The HOME directory was already set to the
2958  // user's home directory by proofd.
2959  gSystem->Setenv("HOME", gSystem->HomeDirectory());
2960 
2961  // Add user name in case of non default workdir
2962  if (fWorkDir.BeginsWith("/") &&
2964  if (!fWorkDir.EndsWith("/"))
2965  fWorkDir += "/";
2967  if (u) {
2968  fWorkDir += u->fUser;
2969  delete u;
2970  }
2971  }
2972 
2973  // Goto to the main PROOF working directory
2975  fWorkDir = workdir;
2976  delete [] workdir;
2977  if (gProofDebugLevel > 0)
2978  Info("Setup", "working directory set to %s", fWorkDir.Data());
2979 
2980  // host first name
2981  TString host = gSystem->HostName();
2982  if (host.Index(".") != kNPOS)
2983  host.Remove(host.Index("."));
2984 
2985  // Session tag
2986  fSessionTag.Form("%s-%s-%ld-%d", fOrdinal.Data(), host.Data(),
2989 
2990  // create session directory and make it the working directory
2992  if (IsMaster())
2993  fSessionDir += "/master-";
2994  else
2995  fSessionDir += "/slave-";
2997 
2998  // Common setup
2999  if (SetupCommon() != 0) {
3000  Error("Setup", "common setup failed");
3001  return -1;
3002  }
3003 
3004  // Incoming OOB should generate a SIGURG
3006 
3007  // Send packets off immediately to reduce latency
3008  fSocket->SetOption(kNoDelay, 1);
3009 
3010  // Check every two hours if client is still alive
3012 
3013  // Done
3014  return 0;
3015 }
3016 
3017 ////////////////////////////////////////////////////////////////////////////////
3018 /// Common part (between TProofServ and TXProofServ) of the setup phase.
3019 /// Return 0 on success, -1 on error
3020 
3022 {
3023  // deny write access for group and world
3024  gSystem->Umask(022);
3025 
3026 #ifdef R__UNIX
3027  // Add bindir to PATH
3028  TString path(gSystem->Getenv("PATH"));
3029  TString bindir;
3030 # ifdef ROOTBINDIR
3031  bindir = ROOTBINDIR;
3032 # else
3033  bindir = gSystem->Getenv("ROOTSYS");
3034  if (!bindir.IsNull()) bindir += "/bin";
3035 # endif
3036  // Augment PATH, if required
3037  // ^<compiler>, <compiler>, ^<sysbin>, <sysbin>
3038  TString paths = gEnv->GetValue("ProofServ.BinPaths", "");
3039  if (paths.Length() > 0) {
3040  Int_t icomp = 0;
3041  if (paths.Contains("^<compiler>"))
3042  icomp = 1;
3043  else if (paths.Contains("<compiler>"))
3044  icomp = -1;
3045  if (icomp != 0) {
3046 # ifdef COMPILER
3047  TString compiler = COMPILER;
3048  if (compiler.Index("is ") != kNPOS)
3049  compiler.Remove(0, compiler.Index("is ") + 3);
3050  compiler = gSystem->DirName(compiler);
3051  if (icomp == 1) {
3052  if (!bindir.IsNull()) bindir += ":";
3053  bindir += compiler;
3054  } else if (icomp == -1) {
3055  if (!path.IsNull()) path += ":";
3056  path += compiler;
3057  }
3058 #endif
3059  }
3060  Int_t isysb = 0;
3061  if (paths.Contains("^<sysbin>"))
3062  isysb = 1;
3063  else if (paths.Contains("<sysbin>"))
3064  isysb = -1;
3065  if (isysb != 0) {
3066  if (isysb == 1) {
3067  if (!bindir.IsNull()) bindir += ":";
3068  bindir += "/bin:/usr/bin:/usr/local/bin";
3069  } else if (isysb == -1) {
3070  if (!path.IsNull()) path += ":";
3071  path += "/bin:/usr/bin:/usr/local/bin";
3072  }
3073  }
3074  }
3075  // Final insert
3076  if (!bindir.IsNull()) bindir += ":";
3077  path.Insert(0, bindir);
3078  gSystem->Setenv("PATH", path);
3079 #endif
3080 
3083  if (!gSystem->ChangeDirectory(fWorkDir)) {
3084  Error("SetupCommon", "can not change to PROOF directory %s",
3085  fWorkDir.Data());
3086  return -1;
3087  }
3088  } else {
3089  if (!gSystem->ChangeDirectory(fWorkDir)) {
3092  if (!gSystem->ChangeDirectory(fWorkDir)) {
3093  Error("SetupCommon", "can not change to PROOF directory %s",
3094  fWorkDir.Data());
3095  return -1;
3096  }
3097  }
3098  }
3099 
3100  // Set group
3101  fGroup = gEnv->GetValue("ProofServ.ProofGroup", "default");
3102 
3103  // Check and make sure "cache" directory exists
3104  fCacheDir = gEnv->GetValue("ProofServ.CacheDir",
3109  if (gProofDebugLevel > 0)
3110  Info("SetupCommon", "cache directory set to %s", fCacheDir.Data());
3111  fCacheLock =
3112  new TProofLockPath(TString::Format("%s/%s%s",
3114  TString(fCacheDir).ReplaceAll("/","%").Data()));
3115 
3116  // Check and make sure "packages" directory exists
3117  fPackageDir = gEnv->GetValue("ProofServ.PackageDir",
3122  if (gProofDebugLevel > 0)
3123  Info("SetupCommon", "package directory set to %s", fPackageDir.Data());
3124  fPackageLock =
3125  new TProofLockPath(TString::Format("%s/%s%s",
3127  TString(fPackageDir).ReplaceAll("/","%").Data()));
3128 
3129  // Check and make sure "data" directory exists
3130  fDataDir = gEnv->GetValue("ProofServ.DataDir","");
3131  Ssiz_t isep = kNPOS;
3132  if (fDataDir.IsNull()) {
3133  // Use default
3134  fDataDir.Form("%s/%s/<ord>/<stag>", fWorkDir.Data(), kPROOF_DataDir);
3135  } else if ((isep = fDataDir.Last(' ')) != kNPOS) {
3136  fDataDirOpts = fDataDir(isep + 1, fDataDir.Length());
3137  fDataDir.Remove(isep);
3138  }
3141  if (gSystem->mkdir(fDataDir, kTRUE) != 0) {
3142  Warning("SetupCommon", "problems creating path '%s' (errno: %d)",
3144  }
3145  if (gProofDebugLevel > 0)
3146  Info("SetupCommon", "data directory set to %s", fDataDir.Data());
3147 
3148  // Check and apply possible options
3149  // (see http://root.cern.ch/drupal/content/configuration-reference-guide#datadir)
3150  TString dataDirOpts = gEnv->GetValue("ProofServ.DataDirOpts","");
3151  if (!dataDirOpts.IsNull()) {
3152  // Do they apply to this server type
3153  Bool_t doit = kTRUE;
3154  if ((IsMaster() && !dataDirOpts.Contains("M")) ||
3155  (!IsMaster() && !dataDirOpts.Contains("W"))) doit = kFALSE;
3156  if (doit) {
3157  // Get the wanted mode
3158  UInt_t m = 0755;
3159  if (dataDirOpts.Contains("g")) m = 0775;
3160  if (dataDirOpts.Contains("a") || dataDirOpts.Contains("o")) m = 0777;
3161  if (gProofDebugLevel > 0)
3162  Info("SetupCommon", "requested mode for data directories is '%o'", m);
3163  // Loop over paths
3164  FileStat_t st;
3165  TString p, subp;
3166  Int_t from = 0;
3167  if (fDataDir.BeginsWith("/")) p = "/";
3168  while (fDataDir.Tokenize(subp, from, "/")) {
3169  if (subp.IsNull()) continue;
3170  p += subp;
3171  if (gSystem->GetPathInfo(p, st) == 0) {
3172  if (st.fUid == (Int_t) gSystem->GetUid() && st.fGid == (Int_t) gSystem->GetGid()) {
3173  if (gSystem->Chmod(p.Data(), m) != 0) {
3174  Warning("SetupCommon", "problems setting mode '%o' on path '%s' (errno: %d)",
3175  m, p.Data(), TSystem::GetErrno());
3176  break;
3177  }
3178  }
3179  p += "/";
3180  } else {
3181  Warning("SetupCommon", "problems stat-ing path '%s' (errno: %d; datadir: %s)",
3182  p.Data(), TSystem::GetErrno(), fDataDir.Data());
3183  break;
3184  }
3185  }
3186  }
3187  }
3188 
3189  // List of directories where to look for global packages
3190  TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
3191  if (globpack.Length() > 0) {
3192  Int_t ng = 0;
3193  Int_t from = 0;
3194  TString ldir;
3195  while (globpack.Tokenize(ldir, from, ":")) {
3196  if (gSystem->AccessPathName(ldir, kReadPermission)) {
3197  Warning("SetupCommon", "directory for global packages %s does not"
3198  " exist or is not readable", ldir.Data());
3199  } else {
3200  // Add to the list, key will be "G<ng>", i.e. "G0", "G1", ...
3201  TString key;
3202  key.Form("G%d", ng++);
3203  if (!fGlobalPackageDirList) {
3206  }
3207  ResolveKeywords(ldir);
3208  fGlobalPackageDirList->Add(new TNamed(key,ldir));
3209  Info("SetupCommon", "directory for global packages %s added to the list",
3210  ldir.Data());
3211  FlushLogFile();
3212  }
3213  }
3214  }
3215 
3216  // Check the session dir
3217  if (fSessionDir != gSystem->WorkingDirectory()) {
3222  Error("SetupCommon", "can not change to working directory '%s'",
3223  fSessionDir.Data());
3224  return -1;
3225  }
3226  }
3227  gSystem->Setenv("PROOF_SANDBOX", fSessionDir);
3228  if (gProofDebugLevel > 0)
3229  Info("SetupCommon", "session dir is '%s'", fSessionDir.Data());
3230 
3231  // On masters, check and make sure that "queries" and "datasets"
3232  // directories exist
3233  if (IsMaster()) {
3234 
3235  // Make sure that the 'queries' dir exist
3236  fQueryDir = fWorkDir;
3237  fQueryDir += TString("/") + kPROOF_QueryDir;
3241  fQueryDir += TString("/session-") + fTopSessionTag;
3244  if (gProofDebugLevel > 0)
3245  Info("SetupCommon", "queries dir is %s", fQueryDir.Data());
3246 
3247  // Create 'queries' locker instance and lock it
3248  fQueryLock = new TProofLockPath(TString::Format("%s/%s%s-%s",
3251  TString(fQueryDir).ReplaceAll("/","%").Data()));
3252  fQueryLock->Lock();
3253  // Create the query manager
3255  fQueryLock, 0);
3256  }
3257 
3258  // Server image
3259  fImage = gEnv->GetValue("ProofServ.Image", "");
3260 
3261  // Get the group priority
3262  if (IsMaster()) {
3263  // Send session tag to client
3265  m << fTopSessionTag << fGroup << fUser;
3266  fSocket->Send(m);
3267  // Group priority
3269  // Dataset manager instance via plug-in
3270  TPluginHandler *h = 0;
3271  TString dsms = gEnv->GetValue("Proof.DataSetManager", "");
3272  if (!dsms.IsNull()) {
3273  TString dsm;
3274  Int_t from = 0;
3275  while (dsms.Tokenize(dsm, from, ",")) {
3277  Warning("SetupCommon", "a valid dataset manager already initialized");
3278  Warning("SetupCommon", "support for multiple managers not yet available");
3279  break;
3280  }
3281  // Get plugin manager to load the appropriate TDataSetManager
3282  if (gROOT->GetPluginManager()) {
3283  // Find the appropriate handler
3284  h = gROOT->GetPluginManager()->FindHandler("TDataSetManager", dsm);
3285  if (h && h->LoadPlugin() != -1) {
3286  // make instance of the dataset manager
3287  fDataSetManager =
3288  reinterpret_cast<TDataSetManager*>(h->ExecPlugin(3, fGroup.Data(),
3289  fUser.Data(), dsm.Data()));
3290  }
3291  }
3292  }
3293  // Check the result of the dataset manager initialization
3295  Warning("SetupCommon", "dataset manager plug-in initialization failed");
3296  SendAsynMessage("TXProofServ::SetupCommon: dataset manager plug-in initialization failed");
3298  }
3299  } else {
3300  // Initialize the default dataset manager
3301  TString opts("Av:");
3302  TString dsetdir = gEnv->GetValue("ProofServ.DataSetDir", "");
3303  if (dsetdir.IsNull()) {
3304  // Use the default in the sandbox
3305  dsetdir.Form("%s/%s", fWorkDir.Data(), kPROOF_DataSetDir);
3308  opts += "Sb:";
3309  }
3310  // Find the appropriate handler
3311  if (!h) {
3312  h = gROOT->GetPluginManager()->FindHandler("TDataSetManager", "file");
3313  if (h && h->LoadPlugin() == -1) h = 0;
3314  }
3315  if (h) {
3316  // make instance of the dataset manager
3317  TString oo = TString::Format("dir:%s opt:%s", dsetdir.Data(), opts.Data());
3318  fDataSetManager = reinterpret_cast<TDataSetManager*>(h->ExecPlugin(3,
3319  fGroup.Data(), fUser.Data(), oo.Data()));
3320  }
3322  Warning("SetupCommon", "default dataset manager plug-in initialization failed");
3324  }
3325  }
3326  // Dataset manager for staging requests
3327  TString dsReqCfg = gEnv->GetValue("Proof.DataSetStagingRequests", "");
3328  if (!dsReqCfg.IsNull()) {
3329  TPMERegexp reReqDir("(^| )(dir:)?([^ ]+)( |$)");
3330 
3331  if (reReqDir.Match(dsReqCfg) == 5) {
3332  TString dsDirFmt;
3333  dsDirFmt.Form("dir:%s perms:open", reReqDir[3].Data());
3334  fDataSetStgRepo = new TDataSetManagerFile("_stage_", "_stage_",
3335  dsDirFmt);
3336  if (fDataSetStgRepo &&
3338  Warning("SetupCommon",
3339  "failed init of dataset staging requests repository");
3341  }
3342  } else {
3343  Warning("SetupCommon",
3344  "specify, with [dir:]<path>, a valid path for staging requests");
3345  }
3346  } else if (gProofDebugLevel > 0) {
3347  Warning("SetupCommon", "no repository for staging requests available");
3348  }
3349  }
3350 
3351  // Quotas
3352  TString quotas = gEnv->GetValue(TString::Format("ProofServ.UserQuotas.%s", fUser.Data()),"");
3353  if (quotas.IsNull())
3354  quotas = gEnv->GetValue(TString::Format("ProofServ.UserQuotasByGroup.%s", fGroup.Data()),"");
3355  if (quotas.IsNull())
3356  quotas = gEnv->GetValue("ProofServ.UserQuotas", "");
3357  if (!quotas.IsNull()) {
3358  // Parse it; format ("maxquerykept=10 hwmsz=800m maxsz=1g")
3359  TString tok;
3360  Ssiz_t from = 0;
3361  while (quotas.Tokenize(tok, from, " ")) {
3362  // Set max number of query results to keep
3363  if (tok.BeginsWith("maxquerykept=")) {
3364  tok.ReplaceAll("maxquerykept=","");
3365  if (tok.IsDigit())
3366  fMaxQueries = tok.Atoi();
3367  else
3368  Info("SetupCommon",
3369  "parsing 'maxquerykept' :ignoring token %s : not a digit", tok.Data());
3370  }
3371  // Set High-Water-Mark or max on the sandbox size
3372  const char *ksz[2] = {"hwmsz=", "maxsz="};
3373  for (Int_t j = 0; j < 2; j++) {
3374  if (tok.BeginsWith(ksz[j])) {
3375  tok.ReplaceAll(ksz[j],"");
3376  Long64_t fact = -1;
3377  if (!tok.IsDigit()) {
3378  // Parse (k, m, g)
3379  tok.ToLower();
3380  const char *s[3] = {"k", "m", "g"};
3381  Int_t i = 0, k = 1024;
3382  while (fact < 0) {
3383  if (tok.EndsWith(s[i]))
3384  fact = k;
3385  else
3386  k *= 1024;
3387  }
3388  tok.Remove(tok.Length()-1);
3389  }
3390  if (tok.IsDigit()) {
3391  if (j == 0)
3392  fHWMBoxSize = (fact > 0) ? tok.Atoi() * fact : tok.Atoi();
3393  else
3394  fMaxBoxSize = (fact > 0) ? tok.Atoi() * fact : tok.Atoi();
3395  } else {
3396  TString ssz(ksz[j], strlen(ksz[j])-1);
3397  Info("SetupCommon", "parsing '%s' : ignoring token %s", ssz.Data(), tok.Data());
3398  }
3399  }
3400  }
3401  }
3402  }
3403 
3404  // Apply quotas, if any
3405  if (IsMaster() && fQMgr)
3406  if (fQMgr->ApplyMaxQueries(fMaxQueries) != 0)
3407  Warning("SetupCommon", "problems applying fMaxQueries");
3408 
3409  // Send "ROOTversion|ArchCompiler" flag
3410  if (fProtocol > 12) {
3411  TString vac = gROOT->GetVersion();
3412  vac += TString::Format(":%s", gROOT->GetGitCommit());
3413  TString rtag = gEnv->GetValue("ProofServ.RootVersionTag", "");
3414  if (rtag.Length() > 0)
3415  vac += TString::Format(":%s", rtag.Data());
3418  m << vac;
3419  fSocket->Send(m);
3420  }
3421 
3422  // Set user vars in TProof
3423  TString all_vars(gSystem->Getenv("PROOF_ALLVARS"));
3424  TString name;
3425  Int_t from = 0;
3426  while (all_vars.Tokenize(name, from, ",")) {
3427  if (!name.IsNull()) {
3428  TString value = gSystem->Getenv(name);
3429  TProof::AddEnvVar(name, value);
3430  }
3431  }
3432 
3433  if (fgLogToSysLog > 0) {
3434  // Set the syslog entity (all the information is available now)
3435  if (!(fUser.IsNull()) && !(fGroup.IsNull())) {
3436  fgSysLogEntity.Form("%s:%s", fUser.Data(), fGroup.Data());
3437  } else if (!(fUser.IsNull()) && fGroup.IsNull()) {
3438  fgSysLogEntity.Form("%s:default", fUser.Data());
3439  } else if (fUser.IsNull() && !(fGroup.IsNull())) {
3440  fgSysLogEntity.Form("undef:%s", fGroup.Data());
3441  }
3442  // Log the beginning of this session
3443  TString s;
3444  s.Form("%s 0 %.3f %.3f", fgSysLogEntity.Data(), fRealTime, fCpuTime);
3445  gSystem->Syslog(kLogNotice, s.Data());
3446  }
3447 
3448  if (gProofDebugLevel > 0)
3449  Info("SetupCommon", "successfully completed");
3450 
3451  // Done
3452  return 0;
3453 }
3454 
3455 ////////////////////////////////////////////////////////////////////////////////
3456 /// Terminate the proof server.
3457 
3459 {
3460  if (fgLogToSysLog > 0) {
3461  TString s;
3462  s.Form("%s -1 %.3f %.3f %d", fgSysLogEntity.Data(), fRealTime, fCpuTime, status);
3463  gSystem->Syslog(kLogNotice, s.Data());
3464  }
3465 
3466  // Notify the memory footprint
3467  ProcInfo_t pi;
3468  if (!gSystem->GetProcInfo(&pi)){
3469  Info("Terminate", "process memory footprint: %ld/%ld kB virtual, %ld/%ld kB resident ",
3471  }
3472 
3473  // Cleanup session directory
3474  if (status == 0) {
3475  // make sure we remain in a "connected" directory
3476  gSystem->ChangeDirectory("/");
3477  // needed in case fSessionDir is on NFS ?!
3478  gSystem->MakeDirectory(fSessionDir+"/.delete");
3480  }
3481 
3482  // Cleanup queries directory if empty
3483  if (IsMaster()) {
3484  if (!(fQMgr && fQMgr->Queries() && fQMgr->Queries()->GetSize())) {
3485  // make sure we remain in a "connected" directory
3486  gSystem->ChangeDirectory("/");
3487  // needed in case fQueryDir is on NFS ?!
3488  gSystem->MakeDirectory(fQueryDir+"/.delete");
3489  gSystem->Exec(TString::Format("%s %s", kRM, fQueryDir.Data()));
3490  // Remove lock file
3491  if (fQueryLock)
3493  }
3494 
3495  // Unlock the query dir owned by this session
3496  if (fQueryLock)
3497  fQueryLock->Unlock();
3498  }
3499 
3500  // Cleanup data directory if empty
3502  if (UnlinkDataDir(fDataDir))
3503  Info("Terminate", "data directory '%s' has been removed", fDataDir.Data());
3504  }
3505 
3506  // Remove input handler to avoid spurious signals in socket
3507  // selection for closing activities executed upon exit()
3509  TObject *fh = 0;
3510  while ((fh = next())) {
3511  TProofServInputHandler *ih = dynamic_cast<TProofServInputHandler *>(fh);
3512  if (ih)
3514  }
3515 
3516  // Stop processing events
3517  gSystem->ExitLoop();
3518 
3519  // Exit() is called in pmain
3520 }
3521 
3522 ////////////////////////////////////////////////////////////////////////////////
3523 /// Scan recursively the datadir and unlink it if empty
3524 /// Return kTRUE if it can be unlinked, kFALSE otherwise
3525 
3527 {
3528  if (!path || strlen(path) <= 0) return kFALSE;
3529 
3530  Bool_t dorm = kTRUE;
3531  void *dirp = gSystem->OpenDirectory(path);
3532  if (dirp) {
3533  TString fpath;
3534  const char *ent = 0;
3535  while (dorm && (ent = gSystem->GetDirEntry(dirp))) {
3536  if (!strcmp(ent, ".") || !strcmp(ent, "..")) continue;
3537  fpath.Form("%s/%s", path, ent);
3538  FileStat_t st;
3539  if (gSystem->GetPathInfo(fpath, st) == 0 && R_ISDIR(st.fMode)) {
3540  dorm = UnlinkDataDir(fpath);
3541  } else {
3542  dorm = kFALSE;
3543  }
3544  }
3545  // Close the directory
3546  gSystem->FreeDirectory(dirp);
3547  } else {
3548  // Cannot open the directory
3549  dorm = kFALSE;
3550  }
3551 
3552  // Do remove, if required
3553  if (dorm && gSystem->Unlink(path) != 0)
3554  Warning("UnlinkDataDir", "data directory '%s' is empty but could not be removed", path);
3555  // done
3556  return dorm;
3557 }
3558 
3559 ////////////////////////////////////////////////////////////////////////////////
3560 /// Static function that returns kTRUE in case we are a PROOF server.
3561 
3563 {
3564  return gProofServ ? kTRUE : kFALSE;
3565 }
3566 
3567 ////////////////////////////////////////////////////////////////////////////////
3568 /// Static function returning pointer to global object gProofServ.
3569 /// Mainly for use via CINT, where the gProofServ symbol might be
3570 /// deleted from the symbol table.
3571 
3573 {
3574  return gProofServ;
3575 }
3576 
3577 ////////////////////////////////////////////////////////////////////////////////
3578 /// Setup authentication related stuff for old versions.
3579 /// Provided for backward compatibility.
3580 
3582 {
3583  OldProofServAuthSetup_t oldAuthSetupHook = 0;
3584 
3585  if (!oldAuthSetupHook) {
3586  // Load libraries needed for (server) authentication ...
3587  TString authlib = "libRootAuth";
3588  char *p = 0;
3589  // The generic one
3590  if ((p = gSystem->DynamicPathName(authlib, kTRUE))) {
3591  delete[] p;
3592  if (gSystem->Load(authlib) == -1) {
3593  Error("OldAuthSetup", "can't load %s",authlib.Data());
3594  return kFALSE;
3595  }
3596  } else {
3597  Error("OldAuthSetup", "can't locate %s",authlib.Data());
3598  return -1;
3599  }
3600  //
3601  // Locate OldProofServAuthSetup
3602  Func_t f = gSystem->DynFindSymbol(authlib,"OldProofServAuthSetup");
3603  if (f)
3604  oldAuthSetupHook = (OldProofServAuthSetup_t)(f);
3605  else {
3606  Error("OldAuthSetup", "can't find OldProofServAuthSetup");
3607  return -1;
3608  }
3609  }
3610  //
3611  // Setup
3612  return (*oldAuthSetupHook)(fSocket, IsMaster(), fProtocol,
3613  fUser, fOrdinal, conf);
3614 }
3615 
3616 ////////////////////////////////////////////////////////////////////////////////
3617 /// Create a TProofQueryResult instance for this query.
3618 
3620  const char *opt,
3621  TList *inlist, Long64_t fst,
3622  TDSet *dset, const char *selec,
3623  TObject *elist)
3624 {
3625  // Increment sequential number
3626  Int_t seqnum = -1;
3627  if (fQMgr) {
3629  seqnum = fQMgr->SeqNum();
3630  }
3631 
3632  // Locally we always use the current streamer
3633  Bool_t olds = (dset && dset->TestBit(TDSet::kWriteV3)) ? kTRUE : kFALSE;
3634  if (olds)
3635  dset->SetWriteV3(kFALSE);
3636 
3637  // Create the instance and add it to the list
3638  TProofQueryResult *pqr = new TProofQueryResult(seqnum, opt, inlist, nent,
3639  fst, dset, selec, elist);
3640  // Title is the session identifier
3642 
3643  // Restore old streamer info
3644  if (olds)
3645  dset->SetWriteV3(kTRUE);
3646 
3647  return pqr;
3648 }
3649 
3650 ////////////////////////////////////////////////////////////////////////////////
3651 /// Set query in running state.
3652 
3654 {
3655  // Record current position in the log file at start
3656  fflush(stdout);
3657  Int_t startlog = lseek(fileno(stdout), (off_t) 0, SEEK_END);
3658 
3659  // Add some header to logs
3660  Printf(" ");
3661  Info("SetQueryRunning", "starting query: %d", pq->GetSeqNum());
3662 
3663  // Build the list of loaded PAR packages
3664  TString parlist = "";
3665  TIter nxp(fEnabledPackages);
3666  TPair *pck= 0;
3667  while ((pck = (TPair *)nxp())) {
3668  if (parlist.Length() <= 0)
3669  parlist = pck->GetName();
3670  else
3671  parlist += TString::Format(";%s", pck->GetName());
3672  }
3673 
3674  if (fProof) {
3675  // Set in running state
3676  pq->SetRunning(startlog, parlist, fProof->GetParallel());
3677 
3678  // Bytes and CPU at start (we will calculate the differential at end)
3679  pq->SetProcessInfo(pq->GetEntries(),
3681  } else {
3682  // Set in running state
3683  pq->SetRunning(startlog, parlist, -1);
3684 
3685  // Bytes and CPU at start (we will calculate the differential at end)
3686  pq->SetProcessInfo(pq->GetEntries(), float(0.), 0);
3687  }
3688 }
3689 
3690 ////////////////////////////////////////////////////////////////////////////////
3691 /// Handle archive request.
3692 
3694 {
3695  PDB(kGlobal, 1)
3696  Info("HandleArchive", "Enter");
3697 
3698  TString queryref;
3699  TString path;
3700  (*mess) >> queryref >> path;
3701 
3702  if (slb) slb->Form("%s %s", queryref.Data(), path.Data());
3703 
3704  // If this is a set default action just save the default
3705  if (queryref == "Default") {
3706  fArchivePath = path;
3707  Info("HandleArchive",
3708  "default path set to %s", fArchivePath.Data());
3709  return;
3710  }
3711 
3712  Int_t qry = -1;
3713  TString qdir;
3714  TProofQueryResult *pqr = fQMgr ? fQMgr->LocateQuery(queryref, qry, qdir) : 0;
3715  TProofQueryResult *pqm = pqr;
3716 
3717  if (path.Length() <= 0) {
3718  if (fArchivePath.Length() <= 0) {
3719  Info("HandleArchive",
3720  "archive paths are not defined - do nothing");
3721  return;
3722  }
3723  if (qry > 0) {
3724  path.Form("%s/session-%s-%d.root",
3725  fArchivePath.Data(), fTopSessionTag.Data(), qry);
3726  } else {
3727  path = queryref;
3728  path.ReplaceAll(":q","-");
3729  path.Insert(0, TString::Format("%s/",fArchivePath.Data()));
3730  path += ".root";
3731  }
3732  }
3733 
3734  // Build file name for specific query
3735  if (!pqr || qry < 0) {
3736  TString fout = qdir;
3737  fout += "/query-result.root";
3738 
3739  TFile *f = TFile::Open(fout,"READ");
3740  pqr = 0;
3741  if (f) {
3742  f->ReadKeys();
3743  TIter nxk(f->GetListOfKeys());
3744  TKey *k = 0;
3745  while ((k = (TKey *)nxk())) {
3746  if (!strcmp(k->GetClassName(), "TProofQueryResult")) {
3747  pqr = (TProofQueryResult *) f->Get(k->GetName());
3748  if (pqr)
3749  break;
3750  }
3751  }
3752  f->Close();
3753  delete f;
3754  } else {
3755  Info("HandleArchive",
3756  "file cannot be open (%s)",fout.Data());
3757  return;
3758  }
3759  }
3760 
3761  if (pqr) {
3762 
3763  PDB(kGlobal, 1) Info("HandleArchive",
3764  "archive path for query #%d: %s",
3765  qry, path.Data());
3766  TFile *farc = 0;
3767  if (gSystem->AccessPathName(path))
3768  farc = TFile::Open(path,"NEW");
3769  else
3770  farc = TFile::Open(path,"UPDATE");
3771  if (!farc || !(farc->IsOpen())) {
3772  Info("HandleArchive",
3773  "archive file cannot be open (%s)",path.Data());
3774  return;
3775  }
3776  farc->cd();
3777 
3778  // Update query status
3779  pqr->SetArchived(path);
3780  if (pqm)
3781  pqm->SetArchived(path);
3782 
3783  // Write to file
3784  pqr->Write();
3785 
3786  // Update temporary files too
3787  if (qry > -1 && fQMgr)
3788  fQMgr->SaveQuery(pqr);
3789 
3790  // Notify
3791  Info("HandleArchive",
3792  "results of query %s archived to file %s",
3793  queryref.Data(), path.Data());
3794  }
3795 
3796  // Done
3797  return;
3798 }
3799 
3800 ////////////////////////////////////////////////////////////////////////////////
3801 /// Get a map {server-name, list-of-files} for collection 'fc' to be used in
3802 /// TPacketizerFile. Returns a pointer to the map (ownership of the caller).
3803 /// Or (TMap *)0 and an error message in emsg.
3804 
3806 {
3807  TMap *fcmap = 0;
3808  emsg = "";
3809 
3810  // Sanity checks
3811  if (!fc) {
3812  emsg.Form("file collection undefined!");
3813  return fcmap;
3814  }
3815 
3816  // Prepare data set map
3817  fcmap = new TMap();
3818 
3819  TIter nxf(fc->GetList());
3820  TFileInfo *fiind = 0;
3821  TString key;
3822  while ((fiind = (TFileInfo *)nxf())) {
3823  TUrl *xurl = fiind->GetCurrentUrl();
3824  // Find the key for this server
3825  key.Form("%s://%s", xurl->GetProtocol(), xurl->GetHostFQDN());
3826  if (xurl->GetPort() > 0)
3827  key += TString::Format(":%d", xurl->GetPort());
3828  // Get the map entry for this key
3829  TPair *ent = 0;
3830  THashList* l = 0;
3831  if ((ent = (TPair *) fcmap->FindObject(key.Data()))) {
3832  // Attach to the list
3833  l = (THashList *) ent->Value();
3834  } else {
3835  // Create list
3836  l = new THashList;
3837  l->SetOwner(kTRUE);
3838  // Add it to the map
3839  fcmap->Add(new TObjString(key.Data()), l);
3840  }
3841  // Add fileinfo with index to list
3842  l->Add(fiind);
3843  }
3844 
3845  // Done
3846  return fcmap;
3847 }
3848 
3849 ////////////////////////////////////////////////////////////////////////////////
3850 /// Handle processing request.
3851 
3853 {
3854  PDB(kGlobal, 1)
3855  Info("HandleProcess", "Enter");
3856 
3857  // Nothing to do for slaves if we are not idle
3858  if (!IsTopMaster() && !IsIdle())
3859  return;
3860 
3861  TDSet *dset;
3862  TString filename, opt;
3863  TList *input;
3864  Long64_t nentries, first;
3865  TEventList *evl = 0;
3866  TEntryList *enl = 0;
3867  Bool_t sync;
3868 
3869  (*mess) >> dset >> filename >> input >> opt >> nentries >> first >> evl >> sync;
3870  // Get entry list information, if any (support started with fProtocol == 15)
3871  if ((mess->BufferSize() > mess->Length()) && fProtocol > 14)
3872  (*mess) >> enl;
3873  Bool_t hasNoData = (!dset || dset->TestBit(TDSet::kEmpty)) ? kTRUE : kFALSE;
3874 
3875  // Priority to the entry list
3876  TObject *elist = (enl) ? (TObject *)enl : (TObject *)evl;
3877  if (enl && evl)
3878  // Cannot specify both at the same time
3879  SafeDelete(evl);
3880  if ((!hasNoData) && elist)
3881  dset->SetEntryList(elist);
3882 
3883  if (IsTopMaster()) {
3884 
3885  TString emsg;
3886  // Make sure the dataset contains the information needed
3887  if ((!hasNoData) && dset->GetListOfElements()->GetSize() == 0) {
3888  if (TProof::AssertDataSet(dset, input, fDataSetManager, emsg) != 0) {
3889  SendAsynMessage(TString::Format("AssertDataSet on %s: %s",
3890  fPrefix.Data(), emsg.Data()));
3891  Error("HandleProcess", "AssertDataSet: %s", emsg.Data());
3892  // To terminate collection
3893  if (sync) SendLogFile();
3894  return;
3895  }
3896  } else if (hasNoData) {
3897  // Check if we are required to process with TPacketizerFile a registered dataset
3898  TNamed *ftp = dynamic_cast<TNamed *>(input->FindObject("PROOF_FilesToProcess"));
3899  if (ftp) {
3900  TString dsn(ftp->GetTitle());
3901  if (!dsn.Contains(":") || dsn.BeginsWith("dataset:")) {
3902  dsn.ReplaceAll("dataset:", "");
3903  // Get the map for TPacketizerFile
3904  // Make sure we have something in input and a dataset manager
3905  if (!fDataSetManager) {
3906  emsg.Form("dataset manager not initialized!");
3907  } else {
3908  TFileCollection *fc = 0;
3909  // Get the dataset
3910  if (!(fc = fDataSetManager->GetDataSet(dsn))) {
3911  emsg.Form("requested dataset '%s' does not exists", dsn.Data());
3912  } else {
3913  TMap *fcmap = GetDataSetNodeMap(fc, emsg);
3914  if (fcmap) {
3915  input->Remove(ftp);
3916  delete ftp;
3917  fcmap->SetOwner(kTRUE);
3918  fcmap->SetName("PROOF_FilesToProcess");
3919  input->Add(fcmap);
3920  }
3921  }
3922  }
3923  if (!emsg.IsNull()) {
3924  SendAsynMessage(TString::Format("HandleProcess on %s: %s",
3925  fPrefix.Data(), emsg.Data()));
3926  Error("HandleProcess", "%s", emsg.Data());
3927  // To terminate collection
3928  if (sync) SendLogFile();
3929  return;
3930  }
3931  }
3932  }
3933  }
3934 
3935  TProofQueryResult *pq = 0;
3936 
3937  // Create instance of query results; we set ownership of the input list
3938  // to the TQueryResult object, to avoid too many instantiations
3939  pq = MakeQueryResult(nentries, opt, 0, first, 0, filename, 0);
3940 
3941  // Prepare the input list and transfer it into the TQueryResult object
3942  if (dset) input->Add(dset);
3943  if (elist) input->Add(elist);
3944  pq->SetInputList(input, kTRUE);
3945 
3946  // Clear the list
3947  input->Clear("nodelete");
3948  SafeDelete(input);
3949 
3950  // Save input data, if any
3951  if (TProof::SaveInputData(pq, fCacheDir.Data(), emsg) != 0)
3952  Warning("HandleProcess", "could not save input data: %s", emsg.Data());
3953 
3954  // If not a draw action add the query to the main list
3955  if (!(pq->IsDraw())) {
3956  if (fQMgr) {
3957  if (fQMgr->Queries()) fQMgr->Queries()->Add(pq);
3958  // Also save it to queries dir
3959  fQMgr->SaveQuery(pq);
3960  }
3961  }
3962 
3963  // Add anyhow to the waiting lists
3964  QueueQuery(pq);
3965 
3966  // Call get Workers
3967  // if we are not idle the scheduler will just enqueue the query and
3968  // send a resume message later.
3969 
3970  Bool_t enqueued = kFALSE;
3971  Int_t pc = 0;
3972  // if the session does not have workers and is in the dynamic mode
3973  if (fProof->UseDynamicStartup()) {
3974  // get the a list of workers and start them
3975  TList* workerList = new TList();
3976  EQueryAction retVal = GetWorkers(workerList, pc);
3977  if (retVal == TProofServ::kQueryStop) {
3978  Error("HandleProcess", "error getting list of worker nodes");
3979  // To terminate collection
3980  if (sync) SendLogFile();
3981  return;
3982  } else if (retVal == TProofServ::kQueryEnqueued) {
3983  // change to an asynchronous query
3984  enqueued = kTRUE;
3985  Info("HandleProcess", "query %d enqueued", pq->GetSeqNum());
3986  } else if (Int_t ret = fProof->AddWorkers(workerList) < 0) {
3987  Error("HandleProcess", "Adding a list of worker nodes returned: %d",
3988  ret);
3989  // To terminate collection
3990  if (sync) SendLogFile();
3991  return;
3992  }
3993  } else {
3994  EQueryAction retVal = GetWorkers(0, pc);
3995  if (retVal == TProofServ::kQueryStop) {
3996  Error("HandleProcess", "error getting list of worker nodes");
3997  // To terminate collection
3998  if (sync) SendLogFile();
3999  return;
4000  } else if (retVal == TProofServ::kQueryEnqueued) {
4001  // change to an asynchronous query
4002  enqueued = kTRUE;
4003  Info("HandleProcess", "query %d enqueued", pq->GetSeqNum());
4004  } else if (retVal != TProofServ::kQueryOK) {
4005  Error("HandleProcess", "unknown return value: %d", retVal);
4006  // To terminate collection
4007  if (sync) SendLogFile();
4008  return;
4009  }
4010  }
4011 
4012  // If the client submission was asynchronous, signal the submission of
4013  // the query and communicate the assigned sequential number for later
4014  // identification
4016  if (!sync || enqueued) {
4017  m << pq->GetSeqNum() << kFALSE;
4018  fSocket->Send(m);
4019  }
4020 
4021  // Nothing more to do if we are not idle
4022  if (!IsIdle()) {
4023  // Notify submission
4024  Info("HandleProcess",
4025  "query \"%s:%s\" submitted", pq->GetTitle(), pq->GetName());
4026  return;
4027  }
4028 
4029  // Process
4030  // in the static mode, if a session is enqueued it will be processed after current query
4031  // (there is no way to enqueue if idle).
4032  // in the dynamic mode we will process here only if the session was idle and got workers!
4033  Bool_t doprocess = kFALSE;
4034  while (WaitingQueries() > 0 && !enqueued) {
4035  doprocess = kTRUE;
4036  //
4037  ProcessNext(slb);
4038  // avoid processing async queries sent during processing in dyn mode
4039  if (fProof->UseDynamicStartup())
4040  enqueued = kTRUE;
4041 
4042  } // Loop on submitted queries
4043 
4044  // Set idle
4045  SetIdle(kTRUE);
4046 
4047  // Reset mergers
4048  fProof->ResetMergers();
4049 
4050  // kPROOF_SETIDLE sets the client to idle; in asynchronous mode clients monitor
4051  // TProof::IsIdle for to check the readiness of a query, so we need to send this
4052  // before to be sure thatn everything about a query is received by the client
4053  if (!sync) SendLogFile();
4054 
4055  // Signal the client that we are idle
4056  if (doprocess) {
4057  m.Reset(kPROOF_SETIDLE);
4058  Bool_t waiting = (WaitingQueries() > 0) ? kTRUE : kFALSE;
4059  m << waiting;
4060  fSocket->Send(m);
4061  }
4062 
4063  // In synchronous mode TProof::Collect is terminated by the reception of the
4064  // log file and subsequent submissions are controlled by TProof::IsIdle(), so
4065  // this must be last one to be sent
4066  if (sync) SendLogFile();
4067 
4068  // Set idle
4069  SetIdle(kTRUE);
4070 
4071  } else {
4072 
4073  // Reset compute stopwatch: we include all what done from now on
4074  fCompute.Reset();
4075  fCompute.Start();
4076 
4077  // Set not idle
4078  SetIdle(kFALSE);
4079 
4080  // Cleanup the player
4081  Bool_t deleteplayer = kTRUE;
4082  MakePlayer();
4083 
4084  // Setup data set
4085  if (dset && (dset->IsA() == TDSetProxy::Class()))
4086  ((TDSetProxy*)dset)->SetProofServ(this);
4087 
4088  // Get input data, if any
4089  TString emsg;
4090  if (TProof::GetInputData(input, fCacheDir.Data(), emsg) != 0)
4091  Warning("HandleProcess", "could not get input data: %s", emsg.Data());
4092 
4093  // Get query sequential number
4094  if (TProof::GetParameter(input, "PROOF_QuerySeqNum", fQuerySeqNum) != 0)
4095  Warning("HandleProcess", "could not get query sequential number!");
4096 
4097  // Make the ordinal number available in the selector
4098  TObject *nord = 0;
4099  while ((nord = input->FindObject("PROOF_Ordinal")))
4100  input->Remove(nord);
4101  input->Add(new TNamed("PROOF_Ordinal", GetOrdinal()));
4102 
4103  // Set input
4104  TIter next(input);
4105  TObject *o = 0;
4106  while ((o = next())) {
4107  PDB(kGlobal, 2) Info("HandleProcess", "adding: %s", o->GetName());
4108  fPlayer->AddInput(o);
4109  }
4110 
4111  // Check if a TSelector object is passed via input list
4112  TObject *obj = 0;
4113  TSelector *selector_obj = 0;
4114  TIter nxt(input);
4115  while ((obj = nxt())){
4116  if (obj->InheritsFrom("TSelector")) {
4117  selector_obj = (TSelector *) obj;
4118  filename = selector_obj->ClassName();
4119  Info("HandleProcess", "selector obj for '%s' found", selector_obj->ClassName());
4120  break;
4121  }
4122  }
4123 
4124  // Signal the master that we are starting processing
4126 
4127  // Reset latency stopwatch
4128  fLatency.Reset();
4129  fSaveOutput.Reset();
4130 
4131  // Process
4132  PDB(kGlobal, 1) Info("HandleProcess", "calling %s::Process()", fPlayer->IsA()->GetName());
4133 
4134  if (selector_obj){
4135  Info("HandleProcess", "calling fPlayer->Process() with selector object: %s", selector_obj->ClassName());
4136  fPlayer->Process(dset, selector_obj, opt, nentries, first);
4137  }
4138  else {
4139  Info("HandleProcess", "calling fPlayer->Process() with selector name: %s", filename.Data());
4140  fPlayer->Process(dset, filename, opt, nentries, first);
4141  }
4142 
4143  // Return number of events processed
4146  if (fProtocol > 18) {
4147  TProofProgressStatus* status =
4149  gPerfStats?gPerfStats->GetBytesRead():0);
4150  if (status)
4151  m << status << abort;
4152  if (slb)
4153  slb->Form("%d %lld %lld", fPlayer->GetExitStatus(),
4154  status->GetEntries(), status->GetBytesRead());
4155  SafeDelete(status);
4156  } else {
4157  m << fPlayer->GetEventsProcessed() << abort;
4158  if (slb)
4159  slb->Form("%d %lld -1", fPlayer->GetExitStatus(), fPlayer->GetEventsProcessed());
4160  }
4161 
4162  fSocket->Send(m);
4163  PDB(kGlobal, 2)
4164  Info("TProofServ::Handleprocess",
4165  "worker %s has finished processing with %d objects in output list",
4167 
4168  // Cleanup the input data set info
4169  SafeDelete(dset);
4170  SafeDelete(enl);
4171  SafeDelete(evl);
4172 
4175  if (outok) {
4176  // Check if in controlled output sending mode or submerging
4177  Int_t cso = 0;
4178  Bool_t isSubMerging = kFALSE;
4179 
4180  // Check if we are in merging mode (i.e. parameter PROOF_UseMergers exists)
4181  Int_t nm = 0;
4182  if (TProof::GetParameter(input, "PROOF_UseMergers", nm) == 0) {
4183  isSubMerging = (nm >= 0) ? kTRUE : kFALSE;
4184  }
4185  if (!isSubMerging) {
4186  cso = gEnv->GetValue("Proof.ControlSendOutput", 1);
4187  if (TProof::GetParameter(input, "PROOF_ControlSendOutput", cso) != 0)
4188  cso = gEnv->GetValue("Proof.ControlSendOutput", 1);
4189  }
4190 
4191  if (cso > 0) {
4192 
4193  // Control output sending mode: wait for the master to ask for the objects.
4194  // Allows controls of memory usage on the master.
4196  fSocket->Send(msg);
4197 
4198  // Set idle
4199  SetIdle(kTRUE);
4200 
4201  // Do not cleanup the player yet: it will be used in sending output activities
4202  deleteplayer = kFALSE;
4203 
4204  PDB(kGlobal, 1)
4205  Info("HandleProcess", "controlled mode: worker %s has finished,"
4206  " sizes sent to master", fOrdinal.Data());
4207  } else {
4208 
4209  // Check if we are in merging mode (i.e. parameter PROOF_UseMergers exists)
4211  if (isSubMerging)
4212  Info("HandleProcess", "submerging disabled because of high-memory case");
4213  isSubMerging = kFALSE;
4214  } else {
4215  PDB(kGlobal, 2) Info("HandleProcess", "merging mode check: %d", isSubMerging);
4216  }
4217 
4218  if (!IsMaster() && isSubMerging) {
4219  // Worker in merging mode.
4220  //----------------------------
4221  // First, it reports only the size of its output to the master
4222  // + port on which it can possibly accept outputs from other workers if it becomes a merger
4223  // Master will later tell it where it should send the output (either to the master or to some merger)
4224  // or if it should become a merger
4225 
4226  TMessage msg_osize(kPROOF_SUBMERGER);
4227  msg_osize << Int_t(TProof::kOutputSize);
4228  msg_osize << fPlayer->GetOutputList()->GetEntries();
4229 
4230  fMergingSocket = new TServerSocket(0);
4231  Int_t merge_port = 0;
4232  if (fMergingSocket) {
4233  PDB(kGlobal, 2)
4234  Info("HandleProcess", "possible port for merging connections: %d",
4236  merge_port = fMergingSocket->GetLocalPort();
4237  }
4238  msg_osize << merge_port;
4239  fSocket->Send(msg_osize);
4240 
4241  // Set idle
4242  SetIdle(kTRUE);
4243 
4244  // Do not cleanup the player yet: it will be used in sub-merging activities
4245  deleteplayer = kFALSE;
4246 
4247  PDB(kSubmerger, 2) Info("HandleProcess", "worker %s has finished", fOrdinal.Data());
4248 
4249  } else {
4250  // Sub-master OR worker not in merging mode
4251  // ---------------------------------------------
4252  PDB(kGlobal, 2) Info("HandleProcess", "sending result directly to master");
4253  if (SendResults(fSocket, fPlayer->GetOutputList()) != 0)
4254  Warning("HandleProcess","problems sending output list");
4255 
4256  // Masters reset the mergers, if any
4257  if (IsMaster()) fProof->ResetMergers();
4258 
4259  // Signal the master that we are idle
4261 
4262  // Set idle
4263  SetIdle(kTRUE);
4264 
4265  // Notify the user
4266  SendLogFile();
4267  }
4268 
4269 
4270 
4271  }
4272 
4273  } else {
4274  // No output list
4276  Warning("HandleProcess","the output list is empty!");
4277  if (SendResults(fSocket) != 0)
4278  Warning("HandleProcess", "problems sending output list");
4279 
4280  // Masters reset the mergers, if any
4281  if (IsMaster()) fProof->ResetMergers();
4282 
4283  // Signal the master that we are idle
4285 
4286  // Set idle
4287  SetIdle(kTRUE);
4288 
4289  // Notify the user
4290  SendLogFile();
4291  }
4292 
4293  // Prevent from double-deleting in input
4294  TIter nex(input);
4295  while ((obj = nex())) {
4296  if (obj->InheritsFrom("TSelector")) input->Remove(obj);
4297  }
4298 
4299  // Make also sure the input list objects are deleted
4300  fPlayer->GetInputList()->SetOwner(0);
4301 
4302  // Remove possible inputs from a file and the file, if any
4303  TList *added = dynamic_cast<TList *>(input->FindObject("PROOF_InputObjsFromFile"));
4304  if (added) {
4305  if (added->GetSize() > 0) {
4306  // The file must be the last one
4307  TFile *f = dynamic_cast<TFile *>(added->Last());
4308  if (f) {
4309  added->Remove(f);
4310  TIter nxo(added);
4311  while ((o = nxo())) { input->Remove(o); }
4312  input->Remove(added);
4313  added->SetOwner(kFALSE);
4314  added->Clear();
4315  f->Close();
4316  delete f;
4317  }
4318  }
4319  SafeDelete(added);
4320  }
4321  input->SetOwner();
4322  SafeDelete(input);
4323 
4324  // Cleanup if required
4325  if (deleteplayer) DeletePlayer();
4326  }
4327 
4328  PDB(kGlobal, 1) Info("HandleProcess", "done");
4329 
4330  // Done
4331  return;
4332 }
4333 
4334 ////////////////////////////////////////////////////////////////////////////////
4335 /// Sends all objects from the given list to the specified socket
4336 
4338 {
4339  PDB(kOutput, 2) Info("SendResults", "enter");
4340 
4341  TString msg;
4342  if (fProtocol > 23 && outlist) {
4343  // Send objects in bunches of max fMsgSizeHWM bytes to optimize transfer
4344  // Objects are merged one-by-one by the client
4345  // Messages for objects
4347  // Objects in the output list
4348  Int_t olsz = outlist->GetSize();
4349  if (IsTopMaster() && pq) {
4350  msg.Form("%s: merging output objects ... done ",
4351  fPrefix.Data());
4352  SendAsynMessage(msg.Data());
4353  // Message for the client
4354  msg.Form("%s: objects merged; sending output: %d objs", fPrefix.Data(), olsz);
4355  SendAsynMessage(msg.Data(), kFALSE);
4356  // Send light query info
4357  mbuf << (Int_t) 0;
4358  mbuf.WriteObject(pq);
4359  if (sock->Send(mbuf) < 0) return -1;
4360  }
4361  // Objects in the output list
4362  Int_t ns = 0, np = 0;
4363  TIter nxo(outlist);
4364  TObject *o = 0;
4365  Int_t totsz = 0, objsz = 0;
4366  mbuf.Reset();
4367  while ((o = nxo())) {
4368  if (mbuf.Length() > fMsgSizeHWM) {
4369  PDB(kOutput, 1)
4370  Info("SendResults",
4371  "message has %d bytes: limit of %lld bytes reached - sending ...",
4372  mbuf.Length(), fMsgSizeHWM);
4373  // Compress the message, if required; for these messages we do it already
4374  // here so we get the size; TXSocket does not do it twice.
4375  if (GetCompressionLevel() > 0) {
4377  mbuf.Compress();
4378  objsz = mbuf.CompLength();
4379  } else {
4380  objsz = mbuf.Length();
4381  }
4382  totsz += objsz;
4383  if (IsTopMaster()) {
4384  msg.Form("%s: objects merged; sending obj %d/%d (%d bytes) ",
4385  fPrefix.Data(), ns, olsz, objsz);
4386  SendAsynMessage(msg.Data(), kFALSE);
4387  }
4388  if (sock->Send(mbuf) < 0) return -1;
4389  // Reset the message
4390  mbuf.Reset();
4391  np = 0;
4392  }
4393  ns++;
4394  np++;
4395  mbuf << (Int_t) ((ns >= olsz) ? 2 : 1);
4396  mbuf << o;
4397  }
4398  if (np > 0) {
4399  // Compress the message, if required; for these messages we do it already
4400  // here so we get the size; TXSocket does not do it twice.
4401  if (GetCompressionLevel() > 0) {
4403  mbuf.Compress();
4404  objsz = mbuf.CompLength();
4405  } else {
4406  objsz = mbuf.Length();
4407  }
4408  totsz += objsz;
4409  if (IsTopMaster()) {
4410  msg.Form("%s: objects merged; sending obj %d/%d (%d bytes) ",
4411  fPrefix.Data(), ns, olsz, objsz);
4412  SendAsynMessage(msg.Data(), kFALSE);
4413  }
4414  if (sock->Send(mbuf) < 0) return -1;
4415  }
4416  if (IsTopMaster()) {
4417  // Send total size
4418  msg.Form("%s: grand total: sent %d objects, size: %d bytes ",
4419  fPrefix.Data(), olsz, totsz);
4420  SendAsynMessage(msg.Data());
4421  }
4422  } else if (fProtocol > 10 && outlist) {
4423 
4424  // Send objects one-by-one to optimize transfer and merging
4425  // Messages for objects
4427  // Objects in the output list
4428  Int_t olsz = outlist->GetSize();
4429  if (IsTopMaster() && pq) {
4430  msg.Form("%s: merging output objects ... done ",
4431  fPrefix.Data());
4432  SendAsynMessage(msg.Data());
4433  // Message for the client
4434  msg.Form("%s: objects merged; sending output: %d objs", fPrefix.Data(), olsz);
4435  SendAsynMessage(msg.Data(), kFALSE);
4436  // Send light query info
4437  mbuf << (Int_t) 0;
4438  mbuf.WriteObject(pq);
4439  if (sock->Send(mbuf) < 0) return -1;
4440  }
4441 
4442  Int_t ns = 0;
4443  Int_t totsz = 0, objsz = 0;
4444  TIter nxo(fPlayer->GetOutputList());
4445  TObject *o = 0;
4446  while ((o = nxo())) {
4447  ns++;
4448  mbuf.Reset();
4449  Int_t type = (Int_t) ((ns >= olsz) ? 2 : 1);
4450  mbuf << type;
4451  mbuf.WriteObject(o);
4452  // Compress the message, if required; for these messages we do it already
4453  // here so we get the size; TXSocket does not do it twice.
4454  if (GetCompressionLevel() > 0) {
4456  mbuf.Compress();
4457  objsz = mbuf.CompLength();
4458  } else {
4459  objsz = mbuf.Length();
4460  }
4461  totsz += objsz;
4462  if (IsTopMaster()) {
4463  msg.Form("%s: objects merged; sending obj %d/%d (%d bytes) ",
4464  fPrefix.Data(), ns, olsz, objsz);
4465  SendAsynMessage(msg.Data(), kFALSE);
4466  }
4467  if (sock->Send(mbuf) < 0) return -1;
4468  }
4469  // Total size
4470  if (IsTopMaster()) {
4471  // Send total size
4472  msg.Form("%s: grand total: sent %d objects, size: %d bytes ",
4473  fPrefix.Data(), olsz, totsz);
4474  SendAsynMessage(msg.Data());
4475  }
4476 
4477  } else if (IsTopMaster() && fProtocol > 6 && outlist) {
4478 
4479  // Buffer to be sent
4481  mbuf.WriteObject(pq);
4482  // Sizes
4483  Int_t blen = mbuf.CompLength();
4484  Int_t olsz = outlist->GetSize();
4485  // Message for the client
4486  msg.Form("%s: sending output: %d objs, %d bytes", fPrefix.Data(), olsz, blen);
4487  SendAsynMessage(msg.Data(), kFALSE);
4488  if (sock->Send(mbuf) < 0) return -1;
4489 
4490  } else {
4491  if (outlist) {
4492  PDB(kGlobal, 2) Info("SendResults", "sending output list");
4493  } else {
4494  PDB(kGlobal, 2) Info("SendResults", "notifying failure or abort");
4495  }
4496  if (sock->SendObject(outlist, kPROOF_OUTPUTLIST) < 0) return -1;
4497  }
4498 
4499  PDB(kOutput,2) Info("SendResults", "done");
4500 
4501  // Done
4502  return 0;
4503 }
4504 
4505 ////////////////////////////////////////////////////////////////////////////////
4506 /// process the next query from the queue of submitted jobs.
4507 /// to be called on the top master only.
4508 
4510 {
4511  TDSet *dset = 0;
4512  TString filename, opt;
4513  TList *input = 0;
4514  Long64_t nentries = -1, first = 0;
4515 
4516  // TObject *elist = 0;
4517  TProofQueryResult *pq = 0;
4518 
4519  TObject* obj = 0;
4520  TSelector* selector_obj = 0;
4521 
4522  // Process
4523 
4524  // Reset compute stopwatch: we include all what done from now on
4525  fCompute.Reset();
4526  fCompute.Start();
4527 
4528  // Get next query info (also removes query from the list)
4529  pq = NextQuery();
4530  if (pq) {
4531 
4532  // Set not idle
4533  SetIdle(kFALSE);
4534  opt = pq->GetOptions();
4535  input = pq->GetInputList();
4536  nentries = pq->GetEntries();
4537  first = pq->GetFirst();
4538  filename = pq->GetSelecImp()->GetName();
4539  Ssiz_t id = opt.Last('#');
4540  if (id != kNPOS && id < opt.Length() - 1) {
4541  filename += opt(id + 1, opt.Length());
4542  // Remove it from 'opt' so user found on the workers what they specified
4543  opt.Remove(id);
4544  }
4545  // Attach to data set and entry- (or event-) list (if any)
4546  TObject *o = 0;
4547  if ((o = pq->GetInputObject("TDSet"))) {
4548  dset = (TDSet *) o;
4549  } else {
4550  // Should never get here
4551  Error("ProcessNext", "no TDset object: cannot continue");
4552  return;
4553  }
4554  // elist = 0;
4555  // if ((o = pq->GetInputObject("TEntryList")))
4556  // elist = o;
4557  // else if ((o = pq->GetInputObject("TEventList")))
4558  // elist = o;
4559 
4560  // Expand selector files
4561  if (pq->GetSelecImp()) {
4562  gSystem->Exec(TString::Format("%s %s", kRM, pq->GetSelecImp()->GetName()));
4563  pq->GetSelecImp()->SaveSource(pq->GetSelecImp()->GetName());
4564  }
4565  if (pq->GetSelecHdr() &&
4566  !strstr(pq->GetSelecHdr()->GetName(), "TProofDrawHist")) {
4567  gSystem->Exec(TString::Format("%s %s", kRM, pq->GetSelecHdr()->GetName()));
4568  pq->GetSelecHdr()->SaveSource(pq->GetSelecHdr()->GetName());
4569  }
4570 
4571  // Taking out a TSelector object from input list
4572  TIter nxt(input);
4573  while ((obj = nxt())){
4574  if (obj->InheritsFrom("TSelector") &&
4575  !strcmp(pq->GetSelecImp()->GetName(), obj->ClassName())) {
4576  selector_obj = (TSelector *) obj;
4577  Info("ProcessNext", "found object for selector '%s'", obj->ClassName());
4578  break;
4579  }
4580  }
4581 
4582  } else {
4583  // Should never get here
4584  Error("ProcessNext", "empty waiting queries list!");
4585  return;
4586  }
4587 
4588  // Set in running state
4589  SetQueryRunning(pq);
4590 
4591  // Save to queries dir, if not standard draw
4592  if (fQMgr) {
4593  if (!(pq->IsDraw()))
4594  fQMgr->SaveQuery(pq);
4595  else
4597  fQMgr->ResetTime();
4598  }
4599 
4600  // Signal the client that we are starting a new query
4602  m << TString(pq->GetSelecImp()->GetName())
4603  << dset->GetNumOfFiles()
4604  << pq->GetFirst() << pq->GetEntries();
4605  fSocket->Send(m);
4606 
4607  // Create player
4608  MakePlayer();
4609 
4610  // Add query results to the player lists
4611  fPlayer->AddQueryResult(pq);
4612 
4613  // Set query currently processed
4614  fPlayer->SetCurrentQuery(pq);
4615 
4616  // Setup data set
4617  if (dset->IsA() == TDSetProxy::Class())
4618  ((TDSetProxy*)dset)->SetProofServ(this);
4619 
4620  // Add the unique query tag as TNamed object to the input list
4621  // so that it is available in TSelectors for monitoring
4622  TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
4623  input->Add(new TNamed("PROOF_QueryTag", qid.Data()));
4624  // ... and the sequential number
4625  fQuerySeqNum = pq->GetSeqNum();
4626  input->Add(new TParameter<Int_t>("PROOF_QuerySeqNum", fQuerySeqNum));
4627 
4628  // Check whether we have to enforce the use of submergers, but only if the user did
4629  // not express itself on the subject
4630  if (gEnv->Lookup("Proof.UseMergers") && !input->FindObject("PROOF_UseMergers")) {
4631  Int_t smg = gEnv->GetValue("Proof.UseMergers",-1);
4632  if (smg >= 0) {
4633  input->Add(new TParameter<Int_t>("PROOF_UseMergers", smg));
4634  PDB(kSubmerger, 2) Info("ProcessNext", "PROOF_UseMergers set to %d", smg);
4635  if (gEnv->Lookup("Proof.MergersByHost")) {
4636  Int_t mbh = gEnv->GetValue("Proof.MergersByHost", 0);
4637  if (mbh != 0) {
4638  // Administrator settings have the priority
4639  TObject *o = 0;
4640  if ((o = input->FindObject("PROOF_MergersByHost"))) { input->Remove(o); delete o; }
4641  input->Add(new TParameter<Int_t>("PROOF_MergersByHost", mbh));
4642  PDB(kSubmerger, 2) Info("ProcessNext", "submergers setup by host/node");
4643  }
4644  }
4645  }
4646  }
4647 
4648  // Set input
4649  TIter next(input);
4650  TObject *o = 0;
4651  while ((o = next())) {
4652  PDB(kGlobal, 2) Info("ProcessNext", "adding: %s", o->GetName());
4653  fPlayer->AddInput(o);
4654  }
4655 
4656  // Remove the list of the missing files from the original list, if any
4657  if ((o = input->FindObject("MissingFiles"))) input->Remove(o);
4658 
4659  // Process
4660  PDB(kGlobal, 1) Info("ProcessNext", "calling %s::Process()", fPlayer->IsA()->GetName());
4661  if (selector_obj){
4662  Info("ProcessNext", "calling fPlayer->Process() with selector object: %s", selector_obj->ClassName());
4663  fPlayer->Process(dset, selector_obj, opt, nentries, first);
4664  }
4665  else {
4666  Info("ProcessNext", "calling fPlayer->Process() with selector name: %s", filename.Data());
4667  fPlayer->Process(dset, filename, opt, nentries, first);
4668  }
4669 
4670  // This is the end of merging
4672 
4673  // Return number of events processed
4674  Bool_t abort =
4678  // message sent from worker to the master
4679  if (fProtocol > 18) {
4681  m << status << abort;
4682  status = 0; // the status belongs to the player.
4683  } else if (fProtocol > 8) {
4684  m << fPlayer->GetEventsProcessed() << abort;
4685  } else {
4686  m << fPlayer->GetEventsProcessed();
4687  }
4688  fSocket->Send(m);
4689  }
4690 
4691  // Register any dataset produced during this processing, if required
4693  TNamed *psr = (TNamed *) fPlayer->GetOutputList()->FindObject("PROOFSERV_RegisterDataSet");
4694  if (psr) {
4695  TString emsg;
4696  if (RegisterDataSets(input, fPlayer->GetOutputList(), fDataSetManager, emsg) != 0)
4697  Warning("ProcessNext", "problems registering produced datasets: %s", emsg.Data());
4698  do {
4699  fPlayer->GetOutputList()->Remove(psr);
4700  delete psr;
4701  } while ((psr = (TNamed *) fPlayer->GetOutputList()->FindObject("PROOFSERV_RegisterDataSet")));
4702  }
4703  }
4704 
4705  // Complete filling of the TQueryResult instance
4706  if (fQMgr && !pq->IsDraw()) {
4707  if (!abort) fProof->AskStatistics();
4708  if (fQMgr->FinalizeQuery(pq, fProof, fPlayer))
4709  fQMgr->SaveQuery(pq, fMaxQueries);
4710  }
4711 
4712  // If we were requested to save results on the master and we are not in save-to-file mode
4713  // then we save the results
4714  if (IsTopMaster() && fPlayer->GetOutputList()) {
4715  Bool_t save = kTRUE;
4716  TIter nxo(fPlayer->GetOutputList());
4717  TObject *xo = 0;
4718  while ((xo = nxo())) {
4719  if (xo->InheritsFrom("TProofOutputFile") && xo->TestBit(TProofOutputFile::kSwapFile)) {
4720  save = kFALSE;
4721  break;
4722  }
4723  }
4724  if (save) {
4725  TNamed *nof = (TNamed *) input->FindObject("PROOF_DefaultOutputOption");
4726  if (nof) {
4727  TString oopt(nof->GetTitle());
4728  if (oopt.BeginsWith("of:")) {
4729  oopt.Replace(0, 3, "");
4730  if (!oopt.IsNull()) fPlayer->SetOutputFilePath(oopt);
4732  }
4733  }
4734  }
4735  }
4736 
4737  // Send back the results
4738  TQueryResult *pqr = pq->CloneInfo();
4739  // At least the TDSet name in the light object
4740  Info("ProcessNext", "adding info about dataset '%s' in the light query result", dset->GetName());
4741  TList rin;
4742  TDSet *ds = new TDSet(dset->GetName(), dset->GetObjName());
4743  rin.Add(ds);
4744  if (pqr) pqr->SetInputList(&rin, kTRUE);
4746  PDB(kGlobal, 2)
4747  Info("ProcessNext", "sending results");
4748  TQueryResult *xpq = (pqr && fProtocol > 10) ? pqr : pq;
4749  if (SendResults(fSocket, fPlayer->GetOutputList(), xpq) != 0)
4750  Warning("ProcessNext", "problems sending output list");
4751  if (slb) slb->Form("%d %lld %lld %.3f", fPlayer->GetExitStatus(), pq->GetEntries(),
4752  pq->GetBytes(), pq->GetUsedCPU());
4753  } else {
4755  Warning("ProcessNext","the output list is empty!");
4756  if (SendResults(fSocket, fPlayer->GetOutputList()) != 0)
4757  Warning("ProcessNext", "problems sending output list");
4758  if (slb) slb->Form("%d -1 -1 %.3f", fPlayer->GetExitStatus(), pq->GetUsedCPU());
4759  }
4760 
4761  // Remove aborted queries from the list
4763  if (pqr) SafeDelete(pqr);
4764  if (fQMgr) fQMgr->RemoveQuery(pq);
4765  } else {
4766  // Keep in memory only light infor about a query
4767  if (!(pq->IsDraw()) && pqr) {
4768  if (fQMgr && fQMgr->Queries()) {
4769  fQMgr->Queries()->Add(pqr);
4770  // Remove from the fQueries list
4771  fQMgr->Queries()->Remove(pq);
4772  }
4773  // These removes 'pq' from the internal player list and
4774  // deletes it; in this way we do not attempt a double delete
4775  // when destroying the player
4777  pq->GetTitle(), pq->GetName()));
4778  }
4779  }
4780 
4781  DeletePlayer();
4782  if (IsMaster() && fProof->UseDynamicStartup())
4783  // stop the workers
4784  fProof->RemoveWorkers(0);
4785 }
4786 
4787 ////////////////////////////////////////////////////////////////////////////////
4788 /// Register TFileCollections in 'out' as datasets according to the rules in 'in'
4789 
4791  TDataSetManager *dsm, TString &msg)
4792 {
4793  PDB(kDataset, 1)
4794  ::Info("TProofServ::RegisterDataSets",
4795  "enter: %d objs in the output list", (out ? out->GetSize() : -1));
4796 
4797  if (!in || !out || !dsm) {
4798  ::Error("TProofServ::RegisterDataSets", "invalid inputs: %p, %p, %p", in, out, dsm);
4799  return 0;
4800  }
4801  msg = "";
4802  THashList tags;
4803  TList torm;
4804  TIter nxo(out);
4805  TObject *o = 0;
4806  while ((o = nxo())) {
4807  // Only file collections TFileCollection
4808  TFileCollection *ds = dynamic_cast<TFileCollection*> (o);
4809  if (ds) {
4810  // Origin of this dataset
4811  ds->SetTitle(gSystem->HostName());
4812  // The tag and register option
4813  TNamed *fcn = 0;
4814  TString tag = TString::Format("DATASET_%s", ds->GetName());
4815  if (!(fcn = (TNamed *) out->FindObject(tag))) continue;
4816  // If this tag is in the list of processed tags, flag it for removal
4817  if (tags.FindObject(tag)) {
4818  torm.Add(o);
4819  continue;
4820  }
4821  // Register option
4822  TString regopt(fcn->GetTitle());
4823  // Sort according to the internal index, if required
4824  if (regopt.Contains(":sortidx:")) {
4825  ds->Sort(kTRUE);
4826  regopt.ReplaceAll(":sortidx:", "");
4827  }
4828  // Register this dataset
4830  // Extract the list
4831  if (ds->GetList()->GetSize() > 0) {
4832  // Register the dataset (quota checks are done inside here)
4833  const char *vfmsg = regopt.Contains("V") ? " and verifying" : "";
4834  msg.Form("Registering%s dataset '%s' ... ", vfmsg, ds->GetName());
4835  // Always allow verification for this action
4836  Bool_t allowVerify = dsm->TestBit(TDataSetManager::kAllowVerify) ? kTRUE : kFALSE;
4837  if (regopt.Contains("V") && !allowVerify) dsm->SetBit(TDataSetManager::kAllowVerify);
4838  // Main action
4839  Int_t rc = dsm->RegisterDataSet(ds->GetName(), ds, regopt);
4840  // Reset to the previous state if needed
4841  if (regopt.Contains("V") && !allowVerify) dsm->ResetBit(TDataSetManager::kAllowVerify);
4842  if (rc != 0) {
4843  ::Warning("TProofServ::RegisterDataSets",
4844  "failure registering or verifying dataset '%s'", ds->GetName());
4845  msg.Form("Registering%s dataset '%s' ... failed! See log for more details", vfmsg, ds->GetName());
4846  } else {
4847  ::Info("TProofServ::RegisterDataSets", "dataset '%s' successfully registered%s",
4848  ds->GetName(), (strlen(vfmsg) > 0) ? " and verified" : "");
4849  msg.Form("Registering%s dataset '%s' ... OK", vfmsg, ds->GetName());
4850  // Add tag to the list of processed tags to avoid double processing
4851  // (there may be more objects with the same name, created by each worker)
4852  tags.Add(new TObjString(tag));
4853  }
4854  // Notify
4855  PDB(kDataset, 2) {
4856  ::Info("TProofServ::RegisterDataSets", "printing collection");
4857  ds->Print("F");
4858  }
4859  } else {
4860  ::Warning("TProofServ::RegisterDataSets", "collection '%s' is empty", o->GetName());
4861  }
4862  } else {
4863  ::Info("TProofServ::RegisterDataSets", "dataset registration not allowed");
4864  return -1;
4865  }
4866  }
4867  }
4868  // Cleanup all temporary stuff possibly created by each worker
4869  TIter nxrm(&torm);
4870  while ((o = nxrm())) out->Remove(o);
4871  torm.SetOwner(kTRUE);
4872  // Remove tags
4873  TIter nxtg(&tags);
4874  while((o = nxtg())) {
4875  TObject *oo = 0;
4876  while ((oo = out->FindObject(o->GetName()))) { out->Remove(oo); }
4877  }
4878  tags.SetOwner(kTRUE);
4879 
4880  PDB(kDataset, 1) ::Info("TProofServ::RegisterDataSets", "exit");
4881  // Done
4882  return 0;
4883 }
4884 
4885 ////////////////////////////////////////////////////////////////////////////////
4886 /// Handle request for list of queries.
4887 
4889 {
4890  PDB(kGlobal, 1)
4891  Info("HandleQueryList", "Enter");
4892 
4893  Bool_t all;
4894  (*mess) >> all;
4895 
4896  TList *ql = new TList;
4897  Int_t ntot = 0, npre = 0, ndraw= 0;
4898  if (fQMgr) {
4899  if (all) {
4900  // Rescan
4901  TString qdir = fQueryDir;
4902  Int_t idx = qdir.Index("session-");
4903  if (idx != kNPOS)
4904  qdir.Remove(idx);
4905  fQMgr->ScanPreviousQueries(qdir);
4906  // Send also information about previous queries, if any
4907  if (fQMgr->PreviousQueries()) {
4908  TIter nxq(fQMgr->PreviousQueries());
4909  TProofQueryResult *pqr = 0;
4910  while ((pqr = (TProofQueryResult *)nxq())) {
4911  ntot++;
4912  pqr->fSeqNum = ntot;
4913  ql->Add(pqr);
4914  }
4915  }
4916  }
4917 
4918  npre = ntot;
4919  if (fQMgr->Queries()) {
4920  // Add info about queries in this session
4921  TIter nxq(fQMgr->Queries());
4922  TProofQueryResult *pqr = 0;
4923  TQueryResult *pqm = 0;
4924  while ((pqr = (TProofQueryResult *)nxq())) {
4925  ntot++;
4926  if ((pqm = pqr->CloneInfo())) {
4927  pqm->fSeqNum = ntot;
4928  ql->Add(pqm);
4929  } else {
4930  Warning("HandleQueryList", "unable to clone TProofQueryResult '%s:%s'",
4931  pqr->GetName(), pqr->GetTitle());
4932  }
4933  }
4934  }
4935  // Number of draw queries
4936  ndraw = fQMgr->DrawQueries();
4937  }
4938 
4940  m << npre << ndraw << ql;
4941  fSocket->Send(m);
4942  delete ql;
4943 
4944  // Done
4945  return;
4946 }
4947 
4948 ////////////////////////////////////////////////////////////////////////////////
4949 /// Handle remove request.
4950 
4952 {
4953  PDB(kGlobal, 1)
4954  Info("HandleRemove", "Enter");
4955 
4956  TString queryref;
4957  (*mess) >> queryref;
4958 
4959  if (slb) *slb = queryref;
4960 
4961  if (queryref == "cleanupqueue") {
4962  // Remove pending requests
4963  Int_t pend = CleanupWaitingQueries();
4964  // Notify
4965  Info("HandleRemove", "%d queries removed from the waiting list", pend);
4966  // We are done
4967  return;
4968  }
4969 
4970  if (queryref == "cleanupdir") {
4971 
4972  // Cleanup previous sessions results
4973  Int_t nd = (fQMgr) ? fQMgr->CleanupQueriesDir() : -1;
4974 
4975  // Notify
4976  Info("HandleRemove", "%d directories removed", nd);
4977  // We are done
4978  return;
4979  }
4980 
4981 
4982  if (fQMgr) {
4983  TProofLockPath *lck = 0;
4984  if (fQMgr->LockSession(queryref, &lck) == 0) {
4985 
4986  // Remove query
4987  TList qtorm;
4988  fQMgr->RemoveQuery(queryref, &qtorm);
4989  CleanupWaitingQueries(kFALSE, &qtorm);
4990 
4991  // Unlock and remove the lock file
4992  if (lck) {
4993  gSystem->Unlink(lck->GetName());
4994  SafeDelete(lck);
4995  }
4996 
4997  // We are done
4998  return;
4999  }
5000  } else {
5001  Warning("HandleRemove", "query result manager undefined!");
5002  }
5003 
5004  // Notify failure
5005  Info("HandleRemove",
5006  "query %s could not be removed (unable to lock session)", queryref.Data());
5007 
5008  // Done
5009  return;
5010 }
5011 
5012 ////////////////////////////////////////////////////////////////////////////////
5013 /// Handle retrieve request.
5014 
5016 {
5017  PDB(kGlobal, 1)
5018  Info("HandleRetrieve", "Enter");
5019 
5020  TString queryref;
5021  (*mess) >> queryref;
5022 
5023  if (slb) *slb = queryref;
5024 
5025  // Parse reference string
5026  Int_t qry = -1;
5027  TString qdir;
5028  if (fQMgr) fQMgr->LocateQuery(queryref, qry, qdir);
5029 
5030  TString fout = qdir;
5031  fout += "/query-result.root";
5032 
5033  TFile *f = TFile::Open(fout,"READ");
5034  TProofQueryResult *pqr = 0;
5035  if (f) {
5036  f->ReadKeys();
5037  TIter nxk(f->GetListOfKeys());
5038  TKey *k = 0;
5039  while ((k = (TKey *)nxk())) {
5040  if (!strcmp(k->GetClassName(), "TProofQueryResult")) {
5041  pqr = (TProofQueryResult *) f->Get(k->GetName());
5042  // For backward compatibility
5043  if (pqr && fProtocol < 13) {
5044  TDSet *d = 0;
5045  TObject *o = 0;
5046  TIter nxi(pqr->GetInputList());
5047  while ((o = nxi()))
5048  if ((d = dynamic_cast<TDSet *>(o)))
5049  break;
5050  d->SetWriteV3(kTRUE);
5051  }
5052  if (pqr) {
5053 
5054  // Message for the client
5055  Float_t qsz = (Float_t) f->GetSize();
5056  Int_t ilb = 0;
5057  static const char *clb[4] = { "bytes", "KB", "MB", "GB" };
5058  while (qsz > 1000. && ilb < 3) {
5059  qsz /= 1000.;
5060  ilb++;
5061  }
5062  SendAsynMessage(TString::Format("%s: sending result of %s:%s (%.1f %s)",
5063  fPrefix.Data(), pqr->GetTitle(), pqr->GetName(),
5064  qsz, clb[ilb]));
5066  } else {
5067  Info("HandleRetrieve",
5068  "query not found in file %s",fout.Data());
5069  // Notify not found
5071  }
5072  break;
5073  }
5074  }
5075  f->Close();
5076  delete f;
5077  } else {
5078  Info("HandleRetrieve",
5079  "file cannot be open (%s)",fout.Data());
5080  // Notify not found
5082  return;
5083  }
5084 
5085  // Done
5086  return;
5087 }
5088 
5089 ////////////////////////////////////////////////////////////////////////////////
5090 /// Handle lib, inc search paths modification request
5091 
5093 {
5094  TString type;
5095  Bool_t add;
5096  TString path;
5097  Int_t rc = 1;
5098  (*mess) >> type >> add >> path;
5099  if (mess->BufferSize() > mess->Length()) (*mess) >> rc;
5100 
5101  // Check type of action
5102  if ((type != "lib") && (type != "inc")) {
5103  Error("HandleLibIncPath","unknown action type: %s", type.Data());
5104  return rc;
5105  }
5106 
5107  // Separators can be either commas or blanks
5108  path.ReplaceAll(","," ");
5109 
5110  // Decompose lists
5111  TObjArray *op = 0;
5112  if (path.Length() > 0 && path != "-") {
5113  if (!(op = path.Tokenize(" "))) {
5114  Error("HandleLibIncPath","decomposing path %s", path.Data());
5115  return rc;
5116  }
5117  }
5118 
5119  if (add) {
5120 
5121  if (type == "lib") {
5122 
5123  // Add libs
5124  TIter nxl(op, kIterBackward);
5125  TObjString *lib = 0;
5126  while ((lib = (TObjString *) nxl())) {
5127  // Expand path
5128  TString xlib = lib->GetName();
5129  gSystem->ExpandPathName(xlib);
5130  // Add to the dynamic lib search path if it exists and can be read
5131  if (!gSystem->AccessPathName(xlib, kReadPermission)) {
5132  TString newlibpath = gSystem->GetDynamicPath();
5133  // In the first position after the working dir
5134  Int_t pos = 0;
5135  if (newlibpath.BeginsWith(".:"))
5136  pos = 2;
5137  if (newlibpath.Index(xlib) == kNPOS) {
5138  newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
5139  gSystem->SetDynamicPath(newlibpath);
5140  }
5141  } else {
5142  Info("HandleLibIncPath",
5143  "libpath %s does not exist or cannot be read - not added", xlib.Data());
5144  }
5145  }
5146 
5147  // Forward the request, if required
5148  if (IsMaster())
5149  fProof->AddDynamicPath(path);
5150 
5151  } else {
5152 
5153  // Add incs
5154  TIter nxi(op);
5155  TObjString *inc = 0;
5156  while ((inc = (TObjString *) nxi())) {
5157  // Expand path
5158  TString xinc = inc->GetName();
5159  gSystem->ExpandPathName(xinc);
5160  // Add to the dynamic lib search path if it exists and can be read
5161  if (!gSystem->AccessPathName(xinc, kReadPermission)) {
5162  TString curincpath = gSystem->GetIncludePath();
5163  if (curincpath.Index(xinc) == kNPOS)
5164  gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
5165  } else
5166  Info("HandleLibIncPath",
5167  "incpath %s does not exist or cannot be read - not added", xinc.Data());
5168  }
5169 
5170  // Forward the request, if required
5171  if (IsMaster())
5172  fProof->AddIncludePath(path);
5173  }
5174 
5175 
5176  } else {
5177 
5178  if (type == "lib") {
5179 
5180  // Remove libs
5181  TIter nxl(op);
5182  TObjString *lib = 0;
5183  while ((lib = (TObjString *) nxl())) {
5184  // Expand path
5185  TString xlib = lib->GetName();
5186  gSystem->ExpandPathName(xlib);
5187  // Remove from the dynamic lib search path
5188  TString newlibpath = gSystem->GetDynamicPath();
5189  newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
5190  gSystem->SetDynamicPath(newlibpath);
5191  }
5192 
5193  // Forward the request, if required
5194  if (IsMaster())
5195  fProof->RemoveDynamicPath(path);
5196 
5197  } else {
5198 
5199  // Remove incs
5200  TIter nxi(op);
5201  TObjString *inc = 0;
5202  while ((inc = (TObjString *) nxi())) {
5203  TString newincpath = gSystem->GetIncludePath();
5204  newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
5205  // Remove the interpreter path (added anyhow internally)
5206  newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
5207  gSystem->SetIncludePath(newincpath);
5208  }
5209 
5210  // Forward the request, if required
5211  if (IsMaster())
5212  fProof->RemoveIncludePath(path);
5213  }
5214  }
5215  // Done
5216  return rc;
5217 }
5218 
5219 ////////////////////////////////////////////////////////////////////////////////
5220 /// Handle file checking request.
5221 
5223 {
5224  TString filenam;
5225  TMD5 md5;
5226  UInt_t opt = TProof::kUntar;
5227 
5228  TMessage reply(kPROOF_CHECKFILE);
5229 
5230  // Parse message
5231  (*mess) >> filenam >> md5;
5232  if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8))
5233  (*mess) >> opt;
5234 
5235  if (slb) *slb = filenam;
5236 
5237  if (filenam.BeginsWith("-")) {
5238  // install package:
5239  // compare md5's, untar, store md5 in PROOF-INF, remove par file
5240  Int_t st = 0;
5241  Bool_t err = kFALSE;
5242  filenam = filenam.Strip(TString::kLeading, '-');
5243  TString packnam = filenam;
5244  packnam.Remove(packnam.Length() - 4); // strip off ".par"
5245  // compare md5's to check if transmission was ok
5246  fPackageLock->Lock();
5247  TMD5 *md5local = TMD5::FileChecksum(fPackageDir + "/" + filenam);
5248  if (md5local && md5 == (*md5local)) {
5249  if ((opt & TProof::kRemoveOld)) {
5250  // remove any previous package directory with same name
5251  st = gSystem->Exec(TString::Format("%s %s/%s", kRM, fPackageDir.Data(),
5252  packnam.Data()));
5253  if (st)
5254  Error("HandleCheckFile", "failure executing: %s %s/%s",
5255  kRM, fPackageDir.Data(), packnam.Data());
5256  }
5257  // find gunzip...
5258  char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP,
5260  if (gunzip) {
5261  // untar package
5263  filenam.Data(), fPackageDir.Data()));
5264  if (st)
5265  Error("HandleCheckFile", "failure executing: %s",
5267  filenam.Data(), fPackageDir.Data()).Data());
5268  delete [] gunzip;
5269  } else
5270  Error("HandleCheckFile", "%s not found", kGUNZIP);
5271  // check that fPackageDir/packnam now exists
5272  if (gSystem->AccessPathName(fPackageDir + "/" + packnam, kWritePermission)) {
5273  // par file did not unpack itself in the expected directory, failure
5274  reply << (Int_t)0;
5275  if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5276  err = kTRUE;
5277  Error("HandleCheckFile", "package %s did not unpack into %s",
5278  filenam.Data(), packnam.Data());
5279  } else {
5280  // store md5 in package/PROOF-INF/md5.txt
5281  TString md5f = fPackageDir + "/" + packnam + "/PROOF-INF/md5.txt";
5282  TMD5::WriteChecksum(md5f, md5local);
5283  // Notify the client
5284  reply << (Int_t)1;
5285  PDB(kPackage, 1)
5286  Info("HandleCheckFile",
5287  "package %s installed on node", filenam.Data());
5288  }
5289  } else {
5290  reply << (Int_t)0;
5291  if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5292  err = kTRUE;
5293  PDB(kPackage, 1)
5294  Info("HandleCheckFile",
5295  "package %s not yet on node", filenam.Data());
5296  }
5297 
5298  // Note: Originally an fPackageLock->Unlock() call was made
5299  // after the if-else statement below. With multilevel masters,
5300  // submasters still check to make sure the package exists with
5301  // the correct md5 checksum and need to do a read lock there.
5302  // As yet locking is not that sophisicated so the lock must
5303  // be released below before the call to fProof->UploadPackage().
5304  if (err) {
5305  // delete par file in case of error
5306  gSystem->Exec(TString::Format("%s %s/%s", kRM, fPackageDir.Data(),
5307  filenam.Data()));
5308  fPackageLock->Unlock();
5309  } else if (IsMaster()) {
5310  // forward to workers
5311  fPackageLock->Unlock();
5312  if (fProof->UploadPackage(fPackageDir + "/" + filenam,
5313  (TProof::EUploadPackageOpt)opt) != 0)
5314  Info("HandleCheckFile",
5315  "problems uploading package %s", filenam.Data());
5316  } else {
5317  // Unlock in all cases
5318  fPackageLock->Unlock();
5319  }
5320  delete md5local;
5321  fSocket->Send(reply);
5322 
5323  } else if (filenam.BeginsWith("+")) {
5324  // check file in package directory
5325  filenam = filenam.Strip(TString::kLeading, '+');
5326  TString packnam = filenam;
5327  packnam.Remove(packnam.Length() - 4); // strip off ".par"
5328  TString md5f = fPackageDir + "/" + packnam + "/PROOF-INF/md5.txt";
5329  fPackageLock->Lock();
5330  TMD5 *md5local = TMD5::ReadChecksum(md5f);
5331  fPackageLock->Unlock();
5332  if (md5local && md5 == (*md5local)) {
5333  // package already on server, unlock directory
5334  reply << (Int_t)1;
5335  PDB(kPackage, 1)
5336  Info("HandleCheckFile",
5337  "package %s already on node", filenam.Data());
5338  if (IsMaster())
5339  if (fProof->UploadPackage(fPackageDir + "/" + filenam) != 0)
5340  Info("HandleCheckFile",
5341  "problems uploading package %s", filenam.Data());
5342 
5343  } else {
5344  reply << (Int_t)0;
5345  if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5346  PDB(kPackage, 1)
5347  Info("HandleCheckFile",
5348  "package %s not yet on node", filenam.Data());
5349  }
5350  delete md5local;
5351  fSocket->Send(reply);
5352 
5353  } else if (filenam.BeginsWith("=")) {
5354  // check file in package directory, do not lock if it is the wrong file
5355  filenam = filenam.Strip(TString::kLeading, '=');
5356  TString packnam = filenam;
5357  packnam.Remove(packnam.Length() - 4); // strip off ".par"
5358  TString md5f = fPackageDir + "/" + packnam + "/PROOF-INF/md5.txt";
5359  fPackageLock->Lock();
5360  TMD5 *md5local = TMD5::ReadChecksum(md5f);
5361  fPackageLock->Unlock();
5362  if (md5local && md5 == (*md5local)) {
5363  // package already on server, unlock directory
5364  reply << (Int_t)1;
5365  PDB(kPackage, 1)
5366  Info("HandleCheckFile",
5367  "package %s already on node", filenam.Data());
5368  if (IsMaster())
5369  if (fProof->UploadPackage(fPackageDir + "/" + filenam) != 0)
5370  Info("HandleCheckFile",
5371  "problems with uploading package %s", filenam.Data());
5372  } else {
5373  reply << (Int_t)0;
5374  if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5375  PDB(kPackage, 1)
5376  Info("HandleCheckFile",
5377  "package %s not yet on node", filenam.Data());
5378  }
5379  delete md5local;
5380  fSocket->Send(reply);
5381 
5382  } else {
5383  // check file in cache directory
5384  TString cachef = fCacheDir + "/" + filenam;
5385  fCacheLock->Lock();
5386  TMD5 *md5local = TMD5::FileChecksum(cachef);
5387 
5388  if (md5local && md5 == (*md5local)) {
5389  reply << (Int_t)1;
5390  PDB(kCache, 1)
5391  Info("HandleCheckFile", "file %s already on node", filenam.Data());
5392  } else {
5393  reply << (Int_t)0;
5394  if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5395  PDB(kCache, 1)
5396  Info("HandleCheckFile", "file %s not yet on node", filenam.Data());
5397  }
5398  delete md5local;
5399  fSocket->Send(reply);
5400  fCacheLock->Unlock();
5401  }
5402 }
5403 
5404 ////////////////////////////////////////////////////////////////////////////////
5405 /// Handle here all cache and package requests.
5406 
5408 {
5409  PDB(kGlobal, 1)
5410  Info("HandleCache", "Enter");
5411 
5412  Int_t status = 0;
5413  Int_t type = 0;
5414  Bool_t all = kFALSE;
5415  TMessage msg;
5416  Bool_t fromglobal = kFALSE;
5417  Int_t chkveropt = TProof::kCheckROOT; // Default: check ROOT version
5418 
5419  // Notification message
5420  TString noth;
5421  const char *k = (IsMaster()) ? "Mst" : "Wrk";
5422  noth.Form("%s-%s", k, fOrdinal.Data());
5423 
5424  TList *optls = 0;
5425  TString packagedir(fPackageDir), package, pdir, ocwd, file;
5426  (*mess) >> type;
5427  switch (type) {
5428  case TProof::kShowCache:
5429  (*mess) >> all;
5430  printf("*** File cache %s:%s ***\n", gSystem->HostName(),
5431  fCacheDir.Data());
5432  fflush(stdout);
5433  PDB(kCache, 1) {
5434  gSystem->Exec(TString::Format("%s -a %s", kLS, fCacheDir.Data()));
5435  } else {
5436  gSystem->Exec(TString::Format("%s %s", kLS, fCacheDir.Data()));
5437  }
5438  if (IsMaster() && all)
5439  fProof->ShowCache(all);
5440  LogToMaster();
5441  if (slb) slb->Form("%d %d", type, all);
5442  break;
5443  case TProof::kClearCache:
5444  file = "";
5445  if ((mess->BufferSize() > mess->Length())) (*mess) >> file;
5446  fCacheLock->Lock();
5447  if (file.IsNull() || file == "*") {
5448  gSystem->Exec(TString::Format("%s %s/* %s/.*.binversion", kRM, fCacheDir.Data(), fCacheDir.Data()));
5449  } else {
5450  gSystem->Exec(TString::Format("%s %s/%s", kRM, fCacheDir.Data(), file.Data()));
5451  }
5452  fCacheLock->Unlock();
5453  if (IsMaster())
5454  fProof->ClearCache(file);
5455  if (slb) slb->Form("%d %s", type, file.Data());
5456  break;
5457  case TProof::kShowPackages:
5458  (*mess) >> all;
5460  // Scan the list of global packages dirs
5462  TNamed *nm = 0;
5463  while ((nm = (TNamed *)nxd())) {
5464  printf("*** Global Package cache %s %s:%s ***\n",
5465  nm->GetName(), gSystem->HostName(), nm->GetTitle());
5466  fflush(stdout);
5467  gSystem->Exec(TString::Format("%s %s", kLS, nm->GetTitle()));
5468  printf("\n");
5469  fflush(stdout);
5470  }
5471  }
5472  printf("*** Package cache %s:%s ***\n", gSystem->HostName(),
5473  fPackageDir.Data());
5474  fflush(stdout);
5476  if (IsMaster() && all)
5477  fProof->ShowPackages(all);
5478  LogToMaster();
5479  if (slb) slb->Form("%d %d", type, all);
5480  break;
5482  status = UnloadPackages();
5483  if (status == 0) {
5484  fPackageLock->Lock();
5485  gSystem->Exec(TString::Format("%s %s/*", kRM, fPackageDir.Data()));
5486  fPackageLock->Unlock();
5487  if (IsMaster())
5488  status = fProof->ClearPackages();
5489  }
5490  if (slb) slb->Form("%d %d", type, status);
5491  break;
5492  case TProof::kClearPackage:
5493  (*mess) >> package;
5494  status = UnloadPackage(package);
5495  if (status == 0) {
5496  fPackageLock->Lock();
5497  // remove package directory and par file
5498  gSystem->Exec(TString::Format("%s %s/%s", kRM, fPackageDir.Data(),
5499  package.Data()));
5500  if (IsMaster())
5501  gSystem->Exec(TString::Format("%s %s/%s.par", kRM, fPackageDir.Data(),
5502  package.Data()));
5503  fPackageLock->Unlock();
5504  if (IsMaster())
5505  status = fProof->ClearPackage(package);
5506  }
5507  if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5508  break;
5509  case TProof::kBuildPackage:
5510  (*mess) >> package;
5511  if ((mess->BufferSize() > mess->Length())) (*mess) >> chkveropt;
5512 
5513  // always follows BuildPackage so no need to check for PROOF-INF
5514  pdir = fPackageDir + "/" + package;
5515 
5516  fromglobal = kFALSE;
5517  if (gSystem->AccessPathName(pdir, kReadPermission) ||
5518  gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission)) {
5519  // Is there a global package with this name?
5521  // Scan the list of global packages dirs
5523  TNamed *nm = 0;
5524  while ((nm = (TNamed *)nxd())) {
5525  pdir.Form("%s/%s", nm->GetTitle(), package.Data());
5526  if (!gSystem->AccessPathName(pdir, kReadPermission) &&
5527  !gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission)) {
5528  // Package found, stop searching
5529  fromglobal = kTRUE;
5530  packagedir = nm->GetTitle();
5531  break;
5532  }
5533  pdir = "";
5534  }
5535  if (pdir.Length() <= 0) {
5536  // Package not found
5537  SendAsynMessage(TString::Format("%s: kBuildPackage: failure locating %s ...",
5538  noth.Data(), package.Data()));
5539  status = -1;
5540  break;
5541  }
5542  }
5543  }
5544 
5545  if (IsMaster() && !fromglobal) {
5546  // Make sure package is available on all slaves, even new ones
5547  if (fProof->UploadPackage(pdir + ".par") != 0) {
5548  Warning("HandleCache",
5549  "kBuildPackage: problems forwarding package %s to workers", package.Data());
5550  SendAsynMessage(TString::Format("%s: kBuildPackage: problems forwarding package %s to workers ...",
5551  noth.Data(), package.Data()));
5552  }
5553  }
5554  fPackageLock->Lock();
5555 
5556  if (!status) {
5557 
5558  PDB(kPackage, 1)
5559  Info("HandleCache",
5560  "kBuildPackage: package %s exists and has PROOF-INF directory", package.Data());
5561 
5562  ocwd = gSystem->WorkingDirectory();
5563  gSystem->ChangeDirectory(pdir);
5564 
5565  // forward build command to slaves, but don't wait for results
5566  if (IsMaster())
5568 
5569  // check for BUILD.sh and execute
5570  if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
5571  // Notify the upper level
5572  SendAsynMessage(TString::Format("%s: building %s ...", noth.Data(), package.Data()));
5573 
5574  // read version from file proofvers.txt, and if current version is
5575  // not the same do a "BUILD.sh clean"
5576  Bool_t goodver = kTRUE;
5577  Bool_t savever = kFALSE;
5578  TString v, r;
5579  FILE *f = fopen("PROOF-INF/proofvers.txt", "r");
5580  if (f) {
5581  v.Gets(f);
5582  r.Gets(f);
5583  fclose(f);
5584  if (chkveropt == TProof::kCheckROOT || chkveropt == TProof::kCheckSVN) {
5585  if (v != gROOT->GetVersion()) goodver = kFALSE;
5586  if (goodver && chkveropt == TProof::kCheckSVN)
5587  if (r != gROOT->GetGitCommit()) goodver = kFALSE;
5588  }
5589  }
5590  if (!f || !goodver) {
5591  if (!fromglobal || !gSystem->AccessPathName(pdir, kWritePermission)) {
5592  savever = kTRUE;
5593  SendAsynMessage(TString::Format("%s: %s: version change (current: %s:%s,"
5594  " build: %s:%s): cleaning ... ",
5595  noth.Data(), package.Data(), gROOT->GetVersion(),
5596  gROOT->GetGitCommit(), v.Data(), r.Data()));
5597  // Hard cleanup: go up the dir tree
5598  gSystem->ChangeDirectory(packagedir);
5599  // remove package directory
5600  gSystem->Exec(TString::Format("%s %s", kRM, pdir.Data()));
5601  // find gunzip...
5602  char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP,
5604  if (gunzip) {
5605  TString par;
5606  par.Form("%s.par", pdir.Data());
5607  // untar package
5608  TString cmd;
5609  cmd.Form(kUNTAR3, gunzip, par.Data());
5610  status = gSystem->Exec(cmd);
5611  if (status) {
5612  Error("HandleCache", "kBuildPackage: failure executing: %s", cmd.Data());
5613  } else {
5614  // Store md5 in package/PROOF-INF/md5.txt
5615  TMD5 *md5local = TMD5::FileChecksum(par);
5616  if (md5local) {
5617  TString md5f = packagedir + "/" + package + "/PROOF-INF/md5.txt";
5618  TMD5::WriteChecksum(md5f, md5local);
5619  // Go down to the package directory
5620  gSystem->ChangeDirectory(pdir);
5621  // Cleanup
5622  SafeDelete(md5local);
5623  } else {
5624  Warning("HandleCache", "kBuildPackage: failure calculating/saving MD5sum for '%s'", par.Data());
5625  }
5626  }
5627  delete [] gunzip;
5628  } else {
5629  Error("HandleCache", "kBuildPackage: %s not found", kGUNZIP);
5630  status = -1;
5631  }
5632  } else {
5633  SendAsynMessage(TString::Format("%s: %s: ROOT version inconsistency (current: %s, build: %s):"
5634  " global package: cannot re-build!!! ",
5635  noth.Data(), package.Data(), gROOT->GetVersion(), v.Data()));
5636  status = -1;
5637  }
5638  }
5639 
5640  if (!status) {
5641  // To build the package we execute PROOF-INF/BUILD.sh via a pipe
5642  // so that we can send back the log in (almost) real-time to the
5643  // (impatient) client. Note that this operation will block, so
5644  // the messages from builds on the workers will reach the client
5645  // shortly after the master ones.
5646  TString ipath(gSystem->GetIncludePath());
5647  ipath.ReplaceAll("\"","");
5648  TString cmd;
5649  cmd.Form("export ROOTINCLUDEPATH=\"%s\" ; PROOF-INF/BUILD.sh", ipath.Data());
5650  {
5652  }
5653  if (!(status = TProofServLogHandler::GetCmdRtn())) {
5654  // Success: write version file
5655  if (savever) {
5656  f = fopen("PROOF-INF/proofvers.txt", "w");
5657  if (f) {
5658  fputs(gROOT->GetVersion(), f);
5659  fputs(TString::Format("\n%s", gROOT->GetGitCommit()), f);
5660  fclose(f);
5661  }
5662  }
5663  }
5664  }
5665  } else {
5666  // Notify the user
5667  PDB(kPackage, 1)
5668  Info("HandleCache", "no PROOF-INF/BUILD.sh found for package %s", package.Data());
5669  }
5670  gSystem->ChangeDirectory(ocwd);
5671  }
5672 
5673  fPackageLock->Unlock();
5674 
5675  if (status) {
5676  // Notify the upper level
5677  SendAsynMessage(TString::Format("%s: failure building %s ... (status: %d)", noth.Data(), package.Data(), status));
5678  } else {
5679  // collect built results from slaves
5680  if (IsMaster())
5681  status = fProof->BuildPackage(package, TProof::kCollectBuildResults);
5682  PDB(kPackage, 1)
5683  Info("HandleCache", "package %s successfully built", package.Data());
5684  }
5685  if (slb) slb->Form("%d %s %d %d", type, package.Data(), status, chkveropt);
5686  break;
5687  case TProof::kLoadPackage:
5688  (*mess) >> package;
5689 
5690  // If already loaded don't do it again
5691  if (fEnabledPackages->FindObject(package)) {
5692  Info("HandleCache",
5693  "package %s already loaded", package.Data());
5694  break;
5695  }
5696 
5697  // always follows BuildPackage so no need to check for PROOF-INF
5698  pdir = fPackageDir + "/" + package;
5699 
5700  if (gSystem->AccessPathName(pdir, kReadPermission)) {
5701  // Is there a global package with this name?
5703  // Scan the list of global packages dirs
5705  TNamed *nm = 0;
5706  while ((nm = (TNamed *)nxd())) {
5707  pdir.Form("%s/%s", nm->GetTitle(), package.Data());
5708  if (!gSystem->AccessPathName(pdir, kReadPermission)) {
5709  // Package found, stop searching
5710  break;
5711  }
5712  pdir = "";
5713  }
5714  if (pdir.Length() <= 0) {
5715  // Package not found
5716  SendAsynMessage(TString::Format("%s: kLoadPackage: failure locating %s ...",
5717  noth.Data(), package.Data()));
5718  status = -1;
5719  break;
5720  }
5721  }
5722  }
5723 
5724  ocwd = gSystem->WorkingDirectory();
5725  gSystem->ChangeDirectory(pdir);
5726 
5727  // We have to be atomic here
5728  fPackageLock->Lock();
5729 
5730  // Check for SETUP.C and execute
5731  if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
5732  // We need to change the name of the function to avoid problems when we load more packages
5733  TString setup;
5734  setup.Form("SETUP_ganis_%d_%x", gSystem->GetPid(), package.Hash());
5735  // Remove special characters
5736  TMacro setupmc("PROOF-INF/SETUP.C");
5737  TObjString *setupline = setupmc.GetLineWith("SETUP(");
5738  if (setupline) {
5739  TString setupstring(setupline->GetString());
5740  setupstring.ReplaceAll("SETUP(", TString::Format("%s(", setup.Data()));
5741  setupline->SetString(setupstring);
5742  } else {
5743  // Macro does not contain SETUP()
5744  SendAsynMessage(TString::Format("%s: warning: macro '%s/PROOF-INF/SETUP.C' does not contain a SETUP()"
5745  " function", noth.Data(), package.Data()));
5746  }
5747 
5748  // Load the macro
5749  if (!setupmc.Load()) {
5750  // Macro could not be loaded
5751  SendAsynMessage(TString::Format("%s: error: macro '%s/PROOF-INF/SETUP.C' could not be loaded:"
5752  " cannot continue",
5753  noth.Data(), package.Data()));
5754  status = -1;
5755  } else {
5756  // Check the signature
5757  TFunction *fun = (TFunction *) gROOT->GetListOfGlobalFunctions()->FindObject(setup);
5758  if (!fun) {
5759  // Notify the upper level
5760  SendAsynMessage(TString::Format("%s: error: function SETUP() not found in macro '%s/PROOF-INF/SETUP.C':"
5761  " cannot continue",
5762  noth.Data(), package.Data()));
5763  status = -1;
5764  } else {
5765  TMethodCall callEnv;
5766  // Check the number of arguments
5767  if (fun->GetNargs() == 0) {
5768  // No arguments (basic signature)
5769  callEnv.Init(fun);
5770  if ((mess->BufferSize() > mess->Length())) {
5771  (*mess) >> optls;
5772  SendAsynMessage(TString::Format("%s: warning: loaded SETUP() does not take any argument:"
5773  " the specified argument will be ignored", noth.Data()));
5774  }
5775  } else if (fun->GetNargs() == 1) {
5776  TMethodArg *arg = (TMethodArg *) fun->GetListOfMethodArgs()->First();
5777  if (arg) {
5778  callEnv.Init(fun);
5779  // Get argument
5780  if ((mess->BufferSize() > mess->Length())) (*mess) >> optls;
5781  // Check argument type
5782  TString argsig(arg->GetTitle());
5783  if (argsig.BeginsWith("TList")) {
5784  callEnv.ResetParam();
5785  callEnv.SetParam((Long_t) optls);
5786  } else if (argsig.BeginsWith("const char")) {
5787  callEnv.ResetParam();
5788  TObjString *os = optls ? dynamic_cast<TObjString *>(optls->First()) : 0;
5789  if (os) {
5790  callEnv.SetParam((Long_t) os->GetName());
5791  } else {
5792  if (optls && optls->First()) {
5793  SendAsynMessage(TString::Format("%s: warning: found object argument of type %s:"
5794  " SETUP expects 'const char *': ignoring",
5795  noth.Data(), optls->First()->ClassName()));
5796  }
5797  callEnv.SetParam((Long_t) 0);
5798  }
5799  } else {
5800  // Notify the upper level
5801  SendAsynMessage(TString::Format("%s: error: unsupported SETUP signature: SETUP(%s)"
5802  " cannot continue", noth.Data(), arg->GetTitle()));
5803  status = -1;
5804  }
5805  } else {
5806  // Notify the upper level
5807  SendAsynMessage(TString::Format("%s: error: cannot get information about the SETUP() argument:"
5808  " cannot continue", noth.Data()));
5809  status = -1;
5810  }
5811  } else if (fun->GetNargs() > 1) {
5812  // Notify the upper level
5813  SendAsynMessage(TString::Format("%s: error: function SETUP() can have at most a 'TList *' argument:"
5814  " cannot continue", noth.Data()));
5815  status = -1;
5816  }
5817  // Execute
5818  Long_t setuprc = (status == 0) ? 0 : -1;
5819  if (status == 0) {
5820  callEnv.Execute(setuprc);
5821  if (setuprc < 0) status = -1;
5822  }
5823  }
5824  }
5825  }
5826 
5827  // End of atomicity
5828  fPackageLock->Unlock();
5829 
5830  gSystem->ChangeDirectory(ocwd);
5831 
5832  if (status < 0) {
5833 
5834  // Notify the upper level
5835  SendAsynMessage(TString::Format("%s: failure loading %s ...", noth.Data(), package.Data()));
5836 
5837  } else {
5838 
5839  // create link to package in working directory
5840  gSystem->Symlink(pdir, package);
5841 
5842  // add package to list of include directories to be searched
5843  // by ACliC
5844  gSystem->AddIncludePath(TString("-I") + package);
5845 
5846  // add package to list of include directories to be searched by CINT
5847  gROOT->ProcessLine(TString(".I ") + package);
5848 
5849  // if successful add to list and propagate to slaves
5850  TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(package), optls->Clone())
5851  : new TPair(new TObjString(package), 0);
5852  fEnabledPackages->Add(pck);
5853  if (IsMaster()) {
5854  if (optls && optls->GetSize() > 0) {
5855  // List argument
5856  status = fProof->LoadPackage(package, kFALSE, optls);
5857  } else {
5858  // No argument
5859  status = fProof->LoadPackage(package);
5860  }
5861  }
5862 
5863  PDB(kPackage, 1)
5864  Info("HandleCache", "package %s successfully loaded", package.Data());
5865  }
5866  if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5867  break;
5869  (*mess) >> all;
5870  if (IsMaster()) {
5871  if (all)
5872  printf("*** Enabled packages on master %s on %s\n",
5873  fOrdinal.Data(), gSystem->HostName());
5874  else
5875  printf("*** Enabled packages ***\n");
5876  } else {
5877  printf("*** Enabled packages on slave %s on %s\n",
5878  fOrdinal.Data(), gSystem->HostName());
5879  }
5880  {
5882  while (TPair *pck = (TPair *) next())
5883  printf("%s\n", pck->GetName());
5884  }
5885  if (IsMaster() && all)
5887  LogToMaster();
5888  if (slb) slb->Form("%d %d", type, all);
5889  break;
5890  case TProof::kShowSubCache:
5891  (*mess) >> all;
5892  if (IsMaster() && all)
5893  fProof->ShowCache(all);
5894  LogToMaster();
5895  if (slb) slb->Form("%d %d", type, all);
5896  break;
5898  file = "";
5899  if ((mess->BufferSize() > mess->Length())) (*mess) >> file;
5900  if (IsMaster())
5901  fProof->ClearCache(file);
5902  if (slb) slb->Form("%d %s", type, file.Data());
5903  break;
5905  (*mess) >> all;
5906  if (IsMaster() && all)
5907  fProof->ShowPackages(all);
5908  LogToMaster();
5909  if (slb) slb->Form("%d %d", type, all);
5910  break;
5912  if (IsMaster())
5914  if (slb) slb->Form("%d", type);
5915  break;
5917  (*mess) >> package;
5918  if (IsMaster())
5919  fProof->DisablePackage(package);
5920  if (slb) slb->Form("%d %s", type, package.Data());
5921  break;
5923  (*mess) >> package;
5924  if ((mess->BufferSize() > mess->Length())) (*mess) >> chkveropt;
5925  if (IsMaster())
5926  fProof->BuildPackage(package, TProof::kBuildAll, chkveropt);
5927  if (slb) slb->Form("%d %s %d", type, package.Data(), chkveropt);
5928  break;
5930  (*mess) >> package;
5931  status = UnloadPackage(package);
5932  if (IsMaster() && status == 0)
5933  status = fProof->UnloadPackage(package);
5934  if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5935  break;
5937  (*mess) >> package;
5938  fPackageLock->Lock();
5939  // remove package directory and par file
5940  gSystem->Exec(TString::Format("%s %s/%s", kRM, fPackageDir.Data(),
5941  package.Data()));
5942  gSystem->Exec(TString::Format("%s %s/%s.par", kRM, fPackageDir.Data(),
5943  package.Data()));
5944  fPackageLock->Unlock();
5945  if (IsMaster())
5946  fProof->DisablePackage(package);
5947  if (slb) slb->Form("%d %s", type, package.Data());
5948  break;
5950  status = UnloadPackages();
5951  if (IsMaster() && status == 0)
5952  status = fProof->UnloadPackages();
5953  if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5954  break;
5956  fPackageLock->Lock();
5957  gSystem->Exec(TString::Format("%s %s/*", kRM, fPackageDir.Data()));
5958  fPackageLock->Unlock();
5959  if (IsMaster())
5961  if (slb) slb->Form("%d %s", type, package.Data());
5962  break;
5965  { TList *epl = new TList;
5966  if (fEnabledPackages->GetSize() > 0) {
5967  TIter nxp(fEnabledPackages);
5968  TObject *o = 0;
5969  while ((o = nxp())) { epl->Add(new TObjString(o->GetName()));}
5970  }
5971  msg << type << epl;
5972  fSocket->Send(msg);
5973  epl->SetOwner();
5974  delete epl;
5975  }
5976  if (slb) slb->Form("%d", type);
5977  break;
5978  case TProof::kListPackages:
5979  {
5980  TList *pack = new TList;
5981  void *dir = gSystem->OpenDirectory(fPackageDir);
5982  if (dir) {
5983  TString pac(gSystem->GetDirEntry(dir));
5984  while (pac.Length() > 0) {
5985  if (pac.EndsWith(".par")) {
5986  pac.ReplaceAll(".par","");
5987  pack->Add(new TObjString(pac.Data()));
5988  }
5989  pac = gSystem->GetDirEntry(dir);
5990  }
5991  }
5992  gSystem->FreeDirectory(dir);
5994  msg << type << pack;
5995  fSocket->Send(msg);
5996  }
5997  if (slb) slb->Form("%d", type);
5998  break;
5999  case TProof::kLoadMacro:
6000  {
6001  (*mess) >> package;
6002 
6003  // By first forwarding the load command to the unique workers
6004  // and only then loading locally we load/build in parallel
6005  if (IsMaster())
6006  fProof->Load(package, kFALSE, kTRUE);
6007 
6008  // Atomic action
6009  fCacheLock->Lock();
6010 
6011  TString originalCwd = gSystem->WorkingDirectory();
6013 
6014  // Load the macro
6015  TString pack(package);
6016  Ssiz_t from = 0;
6017  if ((from = pack.Index(",")) != kNPOS) pack.Remove(from);
6018  Info("HandleCache", "loading macro %s ...", pack.Data());
6019  gROOT->ProcessLine(TString::Format(".L %s", pack.Data()));
6020 
6021  // Release atomicity
6022  gSystem->ChangeDirectory(originalCwd.Data());
6023  fCacheLock->Unlock();
6024 
6025  // Now we collect the result from the unique workers and send the load request
6026  // to the other workers (no compilation)
6027  if (IsMaster())
6028  fProof->Load(package, kFALSE, kFALSE);
6029 
6030  // Notify the upper level
6031  LogToMaster();
6032 
6033  if (slb) slb->Form("%d %s", type, package.Data());
6034  }
6035  break;
6036  default:
6037  Error("HandleCache", "unknown type %d", type);
6038  break;
6039  }
6040 
6041  // We are done
6042  return status;
6043 }
6044 
6045 ////////////////////////////////////////////////////////////////////////////////
6046 /// Handle here all requests to modify worker lists
6047 
6049 {
6050  PDB(kGlobal, 1)
6051  Info("HandleWorkerLists", "Enter");
6052 
6053  Int_t type = 0, rc = 0;
6054  TString ord;
6055 
6056  (*mess) >> type;
6057 
6058  switch (type) {
6060  (*mess) >> ord;
6061  if (ord != "*" && !ord.BeginsWith(GetOrdinal()) && ord != "restore") break;
6062  if (fProof) {
6064  Int_t nactmax = fProof->GetListOfSlaves()->GetSize() -
6066  if (nact < nactmax || !IsEndMaster()) {
6067  Int_t nwc = fProof->ActivateWorker(ord);
6068  Int_t nactnew = fProof->GetListOfActiveSlaves()->GetSize();
6069  if (ord == "*") {
6070  if (nactnew == nactmax) {
6071  PDB(kGlobal, 1) Info("HandleWorkerList", "all workers (re-)activated");
6072  } else {
6073  if (IsEndMaster())
6074  PDB(kGlobal, 1) Info("HandleWorkerList", "%d workers could not be (re-)activated", nactmax - nactnew);
6075  }
6076  } else if (ord == "restore") {
6077  if (nwc > 0) {
6078  PDB(kGlobal, 1) Info("HandleWorkerList","active worker(s) restored");
6079  } else {
6080  Error("HandleWorkerList", "some active worker(s) could not be restored; check logs");
6081  }
6082  } else {
6083  if (nactnew == (nact + nwc)) {
6084  if (nwc > 0)
6085  PDB(kGlobal, 1) Info("HandleWorkerList","worker(s) %s (re-)activated", ord.Data());
6086  } else {
6087  if (nwc != -2 && IsEndMaster()) {
6088  Error("HandleWorkerList", "some worker(s) could not be (re-)activated;"
6089  " # of actives: %d --> %d (nwc: %d)",
6090  nact, nactnew, nwc);
6091  }
6092  rc = (nwc < 0) ? nwc : -1;
6093  }
6094  }
6095  } else {
6096  PDB(kGlobal, 1) Info("HandleWorkerList","all workers are already active");
6097  }
6098  } else {
6099  Warning("HandleWorkerList","undefined PROOF session: protocol error?");
6100  }
6101  break;
6103  (*mess) >> ord;
6104  if (ord != "*" && !ord.BeginsWith(GetOrdinal()) && ord != "restore") break;
6105  if (fProof) {
6107  if (nact > 0) {
6108  Int_t nwc = fProof->DeactivateWorker(ord);
6109  Int_t nactnew = fProof->GetListOfActiveSlaves()->GetSize();
6110  if (ord == "*") {
6111  if (nactnew == 0) {
6112  PDB(kGlobal, 1) Info("HandleWorkerList","all workers deactivated");
6113  } else {
6114  if (IsEndMaster())
6115  PDB(kGlobal, 1) Info("HandleWorkerList","%d workers could not be deactivated", nactnew);
6116  }
6117  } else {
6118  if (nactnew == (nact - nwc)) {
6119  if (nwc > 0)
6120  PDB(kGlobal, 1) Info("HandleWorkerList","worker(s) %s deactivated", ord.Data());
6121  } else {
6122  if (nwc != -2 && IsEndMaster()) {
6123  Error("HandleWorkerList", "some worker(s) could not be deactivated:"
6124  " # of actives: %d --> %d (nwc: %d)",
6125  nact, nactnew, nwc);
6126  }
6127  rc = (nwc < 0) ? nwc : -1;
6128  }
6129  }
6130  } else {
6131  PDB(kGlobal, 1) Info("HandleWorkerList","all workers are already inactive");
6132  }
6133  } else {
6134  Warning("HandleWorkerList","undefined PROOF session: protocol error?");
6135  }
6136  break;
6137  default:
6138  Warning("HandleWorkerList","unknown action type (%d)", type);
6139  rc = -1;
6140  }
6141  // Done
6142  return rc;
6143 }
6144 
6145 ////////////////////////////////////////////////////////////////////////////////
6146 /// Get list of workers to be used from now on.
6147 /// The list must be provided by the caller.
6148 
6150  Int_t & /* prioritychange */,
6151  Bool_t /* resume */)
6152 {
6153  // Parse the config file
6154  TProofResourcesStatic *resources =
6156  fConfFile = resources->GetFileName(); // Update the global file name (with path)
6157  PDB(kGlobal,1)
6158  Info("GetWorkers", "using PROOF config file: %s", fConfFile.Data());
6159 
6160  // Get the master
6161  TProofNodeInfo *master = resources->GetMaster();
6162  if (!master) {
6163  PDB(kAll,1)
6164  Info("GetWorkers",
6165  "no appropriate master line found in %s", fConfFile.Data());
6166  return kQueryStop;
6167  } else {
6168  // Set image if not yet done and available
6169  if (fImage.IsNull() && strlen(master->GetImage()) > 0)
6170  fImage = master->GetImage();
6171  }
6172 
6173  // Fill submaster or worker list
6174  if (workers) {
6175  if (resources->GetSubmasters() && resources->GetSubmasters()->GetSize() > 0) {
6176  PDB(kAll,1)
6177  resources->GetSubmasters()->Print();
6178  TProofNodeInfo *ni = 0;
6179  TIter nw(resources->GetSubmasters());
6180  while ((ni = (TProofNodeInfo *) nw()))
6181  workers->Add(new TProofNodeInfo(*ni));
6182  } else if (resources->GetWorkers() && resources->GetWorkers()->GetSize() > 0) {
6183  PDB(kAll,1)
6184  resources->GetWorkers()->Print();
6185  TProofNodeInfo *ni = 0;
6186  TIter nw(resources->GetWorkers());
6187  while ((ni = (TProofNodeInfo *) nw()))
6188  workers->Add(new TProofNodeInfo(*ni));
6189  }
6190  }
6191 
6192  // We are done
6193  return kQueryOK;
6194 }
6195 
6196 ////////////////////////////////////////////////////////////////////////////////
6197 /// Set the file stream where to log (default stderr).
6198 /// If ferr == 0 the default is restored.
6199 /// Returns current setting.
6200 
6202 {
6203  FILE *oldferr = fgErrorHandlerFile;
6204  fgErrorHandlerFile = (ferr) ? ferr : stderr;
6205  return oldferr;
6206 }
6207 
6208 ////////////////////////////////////////////////////////////////////////////////
6209 /// The PROOF error handler function. It prints the message on fgErrorHandlerFile and
6210 /// if abort is set it aborts the application.
6211 
6212 void TProofServ::ErrorHandler(Int_t level, Bool_t abort, const char *location,
6213  const char *msg)
6214 {
6215  if (gErrorIgnoreLevel == kUnset) {
6216  gErrorIgnoreLevel = 0;
6217  if (gEnv) {
6218  TString lvl = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
6219  if (!lvl.CompareTo("Print", TString::kIgnoreCase))
6221  else if (!lvl.CompareTo("Info", TString::kIgnoreCase))
6223  else if (!lvl.CompareTo("Warning", TString::kIgnoreCase))
6225  else if (!lvl.CompareTo("Error", TString::kIgnoreCase))
6227  else if (!lvl.CompareTo("Break", TString::kIgnoreCase))
6229  else if (!lvl.CompareTo("SysError", TString::kIgnoreCase))
6231  else if (!lvl.CompareTo("Fatal", TString::kIgnoreCase))
6233  }
6234  }
6235 
6236  if (level < gErrorIgnoreLevel)
6237  return;
6238 
6239  // Always communicate errors via SendLogFile
6240  if (level >= kError && gProofServ)
6241  gProofServ->LogToMaster();
6242 
6243  Bool_t tosyslog = (fgLogToSysLog > 2) ? kTRUE : kFALSE;
6244 
6245  const char *type = 0;
6246  ELogLevel loglevel = kLogInfo;
6247 
6248  Int_t ipos = (location) ? strlen(location) : 0;
6249 
6250  if (level >= kPrint) {
6251  loglevel = kLogInfo;
6252  type = "Print";
6253  }
6254  if (level >= kInfo) {
6255  loglevel = kLogInfo;
6256  char *ps = location ? (char *) strrchr(location, '|') : (char *)0;
6257  if (ps) {
6258  ipos = (int)(ps - (char *)location);
6259  type = "SvcMsg";
6260  } else {
6261  type = "Info";
6262  }
6263  }
6264  if (level >= kWarning) {
6265  loglevel = kLogWarning;
6266  type = "Warning";
6267  }
6268  if (level >= kError) {
6269  loglevel = kLogErr;
6270  type = "Error";
6271  }
6272  if (level >= kBreak) {
6273  loglevel = kLogErr;
6274  type = "*** Break ***";
6275  }
6276  if (level >= kSysError) {
6277  loglevel = kLogErr;
6278  type = "SysError";
6279  }
6280  if (level >= kFatal) {
6281  loglevel = kLogErr;
6282  type = "Fatal";
6283  }
6284 
6285 
6286  TString buf;
6287 
6288  // Time stamp
6289  TTimeStamp ts;
6290  TString st(ts.AsString("lc"),19);
6291 
6292  if (!location || ipos == 0 ||
6293  (level >= kPrint && level < kInfo) ||
6294  (level >= kBreak && level < kSysError)) {
6295  fprintf(fgErrorHandlerFile, "%s %5d %s | %s: %s\n", st(11,8).Data(),
6296  gSystem->GetPid(),
6297  (gProofServ ? gProofServ->GetPrefix() : "proof"),
6298  type, msg);
6299  if (tosyslog)
6300  buf.Form("%s: %s:%s", fgSysLogEntity.Data(), type, msg);
6301  } else {
6302  fprintf(fgErrorHandlerFile, "%s %5d %s | %s in <%.*s>: %s\n", st(11,8).Data(),
6303  gSystem->GetPid(),
6304  (gProofServ ? gProofServ->GetPrefix() : "proof"),
6305  type, ipos, location, msg);
6306  if (tosyslog)
6307  buf.Form("%s: %s:<%.*s>: %s", fgSysLogEntity.Data(), type, ipos, location, msg);
6308  }
6309  fflush(fgErrorHandlerFile);
6310 
6311  if (tosyslog)
6312  gSystem->Syslog(loglevel, buf);
6313 
6314 #ifdef __APPLE__
6315  if (__crashreporter_info__)
6316  delete [] __crashreporter_info__;
6317  __crashreporter_info__ = StrDup(buf);
6318 #endif
6319 
6320  if (abort) {
6321 
6322  static Bool_t recursive = kFALSE;
6323 
6324  if (gProofServ != 0 && !recursive) {
6325  recursive = kTRUE;
6326  if (gProofServ->GetSocket()) gProofServ->GetSocket()->Send(kPROOF_FATAL);
6327  recursive = kFALSE;
6328  }
6329 
6330  fprintf(fgErrorHandlerFile, "aborting\n");
6331  fflush(fgErrorHandlerFile);
6332  gSystem->StackTrace();
6333  gSystem->Abort();
6334  }
6335 }
6336 
6337 ////////////////////////////////////////////////////////////////////////////////
6338 /// Make player instance.
6339 
6341 {
6342  TVirtualProofPlayer *p = 0;
6343 
6344  // Cleanup first
6345  DeletePlayer();
6346 
6347  if (IsParallel()) {
6348  // remote mode
6349  p = fProof->MakePlayer();
6350  } else {
6351  // slave or sequential mode
6352  p = TVirtualProofPlayer::Create("slave", 0, fSocket);
6353  if (IsMaster())
6354  fProof->SetPlayer(p);
6355  }
6356 
6357  // set player
6358  fPlayer = p;
6359 }
6360 
6361 ////////////////////////////////////////////////////////////////////////////////
6362 /// Delete player instance.
6363 
6365 {
6366  if (IsMaster()) {
6367  PDB(kGlobal, 1) {
6368  fCompute.Stop();
6369  Printf(" +++ Latest processing times: %f s (CPU: %f s)",
6371  }
6372  if (fProof) fProof->SetPlayer(0);
6373  } else {
6375  }
6376  fPlayer = 0;
6377 }
6378 
6379 ////////////////////////////////////////////////////////////////////////////////
6380 /// Get the processing priority for the group the user belongs too. This
6381 /// priority is a number (0 - 100) determined by a scheduler (third
6382 /// party process) based on some basic priority the group has, e.g.
6383 /// we might want to give users in a specific group (e.g. promptana)
6384 /// a higher priority than users in other groups, and on the analysis
6385 /// of historical logging data (i.e. usage of CPU by the group in a
6386 /// previous time slot, as recorded in TPerfStats::WriteQueryLog()).
6387 ///
6388 /// Currently the group priority is obtained by a query in a SQL DB
6389 /// table proofpriority, which has the format:
6390 /// CREATE TABLE proofpriority (
6391 /// id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
6392 /// group VARCHAR(32) NOT NULL,
6393 /// priority INT
6394 ///)
6395 
6397 {
6398  TString sqlserv = gEnv->GetValue("ProofServ.QueryLogDB","");
6399  TString sqluser = gEnv->GetValue("ProofServ.QueryLogUser","");
6400  TString sqlpass = gEnv->GetValue("ProofServ.QueryLogPasswd","");
6401 
6402  Int_t priority = 100;
6403 
6404  if (sqlserv == "")
6405  return priority;
6406 
6407  TString sql;
6408  sql.Form("SELECT priority WHERE group='%s' FROM proofpriority", fGroup.Data());
6409 
6410  // open connection to SQL server
6411  TSQLServer *db = TSQLServer::Connect(sqlserv, sqluser, sqlpass);
6412 
6413  if (!db || db->IsZombie()) {
6414  Error("GetPriority", "failed to connect to SQL server %s as %s %s",
6415  sqlserv.Data(), sqluser.Data(), sqlpass.Data());
6416  printf("%s\n", sql.Data());
6417  } else {
6418  TSQLResult *res = db->Query(sql);
6419 
6420  if (!res) {
6421  Error("GetPriority", "query into proofpriority failed");
6422  Printf("%s", sql.Data());
6423  } else {
6424  TSQLRow *row = res->Next(); // first row is header
6425  if (row) {
6426  priority = atoi(row->GetField(0));
6427  delete row;
6428  } else {
6429  Error("GetPriority", "first row is header is NULL");
6430  }
6431  }
6432  delete res;
6433  }
6434  delete db;
6435 
6436  return priority;
6437 }
6438 
6439 ////////////////////////////////////////////////////////////////////////////////
6440 /// Send an asychronous message to the master / client .
6441 /// Masters will forward up the message to the client.
6442 /// The client prints 'msg' of stderr and adds a '\n'/'\r' depending on
6443 /// 'lf' being kTRUE (default) or kFALSE.
6444 /// Returns the return value from TSocket::Send(TMessage &) .
6445 
6447 {
6448  static TMessage m(kPROOF_MESSAGE);
6449 
6450  // To leave a track in the output file ... if requested
6451  // (clients will be notified twice)
6452  PDB(kAsyn,1)
6453  Info("SendAsynMessage","%s", (msg ? msg : "(null)"));
6454 
6455  if (fSocket && msg) {
6456  m.Reset(kPROOF_MESSAGE);
6457  m << TString(msg) << lf;
6458  return fSocket->Send(m);
6459  }
6460 
6461  // No message
6462  return -1;
6463 }
6464 
6465 ////////////////////////////////////////////////////////////////////////////////
6466 /// Reposition the read pointer in the log file to the very end.
6467 /// This allows to "hide" useful debug messages during normal operations
6468 /// while preserving the possibility to have them in case of problems.
6469 
6471 {
6472  off_t lend = lseek(fileno(stdout), (off_t)0, SEEK_END);
6473  if (lend >= 0) lseek(fLogFileDes, lend, SEEK_SET);
6474 }
6475 
6476 ////////////////////////////////////////////////////////////////////////////////
6477 /// Truncate the log file to the 80% of the required max size if this
6478 /// is set.
6479 
6481 {
6482 #ifndef WIN32
6483  TString emsg;
6484  if (fLogFileMaxSize > 0 && fLogFileDes > 0) {
6485  fflush(stdout);
6486  struct stat st;
6487  if (fstat(fLogFileDes, &st) == 0) {
6488  if (st.st_size >= fLogFileMaxSize) {
6489  off_t truncsz = (off_t) (( fLogFileMaxSize * 80 ) / 100 );
6490  if (truncsz < 100) {
6491  emsg.Form("+++ WARNING +++: %s: requested truncate size too small"
6492  " (%lld,%lld) - ignore ", fPrefix.Data(), (Long64_t) truncsz, fLogFileMaxSize);
6493  SendAsynMessage(emsg.Data());
6494  return;
6495  }
6497  while (ftruncate(fileno(stdout), truncsz) != 0 &&
6498  (TSystem::GetErrno() == EINTR)) {
6500  }
6501  if (TSystem::GetErrno() > 0) {
6502  Error("TruncateLogFile", "truncating to %lld bytes; file size is %lld bytes (errno: %d)",
6503  (Long64_t)truncsz, (Long64_t)st.st_size, TSystem::GetErrno());
6504  emsg.Form("+++ WARNING +++: %s: problems truncating log file to %lld bytes; file size is %lld bytes"
6505  " (errno: %d)", fPrefix.Data(), (Long64_t)truncsz, (Long64_t)st.st_size, TSystem::GetErrno());
6506  SendAsynMessage(emsg.Data());
6507  } else {
6508  Info("TruncateLogFile", "file truncated to %lld bytes (80%% of %lld); file size was %lld bytes ",
6509  (Long64_t)truncsz, fLogFileMaxSize, (Long64_t)st.st_size);
6510  emsg.Form("+++ WARNING +++: %s: log file truncated to %lld bytes (80%% of %lld)",
6511  fPrefix.Data(), (Long64_t)truncsz, fLogFileMaxSize);
6512  SendAsynMessage(emsg.Data());
6513  }
6514  }
6515  } else {
6516  emsg.Form("+++ WARNING +++: %s: could not stat log file descriptor"
6517  " for truncation (errno: %d)", fPrefix.Data(), TSystem::GetErrno());
6518  SendAsynMessage(emsg.Data());
6519  }
6520  }
6521 #endif
6522 }
6523 
6524 ////////////////////////////////////////////////////////////////////////////////
6525 /// Exception handler: we do not try to recover here, just exit.
6526 
6528 {
6529  Error("HandleException", "caugth exception triggered by signal '%d' %s %lld",
6530  sig, fgLastMsg.Data(), fgLastEntry);
6531  // Description
6532  TString emsg;
6533  emsg.Form("%s: caught exception triggered by signal '%d' %s %lld",
6534  GetOrdinal(), sig, fgLastMsg.Data(), fgLastEntry);
6535  // Try to warn the user
6536  SendAsynMessage(emsg.Data());
6537 
6538  gSystem->Exit(sig);
6539 }
6540 
6541 ////////////////////////////////////////////////////////////////////////////////
6542 /// Handle here requests about datasets.
6543 
6545 {
6546  if (gDebug > 0)
6547  Info("HandleDataSets", "enter");
6548 
6549  // We need a dataset manager
6550  if (!fDataSetManager) {
6551  Warning("HandleDataSets", "no data manager is available to fullfil the request");
6552  return -1;
6553  }
6554 
6555  // Used in most cases
6556  TString dsUser, dsGroup, dsName, dsTree, uri, opt;
6557  Int_t rc = 0;
6558 
6559  // Invalid characters in dataset URI
6560  TPMERegexp reInvalid("[^A-Za-z0-9._-]"); // from ParseUri
6561 
6562  // Message type
6563  Int_t type = 0;
6564  (*mess) >> type;
6565 
6566  switch (type) {
6568  //
6569  // Check whether this dataset exist
6570  {
6571  (*mess) >> uri;
6572  if (slb) slb->Form("%d %s", type, uri.Data());
6573  if (fDataSetManager->ExistsDataSet(uri))
6574  // Dataset name does exist
6575  return -1;
6576  }
6577  break;
6579  // list size must be above 0
6580  {
6582  (*mess) >> uri;
6583  (*mess) >> opt;
6584  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6585  // Extract the list
6586  TFileCollection *dataSet =
6587  dynamic_cast<TFileCollection*> ((mess->ReadObject(TFileCollection::Class())));
6588  if (!dataSet || dataSet->GetList()->GetSize() == 0) {
6589  Error("HandleDataSets", "can not save an empty list.");
6590  return -1;
6591  }
6592  // Register the dataset (quota checks are done inside here)
6593  rc = fDataSetManager->RegisterDataSet(uri, dataSet, opt);
6594  delete dataSet;
6595  return rc;
6596  } else {
6597  Info("HandleDataSets", "dataset registration not allowed");
6598  if (slb) slb->Form("%d notallowed", type);
6599  return -1;
6600  }
6601  }
6602  break;
6603 
6605  {
6606  (*mess) >> uri; // TString
6607 
6608  if (!fDataSetStgRepo) {
6609  Error("HandleDataSets",
6610  "no dataset staging request repository available");
6611  return -1;
6612  }
6613 
6614  // Transform input URI in a valid dataset name
6615  TString validUri = uri;
6616  while (reInvalid.Substitute(validUri, "_")) {}
6617 
6618  // Check if dataset exists beforehand: if it does, staging has
6619  // already been requested
6620  if (fDataSetStgRepo->ExistsDataSet(validUri.Data())) {
6621  Warning("HandleDataSets", "staging of %s already requested",
6622  uri.Data());
6623  return -1;
6624  }
6625 
6626  // Try to get dataset from current manager
6627  TFileCollection *fc = fDataSetManager->GetDataSet(uri.Data());
6628  if (!fc || (fc->GetNFiles() == 0)) {
6629  Error("HandleDataSets", "empty dataset or no dataset returned");
6630  if (fc) delete fc;
6631  return -1;
6632  }
6633 
6634  // Reset all staged bits and remove unnecessary URLs (all but last)
6635  TIter it(fc->GetList());
6636  TFileInfo *fi;
6637  while ((fi = dynamic_cast<TFileInfo *>(it.Next()))) {
6639  Int_t nToErase = fi->GetNUrls() - 1;
6640  for (Int_t i=0; i<nToErase; i++)
6641  fi->RemoveUrlAt(0);
6642  }
6643 
6644  fc->Update(); // absolutely necessary
6645 
6646  // Save request
6647  fDataSetStgRepo->ParseUri(validUri, &dsGroup, &dsUser, &dsName);
6648  if (fDataSetStgRepo->WriteDataSet(dsGroup, dsUser,
6649  dsName, fc) == 0) {
6650  // Error, can't save dataset
6651  Error("HandleDataSets",
6652  "can't register staging request for %s", uri.Data());
6653  delete fc;
6654  return -1;
6655  }
6656 
6657  Info("HandleDataSets",
6658  "Staging request registered for %s", uri.Data());
6659 
6660  delete fc;
6661  return 0; // success (-1 == failure)
6662  }
6663  break;
6664 
6666  {
6667  if (!fDataSetStgRepo) {
6668  Error("HandleDataSets",
6669  "no dataset staging request repository available");
6670  return -1;
6671  }
6672 
6673  (*mess) >> uri; // TString
6674 
6675  // Transform URI in a valid dataset name
6676  while (reInvalid.Substitute(uri, "_")) {}
6677 
6678  // Get the list
6679  TFileCollection *fc = fDataSetStgRepo->GetDataSet(uri.Data());
6680  if (fc) {
6681  fSocket->SendObject(fc, kMESS_OK);
6682  delete fc;
6683  return 0;
6684  }
6685  else {
6686  // No such dataset: not an error, but don't send message
6687  Info("HandleDataSets", "no pending staging request for %s",
6688  uri.Data());
6689  return 0;
6690  }
6691  }
6692  break;
6693 
6695  {
6696  if (!fDataSetStgRepo) {
6697  Error("HandleDataSets",
6698  "no dataset staging request repository available");
6699  return -1;
6700  }
6701 
6702  (*mess) >> uri;
6703 
6704  // Transform URI in a valid dataset name
6705  while (reInvalid.Substitute(uri, "_")) {}
6706 
6707  if (!fDataSetStgRepo->RemoveDataSet(uri.Data()))
6708  return -1; // failure
6709 
6710  return 0; // success
6711  }
6712  break;
6713 
6714  case TProof::kShowDataSets:
6715  {
6716  (*mess) >> uri >> opt;
6717  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6718  // Show content
6719  fDataSetManager->ShowDataSets(uri, opt);
6720  }
6721  break;
6722 
6723  case TProof::kGetDataSets:
6724  {
6725  (*mess) >> uri >> opt;
6726  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6727  // Get the datasets and fill a map
6729  Ssiz_t kLite = opt.Index(":lite:", 0, TString::kIgnoreCase);
6730  if (kLite != kNPOS) {
6732  opt.Remove(kLite, strlen(":lite:"));
6733  }
6734  TMap *returnMap = fDataSetManager->GetDataSets(uri, omsk);
6735  // If defines, option gives the name of a server for which to extract the information
6736  if (returnMap && !opt.IsNull()) {
6737  // The return map will be in the form </group/user/datasetname> --> <dataset>
6738  TMap *rmap = new TMap;
6739  TObject *k = 0;
6740  TFileCollection *fc = 0, *xfc = 0;
6741  TIter nxd(returnMap);
6742  while ((k = nxd()) && (fc = (TFileCollection *) returnMap->GetValue(k))) {
6743  // Get subset on specified server, if any
6744  if ((xfc = fc->GetFilesOnServer(opt.Data()))) {
6745  rmap->Add(new TObjString(k->GetName()), xfc);
6746  }
6747  }
6748  returnMap->DeleteAll();
6749  if (rmap->GetSize() > 0) {
6750  returnMap = rmap;
6751  } else {
6752  Info("HandleDataSets", "no dataset found on server '%s'", opt.Data());
6753  delete rmap;
6754  returnMap = 0;
6755  }
6756  }
6757  if (returnMap) {
6758  // Send them back
6759  fSocket->SendObject(returnMap, kMESS_OK);
6760  returnMap->DeleteAll();
6761  } else {
6762  // Failure
6763  return -1;
6764  }
6765  }
6766  break;
6767  case TProof::kGetDataSet:
6768  {
6769  (*mess) >> uri >> opt;
6770  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6771  // Get the list
6772  TFileCollection *fileList = fDataSetManager->GetDataSet(uri,opt);
6773  if (fileList) {
6774  fSocket->SendObject(fileList, kMESS_OK);
6775  delete fileList;
6776  } else {
6777  // Failure
6778  return -1;
6779  }
6780  }
6781  break;
6783  {
6785  (*mess) >> uri;
6786  if (slb) slb->Form("%d %s", type, uri.Data());
6787  if (!fDataSetManager->RemoveDataSet(uri)) {
6788  // Failure
6789  return -1;
6790  }
6791  } else {
6792  Info("HandleDataSets", "dataset creation / removal not allowed");
6793  if (slb) slb->Form("%d notallowed", type);
6794  return -1;
6795  }
6796  }
6797  break;
6799  {
6801  (*mess) >> uri >> opt;
6802  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6804  rc = fDataSetManager->ScanDataSet(uri, opt);
6805  // TODO: verify in parallel:
6806  // - dataset = GetDataSet(uri)
6807  // - TList flist; TDataSetManager::ScanDataSet(dataset, ..., &flist)
6808  // - fPlayer->Process( ... flist ...) // needs to be developed
6809  // - dataset->Integrate(flist) (perhaps automatic; flist object owned by dataset)
6810  // - RegisterDataSet(uri, dataset, "OT")
6811  } else {
6812  Info("HandleDataSets", "dataset verification not allowed");
6813  return -1;
6814  }
6815  }
6816  break;
6817  case TProof::kGetQuota:
6818  {
6820  if (slb) slb->Form("%d", type);
6821  TMap *groupQuotaMap = fDataSetManager->GetGroupQuotaMap();
6822  if (groupQuotaMap) {
6823  // Send result
6824  fSocket->SendObject(groupQuotaMap, kMESS_OK);
6825  } else {
6826  return -1;
6827  }
6828  } else {
6829  Info("HandleDataSets", "quota control disabled");
6830  if (slb) slb->Form("%d disabled", type);
6831  return -1;
6832  }
6833  }
6834  break;
6835  case TProof::kShowQuota:
6836  {
6838  if (slb) slb->Form("%d", type);
6839  (*mess) >> opt;
6840  // Display quota information
6841  fDataSetManager->ShowQuota(opt);
6842  } else {
6843  Info("HandleDataSets", "quota control disabled");
6844  if (slb) slb->Form("%d disabled", type);
6845  }
6846  }
6847  break;
6849  {
6851  (*mess) >> uri;
6852  if (slb) slb->Form("%d %s", type, uri.Data());
6854  } else {
6855  Info("HandleDataSets", "kSetDefaultTreeName: modification of dataset info not allowed");
6856  if (slb) slb->Form("%d notallowed", type);
6857  return -1;
6858  }
6859  }
6860  break;
6861  case TProof::kCache:
6862  {
6863  (*mess) >> uri >> opt;
6864  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6865  if (opt == "show") {
6866  // Show cache content
6867  fDataSetManager->ShowCache(uri);
6868  } else if (opt == "clear") {
6869  // Clear cache content
6871  } else {
6872  Error("HandleDataSets", "kCache: unknown action: %s", opt.Data());
6873  }
6874  }
6875  break;
6876  default:
6877  rc = -1;
6878  Error("HandleDataSets", "unknown type %d", type);
6879  break;
6880  }
6881 
6882  // We are done
6883  return rc;
6884 }
6885 
6886 ////////////////////////////////////////////////////////////////////////////////
6887 /// Handle a message of type kPROOF_SUBMERGER
6888 
6890 {
6891  // Message type
6892  Int_t type = 0;
6893  (*mess) >> type;
6894 
6895  TString msg;
6896  switch (type) {
6897  case TProof::kOutputSize:
6898  break;
6899 
6900  case TProof::kSendOutput:
6901  {
6902  Bool_t deleteplayer = kTRUE;
6903  if (!IsMaster()) {
6904  if (fMergingMonitor) {
6905  Info("HandleSubmerger", "kSendOutput: interrupting ...");
6907  }
6908  if (fMergingSocket) {
6910  fMergingSocket->Close();
6912  }
6913 
6914  TString name;
6915  Int_t port = 0;
6916  Int_t merger_id = -1;
6917  (*mess) >> merger_id >> name >> port;
6918  PDB(kSubmerger, 1)
6919  Info("HandleSubmerger","worker %s redirected to merger #%d %s:%d", fOrdinal.Data(), merger_id, name.Data(), port);
6920 
6921  TSocket *t = 0;
6922  if (name.Length() > 0 && port > 0 && (t = new TSocket(name, port)) && t->IsValid()) {
6923 
6924  PDB(kSubmerger, 2) Info("HandleSubmerger",
6925  "kSendOutput: worker asked for sending output to merger #%d %s:%d",
6926  merger_id, name.Data(), port);
6927 
6928  if (SendResults(t, fPlayer->GetOutputList()) != 0) {
6929  msg.Form("worker %s cannot send results to merger #%d at %s:%d", GetPrefix(), merger_id, name.Data(), port);
6930  PDB(kSubmerger, 2) Info("HandleSubmerger",
6931  "kSendOutput: %s - inform the master", msg.Data());
6932  SendAsynMessage(msg);
6933  // Results not send
6934  TMessage answ(kPROOF_SUBMERGER);
6935  answ << Int_t(TProof::kMergerDown);
6936  answ << merger_id;
6937  fSocket->Send(answ);
6938  } else {
6939  // Worker informs master that it had sent its output to the merger
6940  TMessage answ(kPROOF_SUBMERGER);
6941  answ << Int_t(TProof::kOutputSent);
6942  answ << merger_id;
6943  fSocket->Send(answ);
6944 
6945  PDB(kSubmerger, 2) Info("HandleSubmerger", "kSendOutput: worker sent its output");
6947  SetIdle(kTRUE);
6948  SendLogFile();
6949  }
6950  } else {
6951 
6952  if (name == "master") {
6953  PDB(kSubmerger, 2) Info("HandleSubmerger",
6954  "kSendOutput: worker was asked for sending output to master");
6955  if (SendResults(fSocket, fPlayer->GetOutputList()) != 0)
6956  Warning("HandleSubmerger", "problems sending output list");
6957  // Signal the master that we are idle
6959  SetIdle(kTRUE);
6960  SendLogFile();
6961 
6962  } else if (!t || !(t->IsValid())) {
6963  msg.Form("worker %s could not open a valid socket to merger #%d at %s:%d",
6964  GetPrefix(), merger_id, name.Data(), port);
6965  PDB(kSubmerger, 2) Info("HandleSubmerger",
6966  "kSendOutput: %s - inform the master", msg.Data());
6967  SendAsynMessage(msg);
6968  // Results not send
6969  TMessage answ(kPROOF_SUBMERGER);
6970  answ << Int_t(TProof::kMergerDown);
6971  answ << merger_id;
6972  fSocket->Send(answ);
6973  deleteplayer = kFALSE;
6974  }
6975 
6976  if (t) SafeDelete(t);
6977 
6978  }
6979 
6980  } else {
6981  Error("HandleSubmerger", "kSendOutput: received not on worker");
6982  }
6983 
6984  // Cleanup
6985  if (deleteplayer) DeletePlayer();
6986  }
6987  break;
6988  case TProof::kBeMerger:
6989  {
6990  Bool_t deleteplayer = kTRUE;
6991  if (!IsMaster()) {
6992  Int_t merger_id = -1;
6993  //Int_t merger_port = 0;
6994  Int_t connections = 0;
6995  (*mess) >> merger_id >> connections;
6996  PDB(kSubmerger, 2)
6997  Info("HandleSubmerger", "worker %s established as merger", fOrdinal.Data());
6998 
6999  PDB(kSubmerger, 2)
7000  Info("HandleSubmerger",
7001  "kBeMerger: worker asked for being merger #%d for %d connections",
7002  merger_id, connections);
7003 
7004  TVirtualProofPlayer *mergerPlayer = TVirtualProofPlayer::Create("remote",fProof,0);
7005 
7006  if (mergerPlayer) {
7007  PDB(kSubmerger, 2) Info("HandleSubmerger",
7008  "kBeMerger: mergerPlayer created (%p) ", mergerPlayer);
7009 
7010  // This may be used internally
7012 
7013  // Accept results from assigned workers
7014  if (AcceptResults(connections, mergerPlayer)) {
7015  PDB(kSubmerger, 2)
7016  Info("HandleSubmerger", "kBeMerger: all outputs from workers accepted");
7017 
7018  PDB(kSubmerger, 2)
7019  Info("","adding own output to the list on %s", fOrdinal.Data());
7020 
7021  // Add own results to the output list.
7022  // On workers the player does not own the output list, which is owned
7023  // by the selector and deleted in there
7024  // On workers the player does not own the output list, which is owned
7025  // by the selector and deleted in there
7026  TIter nxo(fPlayer->GetOutputList());
7027  TObject * o = 0;
7028  while ((o = nxo())) {
7029  if ((mergerPlayer->AddOutputObject(o) != 1)) {
7030  // Remove the object if it has not been merged: it is owned
7031  // now by the merger player (in its output list)
7032  if (fPlayer->GetOutputList()) {
7033  PDB(kSubmerger, 2)
7034  Info("HandleSocketInput", "removing merged object (%p)", o);
7035  fPlayer->GetOutputList()->Remove(o);
7036  }
7037  }
7038  }
7039  PDB(kSubmerger, 2) Info("HandleSubmerger","kBeMerger: own outputs added");
7040  PDB(kSubmerger, 2) Info("HandleSubmerger","starting delayed merging on %s", fOrdinal.Data());
7041 
7042  // Delayed merging if neccessary
7043  mergerPlayer->MergeOutput(kTRUE);
7044 
7045  PDB(kSubmerger, 2) mergerPlayer->GetOutputList()->Print("all");
7046 
7047  PDB(kSubmerger, 2) Info("HandleSubmerger", "delayed merging on %s finished ", fOrdinal.Data());
7048  PDB(kSubmerger, 2) Info("HandleSubmerger", "%s sending results to master ", fOrdinal.Data());
7049  // Send merged results to master
7050  if (SendResults(fSocket, mergerPlayer->GetOutputList()) != 0)
7051  Warning("HandleSubmerger","kBeMerger: problems sending output list");
7052  if (mergerPlayer->GetOutputList())
7053  mergerPlayer->GetOutputList()->SetOwner(kTRUE);
7054 
7055  PDB(kSubmerger, 2) Info("HandleSubmerger","kBeMerger: results sent to master");
7056  // Signal the master that we are idle
7058  SetIdle(kTRUE);
7059  SendLogFile();
7060  } else {
7061  // Results from all assigned workers not accepted
7062  TMessage answ(kPROOF_SUBMERGER);
7063  answ << Int_t(TProof::kMergerDown);
7064  answ << merger_id;
7065  fSocket->Send(answ);
7066  deleteplayer = kFALSE;
7067  }
7068  // Reset
7069  SafeDelete(mergerPlayer);
7070 
7071  } else {
7072  Warning("HandleSubmerger","kBeMerger: problems craeting the merger player!");
7073  // Results from all assigned workers not accepted
7074  TMessage answ(kPROOF_SUBMERGER);
7075  answ << Int_t(TProof::kMergerDown);
7076  answ << merger_id;
7077  fSocket->Send(answ);
7078  deleteplayer = kFALSE;
7079  }
7080  } else {
7081  Error("HandleSubmerger","kSendOutput: received not on worker");
7082  }
7083 
7084  // Cleanup
7085  if (deleteplayer) DeletePlayer();
7086  }
7087  break;
7088 
7089  case TProof::kMergerDown:
7090  break;
7091 
7092  case TProof::kStopMerging:
7093  {
7094  // Received only in case of forced termination of merger by master
7095  PDB(kSubmerger, 2) Info("HandleSubmerger", "kStopMerging");
7096  if (fMergingMonitor) {
7097  Info("HandleSubmerger", "kStopMerging: interrupting ...");
7099  }
7100  }
7101  break;
7102 
7103  case TProof::kOutputSent:
7104  break;
7105  }
7106 }
7107 
7108 ////////////////////////////////////////////////////////////////////////////////
7109 /// Cloning itself via fork. Not implemented
7110 
7112 {
7113  Info("HandleFork", "fork cloning not implemented");
7114 }
7115 
7116 ////////////////////////////////////////////////////////////////////////////////
7117 /// Fork a child.
7118 /// If successful, return 0 in the child process and the child pid in the parent
7119 /// process. The child pid is registered for reaping.
7120 /// Return <0 in the parent process in case of failure.
7121 
7123 {
7124 #ifndef WIN32
7125  // Fork
7126  pid_t pid;
7127  if ((pid = fork()) < 0) {
7128  Error("Fork", "failed to fork");
7129  return pid;
7130  }
7131 
7132  // Nothing else to do in the child
7133  if (!pid) return pid;
7134 
7135  // Make sure that the reaper timer is started
7136  if (!fReaperTimer) {
7137  fReaperTimer = new TReaperTimer(1000);
7138  fReaperTimer->Start(-1);
7139  }
7140 
7141  // Register the new child
7142  fReaperTimer->AddPid(pid);
7143 
7144  // Done
7145  return pid;
7146 #else
7147  Warning("Fork", "Functionality not provided under windows");
7148  return -1;
7149 #endif
7150 }
7151 
7152 ////////////////////////////////////////////////////////////////////////////////
7153 /// Replace <ord>, <user>, <u>, <group>, <stag>, <qnum>, <file>, <rver> and
7154 /// <build> placeholders in fname.
7155 /// Here, <rver> is the root version in integer form, e.g. 53403, and <build> a
7156 /// string includign version, architecture and compiler version, e.g.
7157 /// '53403_linuxx8664gcc_gcc46' .
7158 
7159 void TProofServ::ResolveKeywords(TString &fname, const char *path)
7160 {
7161  // Replace <user>, if any
7162  if (fname.Contains("<user>")) {
7163  if (gProofServ && gProofServ->GetUser() && strlen(gProofServ->GetUser())) {
7164  fname.ReplaceAll("<user>", gProofServ->GetUser());
7165  } else if (gProof && gProof->GetUser() && strlen(gProof->GetUser())) {
7166  fname.ReplaceAll("<user>", gProof->GetUser());
7167  } else {
7168  fname.ReplaceAll("<user>", "nouser");
7169  }
7170  }
7171  // Replace <us>, if any
7172  if (fname.Contains("<u>")) {
7173  if (gProofServ && gProofServ->GetUser() && strlen(gProofServ->GetUser())) {
7174  TString u(gProofServ->GetUser()[0]);
7175  fname.ReplaceAll("<u>", u);
7176  } else if (gProof && gProof->GetUser() && strlen(gProof->GetUser())) {
7177  TString u(gProof->GetUser()[0]);
7178  fname.ReplaceAll("<u>", u);
7179  } else {
7180  fname.ReplaceAll("<u>", "n");
7181  }
7182  }
7183  // Replace <group>, if any
7184  if (fname.Contains("<group>")) {
7185  if (gProofServ && gProofServ->GetGroup() && strlen(gProofServ->GetGroup())) {
7186  fname.ReplaceAll("<group>", gProofServ->GetGroup());
7187  } else if (gProof && gProof->GetGroup() && strlen(gProof->GetGroup())) {
7188  fname.ReplaceAll("<group>", gProof->GetGroup());
7189  } else {
7190  fname.ReplaceAll("<group>", "default");
7191  }
7192  }
7193  // Replace <stag>, if any
7194  if (fname.Contains("<stag>")) {
7195  if (gProofServ && gProofServ->GetSessionTag() && strlen(gProofServ->GetSessionTag())) {
7196  fname.ReplaceAll("<stag>", gProofServ->GetSessionTag());
7197  } else if (gProof && gProof->GetSessionTag() && strlen(gProof->GetSessionTag())) {
7198  fname.ReplaceAll("<stag>", gProof->GetSessionTag());
7199  } else {
7200  ::Warning("TProofServ::ResolveKeywords", "session tag undefined: ignoring");
7201  }
7202  }
7203  // Replace <ord>, if any
7204  if (fname.Contains("<ord>")) {
7205  if (gProofServ && gProofServ->GetOrdinal() && strlen(gProofServ->GetOrdinal()))
7206  fname.ReplaceAll("<ord>", gProofServ->GetOrdinal());
7207  else
7208  ::Warning("TProofServ::ResolveKeywords", "ordinal number undefined: ignoring");
7209  }
7210  // Replace <qnum>, if any
7211  if (fname.Contains("<qnum>")) {
7212  if (gProofServ && gProofServ->GetQuerySeqNum() && gProofServ->GetQuerySeqNum() > 0)
7213  fname.ReplaceAll("<qnum>", TString::Format("%d", gProofServ->GetQuerySeqNum()).Data());
7214  else
7215  ::Warning("TProofServ::ResolveKeywords", "query seqeuntial number undefined: ignoring");
7216  }
7217  // Replace <file>, if any
7218  if (fname.Contains("<file>") && path && strlen(path) > 0) {
7219  fname.ReplaceAll("<file>", path);
7220  }
7221  // Replace <rver>, if any
7222  if (fname.Contains("<rver>")) {
7223  TString v = TString::Format("%d", gROOT->GetVersionInt());
7224  fname.ReplaceAll("<rver>", v);
7225  }
7226  // Replace <build>, if any
7227  if (fname.Contains("<build>")) {
7228  TString b = TString::Format("%d_%s_%s", gROOT->GetVersionInt(), gSystem->GetBuildArch(),
7230  fname.ReplaceAll("<build>", b);
7231  }
7232 }
7233 
7234 ////////////////////////////////////////////////////////////////////////////////
7235 /// Return the status of this session:
7236 /// 0 idle
7237 /// 1 running
7238 /// 2 being terminated (currently unused)
7239 /// 3 queued
7240 /// 4 idle timed-out (not set in here but in TIdleTOTimer::Notify)
7241 /// This is typically run in the reader thread, so access needs to be protected
7242 
7244 {
7246  Int_t st = (fIdle) ? 0 : 1;
7247  if (fIdle && fWaitingQueries->GetSize() > 0) st = 3;
7248  return st;
7249 }
7250 
7251 ////////////////////////////////////////////////////////////////////////////////
7252 /// Update the session status in the relevant file. The status is taken from
7253 /// GetSessionStatus() unless xst >= 0, in which case xst is used.
7254 /// Return 0 on success, -errno if the file could not be opened.
7255 
7257 {
7258  FILE *fs = fopen(fAdminPath.Data(), "w");
7259  if (fs) {
7260  Int_t st = (xst < 0) ? GetSessionStatus() : xst;
7261  fprintf(fs, "%d", st);
7262  fclose(fs);
7263  PDB(kGlobal, 2)
7264  Info("UpdateSessionStatus", "status (=%d) update in path: %s", st, fAdminPath.Data());
7265  } else {
7266  return -errno;
7267  }
7268  // Done
7269  return 0;
7270 }
7271 
7272 ////////////////////////////////////////////////////////////////////////////////
7273 /// Return the idle status
7274 
7276 {
7278  return fIdle;
7279 }
7280 
7281 ////////////////////////////////////////////////////////////////////////////////
7282 /// Change the idle status
7283 
7285 {
7287  fIdle = st;
7288 }
7289 
7290 ////////////////////////////////////////////////////////////////////////////////
7291 /// Return kTRUE if the session is waiting for the OK to start processing
7292 
7294 {
7296  if (fIdle && fWaitingQueries->GetSize() > 0) return kTRUE;
7297  return kFALSE;
7298 }
7299 
7300 ////////////////////////////////////////////////////////////////////////////////
7301 /// Return the number of waiting queries
7302 
7304 {
7306  return fWaitingQueries->GetSize();
7307 }
7308 
7309 ////////////////////////////////////////////////////////////////////////////////
7310 /// Add a query to the waiting list
7311 /// Returns the number of queries in the list
7312 
7314 {
7316  fWaitingQueries->Add(pq);
7317  return fWaitingQueries->GetSize();
7318 }
7319 
7320 ////////////////////////////////////////////////////////////////////////////////
7321 /// Get the next query from the waiting list.
7322 /// The query is removed from the list.
7323 
7325 {
7328  fWaitingQueries->Remove(pq);
7329  return pq;
7330 }
7331 
7332 ////////////////////////////////////////////////////////////////////////////////
7333 /// Cleanup the waiting queries list. The objects are deleted if 'del' is true.
7334 /// If 'qls' is non null, only objects in 'qls' are removed.
7335 /// Returns the number of cleanup queries
7336 
7338 {
7340  Int_t ncq = 0;
7341  if (qls) {
7342  TIter nxq(qls);
7343  TObject *o = 0;
7344  while ((o = nxq())) {
7345  if (fWaitingQueries->FindObject(o)) ncq++;
7346  fWaitingQueries->Remove(o);
7347  if (del) delete o;
7348  }
7349  } else {
7350  ncq = fWaitingQueries->GetSize();
7351  fWaitingQueries->SetOwner(del);
7353  }
7354  // Done
7355  return ncq;
7356 }
7357 
7358 ////////////////////////////////////////////////////////////////////////////////
7359 /// Set the message to be sent back in case of exceptions
7360 
7361 void TProofServ::SetLastMsg(const char *lastmsg)
7362 {
7363  fgLastMsg = lastmsg;
7364 }
7365 
7366 ////////////////////////////////////////////////////////////////////////////////
7367 /// Set the last entry before exception
7368 
7370 {
7371  fgLastEntry = entry;
7372 }
7373 
7374 ////////////////////////////////////////////////////////////////////////////////
7375 /// VirtMemMax getter
7376 
7378 {
7379  return fgVirtMemMax;
7380 }
7381 ////////////////////////////////////////////////////////////////////////////////
7382 /// ResMemMax getter
7383 
7385 {
7386  return fgResMemMax;
7387 }
7388 ////////////////////////////////////////////////////////////////////////////////
7389 /// MemHWM getter
7390 
7392 {
7393  return fgMemHWM;
7394 }
7395 ////////////////////////////////////////////////////////////////////////////////
7396 /// MemStop getter
7397 
7399 {
7400  return fgMemStop;
7401 }
7402 
7403 ////////////////////////////////////////////////////////////////////////////////
7404 /// Extract LOCALDATASERVER info in 'dsrv'
7405 
7407 {
7408  // Check if a local data server has been specified
7409  if (gSystem->Getenv("LOCALDATASERVER")) {
7410  dsrv = gSystem->Getenv("LOCALDATASERVER");
7411  if (!dsrv.EndsWith("/")) dsrv += "/";
7412  }
7413 
7414  // Done
7415  return;
7416 }
7417 
7418 ////////////////////////////////////////////////////////////////////////////////
7419 /// If 'path' is local and 'dsrv' is Xrootd, apply 'path.Localroot' settings,
7420 /// if any.
7421 /// The final path via the server is dsrv+path.
7422 
7423 void TProofServ::FilterLocalroot(TString &path, const char *dsrv)
7424 {
7425  TUrl u(path, kTRUE);
7426  if (!strcmp(u.GetProtocol(), "file")) {
7427  // Remove prefix, if any, if included and if Xrootd
7428  TString pfx = gEnv->GetValue("Path.Localroot","");
7429  if (!pfx.IsNull() && !strncmp(u.GetFile(), pfx.Data(), pfx.Length())) {
7430  TString srvp = TUrl(dsrv).GetProtocol();
7431  if (srvp == "root" || srvp == "xrd") path.Remove(0, pfx.Length());
7432  }
7433  }
7434 
7435  // Done
7436  return;
7437 }
7438 
7439 ////////////////////////////////////////////////////////////////////////////////
7440 /// Locks the directory. Waits if lock is hold by an other process.
7441 /// Returns 0 on success, -1 in case of error.
7442 
7444 {
7445  const char *pname = GetName();
7446 
7447  if (gSystem->AccessPathName(pname))
7448  fLockId = open(pname, O_CREAT|O_RDWR, 0644);
7449  else
7450  fLockId = open(pname, O_RDWR);
7451 
7452  if (fLockId == -1) {
7453  SysError("Lock", "cannot open lock file %s", pname);
7454  return -1;
7455  }
7456 
7457  PDB(kPackage, 2)
7458  Info("Lock", "%d: locking file %s ...", gSystem->GetPid(), pname);
7459  // lock the file
7460 #if !defined(R__WIN32) && !defined(R__WINGCC)
7461  if (lockf(fLockId, F_LOCK, (off_t) 1) == -1) {
7462  SysError("Lock", "error locking %s", pname);
7463  close(fLockId);
7464  fLockId = -1;
7465  return -1;
7466  }
7467 #endif
7468 
7469  PDB(kPackage, 2)
7470  Info("Lock", "%d: file %s locked", gSystem->GetPid(), pname);
7471 
7472  return 0;
7473 }
7474 
7475 ////////////////////////////////////////////////////////////////////////////////
7476 /// Unlock the directory. Returns 0 in case of success,
7477 /// -1 in case of error.
7478 
7480 {
7481  if (!IsLocked())
7482  return 0;
7483 
7484  PDB(kPackage, 2)
7485  Info("Lock", "%d: unlocking file %s ...", gSystem->GetPid(), GetName());
7486  // unlock the file
7487  lseek(fLockId, 0, SEEK_SET);
7488 #if !defined(R__WIN32) && !defined(R__WINGCC)
7489  if (lockf(fLockId, F_ULOCK, (off_t)1) == -1) {
7490  SysError("Unlock", "error unlocking %s", GetName());
7491  close(fLockId);
7492  fLockId = -1;
7493  return -1;
7494  }
7495 #endif
7496 
7497  PDB(kPackage, 2)
7498  Info("Unlock", "%d: file %s unlocked", gSystem->GetPid(), GetName());
7499 
7500  close(fLockId);
7501  fLockId = -1;
7502 
7503  return 0;
7504 }
const char * GetName() const
Returns name of object.
Definition: TObjString.h:42
virtual void HandleException(Int_t sig)
Exception handler: we do not try to recover here, just exit.
TList * GetListOfBadSlaves() const
Definition: TProof.h:692
void SetCompressionSettings(Int_t settings=1)
Definition: TMessage.cxx:268
Bool_t fMasterServ
Definition: TProofServ.h:123
Int_t fNcmd
Definition: TProofServ.h:120
Float_t fEffSessions
Definition: TProofServ.h:134
FILE * fLogFile
Definition: TProofServ.h:111
Bool_t fRealTimeLog
Definition: TProofServ.h:148
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:928
Bool_t AcceptResults(Int_t connections, TVirtualProofPlayer *mergerPlayer)
Accept and merge results from a set of workers.
virtual Int_t GetEntries() const
Definition: TCollection.h:92
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:823
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1265
static Int_t GetCmdRtn()
Static method to get the return code from the execution of a command via the pipe.
Definition: TProofServ.cxx:345
static FILE * SetErrorHandlerFile(FILE *ferr)
Set the file stream where to log (default stderr).
double par[1]
Definition: unuranDistr.cxx:38
void Interrupt(EUrgent type, ESlaves list=kActive)
Send interrupt to master or slave servers.
Definition: TProof.cxx:2271
Int_t Compress()
Compress the message.
Definition: TMessage.cxx:286
Definition: TMutex.h:37
double read(const std::string &file_name)
reading
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:864
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition: TError.cxx:106
static FILE * fgErrorHandlerFile
Definition: TProofServ.h:180
Int_t CatMotd()
Print message of the day (in the file pointed by the env PROOFMOTD or from fConfDir/etc/proof/motd).
Bool_t IsIdle()
Return the idle status.
virtual Long_t ProcessLine(const char *line, Bool_t sync=kFALSE, Int_t *error=0)
Process a single command line, either a C++ statement or an interpreter command starting with a "...
Long64_t GetNFiles() const
virtual TList * GetInputList() const =0
void IncCPUTime(Double_t procTime)
virtual void HandleRemove(TMessage *mess, TString *slb=0)
Handle remove request.
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:711
An array of TObjects.
Definition: TObjArray.h:39
virtual Long64_t GetSize() const
Returns the current file size.
Definition: TFile.cxx:1279
void Print(Option_t *option="") const
Dump the content.
Int_t fActSessions
Definition: TProofServ.h:133
virtual Int_t GetLearnEntries()=0
Int_t UnloadPackages()
Unload all packages.
Definition: TProof.cxx:8600
TList * fChildren
Definition: TProofServ.h:443
Bool_t IsDraw() const
Definition: TQueryResult.h:152
void GetOptions(Int_t *argc, char **argv)
Get and handle command line options.
TList * GetSubmasters()
Get the list of submaster nodes.
const char *const kGUNZIP
Definition: TProof.h:170
TString fConfFile
Definition: TProofServ.h:89
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:404
virtual void Syslog(ELogLevel level, const char *mess)
Send mess to syslog daemon.
Definition: TSystem.cxx:1648
static Long64_t GetEntries(Bool_t isTree, const char *filename, const char *path, TString &objname)
Returns number of entries in tree or objects in file.
Definition: TDSet.cxx:1353
void AskParallel()
Ask the for the number of parallel slaves.
Definition: TProof.cxx:2072
TStopwatch fCompute
Definition: TProofServ.h:128
void LogToMaster(Bool_t on=kTRUE)
Definition: TProofServ.h:334
static Bool_t GetFileInCmd(const char *cmd, TString &fn)
Static method to extract the filename (if any) form a CINT command.
Definition: TProof.cxx:6482
Int_t GetSeqNum() const
Definition: TQueryResult.h:123
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
Definition: TStopwatch.cxx:108
Int_t ClearPackages()
Remove all packages.
Definition: TProof.cxx:7845
TFileCollection * GetFilesOnServer(const char *server)
Return the subset of files served by 'server'.
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition: TMonitor.cxx:214
virtual Int_t ClearCache(const char *uri)
Clear cached information matching uri.
virtual void AddInput(TObject *inp)=0
long long Long64_t
Definition: RtypesCore.h:69
Int_t fGroupSize
Definition: TProofServ.h:118
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
Definition: TStopwatch.cxx:56
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:107
Bool_t IsValid() const
Definition: TProof.h:970
Bool_t IsWaiting()
Return kTRUE if the session is waiting for the OK to start processing.
R__EXTERN TProofDebug::EProofDebugMask gProofDebugMask
Definition: TProofDebug.h:55
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:865
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:736
const char * AsString(const Option_t *option="") const
Return the date & time as a string.
Definition: TTimeStamp.cxx:269
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:487
static TMD5 * FileChecksum(const char *file)
Returns checksum of specified file.
Definition: TMD5.cxx:472
void SetRealTimeLog(Bool_t on=kTRUE)
Switch ON/OFF the real-time logging facility.
Definition: TProof.cxx:7083
void Reset()
Reset the timer.
Definition: TTimer.cxx:155
virtual EQueryAction GetWorkers(TList *workers, Int_t &prioritychange, Bool_t resume=kFALSE)
Get list of workers to be used from now on.
double write(int n, const std::string &file_name, const std::string &vector_type, int compress=0)
writing
static Long_t fgResMemMax
Definition: TProofServ.h:172
void SetCompressionSettings(Int_t settings=1)
Used to specify the compression level and algorithm: settings = 100 * algorithm + level...
Definition: TSocket.cxx:1103
const char *const kCP
Definition: TProof.h:164
Int_t SetupCommon()
Common part (between TProofServ and TXProofServ) of the setup phase.
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
const char *const kLS
Definition: TProof.h:166
Ssiz_t Length() const
Definition: TString.h:390
TLine * line
const double pi
Collectable string class.
Definition: TObjString.h:32
float Float_t
Definition: RtypesCore.h:53
virtual TVirtualProofPlayer * MakePlayer(const char *player=0, TSocket *s=0)
Construct a TProofPlayer object.
Definition: TProof.cxx:10778
const char Option_t
Definition: RtypesCore.h:62
virtual TSQLResult * Query(const char *sql)=0
static TSQLServer * Connect(const char *db, const char *uid, const char *pw)
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition: TProof.cxx:4793
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3715
const char * GetObjName() const
Definition: TDSet.h:229
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:212
Long64_t fHWMBoxSize
Definition: TProofServ.h:168
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:520
Option_t * GetOption() const
Definition: TSocket.h:128
virtual Int_t SetOption(ESockOptions opt, Int_t val)
Set socket options.
Definition: TSocket.cxx:1017
This class represents a WWW compatible URL.
Definition: TUrl.h:41
Int_t fUid
Definition: TSystem.h:139
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
const char * GetDataDir() const
Definition: TProofServ.h:262
void SetWriteV3(Bool_t on=kTRUE)
Set/Reset the 'OldStreamer' bit in this instance and its elements.
Definition: TDSet.cxx:1846
static void FilterLocalroot(TString &path, const char *url="root://dum/")
If 'path' is local and 'dsrv' is Xrootd, apply 'path.Localroot' settings, if any. ...
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition: TSystem.cxx:1363
TMacro * GetSelecHdr() const
Definition: TQueryResult.h:135
TString fSessionTag
Definition: TProofServ.h:92
void SetPlayer(TVirtualProofPlayer *player)
Set a new PROOF player.
Definition: TProof.cxx:10766
#define gDirectory
Definition: TDirectory.h:218
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:818
Definition: TDSet.h:153
TStopwatch fLatency
Definition: TProofServ.h:127
Int_t GetNargs() const
Number of function arguments.
Definition: TFunction.cxx:164
virtual TList * GetListOfKeys() const
void TerminateWorker(TSlave *wrk)
Ask an active worker 'wrk' to terminate, i.e. to shutdown.
Definition: TProof.cxx:4686
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t HandleDataSets(TMessage *mess, TString *slb=0)
Handle here requests about datasets.
Int_t GetPort() const
Definition: TInetAddress.h:77
virtual void MakePlayer()
Make player instance.
const char * GetProtocol() const
Definition: TUrl.h:73
TH1 * h
Definition: legend2.C:5
virtual void HandleProcess(TMessage *mess, TString *slb=0)
Handle processing request.
TVirtualProofPlayer * fPlayer
Definition: TProofServ.h:110
void Interrupt()
Definition: TMonitor.h:75
Bool_t UnlinkDataDir(const char *path)
Scan recursively the datadir and unlink it if empty Return kTRUE if it can be unlinked, kFALSE otherwise.
virtual Bool_t RemoveDataSet(const char *uri)
Removes the indicated dataset.
Int_t GetNumOfFiles()
Return the number of files in the dataset.
Definition: TDSet.cxx:1979
const char * GetSessionTag() const
Definition: TProofServ.h:257
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
Long64_t GetBytesRead() const
const char *const kPROOF_WorkDir
Definition: TProof.h:147
Int_t LockSession(const char *sessiontag, TProofLockPath **lck)
Try locking query area of session tagged sessiontag.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:45
virtual EExitStatus GetExitStatus() const =0
TString fGroup
Definition: TProofServ.h:87
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition: TProof.cxx:10375
static Long_t GetVirtMemMax()
VirtMemMax getter.
TDataSetManager * fDataSetManager
Definition: TProofServ.h:156
virtual Int_t GetLocalPort()
Get port # to which server socket is bound. In case of error returns -1.
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:40
const char * GetOptions() const
Definition: TQueryResult.h:127
virtual int MakeDirectory(const char *name)
Make a directory.
Definition: TSystem.cxx:821
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:536
Int_t DisablePackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7890
virtual const char * HomeDirectory(const char *userName=0)
Return the user's home directory.
Definition: TSystem.cxx:881
virtual TFileCollection * GetDataSet(const char *uri, const char *server=0)
Utility function used in various methods for user dataset upload.
Int_t WaitingQueries()
Return the number of waiting queries.
Int_t UpdateSessionStatus(Int_t xst=-1)
Update the session status in the relevant file.
Int_t BuildPackage(const char *package, EBuildPackageOpt opt=kBuildAll, Int_t chkveropt=kCheckROOT, TList *workers=0)
Build specified package.
Definition: TProof.cxx:8033
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition: TSystem.cxx:856
Bool_t Notify()
Definition: TTimer.cxx:65
TPluginHandler * FindHandler(const char *base, const char *uri=0)
Returns the handler if there exists a handler for the specified URI.
static const char * filename()
void IncProcTime(Double_t procTime)
void Add(TObject *obj)
This function may not be used (but we need to provide it since it is a pure virtual in TCollection)...
Definition: TMap.cxx:52
ClassImp(TProofServ) extern"C"
Definition: TProofServ.cxx:546
TString ferr
Definition: pq2main.cxx:38
#define gROOT
Definition: TROOT.h:340
R__EXTERN Int_t gErrorAbortLevel
Definition: TError.h:108
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor's active list.
Definition: TMonitor.cxx:168
virtual Int_t HandleLibIncPath(TMessage *mess)
Handle lib, inc search paths modification request.
Class supporting a collection of lines with C++ code.
Definition: TMacro.h:33
Int_t LoadPlugin()
Load the plugin library for this handler.
TList * fQueuedMsg
Definition: TProofServ.h:144
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1818
virtual void SetCurrentQuery(TQueryResult *q)=0
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1447
virtual TSeqCollection * GetListOfFileHandlers() const
Definition: TSystem.h:374
Bool_t IsZombie() const
Definition: TObject.h:141
Basic string class.
Definition: TString.h:137
TDataSetManagerFile * fDataSetStgRepo
Definition: TProofServ.h:157
const char * GetSessionTag() const
Definition: TProof.h:942
Double_t CpuTime()
Stop the stopwatch (if it is running) and return the cputime (in seconds) passed between the start an...
Definition: TStopwatch.cxx:123
Int_t CompLength() const
Definition: TMessage.h:95
void SetQueryRunning(TProofQueryResult *pq)
Set query in running state.
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1088
TAlienJobStatus * status
Definition: TAlienJob.cxx:51
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:996
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
TQueryResult * CloneInfo()
Return an instance of TQueryResult containing only the local info fields, i.e.
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual Int_t SendObject(const TObject *obj, Int_t kind=kMESS_OBJECT)
Send an object.
Definition: TSocket.cxx:600
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:496
const char *const kRM
Definition: TProof.h:165
#define gInterpreter
Definition: TInterpreter.h:502
TReaperTimer * fReaperTimer
Definition: TProofServ.h:151
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1511
TString fImage
Definition: TProofServ.h:91
virtual void RemoveAll()
Remove all sockets from the monitor.
Definition: TMonitor.cxx:241
virtual void ShowDataSets(const char *uri="*", const char *opt="")
Prints formatted information about the dataset 'uri'.
const char *const kPROOF_PackageLockFile
Definition: TProof.h:155
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:33
Int_t GetCompressionLevel() const
Definition: TProofServ.h:476
Int_t DrawQueries() const
TString fService
Definition: TProofServ.h:85
TProofQueryResult * LocateQuery(TString queryref, Int_t &qry, TString &qdir)
Locate query referenced by queryref.
virtual TMap * GetGroupQuotaMap()
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:666
Int_t Counter() const
Definition: TStopwatch.h:52
TProofServ * gProofServ
Definition: TProofServ.cxx:116
STL namespace.
void ResetMergers()
Definition: TProof.h:726
Long64_t fMaxBoxSize
Definition: TProofServ.h:167
TProofServLogHandlerGuard(const char *cmd, TSocket *s, const char *pfx="", Bool_t on=kTRUE)
Init a guard for executing a command in a pipe.
Definition: TProofServ.cxx:353
virtual void DeActivateAll()
De-activate all activated sockets.
Definition: TMonitor.cxx:302
TMacro * GetSelecImp() const
Definition: TQueryResult.h:136
static volatile Int_t gProofServDebug
Definition: TProofServ.cxx:119
const char * GetGroup() const
Definition: TProofServ.h:254
Long_t ExecPlugin(int nargs, const T &...params)
TMonitor * fMergingMonitor
Definition: TProofServ.h:162
void ScanPreviousQueries(const char *dir)
Scan the queries directory for the results of previous queries.
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
Int_t AddIncludePath(const char *incpath, Bool_t onClient=kFALSE, TList *wrks=0, Bool_t doCollect=kTRUE)
Add 'incpath' to the inc path search.
Definition: TProof.cxx:9455
static void ResolveKeywords(TString &fname, const char *path=0)
Replace , , , , , , , and placeholders in fname...
Long64_t GetBytesRead() const
Definition: TProof.h:962
TString & Insert(Ssiz_t pos, const char *s)
Definition: TString.h:592
virtual void ClearCache(const char *file=0)
Remove file from all file caches.
Definition: TProof.cxx:7701
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:310
static Float_t GetMemHWM()
MemHWM getter.
TString fPrefix
Definition: TProofServ.h:146
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition: TSystem.cxx:2443
Int_t SendCurrentState(ESlaves list=kActive)
Transfer the current state of the master to the active slave servers.
Definition: TProof.cxx:6745
static Int_t fgRecursive
Definition: TProofServ.h:181
virtual TFileHandler * RemoveFileHandler(TFileHandler *fh)
Remove a file handler from the list of file handlers.
Definition: TSystem.cxx:568
const Int_t kBreak
Definition: TError.h:42
TProofNodeInfo * GetMaster()
Get the master node.
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:900
static Long_t fgVirtMemMax
Definition: TProofServ.h:171
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
virtual void HandleCheckFile(TMessage *mess, TString *slb=0)
Handle file checking request.
const char * GetGroup() const
Definition: TProof.h:940
void SendParallel(Bool_t async=kFALSE)
Send number of parallel nodes to master or client.
Int_t fMaxQueries
Definition: TProofServ.h:166
const char * GetService() const
Definition: TProofServ.h:250
static TString fgPfx
Definition: TProofServ.h:393
virtual void HandleSocketInput()
Handle input coming from the client or from the master server.
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:625
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2406
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:264
EUploadPackageOpt
Definition: TProof.h:389
virtual void HandleArchive(TMessage *mess, TString *slb=0)
Handle archive request.
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3851
virtual void UpdateProgressInfo()=0
Int_t fMode
Definition: TSystem.h:138
TString fArchivePath
Definition: TProofServ.h:107
Int_t RemoveIncludePath(const char *incpath, Bool_t onClient=kFALSE)
Remove 'incpath' from the inc path search.
Definition: TProof.cxx:9534
virtual Long64_t Process(TDSet *set, const char *selector, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
TTimeStamp GetLastUsage()
Definition: TSocket.h:159
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
const char * Data() const
Definition: TString.h:349
virtual TObject * ReadObject(const TClass *cl)
Read object from I/O buffer.
Int_t fGroupId
Definition: TProofServ.h:117
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:946
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:620
static void SetLastEntry(Long64_t lastentry)
Set the last entry before exception.
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:839
Int_t Update(Long64_t avgsize=-1)
Update accumulated information about the elements of the collection (e.g.
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:847
#define SafeDelete(p)
Definition: RConfig.h:436
virtual TList * GetOutputList() const =0
virtual int Unlink(const char *name)
Unlink, i.e. remove, a file.
Definition: TSystem.cxx:1346
TSocket * fSocket
Definition: TProofServ.h:108
TStopwatch timer
Definition: pirndm.C:37
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:75
TList * GetWorkers()
Get the list of worker nodes.
void StopProcess(Bool_t abort, Int_t timeout=-1)
Send STOPPROCESS message to master and workers.
Definition: TProof.cxx:6211
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2334
virtual FILE * TempFileName(TString &base, const char *dir=0)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition: TSystem.cxx:1462
#define PDB(mask, level)
Definition: TProofDebug.h:58
void Class()
Definition: Class.C:29
const Int_t kSysError
Definition: TError.h:43
virtual void HandleFork(TMessage *mess)
Cloning itself via fork. Not implemented.
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:36
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:441
Bool_t IsValid() const
Definition: TInetAddress.h:80
virtual void MergeOutput(Bool_t=kFALSE)=0
const char * ord
Definition: TXSlave.cxx:46
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:46
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
virtual void ShowQuota(const char *opt)
Display quota information.
void SetLogLevel(Int_t level, UInt_t mask=TProofDebug::kAll)
Set server logging level.
Definition: TProof.cxx:7066
virtual void Run(Bool_t retrn=kFALSE)
Main application eventloop. Calls system dependent eventloop via gSystem.
virtual char * ReadString(char *s, Int_t max)
Read string from I/O buffer.
const char *const kPROOF_QueryDir
Definition: TProof.h:151
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2469
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Definition: TFile.cxx:4319
const Int_t kFatal
Definition: TError.h:44
virtual Int_t RegisterDataSet(const char *uri, TFileCollection *dataSet, const char *opt)
Register a dataset, perfoming quota checkings, if needed.
virtual void ShowCache(Bool_t all=kFALSE)
List contents of file cache.
Definition: TProof.cxx:7678
Int_t GetQuerySeqNum() const
Definition: TProofServ.h:272
TDSetElement * GetNextPacket(Long64_t totalEntries=-1)
Get next range of entries to be processed on this server.
virtual void Start(Long_t milliSec=-1, Bool_t singleShot=kFALSE)
Starts the timer with a milliSec timeout.
Definition: TTimer.cxx:209
void Init(const TFunction *func)
Initialize the method invocation environment based on the TFunction object.
TList * GetListOfDeActives() const
Returns a list with all de-active sockets.
Definition: TMonitor.cxx:515
void DeleteAll()
Remove all (key,value) pairs from the map AND delete the keys AND values when they are allocated on t...
Definition: TMap.cxx:166
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1757
Long64_t fLogFileMaxSize
Definition: TProofServ.h:113
TVirtualProofPlayer * GetPlayer() const
Definition: TProof.h:751
virtual void HandleUrgentData()
Handle Out-Of-Band data sent by the master or client.
TFileHandler * fInputHandler
Definition: TProofServ.h:136
Int_t CleanupSession(const char *sessiontag)
Cleanup query dir qdir.
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1627
TList * GetListOfElements() const
Definition: TDSet.h:231
static Int_t RegisterDataSets(TList *in, TList *out, TDataSetManager *dsm, TString &e)
Register TFileCollections in 'out' as datasets according to the rules in 'in'.
Int_t ApplyMaxQueries(Int_t mxq)
Scan the queries directory and remove the oldest ones (and relative dirs, if empty) in such a way onl...
TString & Append(const char *cs)
Definition: TString.h:492
std::vector< std::vector< double > > Data
virtual void ExitLoop()
Exit from event loop.
Definition: TSystem.cxx:396
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:234
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1563
TProofQueryResult * NextQuery()
Get the next query from the waiting list.
TString fDataDir
Definition: TProofServ.h:100
const char * GetUser() const
Definition: TProof.h:939
void FlushLogFile()
Reposition the read pointer in the log file to the very end.
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1964
virtual ~TProofServ()
Cleanup.
Bool_t IsParallel() const
Definition: TProof.h:972
Int_t UnloadPackages()
Unloads all enabled packages. Returns -1 in case of error, 0 otherwise.
TProof * fProof
Definition: TProofServ.h:109
static Long_t GetResMemMax()
ResMemMax getter.
TList * GetListOfInactiveSlaves() const
Definition: TProof.h:690
virtual TSocket * Accept(UChar_t Opt=0)
Accept a connection on a server socket.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:30
TString fConfDir
Definition: TProofServ.h:88
XFontStruct * id
Definition: TGX11.cxx:108
Method or function calling interface.
Definition: TMethodCall.h:41
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
TString flog
Definition: pq2main.cxx:37
virtual Int_t HandleCache(TMessage *mess, TString *slb=0)
Handle here all cache and package requests.
TProofServ * fProofServ
Definition: TProofServ.h:430
virtual void HandleQueryList(TMessage *mess)
Handle request for list of queries.
Bool_t fInterrupt
Definition: TProofServ.h:124
A container class for query results.
Definition: TQueryResult.h:44
Int_t ActivateWorker(const char *ord, Bool_t save=kTRUE)
Make sure that the worker identified by the ordinal number 'ord' is in the active list...
Definition: TProof.cxx:11920
TString fOrdinal
Definition: TProofServ.h:116
Long64_t GetEntries() const
Definition: TQueryResult.h:130
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo's. In case of error return 0.
Definition: TProof.cxx:2316
const char * GetWorkDir() const
Definition: TProofServ.h:255
void Error(const char *location, const char *msgfmt,...)
const char *const kPROOF_DataDir
Definition: TProof.h:153
Int_t fGid
Definition: TSystem.h:140
char * out
Definition: TBase64.cxx:29
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition: TMonitor.cxx:322
virtual Int_t SendAsynMessage(const char *msg, Bool_t lf=kTRUE)
Send an asychronous message to the master / client .
virtual void SetProcessInfo(Long64_t ent, Float_t cpu=0., Long64_t siz=-1, Float_t inittime=0., Float_t proctime=0.)
Set processing info.
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition: TProof.cxx:10485
ELogLevel
Definition: TSystem.h:66
static TVirtualProofPlayer * Create(const char *player, TProof *p, TSocket *s=0)
Create a PROOF player.
TString fAdminPath
Definition: TProofServ.h:102
TObject * FindObject(const char *keyname) const
Check if a (key,value) pair exists with keyname as name of the key.
Definition: TMap.cxx:213
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:594
virtual ~TProofServLogHandler()
Handle available message in the open file.
Definition: TProofServ.cxx:287
A doubly linked list.
Definition: TList.h:47
static const char * what
Definition: stlLoader.cc:6
Int_t fGroupPriority
Definition: TProofServ.h:121
virtual ~TReaperTimer()
Destructor.
Definition: TProofServ.cxx:450
Float_t fCpuTime
Definition: TProofServ.h:126
virtual Int_t Fork()
Fork a child.
Bool_t Notify()
Check if any of the registered children has changed its state.
Definition: TProofServ.cxx:478
TShutdownTimer(TProofServ *p, Int_t delay)
Construtor.
Definition: TProofServ.cxx:405
static TProofServ * This()
Static function returning pointer to global object gProofServ.
Bool_t RemoveDataSet(const char *group, const char *user, const char *dsName)
Removes the indicated dataset.
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition: TEnv.cxx:595
const char *const kPROOF_QueryLockFile
Definition: TProof.h:156
static Float_t GetMemStop()
MemStop getter.
void Sort(Bool_t useindex=kFALSE)
Sort the collection.
void Reset()
Reset the message buffer so we can use (i.e. fill) it again.
Definition: TMessage.cxx:171
Int_t UploadPackage(const char *par, EUploadPackageOpt opt=kUntar, TList *workers=0)
Upload a PROOF archive (PAR file).
Definition: TProof.cxx:8898
Int_t GetPort() const
Definition: TUrl.h:87
const char Int_t const char TProof Int_t const char * workdir
Definition: TXSlave.cxx:46
virtual void AddQueryResult(TQueryResult *q)=0
Named parameter, streamable and storable.
Definition: TParameter.h:49
const Int_t kUnset
Definition: TError.h:37
Int_t GetPriority()
Get the processing priority for the group the user belongs too.
virtual Bool_t Load() const
Load the macro into the interpreter.
Definition: TMacro.cxx:245
TSocket * GetSocket() const
Definition: TProofServ.h:269
Int_t fProtocol
Definition: TProofServ.h:115
const TString & GetWorkDir() const
time_t GetSec() const
Definition: TTimeStamp.h:140
TString fUser
Definition: TSystem.h:152
virtual void Close(Option_t *opt="")
Close the socket.
Definition: TSocket.cxx:388
static double C[]
static Int_t fgLogToSysLog
Definition: TProofServ.h:184
const Int_t kPrint
Definition: TError.h:38
Int_t ReceiveFile(const char *file, Bool_t bin, Long64_t size)
Receive a file, either sent by a client or a master server.
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1611
TString GetString() const
Definition: TObjString.h:50
const char * GetPrefix() const
Definition: TProofServ.h:288
ROOT::R::TRInterface & r
Definition: Object.C:4
Int_t DisablePackages()
Remove all packages.
Definition: TProof.cxx:7982
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2220
const Int_t kInfo
Definition: TError.h:39
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
static Int_t WriteChecksum(const char *file, const TMD5 *md5)
Writes checksum in ASCII format to specified file.
Definition: TMD5.cxx:450
SVector< double, 2 > v
Definition: Dict.h:5
Float_t GetUsedCPU() const
Definition: TQueryResult.h:133
TProofLockPath * fPackageLock
Definition: TProofServ.h:104
Int_t fCompressMsg
Definition: TProofServ.h:154
TString fSessionDir
Definition: TProofServ.h:94
static void GetLocalServer(TString &dsrv)
Extract LOCALDATASERVER info in 'dsrv'.
const char *const kPROOF_DataSetDir
Definition: TProof.h:152
TList * GetListOfSlaves() const
Definition: TProof.h:689
THashList * GetList()
Long64_t GetBytes() const
Definition: TQueryResult.h:132
void SetLearnTime(Double_t learnTime)
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
TList * GetListOfLines() const
Definition: TMacro.h:53
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:674
void ShowPackages(Bool_t all=kFALSE, Bool_t redirlog=kFALSE)
List contents of package directory.
Definition: TProof.cxx:7757
Bool_t Gets(FILE *fp, Bool_t chop=kTRUE)
Read one line from the stream, including the , or until EOF.
Definition: Stringio.cxx:198
virtual Bool_t ExistsDataSet(const char *uri)
Checks if the indicated dataset exits.
Long_t fMemVirtual
Definition: TSystem.h:207
Bool_t ParseUri(const char *uri, TString *dsGroup=0, TString *dsUser=0, TString *dsName=0, TString *dsTree=0, Bool_t onlyCurrent=kFALSE, Bool_t wildcards=kFALSE)
Parses a (relative) URI that describes a DataSet on the cluster.
TList * fEnabledPackages
Definition: TProofServ.h:114
Bool_t Notify()
Handle expiration of the idle timer. The session will just be terminated.
Definition: TProofServ.cxx:516
virtual TEnvRec * Lookup(const char *n)
Loop over all resource records and return the one with name.
Definition: TEnv.cxx:550
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition: TSystem.cxx:1768
virtual Int_t ShowCache(const char *uri)
Show cached information matching uri.
void SetActive(Bool_t=kTRUE)
Definition: TProof.h:1021
Int_t WriteDataSet(const char *group, const char *user, const char *dsName, TFileCollection *dataset, UInt_t option=0, TMD5 *checksum=0)
Writes indicated dataset.
Int_t GetNanoSec() const
Definition: TTimeStamp.h:141
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
Int_t QueueQuery(TProofQueryResult *pq)
Add a query to the waiting list Returns the number of queries in the list.
TObject * Value() const
Definition: TMap.h:125
static Float_t fgMemHWM
Definition: TProofServ.h:174
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2321
const char * GetConfDir() const
Definition: TProofServ.h:251
unsigned int UInt_t
Definition: RtypesCore.h:42
TList * GetInputList()
Definition: TQueryResult.h:128
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
TMarker * m
Definition: textangle.C:8
const char *const kPROOF_CacheLockFile
Definition: TProof.h:154
TIdleTOTimer * fIdleTOTimer
Definition: TProofServ.h:152
Int_t ScanDataSet(const char *uri, const char *opt)
Scans the dataset indicated by 'uri' following the 'opts' directives.
virtual int Umask(Int_t mask)
Set the process file creation mode mask.
Definition: TSystem.cxx:1480
void SetRunning(Int_t startlog, const char *par, Int_t nwrks)
Call when running starts.
TString fDataDirOpts
Definition: TProofServ.h:101
Bool_t IsDataReady(Long64_t &totalbytes, Long64_t &bytesready)
See if the data is ready to be analyzed.
Definition: TProof.cxx:2235
This class implements a plugin library manager.
virtual void SetMerging(Bool_t on=kTRUE)=0
void SaveSource(FILE *fp)
Save macro source in file pointer fp.
Definition: TMacro.cxx:379
virtual Int_t Echo(const TObject *obj)
Sends an object to master and workers and expect them to send back a message with the output of its T...
Definition: TProof.cxx:7015
virtual Int_t ReadFile(const char *filename)
Read lines in filename in this macro.
Definition: TMacro.cxx:334
A TEventList object is a list of selected events (entries) in a TTree.
Definition: TEventList.h:33
TLine * l
Definition: textangle.C:4
virtual void HandleSigPipe()
Called when the client is not alive anymore (i.e.
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:57
virtual const char * GetField(Int_t field)=0
Bool_t IsEndMaster() const
Definition: TProofServ.h:304
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual Bool_t IsValid() const
static void AddEnvVar(const char *name, const char *value)
Add an variable to the list of environment variables passed to proofserv on the master and slaves...
Definition: TProof.cxx:12327
TServerSocket * fMergingSocket
Definition: TProofServ.h:161
TSubString Strip(EStripType s=kTrailing, char c= ' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1069
Int_t GetProtocol() const
Definition: TProofServ.h:264
Int_t Ping(ESlaves list)
Ping PROOF slaves. Returns the number of slaves that responded.
Definition: TProof.cxx:4742
const Int_t kPROOF_Protocol
Definition: TProof.h:143
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:657
const Int_t kWarning
Definition: TError.h:40
static Bool_t IsActive()
Static function that returns kTRUE in case we are a PROOF server.
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:728
void Interrupt()
Definition: TProofServ.h:303
TString fUser
Definition: TProofServ.h:86
Bool_t FinalizeQuery(TProofQueryResult *pq, TProof *proof, TVirtualProofPlayer *player)
Final steps after Process() to complete the TQueryResult instance.
Bool_t fIdle
Definition: TProofServ.h:141
virtual void ProcessNext(TString *slb=0)
process the next query from the queue of submitted jobs.
Bool_t IsNull() const
Definition: TString.h:387
Int_t RemoveWorkers(TList *wrks)
Used for shuting down the workres after a query is finished.
Definition: TProof.cxx:1591
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition: TSystem.cxx:3731
void SetName(const char *name)
Definition: TCollection.h:116
Int_t SendFile(const char *file, Int_t opt=(kBinary|kForward|kCp|kCpBin), const char *rfile=0, TSlave *sl=0)
Send a file to master or slave servers.
Definition: TProof.cxx:6881
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition: TMessage.cxx:116
void Warning(const char *location, const char *msgfmt,...)
Long64_t GetEntries() const
Long64_t entry
TString fDataSetDir
Definition: TProofServ.h:99
TShutdownTimer * fShutdownTimer
Definition: TProofServ.h:150
const char * GetUser() const
Definition: TProofServ.h:253
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:839
Int_t SendResults(TSocket *sock, TList *outlist=0, TQueryResult *pq=0)
Sends all objects from the given list to the specified socket.
const char * GetImage() const
Definition: TProofServ.h:256
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:675
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2240
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition: TProof.cxx:9947
#define Printf
Definition: TGeoToOCC.h:18
void AddPid(Int_t pid)
Add an entry for 'pid' in the internal list.
Definition: TProofServ.cxx:462
virtual void HandleSubmerger(TMessage *mess)
Handle a message of type kPROOF_SUBMERGER.
#define gPerfStats
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2513
Int_t RemoveDynamicPath(const char *libpath, Bool_t onClient=kFALSE)
Remove 'libpath' from the lib path search.
Definition: TProof.cxx:9500
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
virtual void RemoveQueryResult(const char *ref)=0
virtual void HandleRetrieve(TMessage *mess, TString *slb=0)
Handle retrieve request.
TMutex * fQMtx
Definition: TProofServ.h:142
Int_t SendCommand(const char *cmd, ESlaves list=kActive)
Send command to be executed on the PROOF master and/or slaves.
Definition: TProof.cxx:6618
virtual Int_t HandleWorkerLists(TMessage *mess)
Handle here all requests to modify worker lists.
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:580
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=0)
Redirect standard output (stdout, stderr) to the specified file.
Definition: TSystem.cxx:1677
Int_t LoadPackage(const char *package, Bool_t notOnClient=kFALSE, TList *loadopts=0, TList *workers=0)
Load specified package.
Definition: TProof.cxx:8318
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
TObject * Get(const char *namecycle)
Get object with name "name;cycle" (e.g.
int Ssiz_t
Definition: RtypesCore.h:63
virtual int Chmod(const char *file, UInt_t mode)
Set the file permission bits. Returns -1 in case or error, 0 otherwise.
Definition: TSystem.cxx:1471
R__EXTERN TProof * gProof
Definition: TProof.h:1110
TObject * GetInputObject(const char *classname) const
Return first instance of class 'classname' in the input list.
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:932
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:106
Int_t OldAuthSetup(TString &wconf)
Setup authentication related stuff for old versions.
TList * GetListOfActiveSlaves() const
Definition: TProof.h:758
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3805
virtual Int_t GetSize() const
Definition: TCollection.h:95
Bool_t Notify()
Handle available message in the open file.
Definition: TProofServ.cxx:304
Long64_t GetFirst() const
Definition: TQueryResult.h:131
virtual void SendLogFile(Int_t status=0, Int_t start=-1, Int_t end=-1)
Send log file to master.
double f(double x)
static Int_t fgCmdRtn
Definition: TProofServ.h:394
TString GetFileName() const
void ResetParam()
Reset parameter list. To be used before the first call the SetParam().
virtual Long64_t GetEventsProcessed() const =0
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition: TMonitor.cxx:438
TString fTopSessionTag
Definition: TProofServ.h:93
void SetSysInfo(SysInfo_t si)
Setter for fSysInfo.
Definition: TProof.cxx:248
virtual Func_t DynFindSymbol(const char *module, const char *entry)
Find specific entry point in specified library.
Definition: TSystem.cxx:1982
TList * GetListOfMethodArgs()
Return list containing the TMethodArgs of a TFunction.
Definition: TFunction.cxx:126
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
virtual Int_t ReadKeys(Bool_t forceRead=kTRUE)
Read the linked list of keys.
double Double_t
Definition: RtypesCore.h:55
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:307
virtual int Symlink(const char *from, const char *to)
Create a symbolic link from file1 to file2.
Definition: TSystem.cxx:1337
void Reset(const char *dir)
Reset PROOF environment to be ready for execution of next command.
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition: TSystem.cxx:1958
static Float_t fgMemStop
Definition: TProofServ.h:175
Int_t(* OldProofServAuthSetup_t)(TSocket *, Bool_t, Int_t, TString &, TString &, TString &)
Definition: TProofServ.h:71
Int_t Lock()
Locks the directory.
static Int_t GetInputData(TList *input, const char *cachedir, TString &emsg)
Get the input data from the file defined in the input list.
Definition: TProof.cxx:12981
Bool_t UseDynamicStartup() const
Definition: TProof.h:954
Bool_t IsMaster() const
Definition: TProofServ.h:305
void Run(Bool_t retrn=kFALSE)
Main server eventloop.
void SetFd(int fd)
virtual void SetEntryList(TObject *aList)
Set entry (or event) list for this data set.
Definition: TDSet.cxx:1865
Int_t fLogLevel
Definition: TProofServ.h:119
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:44
int type
Definition: TGX11.cxx:120
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
Int_t fMergedWorkers
Definition: TProofServ.h:163
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
const char * GetOrdinal() const
Definition: TProofServ.h:265
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition: TTimeStamp.h:76
Definition: TProof.h:339
int nentries
Definition: THbookFile.cxx:89
virtual void SetInputList(TList *in, Bool_t adopt=kTRUE)
Set / change the input list.
virtual Int_t GetGid(const char *group=0)
Returns the group's id. If group = 0, returns current user's group.
Definition: TSystem.cxx:1543
#define R__LOCKGUARD(mutex)
UInt_t What() const
Definition: TMessage.h:80
virtual TQueryResult * GetCurrentQuery() const =0
void SetRunStatus(ERunStatus rst)
Definition: TProof.h:707
Float_t fRealTime
Definition: TProofServ.h:125
TStopwatch fSaveOutput
Definition: TProofServ.h:129
void RemoveQuery(TQueryResult *qr, Bool_t soft=kFALSE)
Remove everything about query qr.
virtual TInetAddress GetSockName(int sock)
Get Internet Protocol (IP) address of host and port #.
Definition: TSystem.cxx:2263
Int_t Unlock()
Unlock the directory.
virtual void StopProcess(Bool_t abort, Int_t timeout=-1)=0
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:348
virtual Int_t GetUid(const char *user=0)
Returns the user's id. If user = 0, returns current user's id.
Definition: TSystem.cxx:1524
void SetIdle(Bool_t st=kTRUE)
Change the idle status.
Definition: TSocket.h:67
Int_t AddWorkers(TList *wrks)
Works on the master node only.
Definition: TProof.cxx:1320
void SetArchived(const char *archfile)
Set (or update) query in archived state.
Bool_t Notify()
Handle expiration of the shutdown timer.
Definition: TProofServ.cxx:417
Bool_t fEndMaster
Definition: TProofServ.h:122
static TMap * GetDataSetNodeMap(TFileCollection *fc, TString &emsg)
Get a map {server-name, list-of-files} for collection 'fc' to be used in TPacketizerFile.
void Print(Option_t *option="") const
Print status of slave server.
void SaveQuery(TProofQueryResult *qr, const char *fout=0)
Save current status of query 'qr' to file name fout.
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
Definition: TPRegexp.cxx:704
#define name(a, b)
Definition: linkTestLib0.cpp:5
static TString fgSysLogEntity
Definition: TProofServ.h:186
Int_t UnloadPackage(const char *package)
Unload specified package.
Definition: TProof.cxx:8530
void Throw(int code)
If an exception context has been set (using the TRY and RETRY macros) jump back to where it was set...
Definition: TException.cxx:27
Mother of all ROOT objects.
Definition: TObject.h:58
Float_t GetCpuTime() const
Definition: TProof.h:964
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:30
void Print(Option_t *option="") const
Prints the contents of the TFileCollection.
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:556
THashList * fGlobalPackageDirList
Definition: TProofServ.h:96
void TruncateLogFile()
Truncate the log file to the 80% of the required max size if this is set.
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1806
Int_t BufferSize() const
Definition: TBuffer.h:92
virtual Bool_t Add(const char *file, const char *objname=0, const char *dir=0, Long64_t first=0, Long64_t num=-1, const char *msd=0)
Add file to list of files to be analyzed.
Definition: TDSet.cxx:1023
Bool_t ExistsDataSet(const char *group, const char *user, const char *dsName)
Checks if the indicated dataset exits.
TTime fTime
Definition: TTimer.h:60
virtual void HandleGetTreeHeader(TMessage *mess)=0
virtual void Openlog(const char *name, Int_t options, ELogFacility facility)
Open connection to system log daemon.
Definition: TSystem.cxx:1639
void ShowEnabledPackages(Bool_t all=kFALSE)
List which packages are enabled.
Definition: TProof.cxx:7821
Bool_t R_ISDIR(Int_t mode)
Definition: TSystem.h:126
virtual Int_t CreateServer()
Finalize the server setup.
Definition: TProofServ.cxx:796
Int_t UnloadPackage(const char *package)
Removes link to package in working directory, removes entry from include path, removes entry from ena...
virtual Long64_t GetCacheSize()=0
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:103
Int_t Length() const
Definition: TBuffer.h:94
Int_t GetSessionStatus()
Return the status of this session: 0 idle 1 running 2 being terminated (currently unused) 3 queued 4 ...
Class that contains a list of TFileInfo's and accumulated meta data information about its entries...
void Execute(const char *, const char *, int *=0)
Execute method on this object with the given parameter string, e.g.
Definition: TMethodCall.h:68
virtual void SetOutputFilePath(const char *fp)=0
TFileCollection * GetDataSet(const char *uri, const char *srv=0)
Utility function used in various methods for user dataset upload.
TProofQueryResult * MakeQueryResult(Long64_t nentries, const char *opt, TList *inl, Long64_t first, TDSet *dset, const char *selec, TObject *elist)
Create a TProofQueryResult instance for this query.
TList * Queries() const
virtual void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
Definition: TSystem.cxx:720
Int_t CleanupQueriesDir()
Remove all queries results referring to previous sessions.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
R__EXTERN Int_t gProofDebugLevel
Definition: TProofDebug.h:56
static TString fgLastMsg
Definition: TProofServ.h:240
void WriteObject(const TObject *obj)
Write object to message buffer.
Definition: TMessage.cxx:418
virtual Int_t Setup()
Print the ProofServ logo on standard output.
TProofServLogHandler(const char *cmd, TSocket *s, const char *pfx="")
Execute 'cmd' in a pipe and handle output messages from the related file.
Definition: TProofServ.cxx:241
void AskStatistics()
Ask the for the statistics of the slaves.
Definition: TProof.cxx:2017
const Int_t kError
Definition: TError.h:41
const char *const kUNTAR
Definition: TProof.h:167
const char *const kUNTAR3
Definition: TProof.h:169
TString fWorkDir
Definition: TProofServ.h:90
void SetParam(Long_t l)
Add a long method parameter.
static Int_t SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
Save input data file from 'cachedir' into the sandbox or create a the file with input data objects...
Definition: TProof.cxx:12879
Bool_t IsTopMaster() const
Definition: TProofServ.h:307
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7127
TProofServ * fProofServ
Definition: TProofServ.h:457
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:830
ClassImp(TSlaveInfo) Int_t TSlaveInfo const TSlaveInfo * si
Used to sort slaveinfos by ordinal.
Definition: TProof.cxx:167
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
virtual void DeletePlayer()
Delete player instance.
Int_t AddDynamicPath(const char *libpath, Bool_t onClient=kFALSE, TList *wrks=0, Bool_t doCollect=kTRUE)
Add 'libpath' to the lib path search.
Definition: TProof.cxx:9410
virtual TProofProgressStatus * GetProgressStatus() const =0
void Reset()
Definition: TStopwatch.h:54
void RedirectOutput(const char *dir=0, const char *mode="w")
Redirect stdout to a log file.
virtual void AddIncludePath(const char *includePath)
Add includePath to the already set include path.
Definition: TSystem.cxx:3972
virtual Int_t AddOutputObject(TObject *obj)=0
virtual void Stop()
Definition: TTimer.h:99
virtual void AddFileHandler(TFileHandler *fh)
Add a file handler to the list of system file handlers.
Definition: TSystem.cxx:558
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:280
static void SetLastMsg(const char *lastmsg)
Set the message to be sent back in case of exceptions.
double result[121]
Class describing a generic file including meta information.
Definition: TFileInfo.h:50
static void SetDefaultPrefix(const char *pfx)
Static method to set the default prefix.
Definition: TProofServ.cxx:337
void ResetBit(UInt_t f)
Definition: TObject.h:172
This class creates the ROOT Application Environment that interfaces to the windowing system eventloop...
Definition: TApplication.h:45
void RestartComputeTime()
Reset the compute time.
const AParamType & GetVal() const
Definition: TParameter.h:77
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1243
Long64_t fMsgSizeHWM
Definition: TProofServ.h:178
TString fPackageDir
Definition: TProofServ.h:95
virtual void Terminate(Int_t status)
Terminate the proof server.
TList * fWaitingQueries
Definition: TProofServ.h:140
TString fCacheDir
Definition: TProofServ.h:97
TString fQueryDir
Definition: TProofServ.h:98
TClass * GetClass() const
Definition: TMessage.h:76
Int_t fTotSessions
Definition: TProofServ.h:132
virtual ~TProofServLogHandlerGuard()
Close a guard for executing a command in a pipe.
Definition: TProofServ.cxx:393
const Bool_t kIterBackward
Definition: TCollection.h:44
virtual Int_t SavePartialResults(Bool_t queryend=kFALSE, Bool_t force=kFALSE)=0
Bool_t IsParallel() const
True if in parallel mode.
void SendStatistics()
Send statistics of slave server to master or client.
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
virtual Int_t Load(const char *macro, Bool_t notOnClient=kFALSE, Bool_t uniqueOnly=kTRUE, TList *wrks=0)
Load the specified macro on master, workers and, if notOnClient is kFALSE, on the client...
Definition: TProof.cxx:9198
Int_t Substitute(TString &s, const TString &r, Bool_t doDollarSubst=kTRUE)
Substitute matching part of s with r, dollar back-ref substitution is performed if doDollarSubst is t...
Definition: TPRegexp.cxx:870
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition: TSelector.h:39
static void ErrorHandler(Int_t level, Bool_t abort, const char *location, const char *msg)
The PROOF error handler function.
static TMD5 * ReadChecksum(const char *file)
Returns checksum stored in ASCII in specified file.
Definition: TMD5.cxx:420
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:901
const Bool_t kTRUE
Definition: Rtypes.h:91
float * q
Definition: THbookFile.cxx:87
Int_t ClearPackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7862
void SetString(const char *s)
Definition: TObjString.h:49
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
TObject * obj
TList * PreviousQueries() const
Int_t CleanupWaitingQueries(Bool_t del=kTRUE, TList *qls=0)
Cleanup the waiting queries list.
virtual void TurnOn()
Add the timer to the system timer list.
Definition: TTimer.cxx:239
float value
Definition: math.cpp:443
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:27
const char * GetName() const
Returns name of object.
Definition: TMap.h:120
Int_t DeactivateWorker(const char *ord, Bool_t save=kTRUE)
Remove the worker identified by the ordinal number 'ord' from the the active list.
Definition: TProof.cxx:11937
virtual TMap * GetDataSets(const char *uri, UInt_t=TDataSetManager::kExport)
Returns all datasets for the and specified by .
Int_t fQuerySeqNum
Definition: TProofServ.h:130
static TString fgSysLogService
Definition: TProofServ.h:185
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition: TProof.cxx:2299
const Int_t n
Definition: legend1.C:16
Int_t fLogFileDes
Definition: TProofServ.h:112
Bool_t NoLogOpt() const
Definition: TApplication.h:144
TProofServ(Int_t *argc, char **argv, FILE *flog=0)
Main constructor.
Definition: TProofServ.cxx:561
TProofServLogHandler * fExecHandler
Definition: TProofServ.h:416
TProofLockPath * fCacheLock
Definition: TProofServ.h:105
double log(double)
Long_t fMemResident
Definition: TSystem.h:206
const char * GetFile() const
Definition: TUrl.h:78
virtual int GetSysInfo(SysInfo_t *info) const
Returns static system info, like OS type, CPU type, number of CPUs RAM size, etc into the SysInfo_t s...
Definition: TSystem.cxx:2412
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:385
virtual void SetIncludePath(const char *includePath)
IncludePath should contain the list of compiler flags to indicate where to find user defined header f...
Definition: TSystem.cxx:4007
Bool_t IsEndMaster() const
Definition: TProof.h:699
TQueryResultManager * fQMgr
Definition: TProofServ.h:138
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition: TMacro.cxx:299
virtual Long_t ProcessFile(const char *file, Int_t *error=0, Bool_t keep=kFALSE)
Process a file containing a C++ macro.
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:898
Bool_t fSendLogToMaster
Definition: TProofServ.h:159
TProofLockPath * fQueryLock
Definition: TProofServ.h:106
static Long64_t fgLastEntry
Definition: TProofServ.h:241
const char *const kPROOF_CacheDir
Definition: TProof.h:148
virtual TSQLRow * Next()=0
const char *const kPROOF_PackDir
Definition: TProof.h:149
Stopwatch class.
Definition: TStopwatch.h:30
static Int_t AssertDataSet(TDSet *dset, TList *input, TDataSetManager *mgr, TString &emsg)
Make sure that dataset is in the form to be processed.
Definition: TProof.cxx:12582
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904