ROOT  6.06/08
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 
164 Bool_t TProofServTerminationHandler::Notify()
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 
185 Bool_t TProofServInterruptHandler::Notify()
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 
208 Bool_t TProofServSigPipeHandler::Notify()
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 
229 Bool_t TProofServInputHandler::Notify()
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()) {
360  gSystem->AddFileHandler(fExecHandler);
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()) {
380  gSystem->AddFileHandler(fExecHandler);
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()) {
396  gSystem->RemoveFileHandler(fExecHandler);
397  SafeDelete(fExecHandler);
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) {
453  fChildren->SetOwner(kTRUE);
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
2974  char *workdir = gSystem->ExpandPathName(fWorkDir.Data());
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(TROOT::GetBinDir());
3030  // Augment PATH, if required
3031  // ^<compiler>, <compiler>, ^<sysbin>, <sysbin>
3032  TString paths = gEnv->GetValue("ProofServ.BinPaths", "");
3033  if (paths.Length() > 0) {
3034  Int_t icomp = 0;
3035  if (paths.Contains("^<compiler>"))
3036  icomp = 1;
3037  else if (paths.Contains("<compiler>"))
3038  icomp = -1;
3039  if (icomp != 0) {
3040 # ifdef COMPILER
3041  TString compiler = COMPILER;
3042  if (compiler.Index("is ") != kNPOS)
3043  compiler.Remove(0, compiler.Index("is ") + 3);
3044  compiler = gSystem->DirName(compiler);
3045  if (icomp == 1) {
3046  if (!bindir.IsNull()) bindir += ":";
3047  bindir += compiler;
3048  } else if (icomp == -1) {
3049  if (!path.IsNull()) path += ":";
3050  path += compiler;
3051  }
3052 #endif
3053  }
3054  Int_t isysb = 0;
3055  if (paths.Contains("^<sysbin>"))
3056  isysb = 1;
3057  else if (paths.Contains("<sysbin>"))
3058  isysb = -1;
3059  if (isysb != 0) {
3060  if (isysb == 1) {
3061  if (!bindir.IsNull()) bindir += ":";
3062  bindir += "/bin:/usr/bin:/usr/local/bin";
3063  } else if (isysb == -1) {
3064  if (!path.IsNull()) path += ":";
3065  path += "/bin:/usr/bin:/usr/local/bin";
3066  }
3067  }
3068  }
3069  // Final insert
3070  if (!bindir.IsNull()) bindir += ":";
3071  path.Insert(0, bindir);
3072  gSystem->Setenv("PATH", path);
3073 #endif
3074 
3077  if (!gSystem->ChangeDirectory(fWorkDir)) {
3078  Error("SetupCommon", "can not change to PROOF directory %s",
3079  fWorkDir.Data());
3080  return -1;
3081  }
3082  } else {
3083  if (!gSystem->ChangeDirectory(fWorkDir)) {
3086  if (!gSystem->ChangeDirectory(fWorkDir)) {
3087  Error("SetupCommon", "can not change to PROOF directory %s",
3088  fWorkDir.Data());
3089  return -1;
3090  }
3091  }
3092  }
3093 
3094  // Set group
3095  fGroup = gEnv->GetValue("ProofServ.ProofGroup", "default");
3096 
3097  // Check and make sure "cache" directory exists
3098  fCacheDir = gEnv->GetValue("ProofServ.CacheDir",
3103  if (gProofDebugLevel > 0)
3104  Info("SetupCommon", "cache directory set to %s", fCacheDir.Data());
3105  fCacheLock =
3106  new TProofLockPath(TString::Format("%s/%s%s",
3108  TString(fCacheDir).ReplaceAll("/","%").Data()));
3109 
3110  // Check and make sure "packages" directory exists
3111  fPackageDir = gEnv->GetValue("ProofServ.PackageDir",
3116  if (gProofDebugLevel > 0)
3117  Info("SetupCommon", "package directory set to %s", fPackageDir.Data());
3118  fPackageLock =
3119  new TProofLockPath(TString::Format("%s/%s%s",
3121  TString(fPackageDir).ReplaceAll("/","%").Data()));
3122 
3123  // Check and make sure "data" directory exists
3124  fDataDir = gEnv->GetValue("ProofServ.DataDir","");
3125  Ssiz_t isep = kNPOS;
3126  if (fDataDir.IsNull()) {
3127  // Use default
3128  fDataDir.Form("%s/%s/<ord>/<stag>", fWorkDir.Data(), kPROOF_DataDir);
3129  } else if ((isep = fDataDir.Last(' ')) != kNPOS) {
3130  fDataDirOpts = fDataDir(isep + 1, fDataDir.Length());
3131  fDataDir.Remove(isep);
3132  }
3135  if (gSystem->mkdir(fDataDir, kTRUE) != 0) {
3136  Warning("SetupCommon", "problems creating path '%s' (errno: %d)",
3138  }
3139  if (gProofDebugLevel > 0)
3140  Info("SetupCommon", "data directory set to %s", fDataDir.Data());
3141 
3142  // Check and apply possible options
3143  // (see http://root.cern.ch/drupal/content/configuration-reference-guide#datadir)
3144  TString dataDirOpts = gEnv->GetValue("ProofServ.DataDirOpts","");
3145  if (!dataDirOpts.IsNull()) {
3146  // Do they apply to this server type
3147  Bool_t doit = kTRUE;
3148  if ((IsMaster() && !dataDirOpts.Contains("M")) ||
3149  (!IsMaster() && !dataDirOpts.Contains("W"))) doit = kFALSE;
3150  if (doit) {
3151  // Get the wanted mode
3152  UInt_t m = 0755;
3153  if (dataDirOpts.Contains("g")) m = 0775;
3154  if (dataDirOpts.Contains("a") || dataDirOpts.Contains("o")) m = 0777;
3155  if (gProofDebugLevel > 0)
3156  Info("SetupCommon", "requested mode for data directories is '%o'", m);
3157  // Loop over paths
3158  FileStat_t st;
3159  TString p, subp;
3160  Int_t from = 0;
3161  if (fDataDir.BeginsWith("/")) p = "/";
3162  while (fDataDir.Tokenize(subp, from, "/")) {
3163  if (subp.IsNull()) continue;
3164  p += subp;
3165  if (gSystem->GetPathInfo(p, st) == 0) {
3166  if (st.fUid == (Int_t) gSystem->GetUid() && st.fGid == (Int_t) gSystem->GetGid()) {
3167  if (gSystem->Chmod(p.Data(), m) != 0) {
3168  Warning("SetupCommon", "problems setting mode '%o' on path '%s' (errno: %d)",
3169  m, p.Data(), TSystem::GetErrno());
3170  break;
3171  }
3172  }
3173  p += "/";
3174  } else {
3175  Warning("SetupCommon", "problems stat-ing path '%s' (errno: %d; datadir: %s)",
3176  p.Data(), TSystem::GetErrno(), fDataDir.Data());
3177  break;
3178  }
3179  }
3180  }
3181  }
3182 
3183  // List of directories where to look for global packages
3184  TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
3185  if (globpack.Length() > 0) {
3186  Int_t ng = 0;
3187  Int_t from = 0;
3188  TString ldir;
3189  while (globpack.Tokenize(ldir, from, ":")) {
3190  if (gSystem->AccessPathName(ldir, kReadPermission)) {
3191  Warning("SetupCommon", "directory for global packages %s does not"
3192  " exist or is not readable", ldir.Data());
3193  } else {
3194  // Add to the list, key will be "G<ng>", i.e. "G0", "G1", ...
3195  TString key;
3196  key.Form("G%d", ng++);
3197  if (!fGlobalPackageDirList) {
3200  }
3201  ResolveKeywords(ldir);
3202  fGlobalPackageDirList->Add(new TNamed(key,ldir));
3203  Info("SetupCommon", "directory for global packages %s added to the list",
3204  ldir.Data());
3205  FlushLogFile();
3206  }
3207  }
3208  }
3209 
3210  // Check the session dir
3211  if (fSessionDir != gSystem->WorkingDirectory()) {
3216  Error("SetupCommon", "can not change to working directory '%s'",
3217  fSessionDir.Data());
3218  return -1;
3219  }
3220  }
3221  gSystem->Setenv("PROOF_SANDBOX", fSessionDir);
3222  if (gProofDebugLevel > 0)
3223  Info("SetupCommon", "session dir is '%s'", fSessionDir.Data());
3224 
3225  // On masters, check and make sure that "queries" and "datasets"
3226  // directories exist
3227  if (IsMaster()) {
3228 
3229  // Make sure that the 'queries' dir exist
3230  fQueryDir = fWorkDir;
3231  fQueryDir += TString("/") + kPROOF_QueryDir;
3235  fQueryDir += TString("/session-") + fTopSessionTag;
3238  if (gProofDebugLevel > 0)
3239  Info("SetupCommon", "queries dir is %s", fQueryDir.Data());
3240 
3241  // Create 'queries' locker instance and lock it
3242  fQueryLock = new TProofLockPath(TString::Format("%s/%s%s-%s",
3245  TString(fQueryDir).ReplaceAll("/","%").Data()));
3246  fQueryLock->Lock();
3247  // Create the query manager
3249  fQueryLock, 0);
3250  }
3251 
3252  // Server image
3253  fImage = gEnv->GetValue("ProofServ.Image", "");
3254 
3255  // Get the group priority
3256  if (IsMaster()) {
3257  // Send session tag to client
3259  m << fTopSessionTag << fGroup << fUser;
3260  fSocket->Send(m);
3261  // Group priority
3263  // Dataset manager instance via plug-in
3264  TPluginHandler *h = 0;
3265  TString dsms = gEnv->GetValue("Proof.DataSetManager", "");
3266  if (!dsms.IsNull()) {
3267  TString dsm;
3268  Int_t from = 0;
3269  while (dsms.Tokenize(dsm, from, ",")) {
3271  Warning("SetupCommon", "a valid dataset manager already initialized");
3272  Warning("SetupCommon", "support for multiple managers not yet available");
3273  break;
3274  }
3275  // Get plugin manager to load the appropriate TDataSetManager
3276  if (gROOT->GetPluginManager()) {
3277  // Find the appropriate handler
3278  h = gROOT->GetPluginManager()->FindHandler("TDataSetManager", dsm);
3279  if (h && h->LoadPlugin() != -1) {
3280  // make instance of the dataset manager
3281  fDataSetManager =
3282  reinterpret_cast<TDataSetManager*>(h->ExecPlugin(3, fGroup.Data(),
3283  fUser.Data(), dsm.Data()));
3284  }
3285  }
3286  }
3287  // Check the result of the dataset manager initialization
3289  Warning("SetupCommon", "dataset manager plug-in initialization failed");
3290  SendAsynMessage("TXProofServ::SetupCommon: dataset manager plug-in initialization failed");
3292  }
3293  } else {
3294  // Initialize the default dataset manager
3295  TString opts("Av:");
3296  TString dsetdir = gEnv->GetValue("ProofServ.DataSetDir", "");
3297  if (dsetdir.IsNull()) {
3298  // Use the default in the sandbox
3299  dsetdir.Form("%s/%s", fWorkDir.Data(), kPROOF_DataSetDir);
3302  opts += "Sb:";
3303  }
3304  // Find the appropriate handler
3305  if (!h) {
3306  h = gROOT->GetPluginManager()->FindHandler("TDataSetManager", "file");
3307  if (h && h->LoadPlugin() == -1) h = 0;
3308  }
3309  if (h) {
3310  // make instance of the dataset manager
3311  TString oo = TString::Format("dir:%s opt:%s", dsetdir.Data(), opts.Data());
3312  fDataSetManager = reinterpret_cast<TDataSetManager*>(h->ExecPlugin(3,
3313  fGroup.Data(), fUser.Data(), oo.Data()));
3314  }
3316  Warning("SetupCommon", "default dataset manager plug-in initialization failed");
3318  }
3319  }
3320  // Dataset manager for staging requests
3321  TString dsReqCfg = gEnv->GetValue("Proof.DataSetStagingRequests", "");
3322  if (!dsReqCfg.IsNull()) {
3323  TPMERegexp reReqDir("(^| )(dir:)?([^ ]+)( |$)");
3324 
3325  if (reReqDir.Match(dsReqCfg) == 5) {
3326  TString dsDirFmt;
3327  dsDirFmt.Form("dir:%s perms:open", reReqDir[3].Data());
3328  fDataSetStgRepo = new TDataSetManagerFile("_stage_", "_stage_",
3329  dsDirFmt);
3330  if (fDataSetStgRepo &&
3332  Warning("SetupCommon",
3333  "failed init of dataset staging requests repository");
3335  }
3336  } else {
3337  Warning("SetupCommon",
3338  "specify, with [dir:]<path>, a valid path for staging requests");
3339  }
3340  } else if (gProofDebugLevel > 0) {
3341  Warning("SetupCommon", "no repository for staging requests available");
3342  }
3343  }
3344 
3345  // Quotas
3346  TString quotas = gEnv->GetValue(TString::Format("ProofServ.UserQuotas.%s", fUser.Data()),"");
3347  if (quotas.IsNull())
3348  quotas = gEnv->GetValue(TString::Format("ProofServ.UserQuotasByGroup.%s", fGroup.Data()),"");
3349  if (quotas.IsNull())
3350  quotas = gEnv->GetValue("ProofServ.UserQuotas", "");
3351  if (!quotas.IsNull()) {
3352  // Parse it; format ("maxquerykept=10 hwmsz=800m maxsz=1g")
3353  TString tok;
3354  Ssiz_t from = 0;
3355  while (quotas.Tokenize(tok, from, " ")) {
3356  // Set max number of query results to keep
3357  if (tok.BeginsWith("maxquerykept=")) {
3358  tok.ReplaceAll("maxquerykept=","");
3359  if (tok.IsDigit())
3360  fMaxQueries = tok.Atoi();
3361  else
3362  Info("SetupCommon",
3363  "parsing 'maxquerykept' :ignoring token %s : not a digit", tok.Data());
3364  }
3365  // Set High-Water-Mark or max on the sandbox size
3366  const char *ksz[2] = {"hwmsz=", "maxsz="};
3367  for (Int_t j = 0; j < 2; j++) {
3368  if (tok.BeginsWith(ksz[j])) {
3369  tok.ReplaceAll(ksz[j],"");
3370  Long64_t fact = -1;
3371  if (!tok.IsDigit()) {
3372  // Parse (k, m, g)
3373  tok.ToLower();
3374  const char *s[3] = {"k", "m", "g"};
3375  Int_t i = 0, k = 1024;
3376  while (fact < 0) {
3377  if (tok.EndsWith(s[i]))
3378  fact = k;
3379  else
3380  k *= 1024;
3381  }
3382  tok.Remove(tok.Length()-1);
3383  }
3384  if (tok.IsDigit()) {
3385  if (j == 0)
3386  fHWMBoxSize = (fact > 0) ? tok.Atoi() * fact : tok.Atoi();
3387  else
3388  fMaxBoxSize = (fact > 0) ? tok.Atoi() * fact : tok.Atoi();
3389  } else {
3390  TString ssz(ksz[j], strlen(ksz[j])-1);
3391  Info("SetupCommon", "parsing '%s' : ignoring token %s", ssz.Data(), tok.Data());
3392  }
3393  }
3394  }
3395  }
3396  }
3397 
3398  // Apply quotas, if any
3399  if (IsMaster() && fQMgr)
3400  if (fQMgr->ApplyMaxQueries(fMaxQueries) != 0)
3401  Warning("SetupCommon", "problems applying fMaxQueries");
3402 
3403  // Send "ROOTversion|ArchCompiler" flag
3404  if (fProtocol > 12) {
3405  TString vac = gROOT->GetVersion();
3406  vac += TString::Format(":%s", gROOT->GetGitCommit());
3407  TString rtag = gEnv->GetValue("ProofServ.RootVersionTag", "");
3408  if (rtag.Length() > 0)
3409  vac += TString::Format(":%s", rtag.Data());
3412  m << vac;
3413  fSocket->Send(m);
3414  }
3415 
3416  // Set user vars in TProof
3417  TString all_vars(gSystem->Getenv("PROOF_ALLVARS"));
3418  TString name;
3419  Int_t from = 0;
3420  while (all_vars.Tokenize(name, from, ",")) {
3421  if (!name.IsNull()) {
3422  TString value = gSystem->Getenv(name);
3423  TProof::AddEnvVar(name, value);
3424  }
3425  }
3426 
3427  if (fgLogToSysLog > 0) {
3428  // Set the syslog entity (all the information is available now)
3429  if (!(fUser.IsNull()) && !(fGroup.IsNull())) {
3430  fgSysLogEntity.Form("%s:%s", fUser.Data(), fGroup.Data());
3431  } else if (!(fUser.IsNull()) && fGroup.IsNull()) {
3432  fgSysLogEntity.Form("%s:default", fUser.Data());
3433  } else if (fUser.IsNull() && !(fGroup.IsNull())) {
3434  fgSysLogEntity.Form("undef:%s", fGroup.Data());
3435  }
3436  // Log the beginning of this session
3437  TString s;
3438  s.Form("%s 0 %.3f %.3f", fgSysLogEntity.Data(), fRealTime, fCpuTime);
3439  gSystem->Syslog(kLogNotice, s.Data());
3440  }
3441 
3442  if (gProofDebugLevel > 0)
3443  Info("SetupCommon", "successfully completed");
3444 
3445  // Done
3446  return 0;
3447 }
3448 
3449 ////////////////////////////////////////////////////////////////////////////////
3450 /// Terminate the proof server.
3451 
3453 {
3454  if (fgLogToSysLog > 0) {
3455  TString s;
3456  s.Form("%s -1 %.3f %.3f %d", fgSysLogEntity.Data(), fRealTime, fCpuTime, status);
3457  gSystem->Syslog(kLogNotice, s.Data());
3458  }
3459 
3460  // Notify the memory footprint
3461  ProcInfo_t pi;
3462  if (!gSystem->GetProcInfo(&pi)){
3463  Info("Terminate", "process memory footprint: %ld/%ld kB virtual, %ld/%ld kB resident ",
3465  }
3466 
3467  // Cleanup session directory
3468  if (status == 0) {
3469  // make sure we remain in a "connected" directory
3470  gSystem->ChangeDirectory("/");
3471  // needed in case fSessionDir is on NFS ?!
3472  gSystem->MakeDirectory(fSessionDir+"/.delete");
3474  }
3475 
3476  // Cleanup queries directory if empty
3477  if (IsMaster()) {
3478  if (!(fQMgr && fQMgr->Queries() && fQMgr->Queries()->GetSize())) {
3479  // make sure we remain in a "connected" directory
3480  gSystem->ChangeDirectory("/");
3481  // needed in case fQueryDir is on NFS ?!
3482  gSystem->MakeDirectory(fQueryDir+"/.delete");
3483  gSystem->Exec(TString::Format("%s %s", kRM, fQueryDir.Data()));
3484  // Remove lock file
3485  if (fQueryLock)
3487  }
3488 
3489  // Unlock the query dir owned by this session
3490  if (fQueryLock)
3491  fQueryLock->Unlock();
3492  }
3493 
3494  // Cleanup data directory if empty
3496  if (UnlinkDataDir(fDataDir))
3497  Info("Terminate", "data directory '%s' has been removed", fDataDir.Data());
3498  }
3499 
3500  // Remove input handler to avoid spurious signals in socket
3501  // selection for closing activities executed upon exit()
3503  TObject *fh = 0;
3504  while ((fh = next())) {
3505  TProofServInputHandler *ih = dynamic_cast<TProofServInputHandler *>(fh);
3506  if (ih)
3508  }
3509 
3510  // Stop processing events
3511  gSystem->ExitLoop();
3512 
3513  // Exit() is called in pmain
3514 }
3515 
3516 ////////////////////////////////////////////////////////////////////////////////
3517 /// Scan recursively the datadir and unlink it if empty
3518 /// Return kTRUE if it can be unlinked, kFALSE otherwise
3519 
3521 {
3522  if (!path || strlen(path) <= 0) return kFALSE;
3523 
3524  Bool_t dorm = kTRUE;
3525  void *dirp = gSystem->OpenDirectory(path);
3526  if (dirp) {
3527  TString fpath;
3528  const char *ent = 0;
3529  while (dorm && (ent = gSystem->GetDirEntry(dirp))) {
3530  if (!strcmp(ent, ".") || !strcmp(ent, "..")) continue;
3531  fpath.Form("%s/%s", path, ent);
3532  FileStat_t st;
3533  if (gSystem->GetPathInfo(fpath, st) == 0 && R_ISDIR(st.fMode)) {
3534  dorm = UnlinkDataDir(fpath);
3535  } else {
3536  dorm = kFALSE;
3537  }
3538  }
3539  // Close the directory
3540  gSystem->FreeDirectory(dirp);
3541  } else {
3542  // Cannot open the directory
3543  dorm = kFALSE;
3544  }
3545 
3546  // Do remove, if required
3547  if (dorm && gSystem->Unlink(path) != 0)
3548  Warning("UnlinkDataDir", "data directory '%s' is empty but could not be removed", path);
3549  // done
3550  return dorm;
3551 }
3552 
3553 ////////////////////////////////////////////////////////////////////////////////
3554 /// Static function that returns kTRUE in case we are a PROOF server.
3555 
3557 {
3558  return gProofServ ? kTRUE : kFALSE;
3559 }
3560 
3561 ////////////////////////////////////////////////////////////////////////////////
3562 /// Static function returning pointer to global object gProofServ.
3563 /// Mainly for use via CINT, where the gProofServ symbol might be
3564 /// deleted from the symbol table.
3565 
3567 {
3568  return gProofServ;
3569 }
3570 
3571 ////////////////////////////////////////////////////////////////////////////////
3572 /// Setup authentication related stuff for old versions.
3573 /// Provided for backward compatibility.
3574 
3576 {
3577  OldProofServAuthSetup_t oldAuthSetupHook = 0;
3578 
3579  if (!oldAuthSetupHook) {
3580  // Load libraries needed for (server) authentication ...
3581  TString authlib = "libRootAuth";
3582  char *p = 0;
3583  // The generic one
3584  if ((p = gSystem->DynamicPathName(authlib, kTRUE))) {
3585  delete[] p;
3586  if (gSystem->Load(authlib) == -1) {
3587  Error("OldAuthSetup", "can't load %s",authlib.Data());
3588  return kFALSE;
3589  }
3590  } else {
3591  Error("OldAuthSetup", "can't locate %s",authlib.Data());
3592  return -1;
3593  }
3594  //
3595  // Locate OldProofServAuthSetup
3596  Func_t f = gSystem->DynFindSymbol(authlib,"OldProofServAuthSetup");
3597  if (f)
3598  oldAuthSetupHook = (OldProofServAuthSetup_t)(f);
3599  else {
3600  Error("OldAuthSetup", "can't find OldProofServAuthSetup");
3601  return -1;
3602  }
3603  }
3604  //
3605  // Setup
3606  return (*oldAuthSetupHook)(fSocket, IsMaster(), fProtocol,
3607  fUser, fOrdinal, conf);
3608 }
3609 
3610 ////////////////////////////////////////////////////////////////////////////////
3611 /// Create a TProofQueryResult instance for this query.
3612 
3614  const char *opt,
3615  TList *inlist, Long64_t fst,
3616  TDSet *dset, const char *selec,
3617  TObject *elist)
3618 {
3619  // Increment sequential number
3620  Int_t seqnum = -1;
3621  if (fQMgr) {
3623  seqnum = fQMgr->SeqNum();
3624  }
3625 
3626  // Locally we always use the current streamer
3627  Bool_t olds = (dset && dset->TestBit(TDSet::kWriteV3)) ? kTRUE : kFALSE;
3628  if (olds)
3629  dset->SetWriteV3(kFALSE);
3630 
3631  // Create the instance and add it to the list
3632  TProofQueryResult *pqr = new TProofQueryResult(seqnum, opt, inlist, nent,
3633  fst, dset, selec, elist);
3634  // Title is the session identifier
3636 
3637  // Restore old streamer info
3638  if (olds)
3639  dset->SetWriteV3(kTRUE);
3640 
3641  return pqr;
3642 }
3643 
3644 ////////////////////////////////////////////////////////////////////////////////
3645 /// Set query in running state.
3646 
3648 {
3649  // Record current position in the log file at start
3650  fflush(stdout);
3651  Int_t startlog = lseek(fileno(stdout), (off_t) 0, SEEK_END);
3652 
3653  // Add some header to logs
3654  Printf(" ");
3655  Info("SetQueryRunning", "starting query: %d", pq->GetSeqNum());
3656 
3657  // Build the list of loaded PAR packages
3658  TString parlist = "";
3659  TIter nxp(fEnabledPackages);
3660  TPair *pck= 0;
3661  while ((pck = (TPair *)nxp())) {
3662  if (parlist.Length() <= 0)
3663  parlist = pck->GetName();
3664  else
3665  parlist += TString::Format(";%s", pck->GetName());
3666  }
3667 
3668  if (fProof) {
3669  // Set in running state
3670  pq->SetRunning(startlog, parlist, fProof->GetParallel());
3671 
3672  // Bytes and CPU at start (we will calculate the differential at end)
3673  pq->SetProcessInfo(pq->GetEntries(),
3675  } else {
3676  // Set in running state
3677  pq->SetRunning(startlog, parlist, -1);
3678 
3679  // Bytes and CPU at start (we will calculate the differential at end)
3680  pq->SetProcessInfo(pq->GetEntries(), float(0.), 0);
3681  }
3682 }
3683 
3684 ////////////////////////////////////////////////////////////////////////////////
3685 /// Handle archive request.
3686 
3688 {
3689  PDB(kGlobal, 1)
3690  Info("HandleArchive", "Enter");
3691 
3692  TString queryref;
3693  TString path;
3694  (*mess) >> queryref >> path;
3695 
3696  if (slb) slb->Form("%s %s", queryref.Data(), path.Data());
3697 
3698  // If this is a set default action just save the default
3699  if (queryref == "Default") {
3700  fArchivePath = path;
3701  Info("HandleArchive",
3702  "default path set to %s", fArchivePath.Data());
3703  return;
3704  }
3705 
3706  Int_t qry = -1;
3707  TString qdir;
3708  TProofQueryResult *pqr = fQMgr ? fQMgr->LocateQuery(queryref, qry, qdir) : 0;
3709  TProofQueryResult *pqm = pqr;
3710 
3711  if (path.Length() <= 0) {
3712  if (fArchivePath.Length() <= 0) {
3713  Info("HandleArchive",
3714  "archive paths are not defined - do nothing");
3715  return;
3716  }
3717  if (qry > 0) {
3718  path.Form("%s/session-%s-%d.root",
3719  fArchivePath.Data(), fTopSessionTag.Data(), qry);
3720  } else {
3721  path = queryref;
3722  path.ReplaceAll(":q","-");
3723  path.Insert(0, TString::Format("%s/",fArchivePath.Data()));
3724  path += ".root";
3725  }
3726  }
3727 
3728  // Build file name for specific query
3729  if (!pqr || qry < 0) {
3730  TString fout = qdir;
3731  fout += "/query-result.root";
3732 
3733  TFile *f = TFile::Open(fout,"READ");
3734  pqr = 0;
3735  if (f) {
3736  f->ReadKeys();
3737  TIter nxk(f->GetListOfKeys());
3738  TKey *k = 0;
3739  while ((k = (TKey *)nxk())) {
3740  if (!strcmp(k->GetClassName(), "TProofQueryResult")) {
3741  pqr = (TProofQueryResult *) f->Get(k->GetName());
3742  if (pqr)
3743  break;
3744  }
3745  }
3746  f->Close();
3747  delete f;
3748  } else {
3749  Info("HandleArchive",
3750  "file cannot be open (%s)",fout.Data());
3751  return;
3752  }
3753  }
3754 
3755  if (pqr) {
3756 
3757  PDB(kGlobal, 1) Info("HandleArchive",
3758  "archive path for query #%d: %s",
3759  qry, path.Data());
3760  TFile *farc = 0;
3761  if (gSystem->AccessPathName(path))
3762  farc = TFile::Open(path,"NEW");
3763  else
3764  farc = TFile::Open(path,"UPDATE");
3765  if (!farc || !(farc->IsOpen())) {
3766  Info("HandleArchive",
3767  "archive file cannot be open (%s)",path.Data());
3768  return;
3769  }
3770  farc->cd();
3771 
3772  // Update query status
3773  pqr->SetArchived(path);
3774  if (pqm)
3775  pqm->SetArchived(path);
3776 
3777  // Write to file
3778  pqr->Write();
3779 
3780  // Update temporary files too
3781  if (qry > -1 && fQMgr)
3782  fQMgr->SaveQuery(pqr);
3783 
3784  // Notify
3785  Info("HandleArchive",
3786  "results of query %s archived to file %s",
3787  queryref.Data(), path.Data());
3788  }
3789 
3790  // Done
3791  return;
3792 }
3793 
3794 ////////////////////////////////////////////////////////////////////////////////
3795 /// Get a map {server-name, list-of-files} for collection 'fc' to be used in
3796 /// TPacketizerFile. Returns a pointer to the map (ownership of the caller).
3797 /// Or (TMap *)0 and an error message in emsg.
3798 
3800 {
3801  TMap *fcmap = 0;
3802  emsg = "";
3803 
3804  // Sanity checks
3805  if (!fc) {
3806  emsg.Form("file collection undefined!");
3807  return fcmap;
3808  }
3809 
3810  // Prepare data set map
3811  fcmap = new TMap();
3812 
3813  TIter nxf(fc->GetList());
3814  TFileInfo *fiind = 0;
3815  TString key;
3816  while ((fiind = (TFileInfo *)nxf())) {
3817  TUrl *xurl = fiind->GetCurrentUrl();
3818  // Find the key for this server
3819  key.Form("%s://%s", xurl->GetProtocol(), xurl->GetHostFQDN());
3820  if (xurl->GetPort() > 0)
3821  key += TString::Format(":%d", xurl->GetPort());
3822  // Get the map entry for this key
3823  TPair *ent = 0;
3824  THashList* l = 0;
3825  if ((ent = (TPair *) fcmap->FindObject(key.Data()))) {
3826  // Attach to the list
3827  l = (THashList *) ent->Value();
3828  } else {
3829  // Create list
3830  l = new THashList;
3831  l->SetOwner(kTRUE);
3832  // Add it to the map
3833  fcmap->Add(new TObjString(key.Data()), l);
3834  }
3835  // Add fileinfo with index to list
3836  l->Add(fiind);
3837  }
3838 
3839  // Done
3840  return fcmap;
3841 }
3842 
3843 ////////////////////////////////////////////////////////////////////////////////
3844 /// Handle processing request.
3845 
3847 {
3848  PDB(kGlobal, 1)
3849  Info("HandleProcess", "Enter");
3850 
3851  // Nothing to do for slaves if we are not idle
3852  if (!IsTopMaster() && !IsIdle())
3853  return;
3854 
3855  TDSet *dset;
3856  TString filename, opt;
3857  TList *input;
3858  Long64_t nentries, first;
3859  TEventList *evl = 0;
3860  TEntryList *enl = 0;
3861  Bool_t sync;
3862 
3863  (*mess) >> dset >> filename >> input >> opt >> nentries >> first >> evl >> sync;
3864  // Get entry list information, if any (support started with fProtocol == 15)
3865  if ((mess->BufferSize() > mess->Length()) && fProtocol > 14)
3866  (*mess) >> enl;
3867  Bool_t hasNoData = (!dset || dset->TestBit(TDSet::kEmpty)) ? kTRUE : kFALSE;
3868 
3869  // Priority to the entry list
3870  TObject *elist = (enl) ? (TObject *)enl : (TObject *)evl;
3871  if (enl && evl)
3872  // Cannot specify both at the same time
3873  SafeDelete(evl);
3874  if ((!hasNoData) && elist)
3875  dset->SetEntryList(elist);
3876 
3877  if (IsTopMaster()) {
3878 
3879  TString emsg;
3880  // Make sure the dataset contains the information needed
3881  if ((!hasNoData) && dset->GetListOfElements()->GetSize() == 0) {
3882  if (TProof::AssertDataSet(dset, input, fDataSetManager, emsg) != 0) {
3883  SendAsynMessage(TString::Format("AssertDataSet on %s: %s",
3884  fPrefix.Data(), emsg.Data()));
3885  Error("HandleProcess", "AssertDataSet: %s", emsg.Data());
3886  // To terminate collection
3887  if (sync) SendLogFile();
3888  return;
3889  }
3890  } else if (hasNoData) {
3891  // Check if we are required to process with TPacketizerFile a registered dataset
3892  TNamed *ftp = dynamic_cast<TNamed *>(input->FindObject("PROOF_FilesToProcess"));
3893  if (ftp) {
3894  TString dsn(ftp->GetTitle());
3895  if (!dsn.Contains(":") || dsn.BeginsWith("dataset:")) {
3896  dsn.ReplaceAll("dataset:", "");
3897  // Get the map for TPacketizerFile
3898  // Make sure we have something in input and a dataset manager
3899  if (!fDataSetManager) {
3900  emsg.Form("dataset manager not initialized!");
3901  } else {
3902  TFileCollection *fc = 0;
3903  // Get the dataset
3904  if (!(fc = fDataSetManager->GetDataSet(dsn))) {
3905  emsg.Form("requested dataset '%s' does not exists", dsn.Data());
3906  } else {
3907  TMap *fcmap = GetDataSetNodeMap(fc, emsg);
3908  if (fcmap) {
3909  input->Remove(ftp);
3910  delete ftp;
3911  fcmap->SetOwner(kTRUE);
3912  fcmap->SetName("PROOF_FilesToProcess");
3913  input->Add(fcmap);
3914  }
3915  }
3916  }
3917  if (!emsg.IsNull()) {
3918  SendAsynMessage(TString::Format("HandleProcess on %s: %s",
3919  fPrefix.Data(), emsg.Data()));
3920  Error("HandleProcess", "%s", emsg.Data());
3921  // To terminate collection
3922  if (sync) SendLogFile();
3923  return;
3924  }
3925  }
3926  }
3927  }
3928 
3929  TProofQueryResult *pq = 0;
3930 
3931  // Create instance of query results; we set ownership of the input list
3932  // to the TQueryResult object, to avoid too many instantiations
3933  pq = MakeQueryResult(nentries, opt, 0, first, 0, filename, 0);
3934 
3935  // Prepare the input list and transfer it into the TQueryResult object
3936  if (dset) input->Add(dset);
3937  if (elist) input->Add(elist);
3938  pq->SetInputList(input, kTRUE);
3939 
3940  // Clear the list
3941  input->Clear("nodelete");
3942  SafeDelete(input);
3943 
3944  // Save input data, if any
3945  if (TProof::SaveInputData(pq, fCacheDir.Data(), emsg) != 0)
3946  Warning("HandleProcess", "could not save input data: %s", emsg.Data());
3947 
3948  // If not a draw action add the query to the main list
3949  if (!(pq->IsDraw())) {
3950  if (fQMgr) {
3951  if (fQMgr->Queries()) fQMgr->Queries()->Add(pq);
3952  // Also save it to queries dir
3953  fQMgr->SaveQuery(pq);
3954  }
3955  }
3956 
3957  // Add anyhow to the waiting lists
3958  QueueQuery(pq);
3959 
3960  // Call get Workers
3961  // if we are not idle the scheduler will just enqueue the query and
3962  // send a resume message later.
3963 
3964  Bool_t enqueued = kFALSE;
3965  Int_t pc = 0;
3966  // if the session does not have workers and is in the dynamic mode
3967  if (fProof->UseDynamicStartup()) {
3968  // get the a list of workers and start them
3969  TList* workerList = new TList();
3970  EQueryAction retVal = GetWorkers(workerList, pc);
3971  if (retVal == TProofServ::kQueryStop) {
3972  Error("HandleProcess", "error getting list of worker nodes");
3973  // To terminate collection
3974  if (sync) SendLogFile();
3975  return;
3976  } else if (retVal == TProofServ::kQueryEnqueued) {
3977  // change to an asynchronous query
3978  enqueued = kTRUE;
3979  Info("HandleProcess", "query %d enqueued", pq->GetSeqNum());
3980  } else if (Int_t ret = fProof->AddWorkers(workerList) < 0) {
3981  Error("HandleProcess", "Adding a list of worker nodes returned: %d",
3982  ret);
3983  // To terminate collection
3984  if (sync) SendLogFile();
3985  return;
3986  }
3987  } else {
3988  EQueryAction retVal = GetWorkers(0, pc);
3989  if (retVal == TProofServ::kQueryStop) {
3990  Error("HandleProcess", "error getting list of worker nodes");
3991  // To terminate collection
3992  if (sync) SendLogFile();
3993  return;
3994  } else if (retVal == TProofServ::kQueryEnqueued) {
3995  // change to an asynchronous query
3996  enqueued = kTRUE;
3997  Info("HandleProcess", "query %d enqueued", pq->GetSeqNum());
3998  } else if (retVal != TProofServ::kQueryOK) {
3999  Error("HandleProcess", "unknown return value: %d", retVal);
4000  // To terminate collection
4001  if (sync) SendLogFile();
4002  return;
4003  }
4004  }
4005 
4006  // If the client submission was asynchronous, signal the submission of
4007  // the query and communicate the assigned sequential number for later
4008  // identification
4010  if (!sync || enqueued) {
4011  m << pq->GetSeqNum() << kFALSE;
4012  fSocket->Send(m);
4013  }
4014 
4015  // Nothing more to do if we are not idle
4016  if (!IsIdle()) {
4017  // Notify submission
4018  Info("HandleProcess",
4019  "query \"%s:%s\" submitted", pq->GetTitle(), pq->GetName());
4020  return;
4021  }
4022 
4023  // Process
4024  // in the static mode, if a session is enqueued it will be processed after current query
4025  // (there is no way to enqueue if idle).
4026  // in the dynamic mode we will process here only if the session was idle and got workers!
4027  Bool_t doprocess = kFALSE;
4028  while (WaitingQueries() > 0 && !enqueued) {
4029  doprocess = kTRUE;
4030  //
4031  ProcessNext(slb);
4032  // avoid processing async queries sent during processing in dyn mode
4033  if (fProof->UseDynamicStartup())
4034  enqueued = kTRUE;
4035 
4036  } // Loop on submitted queries
4037 
4038  // Set idle
4039  SetIdle(kTRUE);
4040 
4041  // Reset mergers
4042  fProof->ResetMergers();
4043 
4044  // kPROOF_SETIDLE sets the client to idle; in asynchronous mode clients monitor
4045  // TProof::IsIdle for to check the readiness of a query, so we need to send this
4046  // before to be sure thatn everything about a query is received by the client
4047  if (!sync) SendLogFile();
4048 
4049  // Signal the client that we are idle
4050  if (doprocess) {
4051  m.Reset(kPROOF_SETIDLE);
4052  Bool_t waiting = (WaitingQueries() > 0) ? kTRUE : kFALSE;
4053  m << waiting;
4054  fSocket->Send(m);
4055  }
4056 
4057  // In synchronous mode TProof::Collect is terminated by the reception of the
4058  // log file and subsequent submissions are controlled by TProof::IsIdle(), so
4059  // this must be last one to be sent
4060  if (sync) SendLogFile();
4061 
4062  // Set idle
4063  SetIdle(kTRUE);
4064 
4065  } else {
4066 
4067  // Reset compute stopwatch: we include all what done from now on
4068  fCompute.Reset();
4069  fCompute.Start();
4070 
4071  // Set not idle
4072  SetIdle(kFALSE);
4073 
4074  // Cleanup the player
4075  Bool_t deleteplayer = kTRUE;
4076  MakePlayer();
4077 
4078  // Setup data set
4079  if (dset && (dset->IsA() == TDSetProxy::Class()))
4080  ((TDSetProxy*)dset)->SetProofServ(this);
4081 
4082  // Get input data, if any
4083  TString emsg;
4084  if (TProof::GetInputData(input, fCacheDir.Data(), emsg) != 0)
4085  Warning("HandleProcess", "could not get input data: %s", emsg.Data());
4086 
4087  // Get query sequential number
4088  if (TProof::GetParameter(input, "PROOF_QuerySeqNum", fQuerySeqNum) != 0)
4089  Warning("HandleProcess", "could not get query sequential number!");
4090 
4091  // Make the ordinal number available in the selector
4092  TObject *nord = 0;
4093  while ((nord = input->FindObject("PROOF_Ordinal")))
4094  input->Remove(nord);
4095  input->Add(new TNamed("PROOF_Ordinal", GetOrdinal()));
4096 
4097  // Set input
4098  TIter next(input);
4099  TObject *o = 0;
4100  while ((o = next())) {
4101  PDB(kGlobal, 2) Info("HandleProcess", "adding: %s", o->GetName());
4102  fPlayer->AddInput(o);
4103  }
4104 
4105  // Check if a TSelector object is passed via input list
4106  TObject *obj = 0;
4107  TSelector *selector_obj = 0;
4108  TIter nxt(input);
4109  while ((obj = nxt())){
4110  if (obj->InheritsFrom("TSelector")) {
4111  selector_obj = (TSelector *) obj;
4112  filename = selector_obj->ClassName();
4113  Info("HandleProcess", "selector obj for '%s' found", selector_obj->ClassName());
4114  break;
4115  }
4116  }
4117 
4118  // Signal the master that we are starting processing
4120 
4121  // Reset latency stopwatch
4122  fLatency.Reset();
4123  fSaveOutput.Reset();
4124 
4125  // Process
4126  PDB(kGlobal, 1) Info("HandleProcess", "calling %s::Process()", fPlayer->IsA()->GetName());
4127 
4128  if (selector_obj){
4129  Info("HandleProcess", "calling fPlayer->Process() with selector object: %s", selector_obj->ClassName());
4130  fPlayer->Process(dset, selector_obj, opt, nentries, first);
4131  }
4132  else {
4133  Info("HandleProcess", "calling fPlayer->Process() with selector name: %s", filename.Data());
4134  fPlayer->Process(dset, filename, opt, nentries, first);
4135  }
4136 
4137  // Return number of events processed
4140  if (fProtocol > 18) {
4141  TProofProgressStatus* status =
4143  gPerfStats?gPerfStats->GetBytesRead():0);
4144  if (status)
4145  m << status << abort;
4146  if (slb)
4147  slb->Form("%d %lld %lld", fPlayer->GetExitStatus(),
4148  status->GetEntries(), status->GetBytesRead());
4149  SafeDelete(status);
4150  } else {
4151  m << fPlayer->GetEventsProcessed() << abort;
4152  if (slb)
4153  slb->Form("%d %lld -1", fPlayer->GetExitStatus(), fPlayer->GetEventsProcessed());
4154  }
4155 
4156  fSocket->Send(m);
4157  PDB(kGlobal, 2)
4158  Info("TProofServ::Handleprocess",
4159  "worker %s has finished processing with %d objects in output list",
4161 
4162  // Cleanup the input data set info
4163  SafeDelete(dset);
4164  SafeDelete(enl);
4165  SafeDelete(evl);
4166 
4169  if (outok) {
4170  // Check if in controlled output sending mode or submerging
4171  Int_t cso = 0;
4172  Bool_t isSubMerging = kFALSE;
4173 
4174  // Check if we are in merging mode (i.e. parameter PROOF_UseMergers exists)
4175  Int_t nm = 0;
4176  if (TProof::GetParameter(input, "PROOF_UseMergers", nm) == 0) {
4177  isSubMerging = (nm >= 0) ? kTRUE : kFALSE;
4178  }
4179  if (!isSubMerging) {
4180  cso = gEnv->GetValue("Proof.ControlSendOutput", 1);
4181  if (TProof::GetParameter(input, "PROOF_ControlSendOutput", cso) != 0)
4182  cso = gEnv->GetValue("Proof.ControlSendOutput", 1);
4183  }
4184 
4185  if (cso > 0) {
4186 
4187  // Control output sending mode: wait for the master to ask for the objects.
4188  // Allows controls of memory usage on the master.
4190  fSocket->Send(msg);
4191 
4192  // Set idle
4193  SetIdle(kTRUE);
4194 
4195  // Do not cleanup the player yet: it will be used in sending output activities
4196  deleteplayer = kFALSE;
4197 
4198  PDB(kGlobal, 1)
4199  Info("HandleProcess", "controlled mode: worker %s has finished,"
4200  " sizes sent to master", fOrdinal.Data());
4201  } else {
4202 
4203  // Check if we are in merging mode (i.e. parameter PROOF_UseMergers exists)
4205  if (isSubMerging)
4206  Info("HandleProcess", "submerging disabled because of high-memory case");
4207  isSubMerging = kFALSE;
4208  } else {
4209  PDB(kGlobal, 2) Info("HandleProcess", "merging mode check: %d", isSubMerging);
4210  }
4211 
4212  if (!IsMaster() && isSubMerging) {
4213  // Worker in merging mode.
4214  //----------------------------
4215  // First, it reports only the size of its output to the master
4216  // + port on which it can possibly accept outputs from other workers if it becomes a merger
4217  // Master will later tell it where it should send the output (either to the master or to some merger)
4218  // or if it should become a merger
4219 
4220  TMessage msg_osize(kPROOF_SUBMERGER);
4221  msg_osize << Int_t(TProof::kOutputSize);
4222  msg_osize << fPlayer->GetOutputList()->GetEntries();
4223 
4224  fMergingSocket = new TServerSocket(0);
4225  Int_t merge_port = 0;
4226  if (fMergingSocket) {
4227  PDB(kGlobal, 2)
4228  Info("HandleProcess", "possible port for merging connections: %d",
4230  merge_port = fMergingSocket->GetLocalPort();
4231  }
4232  msg_osize << merge_port;
4233  fSocket->Send(msg_osize);
4234 
4235  // Set idle
4236  SetIdle(kTRUE);
4237 
4238  // Do not cleanup the player yet: it will be used in sub-merging activities
4239  deleteplayer = kFALSE;
4240 
4241  PDB(kSubmerger, 2) Info("HandleProcess", "worker %s has finished", fOrdinal.Data());
4242 
4243  } else {
4244  // Sub-master OR worker not in merging mode
4245  // ---------------------------------------------
4246  PDB(kGlobal, 2) Info("HandleProcess", "sending result directly to master");
4247  if (SendResults(fSocket, fPlayer->GetOutputList()) != 0)
4248  Warning("HandleProcess","problems sending output list");
4249 
4250  // Masters reset the mergers, if any
4251  if (IsMaster()) fProof->ResetMergers();
4252 
4253  // Signal the master that we are idle
4255 
4256  // Set idle
4257  SetIdle(kTRUE);
4258 
4259  // Notify the user
4260  SendLogFile();
4261  }
4262 
4263 
4264 
4265  }
4266 
4267  } else {
4268  // No output list
4270  Warning("HandleProcess","the output list is empty!");
4271  if (SendResults(fSocket) != 0)
4272  Warning("HandleProcess", "problems sending output list");
4273 
4274  // Masters reset the mergers, if any
4275  if (IsMaster()) fProof->ResetMergers();
4276 
4277  // Signal the master that we are idle
4279 
4280  // Set idle
4281  SetIdle(kTRUE);
4282 
4283  // Notify the user
4284  SendLogFile();
4285  }
4286 
4287  // Prevent from double-deleting in input
4288  TIter nex(input);
4289  while ((obj = nex())) {
4290  if (obj->InheritsFrom("TSelector")) input->Remove(obj);
4291  }
4292 
4293  // Make also sure the input list objects are deleted
4294  fPlayer->GetInputList()->SetOwner(0);
4295 
4296  // Remove possible inputs from a file and the file, if any
4297  TList *added = dynamic_cast<TList *>(input->FindObject("PROOF_InputObjsFromFile"));
4298  if (added) {
4299  if (added->GetSize() > 0) {
4300  // The file must be the last one
4301  TFile *f = dynamic_cast<TFile *>(added->Last());
4302  if (f) {
4303  added->Remove(f);
4304  TIter nxo(added);
4305  while ((o = nxo())) { input->Remove(o); }
4306  input->Remove(added);
4307  added->SetOwner(kFALSE);
4308  added->Clear();
4309  f->Close();
4310  delete f;
4311  }
4312  }
4313  SafeDelete(added);
4314  }
4315  input->SetOwner();
4316  SafeDelete(input);
4317 
4318  // Cleanup if required
4319  if (deleteplayer) DeletePlayer();
4320  }
4321 
4322  PDB(kGlobal, 1) Info("HandleProcess", "done");
4323 
4324  // Done
4325  return;
4326 }
4327 
4328 ////////////////////////////////////////////////////////////////////////////////
4329 /// Sends all objects from the given list to the specified socket
4330 
4332 {
4333  PDB(kOutput, 2) Info("SendResults", "enter");
4334 
4335  TString msg;
4336  if (fProtocol > 23 && outlist) {
4337  // Send objects in bunches of max fMsgSizeHWM bytes to optimize transfer
4338  // Objects are merged one-by-one by the client
4339  // Messages for objects
4341  // Objects in the output list
4342  Int_t olsz = outlist->GetSize();
4343  if (IsTopMaster() && pq) {
4344  msg.Form("%s: merging output objects ... done ",
4345  fPrefix.Data());
4346  SendAsynMessage(msg.Data());
4347  // Message for the client
4348  msg.Form("%s: objects merged; sending output: %d objs", fPrefix.Data(), olsz);
4349  SendAsynMessage(msg.Data(), kFALSE);
4350  // Send light query info
4351  mbuf << (Int_t) 0;
4352  mbuf.WriteObject(pq);
4353  if (sock->Send(mbuf) < 0) return -1;
4354  }
4355  // Objects in the output list
4356  Int_t ns = 0, np = 0;
4357  TIter nxo(outlist);
4358  TObject *o = 0;
4359  Int_t totsz = 0, objsz = 0;
4360  mbuf.Reset();
4361  while ((o = nxo())) {
4362  if (mbuf.Length() > fMsgSizeHWM) {
4363  PDB(kOutput, 1)
4364  Info("SendResults",
4365  "message has %d bytes: limit of %lld bytes reached - sending ...",
4366  mbuf.Length(), fMsgSizeHWM);
4367  // Compress the message, if required; for these messages we do it already
4368  // here so we get the size; TXSocket does not do it twice.
4369  if (GetCompressionLevel() > 0) {
4371  mbuf.Compress();
4372  objsz = mbuf.CompLength();
4373  } else {
4374  objsz = mbuf.Length();
4375  }
4376  totsz += objsz;
4377  if (IsTopMaster()) {
4378  msg.Form("%s: objects merged; sending obj %d/%d (%d bytes) ",
4379  fPrefix.Data(), ns, olsz, objsz);
4380  SendAsynMessage(msg.Data(), kFALSE);
4381  }
4382  if (sock->Send(mbuf) < 0) return -1;
4383  // Reset the message
4384  mbuf.Reset();
4385  np = 0;
4386  }
4387  ns++;
4388  np++;
4389  mbuf << (Int_t) ((ns >= olsz) ? 2 : 1);
4390  mbuf << o;
4391  }
4392  if (np > 0) {
4393  // Compress the message, if required; for these messages we do it already
4394  // here so we get the size; TXSocket does not do it twice.
4395  if (GetCompressionLevel() > 0) {
4397  mbuf.Compress();
4398  objsz = mbuf.CompLength();
4399  } else {
4400  objsz = mbuf.Length();
4401  }
4402  totsz += objsz;
4403  if (IsTopMaster()) {
4404  msg.Form("%s: objects merged; sending obj %d/%d (%d bytes) ",
4405  fPrefix.Data(), ns, olsz, objsz);
4406  SendAsynMessage(msg.Data(), kFALSE);
4407  }
4408  if (sock->Send(mbuf) < 0) return -1;
4409  }
4410  if (IsTopMaster()) {
4411  // Send total size
4412  msg.Form("%s: grand total: sent %d objects, size: %d bytes ",
4413  fPrefix.Data(), olsz, totsz);
4414  SendAsynMessage(msg.Data());
4415  }
4416  } else if (fProtocol > 10 && outlist) {
4417 
4418  // Send objects one-by-one to optimize transfer and merging
4419  // Messages for objects
4421  // Objects in the output list
4422  Int_t olsz = outlist->GetSize();
4423  if (IsTopMaster() && pq) {
4424  msg.Form("%s: merging output objects ... done ",
4425  fPrefix.Data());
4426  SendAsynMessage(msg.Data());
4427  // Message for the client
4428  msg.Form("%s: objects merged; sending output: %d objs", fPrefix.Data(), olsz);
4429  SendAsynMessage(msg.Data(), kFALSE);
4430  // Send light query info
4431  mbuf << (Int_t) 0;
4432  mbuf.WriteObject(pq);
4433  if (sock->Send(mbuf) < 0) return -1;
4434  }
4435 
4436  Int_t ns = 0;
4437  Int_t totsz = 0, objsz = 0;
4438  TIter nxo(fPlayer->GetOutputList());
4439  TObject *o = 0;
4440  while ((o = nxo())) {
4441  ns++;
4442  mbuf.Reset();
4443  Int_t type = (Int_t) ((ns >= olsz) ? 2 : 1);
4444  mbuf << type;
4445  mbuf.WriteObject(o);
4446  // Compress the message, if required; for these messages we do it already
4447  // here so we get the size; TXSocket does not do it twice.
4448  if (GetCompressionLevel() > 0) {
4450  mbuf.Compress();
4451  objsz = mbuf.CompLength();
4452  } else {
4453  objsz = mbuf.Length();
4454  }
4455  totsz += objsz;
4456  if (IsTopMaster()) {
4457  msg.Form("%s: objects merged; sending obj %d/%d (%d bytes) ",
4458  fPrefix.Data(), ns, olsz, objsz);
4459  SendAsynMessage(msg.Data(), kFALSE);
4460  }
4461  if (sock->Send(mbuf) < 0) return -1;
4462  }
4463  // Total size
4464  if (IsTopMaster()) {
4465  // Send total size
4466  msg.Form("%s: grand total: sent %d objects, size: %d bytes ",
4467  fPrefix.Data(), olsz, totsz);
4468  SendAsynMessage(msg.Data());
4469  }
4470 
4471  } else if (IsTopMaster() && fProtocol > 6 && outlist) {
4472 
4473  // Buffer to be sent
4475  mbuf.WriteObject(pq);
4476  // Sizes
4477  Int_t blen = mbuf.CompLength();
4478  Int_t olsz = outlist->GetSize();
4479  // Message for the client
4480  msg.Form("%s: sending output: %d objs, %d bytes", fPrefix.Data(), olsz, blen);
4481  SendAsynMessage(msg.Data(), kFALSE);
4482  if (sock->Send(mbuf) < 0) return -1;
4483 
4484  } else {
4485  if (outlist) {
4486  PDB(kGlobal, 2) Info("SendResults", "sending output list");
4487  } else {
4488  PDB(kGlobal, 2) Info("SendResults", "notifying failure or abort");
4489  }
4490  if (sock->SendObject(outlist, kPROOF_OUTPUTLIST) < 0) return -1;
4491  }
4492 
4493  PDB(kOutput,2) Info("SendResults", "done");
4494 
4495  // Done
4496  return 0;
4497 }
4498 
4499 ////////////////////////////////////////////////////////////////////////////////
4500 /// process the next query from the queue of submitted jobs.
4501 /// to be called on the top master only.
4502 
4504 {
4505  TDSet *dset = 0;
4506  TString filename, opt;
4507  TList *input = 0;
4508  Long64_t nentries = -1, first = 0;
4509 
4510  // TObject *elist = 0;
4511  TProofQueryResult *pq = 0;
4512 
4513  TObject* obj = 0;
4514  TSelector* selector_obj = 0;
4515 
4516  // Process
4517 
4518  // Reset compute stopwatch: we include all what done from now on
4519  fCompute.Reset();
4520  fCompute.Start();
4521 
4522  // Get next query info (also removes query from the list)
4523  pq = NextQuery();
4524  if (pq) {
4525 
4526  // Set not idle
4527  SetIdle(kFALSE);
4528  opt = pq->GetOptions();
4529  input = pq->GetInputList();
4530  nentries = pq->GetEntries();
4531  first = pq->GetFirst();
4532  filename = pq->GetSelecImp()->GetName();
4533  Ssiz_t id = opt.Last('#');
4534  if (id != kNPOS && id < opt.Length() - 1) {
4535  filename += opt(id + 1, opt.Length());
4536  // Remove it from 'opt' so user found on the workers what they specified
4537  opt.Remove(id);
4538  }
4539  // Attach to data set and entry- (or event-) list (if any)
4540  TObject *o = 0;
4541  if ((o = pq->GetInputObject("TDSet"))) {
4542  dset = (TDSet *) o;
4543  } else {
4544  // Should never get here
4545  Error("ProcessNext", "no TDset object: cannot continue");
4546  return;
4547  }
4548  // elist = 0;
4549  // if ((o = pq->GetInputObject("TEntryList")))
4550  // elist = o;
4551  // else if ((o = pq->GetInputObject("TEventList")))
4552  // elist = o;
4553 
4554  // Expand selector files
4555  if (pq->GetSelecImp()) {
4556  gSystem->Exec(TString::Format("%s %s", kRM, pq->GetSelecImp()->GetName()));
4557  pq->GetSelecImp()->SaveSource(pq->GetSelecImp()->GetName());
4558  }
4559  if (pq->GetSelecHdr() &&
4560  !strstr(pq->GetSelecHdr()->GetName(), "TProofDrawHist")) {
4561  gSystem->Exec(TString::Format("%s %s", kRM, pq->GetSelecHdr()->GetName()));
4562  pq->GetSelecHdr()->SaveSource(pq->GetSelecHdr()->GetName());
4563  }
4564 
4565  // Taking out a TSelector object from input list
4566  TIter nxt(input);
4567  while ((obj = nxt())){
4568  if (obj->InheritsFrom("TSelector") &&
4569  !strcmp(pq->GetSelecImp()->GetName(), obj->ClassName())) {
4570  selector_obj = (TSelector *) obj;
4571  Info("ProcessNext", "found object for selector '%s'", obj->ClassName());
4572  break;
4573  }
4574  }
4575 
4576  } else {
4577  // Should never get here
4578  Error("ProcessNext", "empty waiting queries list!");
4579  return;
4580  }
4581 
4582  // Set in running state
4583  SetQueryRunning(pq);
4584 
4585  // Save to queries dir, if not standard draw
4586  if (fQMgr) {
4587  if (!(pq->IsDraw()))
4588  fQMgr->SaveQuery(pq);
4589  else
4591  fQMgr->ResetTime();
4592  }
4593 
4594  // Signal the client that we are starting a new query
4596  m << TString(pq->GetSelecImp()->GetName())
4597  << dset->GetNumOfFiles()
4598  << pq->GetFirst() << pq->GetEntries();
4599  fSocket->Send(m);
4600 
4601  // Create player
4602  MakePlayer();
4603 
4604  // Add query results to the player lists
4605  fPlayer->AddQueryResult(pq);
4606 
4607  // Set query currently processed
4608  fPlayer->SetCurrentQuery(pq);
4609 
4610  // Setup data set
4611  if (dset->IsA() == TDSetProxy::Class())
4612  ((TDSetProxy*)dset)->SetProofServ(this);
4613 
4614  // Add the unique query tag as TNamed object to the input list
4615  // so that it is available in TSelectors for monitoring
4616  TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
4617  input->Add(new TNamed("PROOF_QueryTag", qid.Data()));
4618  // ... and the sequential number
4619  fQuerySeqNum = pq->GetSeqNum();
4620  input->Add(new TParameter<Int_t>("PROOF_QuerySeqNum", fQuerySeqNum));
4621 
4622  // Check whether we have to enforce the use of submergers, but only if the user did
4623  // not express itself on the subject
4624  if (gEnv->Lookup("Proof.UseMergers") && !input->FindObject("PROOF_UseMergers")) {
4625  Int_t smg = gEnv->GetValue("Proof.UseMergers",-1);
4626  if (smg >= 0) {
4627  input->Add(new TParameter<Int_t>("PROOF_UseMergers", smg));
4628  PDB(kSubmerger, 2) Info("ProcessNext", "PROOF_UseMergers set to %d", smg);
4629  if (gEnv->Lookup("Proof.MergersByHost")) {
4630  Int_t mbh = gEnv->GetValue("Proof.MergersByHost", 0);
4631  if (mbh != 0) {
4632  // Administrator settings have the priority
4633  TObject *o = 0;
4634  if ((o = input->FindObject("PROOF_MergersByHost"))) { input->Remove(o); delete o; }
4635  input->Add(new TParameter<Int_t>("PROOF_MergersByHost", mbh));
4636  PDB(kSubmerger, 2) Info("ProcessNext", "submergers setup by host/node");
4637  }
4638  }
4639  }
4640  }
4641 
4642  // Set input
4643  TIter next(input);
4644  TObject *o = 0;
4645  while ((o = next())) {
4646  PDB(kGlobal, 2) Info("ProcessNext", "adding: %s", o->GetName());
4647  fPlayer->AddInput(o);
4648  }
4649 
4650  // Remove the list of the missing files from the original list, if any
4651  if ((o = input->FindObject("MissingFiles"))) input->Remove(o);
4652 
4653  // Process
4654  PDB(kGlobal, 1) Info("ProcessNext", "calling %s::Process()", fPlayer->IsA()->GetName());
4655  if (selector_obj){
4656  Info("ProcessNext", "calling fPlayer->Process() with selector object: %s", selector_obj->ClassName());
4657  fPlayer->Process(dset, selector_obj, opt, nentries, first);
4658  }
4659  else {
4660  Info("ProcessNext", "calling fPlayer->Process() with selector name: %s", filename.Data());
4661  fPlayer->Process(dset, filename, opt, nentries, first);
4662  }
4663 
4664  // This is the end of merging
4666 
4667  // Return number of events processed
4668  Bool_t abort =
4672  // message sent from worker to the master
4673  if (fProtocol > 18) {
4675  m << status << abort;
4676  status = 0; // the status belongs to the player.
4677  } else if (fProtocol > 8) {
4678  m << fPlayer->GetEventsProcessed() << abort;
4679  } else {
4680  m << fPlayer->GetEventsProcessed();
4681  }
4682  fSocket->Send(m);
4683  }
4684 
4685  // Register any dataset produced during this processing, if required
4687  TNamed *psr = (TNamed *) fPlayer->GetOutputList()->FindObject("PROOFSERV_RegisterDataSet");
4688  if (psr) {
4689  TString emsg;
4690  if (RegisterDataSets(input, fPlayer->GetOutputList(), fDataSetManager, emsg) != 0)
4691  Warning("ProcessNext", "problems registering produced datasets: %s", emsg.Data());
4692  do {
4693  fPlayer->GetOutputList()->Remove(psr);
4694  delete psr;
4695  } while ((psr = (TNamed *) fPlayer->GetOutputList()->FindObject("PROOFSERV_RegisterDataSet")));
4696  }
4697  }
4698 
4699  // Complete filling of the TQueryResult instance
4700  if (fQMgr && !pq->IsDraw()) {
4701  if (!abort) fProof->AskStatistics();
4702  if (fQMgr->FinalizeQuery(pq, fProof, fPlayer))
4703  fQMgr->SaveQuery(pq, fMaxQueries);
4704  }
4705 
4706  // If we were requested to save results on the master and we are not in save-to-file mode
4707  // then we save the results
4708  if (IsTopMaster() && fPlayer->GetOutputList()) {
4709  Bool_t save = kTRUE;
4710  TIter nxo(fPlayer->GetOutputList());
4711  TObject *xo = 0;
4712  while ((xo = nxo())) {
4713  if (xo->InheritsFrom("TProofOutputFile") && xo->TestBit(TProofOutputFile::kSwapFile)) {
4714  save = kFALSE;
4715  break;
4716  }
4717  }
4718  if (save) {
4719  TNamed *nof = (TNamed *) input->FindObject("PROOF_DefaultOutputOption");
4720  if (nof) {
4721  TString oopt(nof->GetTitle());
4722  if (oopt.BeginsWith("of:")) {
4723  oopt.Replace(0, 3, "");
4724  if (!oopt.IsNull()) fPlayer->SetOutputFilePath(oopt);
4726  }
4727  }
4728  }
4729  }
4730 
4731  // Send back the results
4732  TQueryResult *pqr = pq->CloneInfo();
4733  // At least the TDSet name in the light object
4734  Info("ProcessNext", "adding info about dataset '%s' in the light query result", dset->GetName());
4735  TList rin;
4736  TDSet *ds = new TDSet(dset->GetName(), dset->GetObjName());
4737  rin.Add(ds);
4738  if (pqr) pqr->SetInputList(&rin, kTRUE);
4740  PDB(kGlobal, 2)
4741  Info("ProcessNext", "sending results");
4742  TQueryResult *xpq = (pqr && fProtocol > 10) ? pqr : pq;
4743  if (SendResults(fSocket, fPlayer->GetOutputList(), xpq) != 0)
4744  Warning("ProcessNext", "problems sending output list");
4745  if (slb) slb->Form("%d %lld %lld %.3f", fPlayer->GetExitStatus(), pq->GetEntries(),
4746  pq->GetBytes(), pq->GetUsedCPU());
4747  } else {
4749  Warning("ProcessNext","the output list is empty!");
4750  if (SendResults(fSocket, fPlayer->GetOutputList()) != 0)
4751  Warning("ProcessNext", "problems sending output list");
4752  if (slb) slb->Form("%d -1 -1 %.3f", fPlayer->GetExitStatus(), pq->GetUsedCPU());
4753  }
4754 
4755  // Remove aborted queries from the list
4757  if (pqr) SafeDelete(pqr);
4758  if (fQMgr) fQMgr->RemoveQuery(pq);
4759  } else {
4760  // Keep in memory only light infor about a query
4761  if (!(pq->IsDraw()) && pqr) {
4762  if (fQMgr && fQMgr->Queries()) {
4763  fQMgr->Queries()->Add(pqr);
4764  // Remove from the fQueries list
4765  fQMgr->Queries()->Remove(pq);
4766  }
4767  // These removes 'pq' from the internal player list and
4768  // deletes it; in this way we do not attempt a double delete
4769  // when destroying the player
4771  pq->GetTitle(), pq->GetName()));
4772  }
4773  }
4774 
4775  DeletePlayer();
4776  if (IsMaster() && fProof->UseDynamicStartup())
4777  // stop the workers
4778  fProof->RemoveWorkers(0);
4779 }
4780 
4781 ////////////////////////////////////////////////////////////////////////////////
4782 /// Register TFileCollections in 'out' as datasets according to the rules in 'in'
4783 
4785  TDataSetManager *dsm, TString &msg)
4786 {
4787  PDB(kDataset, 1)
4788  ::Info("TProofServ::RegisterDataSets",
4789  "enter: %d objs in the output list", (out ? out->GetSize() : -1));
4790 
4791  if (!in || !out || !dsm) {
4792  ::Error("TProofServ::RegisterDataSets", "invalid inputs: %p, %p, %p", in, out, dsm);
4793  return 0;
4794  }
4795  msg = "";
4796  THashList tags;
4797  TList torm;
4798  TIter nxo(out);
4799  TObject *o = 0;
4800  while ((o = nxo())) {
4801  // Only file collections TFileCollection
4802  TFileCollection *ds = dynamic_cast<TFileCollection*> (o);
4803  if (ds) {
4804  // Origin of this dataset
4805  ds->SetTitle(gSystem->HostName());
4806  // The tag and register option
4807  TNamed *fcn = 0;
4808  TString tag = TString::Format("DATASET_%s", ds->GetName());
4809  if (!(fcn = (TNamed *) out->FindObject(tag))) continue;
4810  // If this tag is in the list of processed tags, flag it for removal
4811  if (tags.FindObject(tag)) {
4812  torm.Add(o);
4813  continue;
4814  }
4815  // Register option
4816  TString regopt(fcn->GetTitle());
4817  // Sort according to the internal index, if required
4818  if (regopt.Contains(":sortidx:")) {
4819  ds->Sort(kTRUE);
4820  regopt.ReplaceAll(":sortidx:", "");
4821  }
4822  // Register this dataset
4824  // Extract the list
4825  if (ds->GetList()->GetSize() > 0) {
4826  // Register the dataset (quota checks are done inside here)
4827  const char *vfmsg = regopt.Contains("V") ? " and verifying" : "";
4828  msg.Form("Registering%s dataset '%s' ... ", vfmsg, ds->GetName());
4829  // Always allow verification for this action
4830  Bool_t allowVerify = dsm->TestBit(TDataSetManager::kAllowVerify) ? kTRUE : kFALSE;
4831  if (regopt.Contains("V") && !allowVerify) dsm->SetBit(TDataSetManager::kAllowVerify);
4832  // Main action
4833  Int_t rc = dsm->RegisterDataSet(ds->GetName(), ds, regopt);
4834  // Reset to the previous state if needed
4835  if (regopt.Contains("V") && !allowVerify) dsm->ResetBit(TDataSetManager::kAllowVerify);
4836  if (rc != 0) {
4837  ::Warning("TProofServ::RegisterDataSets",
4838  "failure registering or verifying dataset '%s'", ds->GetName());
4839  msg.Form("Registering%s dataset '%s' ... failed! See log for more details", vfmsg, ds->GetName());
4840  } else {
4841  ::Info("TProofServ::RegisterDataSets", "dataset '%s' successfully registered%s",
4842  ds->GetName(), (strlen(vfmsg) > 0) ? " and verified" : "");
4843  msg.Form("Registering%s dataset '%s' ... OK", vfmsg, ds->GetName());
4844  // Add tag to the list of processed tags to avoid double processing
4845  // (there may be more objects with the same name, created by each worker)
4846  tags.Add(new TObjString(tag));
4847  }
4848  // Notify
4849  PDB(kDataset, 2) {
4850  ::Info("TProofServ::RegisterDataSets", "printing collection");
4851  ds->Print("F");
4852  }
4853  } else {
4854  ::Warning("TProofServ::RegisterDataSets", "collection '%s' is empty", o->GetName());
4855  }
4856  } else {
4857  ::Info("TProofServ::RegisterDataSets", "dataset registration not allowed");
4858  return -1;
4859  }
4860  }
4861  }
4862  // Cleanup all temporary stuff possibly created by each worker
4863  TIter nxrm(&torm);
4864  while ((o = nxrm())) out->Remove(o);
4865  torm.SetOwner(kTRUE);
4866  // Remove tags
4867  TIter nxtg(&tags);
4868  while((o = nxtg())) {
4869  TObject *oo = 0;
4870  while ((oo = out->FindObject(o->GetName()))) { out->Remove(oo); }
4871  }
4872  tags.SetOwner(kTRUE);
4873 
4874  PDB(kDataset, 1) ::Info("TProofServ::RegisterDataSets", "exit");
4875  // Done
4876  return 0;
4877 }
4878 
4879 ////////////////////////////////////////////////////////////////////////////////
4880 /// Handle request for list of queries.
4881 
4883 {
4884  PDB(kGlobal, 1)
4885  Info("HandleQueryList", "Enter");
4886 
4887  Bool_t all;
4888  (*mess) >> all;
4889 
4890  TList *ql = new TList;
4891  Int_t ntot = 0, npre = 0, ndraw= 0;
4892  if (fQMgr) {
4893  if (all) {
4894  // Rescan
4895  TString qdir = fQueryDir;
4896  Int_t idx = qdir.Index("session-");
4897  if (idx != kNPOS)
4898  qdir.Remove(idx);
4899  fQMgr->ScanPreviousQueries(qdir);
4900  // Send also information about previous queries, if any
4901  if (fQMgr->PreviousQueries()) {
4902  TIter nxq(fQMgr->PreviousQueries());
4903  TProofQueryResult *pqr = 0;
4904  while ((pqr = (TProofQueryResult *)nxq())) {
4905  ntot++;
4906  pqr->fSeqNum = ntot;
4907  ql->Add(pqr);
4908  }
4909  }
4910  }
4911 
4912  npre = ntot;
4913  if (fQMgr->Queries()) {
4914  // Add info about queries in this session
4915  TIter nxq(fQMgr->Queries());
4916  TProofQueryResult *pqr = 0;
4917  TQueryResult *pqm = 0;
4918  while ((pqr = (TProofQueryResult *)nxq())) {
4919  ntot++;
4920  if ((pqm = pqr->CloneInfo())) {
4921  pqm->fSeqNum = ntot;
4922  ql->Add(pqm);
4923  } else {
4924  Warning("HandleQueryList", "unable to clone TProofQueryResult '%s:%s'",
4925  pqr->GetName(), pqr->GetTitle());
4926  }
4927  }
4928  }
4929  // Number of draw queries
4930  ndraw = fQMgr->DrawQueries();
4931  }
4932 
4934  m << npre << ndraw << ql;
4935  fSocket->Send(m);
4936  delete ql;
4937 
4938  // Done
4939  return;
4940 }
4941 
4942 ////////////////////////////////////////////////////////////////////////////////
4943 /// Handle remove request.
4944 
4946 {
4947  PDB(kGlobal, 1)
4948  Info("HandleRemove", "Enter");
4949 
4950  TString queryref;
4951  (*mess) >> queryref;
4952 
4953  if (slb) *slb = queryref;
4954 
4955  if (queryref == "cleanupqueue") {
4956  // Remove pending requests
4957  Int_t pend = CleanupWaitingQueries();
4958  // Notify
4959  Info("HandleRemove", "%d queries removed from the waiting list", pend);
4960  // We are done
4961  return;
4962  }
4963 
4964  if (queryref == "cleanupdir") {
4965 
4966  // Cleanup previous sessions results
4967  Int_t nd = (fQMgr) ? fQMgr->CleanupQueriesDir() : -1;
4968 
4969  // Notify
4970  Info("HandleRemove", "%d directories removed", nd);
4971  // We are done
4972  return;
4973  }
4974 
4975 
4976  if (fQMgr) {
4977  TProofLockPath *lck = 0;
4978  if (fQMgr->LockSession(queryref, &lck) == 0) {
4979 
4980  // Remove query
4981  TList qtorm;
4982  fQMgr->RemoveQuery(queryref, &qtorm);
4983  CleanupWaitingQueries(kFALSE, &qtorm);
4984 
4985  // Unlock and remove the lock file
4986  if (lck) {
4987  gSystem->Unlink(lck->GetName());
4988  SafeDelete(lck);
4989  }
4990 
4991  // We are done
4992  return;
4993  }
4994  } else {
4995  Warning("HandleRemove", "query result manager undefined!");
4996  }
4997 
4998  // Notify failure
4999  Info("HandleRemove",
5000  "query %s could not be removed (unable to lock session)", queryref.Data());
5001 
5002  // Done
5003  return;
5004 }
5005 
5006 ////////////////////////////////////////////////////////////////////////////////
5007 /// Handle retrieve request.
5008 
5010 {
5011  PDB(kGlobal, 1)
5012  Info("HandleRetrieve", "Enter");
5013 
5014  TString queryref;
5015  (*mess) >> queryref;
5016 
5017  if (slb) *slb = queryref;
5018 
5019  // Parse reference string
5020  Int_t qry = -1;
5021  TString qdir;
5022  if (fQMgr) fQMgr->LocateQuery(queryref, qry, qdir);
5023 
5024  TString fout = qdir;
5025  fout += "/query-result.root";
5026 
5027  TFile *f = TFile::Open(fout,"READ");
5028  TProofQueryResult *pqr = 0;
5029  if (f) {
5030  f->ReadKeys();
5031  TIter nxk(f->GetListOfKeys());
5032  TKey *k = 0;
5033  while ((k = (TKey *)nxk())) {
5034  if (!strcmp(k->GetClassName(), "TProofQueryResult")) {
5035  pqr = (TProofQueryResult *) f->Get(k->GetName());
5036  // For backward compatibility
5037  if (pqr && fProtocol < 13) {
5038  TDSet *d = 0;
5039  TObject *o = 0;
5040  TIter nxi(pqr->GetInputList());
5041  while ((o = nxi()))
5042  if ((d = dynamic_cast<TDSet *>(o)))
5043  break;
5044  d->SetWriteV3(kTRUE);
5045  }
5046  if (pqr) {
5047 
5048  // Message for the client
5049  Float_t qsz = (Float_t) f->GetSize();
5050  Int_t ilb = 0;
5051  static const char *clb[4] = { "bytes", "KB", "MB", "GB" };
5052  while (qsz > 1000. && ilb < 3) {
5053  qsz /= 1000.;
5054  ilb++;
5055  }
5056  SendAsynMessage(TString::Format("%s: sending result of %s:%s (%.1f %s)",
5057  fPrefix.Data(), pqr->GetTitle(), pqr->GetName(),
5058  qsz, clb[ilb]));
5060  } else {
5061  Info("HandleRetrieve",
5062  "query not found in file %s",fout.Data());
5063  // Notify not found
5065  }
5066  break;
5067  }
5068  }
5069  f->Close();
5070  delete f;
5071  } else {
5072  Info("HandleRetrieve",
5073  "file cannot be open (%s)",fout.Data());
5074  // Notify not found
5076  return;
5077  }
5078 
5079  // Done
5080  return;
5081 }
5082 
5083 ////////////////////////////////////////////////////////////////////////////////
5084 /// Handle lib, inc search paths modification request
5085 
5087 {
5088  TString type;
5089  Bool_t add;
5090  TString path;
5091  Int_t rc = 1;
5092  (*mess) >> type >> add >> path;
5093  if (mess->BufferSize() > mess->Length()) (*mess) >> rc;
5094 
5095  // Check type of action
5096  if ((type != "lib") && (type != "inc")) {
5097  Error("HandleLibIncPath","unknown action type: %s", type.Data());
5098  return rc;
5099  }
5100 
5101  // Separators can be either commas or blanks
5102  path.ReplaceAll(","," ");
5103 
5104  // Decompose lists
5105  TObjArray *op = 0;
5106  if (path.Length() > 0 && path != "-") {
5107  if (!(op = path.Tokenize(" "))) {
5108  Error("HandleLibIncPath","decomposing path %s", path.Data());
5109  return rc;
5110  }
5111  }
5112 
5113  if (add) {
5114 
5115  if (type == "lib") {
5116 
5117  // Add libs
5118  TIter nxl(op, kIterBackward);
5119  TObjString *lib = 0;
5120  while ((lib = (TObjString *) nxl())) {
5121  // Expand path
5122  TString xlib = lib->GetName();
5123  gSystem->ExpandPathName(xlib);
5124  // Add to the dynamic lib search path if it exists and can be read
5125  if (!gSystem->AccessPathName(xlib, kReadPermission)) {
5126  TString newlibpath = gSystem->GetDynamicPath();
5127  // In the first position after the working dir
5128  Int_t pos = 0;
5129  if (newlibpath.BeginsWith(".:"))
5130  pos = 2;
5131  if (newlibpath.Index(xlib) == kNPOS) {
5132  newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
5133  gSystem->SetDynamicPath(newlibpath);
5134  }
5135  } else {
5136  Info("HandleLibIncPath",
5137  "libpath %s does not exist or cannot be read - not added", xlib.Data());
5138  }
5139  }
5140 
5141  // Forward the request, if required
5142  if (IsMaster())
5143  fProof->AddDynamicPath(path);
5144 
5145  } else {
5146 
5147  // Add incs
5148  TIter nxi(op);
5149  TObjString *inc = 0;
5150  while ((inc = (TObjString *) nxi())) {
5151  // Expand path
5152  TString xinc = inc->GetName();
5153  gSystem->ExpandPathName(xinc);
5154  // Add to the dynamic lib search path if it exists and can be read
5155  if (!gSystem->AccessPathName(xinc, kReadPermission)) {
5156  TString curincpath = gSystem->GetIncludePath();
5157  if (curincpath.Index(xinc) == kNPOS)
5158  gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
5159  } else
5160  Info("HandleLibIncPath",
5161  "incpath %s does not exist or cannot be read - not added", xinc.Data());
5162  }
5163 
5164  // Forward the request, if required
5165  if (IsMaster())
5166  fProof->AddIncludePath(path);
5167  }
5168 
5169 
5170  } else {
5171 
5172  if (type == "lib") {
5173 
5174  // Remove libs
5175  TIter nxl(op);
5176  TObjString *lib = 0;
5177  while ((lib = (TObjString *) nxl())) {
5178  // Expand path
5179  TString xlib = lib->GetName();
5180  gSystem->ExpandPathName(xlib);
5181  // Remove from the dynamic lib search path
5182  TString newlibpath = gSystem->GetDynamicPath();
5183  newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
5184  gSystem->SetDynamicPath(newlibpath);
5185  }
5186 
5187  // Forward the request, if required
5188  if (IsMaster())
5189  fProof->RemoveDynamicPath(path);
5190 
5191  } else {
5192 
5193  // Remove incs
5194  TIter nxi(op);
5195  TObjString *inc = 0;
5196  while ((inc = (TObjString *) nxi())) {
5197  TString newincpath = gSystem->GetIncludePath();
5198  newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
5199  // Remove the interpreter path (added anyhow internally)
5200  newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
5201  gSystem->SetIncludePath(newincpath);
5202  }
5203 
5204  // Forward the request, if required
5205  if (IsMaster())
5206  fProof->RemoveIncludePath(path);
5207  }
5208  }
5209  // Done
5210  return rc;
5211 }
5212 
5213 ////////////////////////////////////////////////////////////////////////////////
5214 /// Handle file checking request.
5215 
5217 {
5218  TString filenam;
5219  TMD5 md5;
5220  UInt_t opt = TProof::kUntar;
5221 
5222  TMessage reply(kPROOF_CHECKFILE);
5223 
5224  // Parse message
5225  (*mess) >> filenam >> md5;
5226  if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8))
5227  (*mess) >> opt;
5228 
5229  if (slb) *slb = filenam;
5230 
5231  if (filenam.BeginsWith("-")) {
5232  // install package:
5233  // compare md5's, untar, store md5 in PROOF-INF, remove par file
5234  Int_t st = 0;
5235  Bool_t err = kFALSE;
5236  filenam = filenam.Strip(TString::kLeading, '-');
5237  TString packnam = filenam;
5238  packnam.Remove(packnam.Length() - 4); // strip off ".par"
5239  // compare md5's to check if transmission was ok
5240  fPackageLock->Lock();
5241  TMD5 *md5local = TMD5::FileChecksum(fPackageDir + "/" + filenam);
5242  if (md5local && md5 == (*md5local)) {
5243  if ((opt & TProof::kRemoveOld)) {
5244  // remove any previous package directory with same name
5245  st = gSystem->Exec(TString::Format("%s %s/%s", kRM, fPackageDir.Data(),
5246  packnam.Data()));
5247  if (st)
5248  Error("HandleCheckFile", "failure executing: %s %s/%s",
5249  kRM, fPackageDir.Data(), packnam.Data());
5250  }
5251  // find gunzip...
5252  char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP,
5254  if (gunzip) {
5255  // untar package
5257  filenam.Data(), fPackageDir.Data()));
5258  if (st)
5259  Error("HandleCheckFile", "failure executing: %s",
5261  filenam.Data(), fPackageDir.Data()).Data());
5262  delete [] gunzip;
5263  } else
5264  Error("HandleCheckFile", "%s not found", kGUNZIP);
5265  // check that fPackageDir/packnam now exists
5266  if (gSystem->AccessPathName(fPackageDir + "/" + packnam, kWritePermission)) {
5267  // par file did not unpack itself in the expected directory, failure
5268  reply << (Int_t)0;
5269  if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5270  err = kTRUE;
5271  Error("HandleCheckFile", "package %s did not unpack into %s",
5272  filenam.Data(), packnam.Data());
5273  } else {
5274  // store md5 in package/PROOF-INF/md5.txt
5275  TString md5f = fPackageDir + "/" + packnam + "/PROOF-INF/md5.txt";
5276  TMD5::WriteChecksum(md5f, md5local);
5277  // Notify the client
5278  reply << (Int_t)1;
5279  PDB(kPackage, 1)
5280  Info("HandleCheckFile",
5281  "package %s installed on node", filenam.Data());
5282  }
5283  } else {
5284  reply << (Int_t)0;
5285  if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5286  err = kTRUE;
5287  PDB(kPackage, 1)
5288  Info("HandleCheckFile",
5289  "package %s not yet on node", filenam.Data());
5290  }
5291 
5292  // Note: Originally an fPackageLock->Unlock() call was made
5293  // after the if-else statement below. With multilevel masters,
5294  // submasters still check to make sure the package exists with
5295  // the correct md5 checksum and need to do a read lock there.
5296  // As yet locking is not that sophisicated so the lock must
5297  // be released below before the call to fProof->UploadPackage().
5298  if (err) {
5299  // delete par file in case of error
5300  gSystem->Exec(TString::Format("%s %s/%s", kRM, fPackageDir.Data(),
5301  filenam.Data()));
5302  fPackageLock->Unlock();
5303  } else if (IsMaster()) {
5304  // forward to workers
5305  fPackageLock->Unlock();
5306  if (fProof->UploadPackage(fPackageDir + "/" + filenam,
5307  (TProof::EUploadPackageOpt)opt) != 0)
5308  Info("HandleCheckFile",
5309  "problems uploading package %s", filenam.Data());
5310  } else {
5311  // Unlock in all cases
5312  fPackageLock->Unlock();
5313  }
5314  delete md5local;
5315  fSocket->Send(reply);
5316 
5317  } else if (filenam.BeginsWith("+")) {
5318  // check file in package directory
5319  filenam = filenam.Strip(TString::kLeading, '+');
5320  TString packnam = filenam;
5321  packnam.Remove(packnam.Length() - 4); // strip off ".par"
5322  TString md5f = fPackageDir + "/" + packnam + "/PROOF-INF/md5.txt";
5323  fPackageLock->Lock();
5324  TMD5 *md5local = TMD5::ReadChecksum(md5f);
5325  fPackageLock->Unlock();
5326  if (md5local && md5 == (*md5local)) {
5327  // package already on server, unlock directory
5328  reply << (Int_t)1;
5329  PDB(kPackage, 1)
5330  Info("HandleCheckFile",
5331  "package %s already on node", filenam.Data());
5332  if (IsMaster())
5333  if (fProof->UploadPackage(fPackageDir + "/" + filenam) != 0)
5334  Info("HandleCheckFile",
5335  "problems uploading package %s", filenam.Data());
5336 
5337  } else {
5338  reply << (Int_t)0;
5339  if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5340  PDB(kPackage, 1)
5341  Info("HandleCheckFile",
5342  "package %s not yet on node", filenam.Data());
5343  }
5344  delete md5local;
5345  fSocket->Send(reply);
5346 
5347  } else if (filenam.BeginsWith("=")) {
5348  // check file in package directory, do not lock if it is the wrong file
5349  filenam = filenam.Strip(TString::kLeading, '=');
5350  TString packnam = filenam;
5351  packnam.Remove(packnam.Length() - 4); // strip off ".par"
5352  TString md5f = fPackageDir + "/" + packnam + "/PROOF-INF/md5.txt";
5353  fPackageLock->Lock();
5354  TMD5 *md5local = TMD5::ReadChecksum(md5f);
5355  fPackageLock->Unlock();
5356  if (md5local && md5 == (*md5local)) {
5357  // package already on server, unlock directory
5358  reply << (Int_t)1;
5359  PDB(kPackage, 1)
5360  Info("HandleCheckFile",
5361  "package %s already on node", filenam.Data());
5362  if (IsMaster())
5363  if (fProof->UploadPackage(fPackageDir + "/" + filenam) != 0)
5364  Info("HandleCheckFile",
5365  "problems with uploading package %s", filenam.Data());
5366  } else {
5367  reply << (Int_t)0;
5368  if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5369  PDB(kPackage, 1)
5370  Info("HandleCheckFile",
5371  "package %s not yet on node", filenam.Data());
5372  }
5373  delete md5local;
5374  fSocket->Send(reply);
5375 
5376  } else {
5377  // check file in cache directory
5378  TString cachef = fCacheDir + "/" + filenam;
5379  fCacheLock->Lock();
5380  TMD5 *md5local = TMD5::FileChecksum(cachef);
5381 
5382  if (md5local && md5 == (*md5local)) {
5383  reply << (Int_t)1;
5384  PDB(kCache, 1)
5385  Info("HandleCheckFile", "file %s already on node", filenam.Data());
5386  } else {
5387  reply << (Int_t)0;
5388  if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5389  PDB(kCache, 1)
5390  Info("HandleCheckFile", "file %s not yet on node", filenam.Data());
5391  }
5392  delete md5local;
5393  fSocket->Send(reply);
5394  fCacheLock->Unlock();
5395  }
5396 }
5397 
5398 ////////////////////////////////////////////////////////////////////////////////
5399 /// Handle here all cache and package requests.
5400 
5402 {
5403  PDB(kGlobal, 1)
5404  Info("HandleCache", "Enter");
5405 
5406  Int_t status = 0;
5407  Int_t type = 0;
5408  Bool_t all = kFALSE;
5409  TMessage msg;
5410  Bool_t fromglobal = kFALSE;
5411  Int_t chkveropt = TProof::kCheckROOT; // Default: check ROOT version
5412 
5413  // Notification message
5414  TString noth;
5415  const char *k = (IsMaster()) ? "Mst" : "Wrk";
5416  noth.Form("%s-%s", k, fOrdinal.Data());
5417 
5418  TList *optls = 0;
5419  TString packagedir(fPackageDir), package, pdir, ocwd, file;
5420  (*mess) >> type;
5421  switch (type) {
5422  case TProof::kShowCache:
5423  (*mess) >> all;
5424  printf("*** File cache %s:%s ***\n", gSystem->HostName(),
5425  fCacheDir.Data());
5426  fflush(stdout);
5427  PDB(kCache, 1) {
5428  gSystem->Exec(TString::Format("%s -a %s", kLS, fCacheDir.Data()));
5429  } else {
5430  gSystem->Exec(TString::Format("%s %s", kLS, fCacheDir.Data()));
5431  }
5432  if (IsMaster() && all)
5433  fProof->ShowCache(all);
5434  LogToMaster();
5435  if (slb) slb->Form("%d %d", type, all);
5436  break;
5437  case TProof::kClearCache:
5438  file = "";
5439  if ((mess->BufferSize() > mess->Length())) (*mess) >> file;
5440  fCacheLock->Lock();
5441  if (file.IsNull() || file == "*") {
5442  gSystem->Exec(TString::Format("%s %s/* %s/.*.binversion", kRM, fCacheDir.Data(), fCacheDir.Data()));
5443  } else {
5444  gSystem->Exec(TString::Format("%s %s/%s", kRM, fCacheDir.Data(), file.Data()));
5445  }
5446  fCacheLock->Unlock();
5447  if (IsMaster())
5448  fProof->ClearCache(file);
5449  if (slb) slb->Form("%d %s", type, file.Data());
5450  break;
5451  case TProof::kShowPackages:
5452  (*mess) >> all;
5454  // Scan the list of global packages dirs
5456  TNamed *nm = 0;
5457  while ((nm = (TNamed *)nxd())) {
5458  printf("*** Global Package cache %s %s:%s ***\n",
5459  nm->GetName(), gSystem->HostName(), nm->GetTitle());
5460  fflush(stdout);
5461  gSystem->Exec(TString::Format("%s %s", kLS, nm->GetTitle()));
5462  printf("\n");
5463  fflush(stdout);
5464  }
5465  }
5466  printf("*** Package cache %s:%s ***\n", gSystem->HostName(),
5467  fPackageDir.Data());
5468  fflush(stdout);
5470  if (IsMaster() && all)
5471  fProof->ShowPackages(all);
5472  LogToMaster();
5473  if (slb) slb->Form("%d %d", type, all);
5474  break;
5476  status = UnloadPackages();
5477  if (status == 0) {
5478  fPackageLock->Lock();
5479  gSystem->Exec(TString::Format("%s %s/*", kRM, fPackageDir.Data()));
5480  fPackageLock->Unlock();
5481  if (IsMaster())
5482  status = fProof->ClearPackages();
5483  }
5484  if (slb) slb->Form("%d %d", type, status);
5485  break;
5486  case TProof::kClearPackage:
5487  (*mess) >> package;
5488  status = UnloadPackage(package);
5489  if (status == 0) {
5490  fPackageLock->Lock();
5491  // remove package directory and par file
5492  gSystem->Exec(TString::Format("%s %s/%s", kRM, fPackageDir.Data(),
5493  package.Data()));
5494  if (IsMaster())
5495  gSystem->Exec(TString::Format("%s %s/%s.par", kRM, fPackageDir.Data(),
5496  package.Data()));
5497  fPackageLock->Unlock();
5498  if (IsMaster())
5499  status = fProof->ClearPackage(package);
5500  }
5501  if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5502  break;
5503  case TProof::kBuildPackage:
5504  (*mess) >> package;
5505  if ((mess->BufferSize() > mess->Length())) (*mess) >> chkveropt;
5506 
5507  // always follows BuildPackage so no need to check for PROOF-INF
5508  pdir = fPackageDir + "/" + package;
5509 
5510  fromglobal = kFALSE;
5511  if (gSystem->AccessPathName(pdir, kReadPermission) ||
5512  gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission)) {
5513  // Is there a global package with this name?
5515  // Scan the list of global packages dirs
5517  TNamed *nm = 0;
5518  while ((nm = (TNamed *)nxd())) {
5519  pdir.Form("%s/%s", nm->GetTitle(), package.Data());
5520  if (!gSystem->AccessPathName(pdir, kReadPermission) &&
5521  !gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission)) {
5522  // Package found, stop searching
5523  fromglobal = kTRUE;
5524  packagedir = nm->GetTitle();
5525  break;
5526  }
5527  pdir = "";
5528  }
5529  if (pdir.Length() <= 0) {
5530  // Package not found
5531  SendAsynMessage(TString::Format("%s: kBuildPackage: failure locating %s ...",
5532  noth.Data(), package.Data()));
5533  status = -1;
5534  break;
5535  }
5536  }
5537  }
5538 
5539  if (IsMaster() && !fromglobal) {
5540  // Make sure package is available on all slaves, even new ones
5541  if (fProof->UploadPackage(pdir + ".par") != 0) {
5542  Warning("HandleCache",
5543  "kBuildPackage: problems forwarding package %s to workers", package.Data());
5544  SendAsynMessage(TString::Format("%s: kBuildPackage: problems forwarding package %s to workers ...",
5545  noth.Data(), package.Data()));
5546  }
5547  }
5548  fPackageLock->Lock();
5549 
5550  if (!status) {
5551 
5552  PDB(kPackage, 1)
5553  Info("HandleCache",
5554  "kBuildPackage: package %s exists and has PROOF-INF directory", package.Data());
5555 
5556  ocwd = gSystem->WorkingDirectory();
5557  gSystem->ChangeDirectory(pdir);
5558 
5559  // forward build command to slaves, but don't wait for results
5560  if (IsMaster())
5562 
5563  // check for BUILD.sh and execute
5564  if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
5565  // Notify the upper level
5566  SendAsynMessage(TString::Format("%s: building %s ...", noth.Data(), package.Data()));
5567 
5568  // read version from file proofvers.txt, and if current version is
5569  // not the same do a "BUILD.sh clean"
5570  Bool_t goodver = kTRUE;
5571  Bool_t savever = kFALSE;
5572  TString v, r;
5573  FILE *f = fopen("PROOF-INF/proofvers.txt", "r");
5574  if (f) {
5575  v.Gets(f);
5576  r.Gets(f);
5577  fclose(f);
5578  if (chkveropt == TProof::kCheckROOT || chkveropt == TProof::kCheckSVN) {
5579  if (v != gROOT->GetVersion()) goodver = kFALSE;
5580  if (goodver && chkveropt == TProof::kCheckSVN)
5581  if (r != gROOT->GetGitCommit()) goodver = kFALSE;
5582  }
5583  }
5584  if (!f || !goodver) {
5585  if (!fromglobal || !gSystem->AccessPathName(pdir, kWritePermission)) {
5586  savever = kTRUE;
5587  SendAsynMessage(TString::Format("%s: %s: version change (current: %s:%s,"
5588  " build: %s:%s): cleaning ... ",
5589  noth.Data(), package.Data(), gROOT->GetVersion(),
5590  gROOT->GetGitCommit(), v.Data(), r.Data()));
5591  // Hard cleanup: go up the dir tree
5592  gSystem->ChangeDirectory(packagedir);
5593  // remove package directory
5594  gSystem->Exec(TString::Format("%s %s", kRM, pdir.Data()));
5595  // find gunzip...
5596  char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP,
5598  if (gunzip) {
5599  TString par;
5600  par.Form("%s.par", pdir.Data());
5601  // untar package
5602  TString cmd;
5603  cmd.Form(kUNTAR3, gunzip, par.Data());
5604  status = gSystem->Exec(cmd);
5605  if (status) {
5606  Error("HandleCache", "kBuildPackage: failure executing: %s", cmd.Data());
5607  } else {
5608  // Store md5 in package/PROOF-INF/md5.txt
5609  TMD5 *md5local = TMD5::FileChecksum(par);
5610  if (md5local) {
5611  TString md5f = packagedir + "/" + package + "/PROOF-INF/md5.txt";
5612  TMD5::WriteChecksum(md5f, md5local);
5613  // Go down to the package directory
5614  gSystem->ChangeDirectory(pdir);
5615  // Cleanup
5616  SafeDelete(md5local);
5617  } else {
5618  Warning("HandleCache", "kBuildPackage: failure calculating/saving MD5sum for '%s'", par.Data());
5619  }
5620  }
5621  delete [] gunzip;
5622  } else {
5623  Error("HandleCache", "kBuildPackage: %s not found", kGUNZIP);
5624  status = -1;
5625  }
5626  } else {
5627  SendAsynMessage(TString::Format("%s: %s: ROOT version inconsistency (current: %s, build: %s):"
5628  " global package: cannot re-build!!! ",
5629  noth.Data(), package.Data(), gROOT->GetVersion(), v.Data()));
5630  status = -1;
5631  }
5632  }
5633 
5634  if (!status) {
5635  // To build the package we execute PROOF-INF/BUILD.sh via a pipe
5636  // so that we can send back the log in (almost) real-time to the
5637  // (impatient) client. Note that this operation will block, so
5638  // the messages from builds on the workers will reach the client
5639  // shortly after the master ones.
5640  TString ipath(gSystem->GetIncludePath());
5641  ipath.ReplaceAll("\"","");
5642  TString cmd;
5643  cmd.Form("export ROOTINCLUDEPATH=\"%s\" ; PROOF-INF/BUILD.sh", ipath.Data());
5644  {
5646  }
5647  if (!(status = TProofServLogHandler::GetCmdRtn())) {
5648  // Success: write version file
5649  if (savever) {
5650  f = fopen("PROOF-INF/proofvers.txt", "w");
5651  if (f) {
5652  fputs(gROOT->GetVersion(), f);
5653  fputs(TString::Format("\n%s", gROOT->GetGitCommit()), f);
5654  fclose(f);
5655  }
5656  }
5657  }
5658  }
5659  } else {
5660  // Notify the user
5661  PDB(kPackage, 1)
5662  Info("HandleCache", "no PROOF-INF/BUILD.sh found for package %s", package.Data());
5663  }
5664  gSystem->ChangeDirectory(ocwd);
5665  }
5666 
5667  fPackageLock->Unlock();
5668 
5669  if (status) {
5670  // Notify the upper level
5671  SendAsynMessage(TString::Format("%s: failure building %s ... (status: %d)", noth.Data(), package.Data(), status));
5672  } else {
5673  // collect built results from slaves
5674  if (IsMaster())
5675  status = fProof->BuildPackage(package, TProof::kCollectBuildResults);
5676  PDB(kPackage, 1)
5677  Info("HandleCache", "package %s successfully built", package.Data());
5678  }
5679  if (slb) slb->Form("%d %s %d %d", type, package.Data(), status, chkveropt);
5680  break;
5681  case TProof::kLoadPackage:
5682  (*mess) >> package;
5683 
5684  // If already loaded don't do it again
5685  if (fEnabledPackages->FindObject(package)) {
5686  Info("HandleCache",
5687  "package %s already loaded", package.Data());
5688  break;
5689  }
5690 
5691  // always follows BuildPackage so no need to check for PROOF-INF
5692  pdir = fPackageDir + "/" + package;
5693 
5694  if (gSystem->AccessPathName(pdir, kReadPermission)) {
5695  // Is there a global package with this name?
5697  // Scan the list of global packages dirs
5699  TNamed *nm = 0;
5700  while ((nm = (TNamed *)nxd())) {
5701  pdir.Form("%s/%s", nm->GetTitle(), package.Data());
5702  if (!gSystem->AccessPathName(pdir, kReadPermission)) {
5703  // Package found, stop searching
5704  break;
5705  }
5706  pdir = "";
5707  }
5708  if (pdir.Length() <= 0) {
5709  // Package not found
5710  SendAsynMessage(TString::Format("%s: kLoadPackage: failure locating %s ...",
5711  noth.Data(), package.Data()));
5712  status = -1;
5713  break;
5714  }
5715  }
5716  }
5717 
5718  ocwd = gSystem->WorkingDirectory();
5719  gSystem->ChangeDirectory(pdir);
5720 
5721  // We have to be atomic here
5722  fPackageLock->Lock();
5723 
5724  // Check for SETUP.C and execute
5725  if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
5726  // We need to change the name of the function to avoid problems when we load more packages
5727  TString setup;
5728  setup.Form("SETUP_ganis_%d_%x", gSystem->GetPid(), package.Hash());
5729  // Remove special characters
5730  TMacro setupmc("PROOF-INF/SETUP.C");
5731  TObjString *setupline = setupmc.GetLineWith("SETUP(");
5732  if (setupline) {
5733  TString setupstring(setupline->GetString());
5734  setupstring.ReplaceAll("SETUP(", TString::Format("%s(", setup.Data()));
5735  setupline->SetString(setupstring);
5736  } else {
5737  // Macro does not contain SETUP()
5738  SendAsynMessage(TString::Format("%s: warning: macro '%s/PROOF-INF/SETUP.C' does not contain a SETUP()"
5739  " function", noth.Data(), package.Data()));
5740  }
5741 
5742  // Load the macro
5743  if (!setupmc.Load()) {
5744  // Macro could not be loaded
5745  SendAsynMessage(TString::Format("%s: error: macro '%s/PROOF-INF/SETUP.C' could not be loaded:"
5746  " cannot continue",
5747  noth.Data(), package.Data()));
5748  status = -1;
5749  } else {
5750  // Check the signature
5751  TFunction *fun = (TFunction *) gROOT->GetListOfGlobalFunctions()->FindObject(setup);
5752  if (!fun) {
5753  // Notify the upper level
5754  SendAsynMessage(TString::Format("%s: error: function SETUP() not found in macro '%s/PROOF-INF/SETUP.C':"
5755  " cannot continue",
5756  noth.Data(), package.Data()));
5757  status = -1;
5758  } else {
5759  TMethodCall callEnv;
5760  // Check the number of arguments
5761  if (fun->GetNargs() == 0) {
5762  // No arguments (basic signature)
5763  callEnv.Init(fun);
5764  if ((mess->BufferSize() > mess->Length())) {
5765  (*mess) >> optls;
5766  SendAsynMessage(TString::Format("%s: warning: loaded SETUP() does not take any argument:"
5767  " the specified argument will be ignored", noth.Data()));
5768  }
5769  } else if (fun->GetNargs() == 1) {
5770  TMethodArg *arg = (TMethodArg *) fun->GetListOfMethodArgs()->First();
5771  if (arg) {
5772  callEnv.Init(fun);
5773  // Get argument
5774  if ((mess->BufferSize() > mess->Length())) (*mess) >> optls;
5775  // Check argument type
5776  TString argsig(arg->GetTitle());
5777  if (argsig.BeginsWith("TList")) {
5778  callEnv.ResetParam();
5779  callEnv.SetParam((Long_t) optls);
5780  } else if (argsig.BeginsWith("const char")) {
5781  callEnv.ResetParam();
5782  TObjString *os = optls ? dynamic_cast<TObjString *>(optls->First()) : 0;
5783  if (os) {
5784  callEnv.SetParam((Long_t) os->GetName());
5785  } else {
5786  if (optls && optls->First()) {
5787  SendAsynMessage(TString::Format("%s: warning: found object argument of type %s:"
5788  " SETUP expects 'const char *': ignoring",
5789  noth.Data(), optls->First()->ClassName()));
5790  }
5791  callEnv.SetParam((Long_t) 0);
5792  }
5793  } else {
5794  // Notify the upper level
5795  SendAsynMessage(TString::Format("%s: error: unsupported SETUP signature: SETUP(%s)"
5796  " cannot continue", noth.Data(), arg->GetTitle()));
5797  status = -1;
5798  }
5799  } else {
5800  // Notify the upper level
5801  SendAsynMessage(TString::Format("%s: error: cannot get information about the SETUP() argument:"
5802  " cannot continue", noth.Data()));
5803  status = -1;
5804  }
5805  } else if (fun->GetNargs() > 1) {
5806  // Notify the upper level
5807  SendAsynMessage(TString::Format("%s: error: function SETUP() can have at most a 'TList *' argument:"
5808  " cannot continue", noth.Data()));
5809  status = -1;
5810  }
5811  // Execute
5812  Long_t setuprc = (status == 0) ? 0 : -1;
5813  if (status == 0) {
5814  callEnv.Execute(setuprc);
5815  if (setuprc < 0) status = -1;
5816  }
5817  }
5818  }
5819  }
5820 
5821  // End of atomicity
5822  fPackageLock->Unlock();
5823 
5824  gSystem->ChangeDirectory(ocwd);
5825 
5826  if (status < 0) {
5827 
5828  // Notify the upper level
5829  SendAsynMessage(TString::Format("%s: failure loading %s ...", noth.Data(), package.Data()));
5830 
5831  } else {
5832 
5833  // create link to package in working directory
5834  gSystem->Symlink(pdir, package);
5835 
5836  // add package to list of include directories to be searched
5837  // by ACliC
5838  gSystem->AddIncludePath(TString("-I") + package);
5839 
5840  // add package to list of include directories to be searched by CINT
5841  gROOT->ProcessLine(TString(".I ") + package);
5842 
5843  // if successful add to list and propagate to slaves
5844  TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(package), optls->Clone())
5845  : new TPair(new TObjString(package), 0);
5846  fEnabledPackages->Add(pck);
5847  if (IsMaster()) {
5848  if (optls && optls->GetSize() > 0) {
5849  // List argument
5850  status = fProof->LoadPackage(package, kFALSE, optls);
5851  } else {
5852  // No argument
5853  status = fProof->LoadPackage(package);
5854  }
5855  }
5856 
5857  PDB(kPackage, 1)
5858  Info("HandleCache", "package %s successfully loaded", package.Data());
5859  }
5860  if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5861  break;
5863  (*mess) >> all;
5864  if (IsMaster()) {
5865  if (all)
5866  printf("*** Enabled packages on master %s on %s\n",
5867  fOrdinal.Data(), gSystem->HostName());
5868  else
5869  printf("*** Enabled packages ***\n");
5870  } else {
5871  printf("*** Enabled packages on slave %s on %s\n",
5872  fOrdinal.Data(), gSystem->HostName());
5873  }
5874  {
5875  TIter next(fEnabledPackages);
5876  while (TPair *pck = (TPair *) next())
5877  printf("%s\n", pck->GetName());
5878  }
5879  if (IsMaster() && all)
5881  LogToMaster();
5882  if (slb) slb->Form("%d %d", type, all);
5883  break;
5884  case TProof::kShowSubCache:
5885  (*mess) >> all;
5886  if (IsMaster() && all)
5887  fProof->ShowCache(all);
5888  LogToMaster();
5889  if (slb) slb->Form("%d %d", type, all);
5890  break;
5892  file = "";
5893  if ((mess->BufferSize() > mess->Length())) (*mess) >> file;
5894  if (IsMaster())
5895  fProof->ClearCache(file);
5896  if (slb) slb->Form("%d %s", type, file.Data());
5897  break;
5899  (*mess) >> all;
5900  if (IsMaster() && all)
5901  fProof->ShowPackages(all);
5902  LogToMaster();
5903  if (slb) slb->Form("%d %d", type, all);
5904  break;
5906  if (IsMaster())
5908  if (slb) slb->Form("%d", type);
5909  break;
5911  (*mess) >> package;
5912  if (IsMaster())
5913  fProof->DisablePackage(package);
5914  if (slb) slb->Form("%d %s", type, package.Data());
5915  break;
5917  (*mess) >> package;
5918  if ((mess->BufferSize() > mess->Length())) (*mess) >> chkveropt;
5919  if (IsMaster())
5920  fProof->BuildPackage(package, TProof::kBuildAll, chkveropt);
5921  if (slb) slb->Form("%d %s %d", type, package.Data(), chkveropt);
5922  break;
5924  (*mess) >> package;
5925  status = UnloadPackage(package);
5926  if (IsMaster() && status == 0)
5927  status = fProof->UnloadPackage(package);
5928  if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5929  break;
5931  (*mess) >> package;
5932  fPackageLock->Lock();
5933  // remove package directory and par file
5934  gSystem->Exec(TString::Format("%s %s/%s", kRM, fPackageDir.Data(),
5935  package.Data()));
5936  gSystem->Exec(TString::Format("%s %s/%s.par", kRM, fPackageDir.Data(),
5937  package.Data()));
5938  fPackageLock->Unlock();
5939  if (IsMaster())
5940  fProof->DisablePackage(package);
5941  if (slb) slb->Form("%d %s", type, package.Data());
5942  break;
5944  status = UnloadPackages();
5945  if (IsMaster() && status == 0)
5946  status = fProof->UnloadPackages();
5947  if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5948  break;
5950  fPackageLock->Lock();
5951  gSystem->Exec(TString::Format("%s %s/*", kRM, fPackageDir.Data()));
5952  fPackageLock->Unlock();
5953  if (IsMaster())
5955  if (slb) slb->Form("%d %s", type, package.Data());
5956  break;
5959  { TList *epl = new TList;
5960  if (fEnabledPackages->GetSize() > 0) {
5961  TIter nxp(fEnabledPackages);
5962  TObject *o = 0;
5963  while ((o = nxp())) { epl->Add(new TObjString(o->GetName()));}
5964  }
5965  msg << type << epl;
5966  fSocket->Send(msg);
5967  epl->SetOwner();
5968  delete epl;
5969  }
5970  if (slb) slb->Form("%d", type);
5971  break;
5972  case TProof::kListPackages:
5973  {
5974  TList *pack = new TList;
5975  void *dir = gSystem->OpenDirectory(fPackageDir);
5976  if (dir) {
5977  TString pac(gSystem->GetDirEntry(dir));
5978  while (pac.Length() > 0) {
5979  if (pac.EndsWith(".par")) {
5980  pac.ReplaceAll(".par","");
5981  pack->Add(new TObjString(pac.Data()));
5982  }
5983  pac = gSystem->GetDirEntry(dir);
5984  }
5985  }
5986  gSystem->FreeDirectory(dir);
5988  msg << type << pack;
5989  fSocket->Send(msg);
5990  }
5991  if (slb) slb->Form("%d", type);
5992  break;
5993  case TProof::kLoadMacro:
5994  {
5995  (*mess) >> package;
5996 
5997  // By first forwarding the load command to the unique workers
5998  // and only then loading locally we load/build in parallel
5999  if (IsMaster())
6000  fProof->Load(package, kFALSE, kTRUE);
6001 
6002  // Atomic action
6003  fCacheLock->Lock();
6004 
6005  TString originalCwd = gSystem->WorkingDirectory();
6007 
6008  // Load the macro
6009  TString pack(package);
6010  Ssiz_t from = 0;
6011  if ((from = pack.Index(",")) != kNPOS) pack.Remove(from);
6012  Info("HandleCache", "loading macro %s ...", pack.Data());
6013  gROOT->ProcessLine(TString::Format(".L %s", pack.Data()));
6014 
6015  // Release atomicity
6016  gSystem->ChangeDirectory(originalCwd.Data());
6017  fCacheLock->Unlock();
6018 
6019  // Now we collect the result from the unique workers and send the load request
6020  // to the other workers (no compilation)
6021  if (IsMaster())
6022  fProof->Load(package, kFALSE, kFALSE);
6023 
6024  // Notify the upper level
6025  LogToMaster();
6026 
6027  if (slb) slb->Form("%d %s", type, package.Data());
6028  }
6029  break;
6030  default:
6031  Error("HandleCache", "unknown type %d", type);
6032  break;
6033  }
6034 
6035  // We are done
6036  return status;
6037 }
6038 
6039 ////////////////////////////////////////////////////////////////////////////////
6040 /// Handle here all requests to modify worker lists
6041 
6043 {
6044  PDB(kGlobal, 1)
6045  Info("HandleWorkerLists", "Enter");
6046 
6047  Int_t type = 0, rc = 0;
6048  TString ord;
6049 
6050  (*mess) >> type;
6051 
6052  switch (type) {
6054  (*mess) >> ord;
6055  if (ord != "*" && !ord.BeginsWith(GetOrdinal()) && ord != "restore") break;
6056  if (fProof) {
6058  Int_t nactmax = fProof->GetListOfSlaves()->GetSize() -
6060  if (nact < nactmax || !IsEndMaster()) {
6061  Int_t nwc = fProof->ActivateWorker(ord);
6062  Int_t nactnew = fProof->GetListOfActiveSlaves()->GetSize();
6063  if (ord == "*") {
6064  if (nactnew == nactmax) {
6065  PDB(kGlobal, 1) Info("HandleWorkerList", "all workers (re-)activated");
6066  } else {
6067  if (IsEndMaster())
6068  PDB(kGlobal, 1) Info("HandleWorkerList", "%d workers could not be (re-)activated", nactmax - nactnew);
6069  }
6070  } else if (ord == "restore") {
6071  if (nwc > 0) {
6072  PDB(kGlobal, 1) Info("HandleWorkerList","active worker(s) restored");
6073  } else {
6074  Error("HandleWorkerList", "some active worker(s) could not be restored; check logs");
6075  }
6076  } else {
6077  if (nactnew == (nact + nwc)) {
6078  if (nwc > 0)
6079  PDB(kGlobal, 1) Info("HandleWorkerList","worker(s) %s (re-)activated", ord.Data());
6080  } else {
6081  if (nwc != -2 && IsEndMaster()) {
6082  Error("HandleWorkerList", "some worker(s) could not be (re-)activated;"
6083  " # of actives: %d --> %d (nwc: %d)",
6084  nact, nactnew, nwc);
6085  }
6086  rc = (nwc < 0) ? nwc : -1;
6087  }
6088  }
6089  } else {
6090  PDB(kGlobal, 1) Info("HandleWorkerList","all workers are already active");
6091  }
6092  } else {
6093  Warning("HandleWorkerList","undefined PROOF session: protocol error?");
6094  }
6095  break;
6097  (*mess) >> ord;
6098  if (ord != "*" && !ord.BeginsWith(GetOrdinal()) && ord != "restore") break;
6099  if (fProof) {
6101  if (nact > 0) {
6102  Int_t nwc = fProof->DeactivateWorker(ord);
6103  Int_t nactnew = fProof->GetListOfActiveSlaves()->GetSize();
6104  if (ord == "*") {
6105  if (nactnew == 0) {
6106  PDB(kGlobal, 1) Info("HandleWorkerList","all workers deactivated");
6107  } else {
6108  if (IsEndMaster())
6109  PDB(kGlobal, 1) Info("HandleWorkerList","%d workers could not be deactivated", nactnew);
6110  }
6111  } else {
6112  if (nactnew == (nact - nwc)) {
6113  if (nwc > 0)
6114  PDB(kGlobal, 1) Info("HandleWorkerList","worker(s) %s deactivated", ord.Data());
6115  } else {
6116  if (nwc != -2 && IsEndMaster()) {
6117  Error("HandleWorkerList", "some worker(s) could not be deactivated:"
6118  " # of actives: %d --> %d (nwc: %d)",
6119  nact, nactnew, nwc);
6120  }
6121  rc = (nwc < 0) ? nwc : -1;
6122  }
6123  }
6124  } else {
6125  PDB(kGlobal, 1) Info("HandleWorkerList","all workers are already inactive");
6126  }
6127  } else {
6128  Warning("HandleWorkerList","undefined PROOF session: protocol error?");
6129  }
6130  break;
6131  default:
6132  Warning("HandleWorkerList","unknown action type (%d)", type);
6133  rc = -1;
6134  }
6135  // Done
6136  return rc;
6137 }
6138 
6139 ////////////////////////////////////////////////////////////////////////////////
6140 /// Get list of workers to be used from now on.
6141 /// The list must be provided by the caller.
6142 
6144  Int_t & /* prioritychange */,
6145  Bool_t /* resume */)
6146 {
6147  // Parse the config file
6148  TProofResourcesStatic *resources =
6150  fConfFile = resources->GetFileName(); // Update the global file name (with path)
6151  PDB(kGlobal,1)
6152  Info("GetWorkers", "using PROOF config file: %s", fConfFile.Data());
6153 
6154  // Get the master
6155  TProofNodeInfo *master = resources->GetMaster();
6156  if (!master) {
6157  PDB(kAll,1)
6158  Info("GetWorkers",
6159  "no appropriate master line found in %s", fConfFile.Data());
6160  return kQueryStop;
6161  } else {
6162  // Set image if not yet done and available
6163  if (fImage.IsNull() && strlen(master->GetImage()) > 0)
6164  fImage = master->GetImage();
6165  }
6166 
6167  // Fill submaster or worker list
6168  if (workers) {
6169  if (resources->GetSubmasters() && resources->GetSubmasters()->GetSize() > 0) {
6170  PDB(kAll,1)
6171  resources->GetSubmasters()->Print();
6172  TProofNodeInfo *ni = 0;
6173  TIter nw(resources->GetSubmasters());
6174  while ((ni = (TProofNodeInfo *) nw()))
6175  workers->Add(new TProofNodeInfo(*ni));
6176  } else if (resources->GetWorkers() && resources->GetWorkers()->GetSize() > 0) {
6177  PDB(kAll,1)
6178  resources->GetWorkers()->Print();
6179  TProofNodeInfo *ni = 0;
6180  TIter nw(resources->GetWorkers());
6181  while ((ni = (TProofNodeInfo *) nw()))
6182  workers->Add(new TProofNodeInfo(*ni));
6183  }
6184  }
6185 
6186  // We are done
6187  return kQueryOK;
6188 }
6189 
6190 ////////////////////////////////////////////////////////////////////////////////
6191 /// Set the file stream where to log (default stderr).
6192 /// If ferr == 0 the default is restored.
6193 /// Returns current setting.
6194 
6196 {
6197  FILE *oldferr = fgErrorHandlerFile;
6198  fgErrorHandlerFile = (ferr) ? ferr : stderr;
6199  return oldferr;
6200 }
6201 
6202 ////////////////////////////////////////////////////////////////////////////////
6203 /// The PROOF error handler function. It prints the message on fgErrorHandlerFile and
6204 /// if abort is set it aborts the application.
6205 
6206 void TProofServ::ErrorHandler(Int_t level, Bool_t abort, const char *location,
6207  const char *msg)
6208 {
6209  if (gErrorIgnoreLevel == kUnset) {
6210  gErrorIgnoreLevel = 0;
6211  if (gEnv) {
6212  TString lvl = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
6213  if (!lvl.CompareTo("Print", TString::kIgnoreCase))
6215  else if (!lvl.CompareTo("Info", TString::kIgnoreCase))
6217  else if (!lvl.CompareTo("Warning", TString::kIgnoreCase))
6219  else if (!lvl.CompareTo("Error", TString::kIgnoreCase))
6221  else if (!lvl.CompareTo("Break", TString::kIgnoreCase))
6223  else if (!lvl.CompareTo("SysError", TString::kIgnoreCase))
6225  else if (!lvl.CompareTo("Fatal", TString::kIgnoreCase))
6227  }
6228  }
6229 
6230  if (level < gErrorIgnoreLevel)
6231  return;
6232 
6233  // Always communicate errors via SendLogFile
6234  if (level >= kError && gProofServ)
6235  gProofServ->LogToMaster();
6236 
6237  Bool_t tosyslog = (fgLogToSysLog > 2) ? kTRUE : kFALSE;
6238 
6239  const char *type = 0;
6240  ELogLevel loglevel = kLogInfo;
6241 
6242  Int_t ipos = (location) ? strlen(location) : 0;
6243 
6244  if (level >= kPrint) {
6245  loglevel = kLogInfo;
6246  type = "Print";
6247  }
6248  if (level >= kInfo) {
6249  loglevel = kLogInfo;
6250  char *ps = location ? (char *) strrchr(location, '|') : (char *)0;
6251  if (ps) {
6252  ipos = (int)(ps - (char *)location);
6253  type = "SvcMsg";
6254  } else {
6255  type = "Info";
6256  }
6257  }
6258  if (level >= kWarning) {
6259  loglevel = kLogWarning;
6260  type = "Warning";
6261  }
6262  if (level >= kError) {
6263  loglevel = kLogErr;
6264  type = "Error";
6265  }
6266  if (level >= kBreak) {
6267  loglevel = kLogErr;
6268  type = "*** Break ***";
6269  }
6270  if (level >= kSysError) {
6271  loglevel = kLogErr;
6272  type = "SysError";
6273  }
6274  if (level >= kFatal) {
6275  loglevel = kLogErr;
6276  type = "Fatal";
6277  }
6278 
6279 
6280  TString buf;
6281 
6282  // Time stamp
6283  TTimeStamp ts;
6284  TString st(ts.AsString("lc"),19);
6285 
6286  if (!location || ipos == 0 ||
6287  (level >= kPrint && level < kInfo) ||
6288  (level >= kBreak && level < kSysError)) {
6289  fprintf(fgErrorHandlerFile, "%s %5d %s | %s: %s\n", st(11,8).Data(),
6290  gSystem->GetPid(),
6291  (gProofServ ? gProofServ->GetPrefix() : "proof"),
6292  type, msg);
6293  if (tosyslog)
6294  buf.Form("%s: %s:%s", fgSysLogEntity.Data(), type, msg);
6295  } else {
6296  fprintf(fgErrorHandlerFile, "%s %5d %s | %s in <%.*s>: %s\n", st(11,8).Data(),
6297  gSystem->GetPid(),
6298  (gProofServ ? gProofServ->GetPrefix() : "proof"),
6299  type, ipos, location, msg);
6300  if (tosyslog)
6301  buf.Form("%s: %s:<%.*s>: %s", fgSysLogEntity.Data(), type, ipos, location, msg);
6302  }
6303  fflush(fgErrorHandlerFile);
6304 
6305  if (tosyslog)
6306  gSystem->Syslog(loglevel, buf);
6307 
6308 #ifdef __APPLE__
6309  if (__crashreporter_info__)
6310  delete [] __crashreporter_info__;
6311  __crashreporter_info__ = StrDup(buf);
6312 #endif
6313 
6314  if (abort) {
6315 
6316  static Bool_t recursive = kFALSE;
6317 
6318  if (gProofServ != 0 && !recursive) {
6319  recursive = kTRUE;
6320  if (gProofServ->GetSocket()) gProofServ->GetSocket()->Send(kPROOF_FATAL);
6321  recursive = kFALSE;
6322  }
6323 
6324  fprintf(fgErrorHandlerFile, "aborting\n");
6325  fflush(fgErrorHandlerFile);
6326  gSystem->StackTrace();
6327  gSystem->Abort();
6328  }
6329 }
6330 
6331 ////////////////////////////////////////////////////////////////////////////////
6332 /// Make player instance.
6333 
6335 {
6336  TVirtualProofPlayer *p = 0;
6337 
6338  // Cleanup first
6339  DeletePlayer();
6340 
6341  if (IsParallel()) {
6342  // remote mode
6343  p = fProof->MakePlayer();
6344  } else {
6345  // slave or sequential mode
6346  p = TVirtualProofPlayer::Create("slave", 0, fSocket);
6347  if (IsMaster())
6348  fProof->SetPlayer(p);
6349  }
6350 
6351  // set player
6352  fPlayer = p;
6353 }
6354 
6355 ////////////////////////////////////////////////////////////////////////////////
6356 /// Delete player instance.
6357 
6359 {
6360  if (IsMaster()) {
6361  PDB(kGlobal, 1) {
6362  fCompute.Stop();
6363  Printf(" +++ Latest processing times: %f s (CPU: %f s)",
6365  }
6366  if (fProof) fProof->SetPlayer(0);
6367  } else {
6369  }
6370  fPlayer = 0;
6371 }
6372 
6373 ////////////////////////////////////////////////////////////////////////////////
6374 /// Get the processing priority for the group the user belongs too. This
6375 /// priority is a number (0 - 100) determined by a scheduler (third
6376 /// party process) based on some basic priority the group has, e.g.
6377 /// we might want to give users in a specific group (e.g. promptana)
6378 /// a higher priority than users in other groups, and on the analysis
6379 /// of historical logging data (i.e. usage of CPU by the group in a
6380 /// previous time slot, as recorded in TPerfStats::WriteQueryLog()).
6381 ///
6382 /// Currently the group priority is obtained by a query in a SQL DB
6383 /// table proofpriority, which has the format:
6384 /// CREATE TABLE proofpriority (
6385 /// id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
6386 /// group VARCHAR(32) NOT NULL,
6387 /// priority INT
6388 ///)
6389 
6391 {
6392  TString sqlserv = gEnv->GetValue("ProofServ.QueryLogDB","");
6393  TString sqluser = gEnv->GetValue("ProofServ.QueryLogUser","");
6394  TString sqlpass = gEnv->GetValue("ProofServ.QueryLogPasswd","");
6395 
6396  Int_t priority = 100;
6397 
6398  if (sqlserv == "")
6399  return priority;
6400 
6401  TString sql;
6402  sql.Form("SELECT priority WHERE group='%s' FROM proofpriority", fGroup.Data());
6403 
6404  // open connection to SQL server
6405  TSQLServer *db = TSQLServer::Connect(sqlserv, sqluser, sqlpass);
6406 
6407  if (!db || db->IsZombie()) {
6408  Error("GetPriority", "failed to connect to SQL server %s as %s %s",
6409  sqlserv.Data(), sqluser.Data(), sqlpass.Data());
6410  printf("%s\n", sql.Data());
6411  } else {
6412  TSQLResult *res = db->Query(sql);
6413 
6414  if (!res) {
6415  Error("GetPriority", "query into proofpriority failed");
6416  Printf("%s", sql.Data());
6417  } else {
6418  TSQLRow *row = res->Next(); // first row is header
6419  if (row) {
6420  priority = atoi(row->GetField(0));
6421  delete row;
6422  } else {
6423  Error("GetPriority", "first row is header is NULL");
6424  }
6425  }
6426  delete res;
6427  }
6428  delete db;
6429 
6430  return priority;
6431 }
6432 
6433 ////////////////////////////////////////////////////////////////////////////////
6434 /// Send an asychronous message to the master / client .
6435 /// Masters will forward up the message to the client.
6436 /// The client prints 'msg' of stderr and adds a '\n'/'\r' depending on
6437 /// 'lf' being kTRUE (default) or kFALSE.
6438 /// Returns the return value from TSocket::Send(TMessage &) .
6439 
6441 {
6442  static TMessage m(kPROOF_MESSAGE);
6443 
6444  // To leave a track in the output file ... if requested
6445  // (clients will be notified twice)
6446  PDB(kAsyn,1)
6447  Info("SendAsynMessage","%s", (msg ? msg : "(null)"));
6448 
6449  if (fSocket && msg) {
6450  m.Reset(kPROOF_MESSAGE);
6451  m << TString(msg) << lf;
6452  return fSocket->Send(m);
6453  }
6454 
6455  // No message
6456  return -1;
6457 }
6458 
6459 ////////////////////////////////////////////////////////////////////////////////
6460 /// Reposition the read pointer in the log file to the very end.
6461 /// This allows to "hide" useful debug messages during normal operations
6462 /// while preserving the possibility to have them in case of problems.
6463 
6465 {
6466  off_t lend = lseek(fileno(stdout), (off_t)0, SEEK_END);
6467  if (lend >= 0) lseek(fLogFileDes, lend, SEEK_SET);
6468 }
6469 
6470 ////////////////////////////////////////////////////////////////////////////////
6471 /// Truncate the log file to the 80% of the required max size if this
6472 /// is set.
6473 
6475 {
6476 #ifndef WIN32
6477  TString emsg;
6478  if (fLogFileMaxSize > 0 && fLogFileDes > 0) {
6479  fflush(stdout);
6480  struct stat st;
6481  if (fstat(fLogFileDes, &st) == 0) {
6482  if (st.st_size >= fLogFileMaxSize) {
6483  off_t truncsz = (off_t) (( fLogFileMaxSize * 80 ) / 100 );
6484  if (truncsz < 100) {
6485  emsg.Form("+++ WARNING +++: %s: requested truncate size too small"
6486  " (%lld,%lld) - ignore ", fPrefix.Data(), (Long64_t) truncsz, fLogFileMaxSize);
6487  SendAsynMessage(emsg.Data());
6488  return;
6489  }
6491  while (ftruncate(fileno(stdout), truncsz) != 0 &&
6492  (TSystem::GetErrno() == EINTR)) {
6494  }
6495  if (TSystem::GetErrno() > 0) {
6496  Error("TruncateLogFile", "truncating to %lld bytes; file size is %lld bytes (errno: %d)",
6497  (Long64_t)truncsz, (Long64_t)st.st_size, TSystem::GetErrno());
6498  emsg.Form("+++ WARNING +++: %s: problems truncating log file to %lld bytes; file size is %lld bytes"
6499  " (errno: %d)", fPrefix.Data(), (Long64_t)truncsz, (Long64_t)st.st_size, TSystem::GetErrno());
6500  SendAsynMessage(emsg.Data());
6501  } else {
6502  Info("TruncateLogFile", "file truncated to %lld bytes (80%% of %lld); file size was %lld bytes ",
6503  (Long64_t)truncsz, fLogFileMaxSize, (Long64_t)st.st_size);
6504  emsg.Form("+++ WARNING +++: %s: log file truncated to %lld bytes (80%% of %lld)",
6505  fPrefix.Data(), (Long64_t)truncsz, fLogFileMaxSize);
6506  SendAsynMessage(emsg.Data());
6507  }
6508  }
6509  } else {
6510  emsg.Form("+++ WARNING +++: %s: could not stat log file descriptor"
6511  " for truncation (errno: %d)", fPrefix.Data(), TSystem::GetErrno());
6512  SendAsynMessage(emsg.Data());
6513  }
6514  }
6515 #endif
6516 }
6517 
6518 ////////////////////////////////////////////////////////////////////////////////
6519 /// Exception handler: we do not try to recover here, just exit.
6520 
6522 {
6523  Error("HandleException", "caugth exception triggered by signal '%d' %s %lld",
6524  sig, fgLastMsg.Data(), fgLastEntry);
6525  // Description
6526  TString emsg;
6527  emsg.Form("%s: caught exception triggered by signal '%d' %s %lld",
6528  GetOrdinal(), sig, fgLastMsg.Data(), fgLastEntry);
6529  // Try to warn the user
6530  SendAsynMessage(emsg.Data());
6531 
6532  gSystem->Exit(sig);
6533 }
6534 
6535 ////////////////////////////////////////////////////////////////////////////////
6536 /// Handle here requests about datasets.
6537 
6539 {
6540  if (gDebug > 0)
6541  Info("HandleDataSets", "enter");
6542 
6543  // We need a dataset manager
6544  if (!fDataSetManager) {
6545  Warning("HandleDataSets", "no data manager is available to fullfil the request");
6546  return -1;
6547  }
6548 
6549  // Used in most cases
6550  TString dsUser, dsGroup, dsName, dsTree, uri, opt;
6551  Int_t rc = 0;
6552 
6553  // Invalid characters in dataset URI
6554  TPMERegexp reInvalid("[^A-Za-z0-9._-]"); // from ParseUri
6555 
6556  // Message type
6557  Int_t type = 0;
6558  (*mess) >> type;
6559 
6560  switch (type) {
6562  //
6563  // Check whether this dataset exist
6564  {
6565  (*mess) >> uri;
6566  if (slb) slb->Form("%d %s", type, uri.Data());
6567  if (fDataSetManager->ExistsDataSet(uri))
6568  // Dataset name does exist
6569  return -1;
6570  }
6571  break;
6573  // list size must be above 0
6574  {
6576  (*mess) >> uri;
6577  (*mess) >> opt;
6578  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6579  // Extract the list
6580  TFileCollection *dataSet =
6581  dynamic_cast<TFileCollection*> ((mess->ReadObject(TFileCollection::Class())));
6582  if (!dataSet || dataSet->GetList()->GetSize() == 0) {
6583  Error("HandleDataSets", "can not save an empty list.");
6584  return -1;
6585  }
6586  // Register the dataset (quota checks are done inside here)
6587  rc = fDataSetManager->RegisterDataSet(uri, dataSet, opt);
6588  delete dataSet;
6589  return rc;
6590  } else {
6591  Info("HandleDataSets", "dataset registration not allowed");
6592  if (slb) slb->Form("%d notallowed", type);
6593  return -1;
6594  }
6595  }
6596  break;
6597 
6599  {
6600  (*mess) >> uri; // TString
6601 
6602  if (!fDataSetStgRepo) {
6603  Error("HandleDataSets",
6604  "no dataset staging request repository available");
6605  return -1;
6606  }
6607 
6608  // Transform input URI in a valid dataset name
6609  TString validUri = uri;
6610  while (reInvalid.Substitute(validUri, "_")) {}
6611 
6612  // Check if dataset exists beforehand: if it does, staging has
6613  // already been requested
6614  if (fDataSetStgRepo->ExistsDataSet(validUri.Data())) {
6615  Warning("HandleDataSets", "staging of %s already requested",
6616  uri.Data());
6617  return -1;
6618  }
6619 
6620  // Try to get dataset from current manager
6621  TFileCollection *fc = fDataSetManager->GetDataSet(uri.Data());
6622  if (!fc || (fc->GetNFiles() == 0)) {
6623  Error("HandleDataSets", "empty dataset or no dataset returned");
6624  if (fc) delete fc;
6625  return -1;
6626  }
6627 
6628  // Reset all staged bits and remove unnecessary URLs (all but last)
6629  TIter it(fc->GetList());
6630  TFileInfo *fi;
6631  while ((fi = dynamic_cast<TFileInfo *>(it.Next()))) {
6633  Int_t nToErase = fi->GetNUrls() - 1;
6634  for (Int_t i=0; i<nToErase; i++)
6635  fi->RemoveUrlAt(0);
6636  }
6637 
6638  fc->Update(); // absolutely necessary
6639 
6640  // Save request
6641  fDataSetStgRepo->ParseUri(validUri, &dsGroup, &dsUser, &dsName);
6642  if (fDataSetStgRepo->WriteDataSet(dsGroup, dsUser,
6643  dsName, fc) == 0) {
6644  // Error, can't save dataset
6645  Error("HandleDataSets",
6646  "can't register staging request for %s", uri.Data());
6647  delete fc;
6648  return -1;
6649  }
6650 
6651  Info("HandleDataSets",
6652  "Staging request registered for %s", uri.Data());
6653 
6654  delete fc;
6655  return 0; // success (-1 == failure)
6656  }
6657  break;
6658 
6660  {
6661  if (!fDataSetStgRepo) {
6662  Error("HandleDataSets",
6663  "no dataset staging request repository available");
6664  return -1;
6665  }
6666 
6667  (*mess) >> uri; // TString
6668 
6669  // Transform URI in a valid dataset name
6670  while (reInvalid.Substitute(uri, "_")) {}
6671 
6672  // Get the list
6673  TFileCollection *fc = fDataSetStgRepo->GetDataSet(uri.Data());
6674  if (fc) {
6675  fSocket->SendObject(fc, kMESS_OK);
6676  delete fc;
6677  return 0;
6678  }
6679  else {
6680  // No such dataset: not an error, but don't send message
6681  Info("HandleDataSets", "no pending staging request for %s",
6682  uri.Data());
6683  return 0;
6684  }
6685  }
6686  break;
6687 
6689  {
6690  if (!fDataSetStgRepo) {
6691  Error("HandleDataSets",
6692  "no dataset staging request repository available");
6693  return -1;
6694  }
6695 
6696  (*mess) >> uri;
6697 
6698  // Transform URI in a valid dataset name
6699  while (reInvalid.Substitute(uri, "_")) {}
6700 
6701  if (!fDataSetStgRepo->RemoveDataSet(uri.Data()))
6702  return -1; // failure
6703 
6704  return 0; // success
6705  }
6706  break;
6707 
6708  case TProof::kShowDataSets:
6709  {
6710  (*mess) >> uri >> opt;
6711  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6712  // Show content
6713  fDataSetManager->ShowDataSets(uri, opt);
6714  }
6715  break;
6716 
6717  case TProof::kGetDataSets:
6718  {
6719  (*mess) >> uri >> opt;
6720  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6721  // Get the datasets and fill a map
6723  Ssiz_t kLite = opt.Index(":lite:", 0, TString::kIgnoreCase);
6724  if (kLite != kNPOS) {
6726  opt.Remove(kLite, strlen(":lite:"));
6727  }
6728  TMap *returnMap = fDataSetManager->GetDataSets(uri, omsk);
6729  // If defines, option gives the name of a server for which to extract the information
6730  if (returnMap && !opt.IsNull()) {
6731  // The return map will be in the form </group/user/datasetname> --> <dataset>
6732  TMap *rmap = new TMap;
6733  TObject *k = 0;
6734  TFileCollection *fc = 0, *xfc = 0;
6735  TIter nxd(returnMap);
6736  while ((k = nxd()) && (fc = (TFileCollection *) returnMap->GetValue(k))) {
6737  // Get subset on specified server, if any
6738  if ((xfc = fc->GetFilesOnServer(opt.Data()))) {
6739  rmap->Add(new TObjString(k->GetName()), xfc);
6740  }
6741  }
6742  returnMap->DeleteAll();
6743  if (rmap->GetSize() > 0) {
6744  returnMap = rmap;
6745  } else {
6746  Info("HandleDataSets", "no dataset found on server '%s'", opt.Data());
6747  delete rmap;
6748  returnMap = 0;
6749  }
6750  }
6751  if (returnMap) {
6752  // Send them back
6753  fSocket->SendObject(returnMap, kMESS_OK);
6754  returnMap->DeleteAll();
6755  } else {
6756  // Failure
6757  return -1;
6758  }
6759  }
6760  break;
6761  case TProof::kGetDataSet:
6762  {
6763  (*mess) >> uri >> opt;
6764  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6765  // Get the list
6766  TFileCollection *fileList = fDataSetManager->GetDataSet(uri,opt);
6767  if (fileList) {
6768  fSocket->SendObject(fileList, kMESS_OK);
6769  delete fileList;
6770  } else {
6771  // Failure
6772  return -1;
6773  }
6774  }
6775  break;
6777  {
6779  (*mess) >> uri;
6780  if (slb) slb->Form("%d %s", type, uri.Data());
6781  if (!fDataSetManager->RemoveDataSet(uri)) {
6782  // Failure
6783  return -1;
6784  }
6785  } else {
6786  Info("HandleDataSets", "dataset creation / removal not allowed");
6787  if (slb) slb->Form("%d notallowed", type);
6788  return -1;
6789  }
6790  }
6791  break;
6793  {
6795  (*mess) >> uri >> opt;
6796  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6798  rc = fDataSetManager->ScanDataSet(uri, opt);
6799  // TODO: verify in parallel:
6800  // - dataset = GetDataSet(uri)
6801  // - TList flist; TDataSetManager::ScanDataSet(dataset, ..., &flist)
6802  // - fPlayer->Process( ... flist ...) // needs to be developed
6803  // - dataset->Integrate(flist) (perhaps automatic; flist object owned by dataset)
6804  // - RegisterDataSet(uri, dataset, "OT")
6805  } else {
6806  Info("HandleDataSets", "dataset verification not allowed");
6807  return -1;
6808  }
6809  }
6810  break;
6811  case TProof::kGetQuota:
6812  {
6814  if (slb) slb->Form("%d", type);
6815  TMap *groupQuotaMap = fDataSetManager->GetGroupQuotaMap();
6816  if (groupQuotaMap) {
6817  // Send result
6818  fSocket->SendObject(groupQuotaMap, kMESS_OK);
6819  } else {
6820  return -1;
6821  }
6822  } else {
6823  Info("HandleDataSets", "quota control disabled");
6824  if (slb) slb->Form("%d disabled", type);
6825  return -1;
6826  }
6827  }
6828  break;
6829  case TProof::kShowQuota:
6830  {
6832  if (slb) slb->Form("%d", type);
6833  (*mess) >> opt;
6834  // Display quota information
6835  fDataSetManager->ShowQuota(opt);
6836  } else {
6837  Info("HandleDataSets", "quota control disabled");
6838  if (slb) slb->Form("%d disabled", type);
6839  }
6840  }
6841  break;
6843  {
6845  (*mess) >> uri;
6846  if (slb) slb->Form("%d %s", type, uri.Data());
6848  } else {
6849  Info("HandleDataSets", "kSetDefaultTreeName: modification of dataset info not allowed");
6850  if (slb) slb->Form("%d notallowed", type);
6851  return -1;
6852  }
6853  }
6854  break;
6855  case TProof::kCache:
6856  {
6857  (*mess) >> uri >> opt;
6858  if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6859  if (opt == "show") {
6860  // Show cache content
6861  fDataSetManager->ShowCache(uri);
6862  } else if (opt == "clear") {
6863  // Clear cache content
6865  } else {
6866  Error("HandleDataSets", "kCache: unknown action: %s", opt.Data());
6867  }
6868  }
6869  break;
6870  default:
6871  rc = -1;
6872  Error("HandleDataSets", "unknown type %d", type);
6873  break;
6874  }
6875 
6876  // We are done
6877  return rc;
6878 }
6879 
6880 ////////////////////////////////////////////////////////////////////////////////
6881 /// Handle a message of type kPROOF_SUBMERGER
6882 
6884 {
6885  // Message type
6886  Int_t type = 0;
6887  (*mess) >> type;
6888 
6889  TString msg;
6890  switch (type) {
6891  case TProof::kOutputSize:
6892  break;
6893 
6894  case TProof::kSendOutput:
6895  {
6896  Bool_t deleteplayer = kTRUE;
6897  if (!IsMaster()) {
6898  if (fMergingMonitor) {
6899  Info("HandleSubmerger", "kSendOutput: interrupting ...");
6901  }
6902  if (fMergingSocket) {
6904  fMergingSocket->Close();
6906  }
6907 
6908  TString name;
6909  Int_t port = 0;
6910  Int_t merger_id = -1;
6911  (*mess) >> merger_id >> name >> port;
6912  PDB(kSubmerger, 1)
6913  Info("HandleSubmerger","worker %s redirected to merger #%d %s:%d", fOrdinal.Data(), merger_id, name.Data(), port);
6914 
6915  TSocket *t = 0;
6916  if (name.Length() > 0 && port > 0 && (t = new TSocket(name, port)) && t->IsValid()) {
6917 
6918  PDB(kSubmerger, 2) Info("HandleSubmerger",
6919  "kSendOutput: worker asked for sending output to merger #%d %s:%d",
6920  merger_id, name.Data(), port);
6921 
6922  if (SendResults(t, fPlayer->GetOutputList()) != 0) {
6923  msg.Form("worker %s cannot send results to merger #%d at %s:%d", GetPrefix(), merger_id, name.Data(), port);
6924  PDB(kSubmerger, 2) Info("HandleSubmerger",
6925  "kSendOutput: %s - inform the master", msg.Data());
6926  SendAsynMessage(msg);
6927  // Results not send
6928  TMessage answ(kPROOF_SUBMERGER);
6929  answ << Int_t(TProof::kMergerDown);
6930  answ << merger_id;
6931  fSocket->Send(answ);
6932  } else {
6933  // Worker informs master that it had sent its output to the merger
6934  TMessage answ(kPROOF_SUBMERGER);
6935  answ << Int_t(TProof::kOutputSent);
6936  answ << merger_id;
6937  fSocket->Send(answ);
6938 
6939  PDB(kSubmerger, 2) Info("HandleSubmerger", "kSendOutput: worker sent its output");
6941  SetIdle(kTRUE);
6942  SendLogFile();
6943  }
6944  } else {
6945 
6946  if (name == "master") {
6947  PDB(kSubmerger, 2) Info("HandleSubmerger",
6948  "kSendOutput: worker was asked for sending output to master");
6949  if (SendResults(fSocket, fPlayer->GetOutputList()) != 0)
6950  Warning("HandleSubmerger", "problems sending output list");
6951  // Signal the master that we are idle
6953  SetIdle(kTRUE);
6954  SendLogFile();
6955 
6956  } else if (!t || !(t->IsValid())) {
6957  msg.Form("worker %s could not open a valid socket to merger #%d at %s:%d",
6958  GetPrefix(), merger_id, name.Data(), port);
6959  PDB(kSubmerger, 2) Info("HandleSubmerger",
6960  "kSendOutput: %s - inform the master", msg.Data());
6961  SendAsynMessage(msg);
6962  // Results not send
6963  TMessage answ(kPROOF_SUBMERGER);
6964  answ << Int_t(TProof::kMergerDown);
6965  answ << merger_id;
6966  fSocket->Send(answ);
6967  deleteplayer = kFALSE;
6968  }
6969 
6970  if (t) SafeDelete(t);
6971 
6972  }
6973 
6974  } else {
6975  Error("HandleSubmerger", "kSendOutput: received not on worker");
6976  }
6977 
6978  // Cleanup
6979  if (deleteplayer) DeletePlayer();
6980  }
6981  break;
6982  case TProof::kBeMerger:
6983  {
6984  Bool_t deleteplayer = kTRUE;
6985  if (!IsMaster()) {
6986  Int_t merger_id = -1;
6987  //Int_t merger_port = 0;
6988  Int_t connections = 0;
6989  (*mess) >> merger_id >> connections;
6990  PDB(kSubmerger, 2)
6991  Info("HandleSubmerger", "worker %s established as merger", fOrdinal.Data());
6992 
6993  PDB(kSubmerger, 2)
6994  Info("HandleSubmerger",
6995  "kBeMerger: worker asked for being merger #%d for %d connections",
6996  merger_id, connections);
6997 
6998  TVirtualProofPlayer *mergerPlayer = TVirtualProofPlayer::Create("remote",fProof,0);
6999 
7000  if (mergerPlayer) {
7001  PDB(kSubmerger, 2) Info("HandleSubmerger",
7002  "kBeMerger: mergerPlayer created (%p) ", mergerPlayer);
7003 
7004  // This may be used internally
7006 
7007  // Accept results from assigned workers
7008  if (AcceptResults(connections, mergerPlayer)) {
7009  PDB(kSubmerger, 2)
7010  Info("HandleSubmerger", "kBeMerger: all outputs from workers accepted");
7011 
7012  PDB(kSubmerger, 2)
7013  Info("","adding own output to the list on %s", fOrdinal.Data());
7014 
7015  // Add own results to the output list.
7016  // On workers the player does not own the output list, which is owned
7017  // by the selector and deleted in there
7018  // On workers the player does not own the output list, which is owned
7019  // by the selector and deleted in there
7020  TIter nxo(fPlayer->GetOutputList());
7021  TObject * o = 0;
7022  while ((o = nxo())) {
7023  if ((mergerPlayer->AddOutputObject(o) != 1)) {
7024  // Remove the object if it has not been merged: it is owned
7025  // now by the merger player (in its output list)
7026  if (fPlayer->GetOutputList()) {
7027  PDB(kSubmerger, 2)
7028  Info("HandleSocketInput", "removing merged object (%p)", o);
7029  fPlayer->GetOutputList()->Remove(o);
7030  }
7031  }
7032  }
7033  PDB(kSubmerger, 2) Info("HandleSubmerger","kBeMerger: own outputs added");
7034  PDB(kSubmerger, 2) Info("HandleSubmerger","starting delayed merging on %s", fOrdinal.Data());
7035 
7036  // Delayed merging if neccessary
7037  mergerPlayer->MergeOutput(kTRUE);
7038 
7039  PDB(kSubmerger, 2) mergerPlayer->GetOutputList()->Print("all");
7040 
7041  PDB(kSubmerger, 2) Info("HandleSubmerger", "delayed merging on %s finished ", fOrdinal.Data());
7042  PDB(kSubmerger, 2) Info("HandleSubmerger", "%s sending results to master ", fOrdinal.Data());
7043  // Send merged results to master
7044  if (SendResults(fSocket, mergerPlayer->GetOutputList()) != 0)
7045  Warning("HandleSubmerger","kBeMerger: problems sending output list");
7046  if (mergerPlayer->GetOutputList())
7047  mergerPlayer->GetOutputList()->SetOwner(kTRUE);
7048 
7049  PDB(kSubmerger, 2) Info("HandleSubmerger","kBeMerger: results sent to master");
7050  // Signal the master that we are idle
7052  SetIdle(kTRUE);
7053  SendLogFile();
7054  } else {
7055  // Results from all assigned workers not accepted
7056  TMessage answ(kPROOF_SUBMERGER);
7057  answ << Int_t(TProof::kMergerDown);
7058  answ << merger_id;
7059  fSocket->Send(answ);
7060  deleteplayer = kFALSE;
7061  }
7062  // Reset
7063  SafeDelete(mergerPlayer);
7064 
7065  } else {
7066  Warning("HandleSubmerger","kBeMerger: problems craeting the merger player!");
7067  // Results from all assigned workers not accepted
7068  TMessage answ(kPROOF_SUBMERGER);
7069  answ << Int_t(TProof::kMergerDown);
7070  answ << merger_id;
7071  fSocket->Send(answ);
7072  deleteplayer = kFALSE;
7073  }
7074  } else {
7075  Error("HandleSubmerger","kSendOutput: received not on worker");
7076  }
7077 
7078  // Cleanup
7079  if (deleteplayer) DeletePlayer();
7080  }
7081  break;
7082 
7083  case TProof::kMergerDown:
7084  break;
7085 
7086  case TProof::kStopMerging:
7087  {
7088  // Received only in case of forced termination of merger by master
7089  PDB(kSubmerger, 2) Info("HandleSubmerger", "kStopMerging");
7090  if (fMergingMonitor) {
7091  Info("HandleSubmerger", "kStopMerging: interrupting ...");
7093  }
7094  }
7095  break;
7096 
7097  case TProof::kOutputSent:
7098  break;
7099  }
7100 }
7101 
7102 ////////////////////////////////////////////////////////////////////////////////
7103 /// Cloning itself via fork. Not implemented
7104 
7106 {
7107  Info("HandleFork", "fork cloning not implemented");
7108 }
7109 
7110 ////////////////////////////////////////////////////////////////////////////////
7111 /// Fork a child.
7112 /// If successful, return 0 in the child process and the child pid in the parent
7113 /// process. The child pid is registered for reaping.
7114 /// Return <0 in the parent process in case of failure.
7115 
7117 {
7118 #ifndef WIN32
7119  // Fork
7120  pid_t pid;
7121  if ((pid = fork()) < 0) {
7122  Error("Fork", "failed to fork");
7123  return pid;
7124  }
7125 
7126  // Nothing else to do in the child
7127  if (!pid) return pid;
7128 
7129  // Make sure that the reaper timer is started
7130  if (!fReaperTimer) {
7131  fReaperTimer = new TReaperTimer(1000);
7132  fReaperTimer->Start(-1);
7133  }
7134 
7135  // Register the new child
7136  fReaperTimer->AddPid(pid);
7137 
7138  // Done
7139  return pid;
7140 #else
7141  Warning("Fork", "Functionality not provided under windows");
7142  return -1;
7143 #endif
7144 }
7145 
7146 ////////////////////////////////////////////////////////////////////////////////
7147 /// Replace <ord>, <user>, <u>, <group>, <stag>, <qnum>, <file>, <rver> and
7148 /// <build> placeholders in fname.
7149 /// Here, <rver> is the root version in integer form, e.g. 53403, and <build> a
7150 /// string includign version, architecture and compiler version, e.g.
7151 /// '53403_linuxx8664gcc_gcc46' .
7152 
7153 void TProofServ::ResolveKeywords(TString &fname, const char *path)
7154 {
7155  // Replace <user>, if any
7156  if (fname.Contains("<user>")) {
7157  if (gProofServ && gProofServ->GetUser() && strlen(gProofServ->GetUser())) {
7158  fname.ReplaceAll("<user>", gProofServ->GetUser());
7159  } else if (gProof && gProof->GetUser() && strlen(gProof->GetUser())) {
7160  fname.ReplaceAll("<user>", gProof->GetUser());
7161  } else {
7162  fname.ReplaceAll("<user>", "nouser");
7163  }
7164  }
7165  // Replace <us>, if any
7166  if (fname.Contains("<u>")) {
7167  if (gProofServ && gProofServ->GetUser() && strlen(gProofServ->GetUser())) {
7168  TString u(gProofServ->GetUser()[0]);
7169  fname.ReplaceAll("<u>", u);
7170  } else if (gProof && gProof->GetUser() && strlen(gProof->GetUser())) {
7171  TString u(gProof->GetUser()[0]);
7172  fname.ReplaceAll("<u>", u);
7173  } else {
7174  fname.ReplaceAll("<u>", "n");
7175  }
7176  }
7177  // Replace <group>, if any
7178  if (fname.Contains("<group>")) {
7179  if (gProofServ && gProofServ->GetGroup() && strlen(gProofServ->GetGroup())) {
7180  fname.ReplaceAll("<group>", gProofServ->GetGroup());
7181  } else if (gProof && gProof->GetGroup() && strlen(gProof->GetGroup())) {
7182  fname.ReplaceAll("<group>", gProof->GetGroup());
7183  } else {
7184  fname.ReplaceAll("<group>", "default");
7185  }
7186  }
7187  // Replace <stag>, if any
7188  if (fname.Contains("<stag>")) {
7189  if (gProofServ && gProofServ->GetSessionTag() && strlen(gProofServ->GetSessionTag())) {
7190  fname.ReplaceAll("<stag>", gProofServ->GetSessionTag());
7191  } else if (gProof && gProof->GetSessionTag() && strlen(gProof->GetSessionTag())) {
7192  fname.ReplaceAll("<stag>", gProof->GetSessionTag());
7193  } else {
7194  ::Warning("TProofServ::ResolveKeywords", "session tag undefined: ignoring");
7195  }
7196  }
7197  // Replace <ord>, if any
7198  if (fname.Contains("<ord>")) {
7199  if (gProofServ && gProofServ->GetOrdinal() && strlen(gProofServ->GetOrdinal()))
7200  fname.ReplaceAll("<ord>", gProofServ->GetOrdinal());
7201  else
7202  ::Warning("TProofServ::ResolveKeywords", "ordinal number undefined: ignoring");
7203  }
7204  // Replace <qnum>, if any
7205  if (fname.Contains("<qnum>")) {
7206  if (gProofServ && gProofServ->GetQuerySeqNum() && gProofServ->GetQuerySeqNum() > 0)
7207  fname.ReplaceAll("<qnum>", TString::Format("%d", gProofServ->GetQuerySeqNum()).Data());
7208  else
7209  ::Warning("TProofServ::ResolveKeywords", "query seqeuntial number undefined: ignoring");
7210  }
7211  // Replace <file>, if any
7212  if (fname.Contains("<file>") && path && strlen(path) > 0) {
7213  fname.ReplaceAll("<file>", path);
7214  }
7215  // Replace <rver>, if any
7216  if (fname.Contains("<rver>")) {
7217  TString v = TString::Format("%d", gROOT->GetVersionInt());
7218  fname.ReplaceAll("<rver>", v);
7219  }
7220  // Replace <build>, if any
7221  if (fname.Contains("<build>")) {
7222  TString b = TString::Format("%d_%s_%s", gROOT->GetVersionInt(), gSystem->GetBuildArch(),
7224  fname.ReplaceAll("<build>", b);
7225  }
7226 }
7227 
7228 ////////////////////////////////////////////////////////////////////////////////
7229 /// Return the status of this session:
7230 /// 0 idle
7231 /// 1 running
7232 /// 2 being terminated (currently unused)
7233 /// 3 queued
7234 /// 4 idle timed-out (not set in here but in TIdleTOTimer::Notify)
7235 /// This is typically run in the reader thread, so access needs to be protected
7236 
7238 {
7240  Int_t st = (fIdle) ? 0 : 1;
7241  if (fIdle && fWaitingQueries->GetSize() > 0) st = 3;
7242  return st;
7243 }
7244 
7245 ////////////////////////////////////////////////////////////////////////////////
7246 /// Update the session status in the relevant file. The status is taken from
7247 /// GetSessionStatus() unless xst >= 0, in which case xst is used.
7248 /// Return 0 on success, -errno if the file could not be opened.
7249 
7251 {
7252  FILE *fs = fopen(fAdminPath.Data(), "w");
7253  if (fs) {
7254  Int_t st = (xst < 0) ? GetSessionStatus() : xst;
7255  fprintf(fs, "%d", st);
7256  fclose(fs);
7257  PDB(kGlobal, 2)
7258  Info("UpdateSessionStatus", "status (=%d) update in path: %s", st, fAdminPath.Data());
7259  } else {
7260  return -errno;
7261  }
7262  // Done
7263  return 0;
7264 }
7265 
7266 ////////////////////////////////////////////////////////////////////////////////
7267 /// Return the idle status
7268 
7270 {
7272  return fIdle;
7273 }
7274 
7275 ////////////////////////////////////////////////////////////////////////////////
7276 /// Change the idle status
7277 
7279 {
7281  fIdle = st;
7282 }
7283 
7284 ////////////////////////////////////////////////////////////////////////////////
7285 /// Return kTRUE if the session is waiting for the OK to start processing
7286 
7288 {
7290  if (fIdle && fWaitingQueries->GetSize() > 0) return kTRUE;
7291  return kFALSE;
7292 }
7293 
7294 ////////////////////////////////////////////////////////////////////////////////
7295 /// Return the number of waiting queries
7296 
7298 {
7300  return fWaitingQueries->GetSize();
7301 }
7302 
7303 ////////////////////////////////////////////////////////////////////////////////
7304 /// Add a query to the waiting list
7305 /// Returns the number of queries in the list
7306 
7308 {
7310  fWaitingQueries->Add(pq);
7311  return fWaitingQueries->GetSize();
7312 }
7313 
7314 ////////////////////////////////////////////////////////////////////////////////
7315 /// Get the next query from the waiting list.
7316 /// The query is removed from the list.
7317 
7319 {
7322  fWaitingQueries->Remove(pq);
7323  return pq;
7324 }
7325 
7326 ////////////////////////////////////////////////////////////////////////////////
7327 /// Cleanup the waiting queries list. The objects are deleted if 'del' is true.
7328 /// If 'qls' is non null, only objects in 'qls' are removed.
7329 /// Returns the number of cleanup queries
7330 
7332 {
7334  Int_t ncq = 0;
7335  if (qls) {
7336  TIter nxq(qls);
7337  TObject *o = 0;
7338  while ((o = nxq())) {
7339  if (fWaitingQueries->FindObject(o)) ncq++;
7340  fWaitingQueries->Remove(o);
7341  if (del) delete o;
7342  }
7343  } else {
7344  ncq = fWaitingQueries->GetSize();
7345  fWaitingQueries->SetOwner(del);
7347  }
7348  // Done
7349  return ncq;
7350 }
7351 
7352 ////////////////////////////////////////////////////////////////////////////////
7353 /// Set the message to be sent back in case of exceptions
7354 
7355 void TProofServ::SetLastMsg(const char *lastmsg)
7356 {
7357  fgLastMsg = lastmsg;
7358 }
7359 
7360 ////////////////////////////////////////////////////////////////////////////////
7361 /// Set the last entry before exception
7362 
7364 {
7365  fgLastEntry = entry;
7366 }
7367 
7368 ////////////////////////////////////////////////////////////////////////////////
7369 /// VirtMemMax getter
7370 
7372 {
7373  return fgVirtMemMax;
7374 }
7375 ////////////////////////////////////////////////////////////////////////////////
7376 /// ResMemMax getter
7377 
7379 {
7380  return fgResMemMax;
7381 }
7382 ////////////////////////////////////////////////////////////////////////////////
7383 /// MemHWM getter
7384 
7386 {
7387  return fgMemHWM;
7388 }
7389 ////////////////////////////////////////////////////////////////////////////////
7390 /// MemStop getter
7391 
7393 {
7394  return fgMemStop;
7395 }
7396 
7397 ////////////////////////////////////////////////////////////////////////////////
7398 /// Extract LOCALDATASERVER info in 'dsrv'
7399 
7401 {
7402  // Check if a local data server has been specified
7403  if (gSystem->Getenv("LOCALDATASERVER")) {
7404  dsrv = gSystem->Getenv("LOCALDATASERVER");
7405  if (!dsrv.EndsWith("/")) dsrv += "/";
7406  }
7407 
7408  // Done
7409  return;
7410 }
7411 
7412 ////////////////////////////////////////////////////////////////////////////////
7413 /// If 'path' is local and 'dsrv' is Xrootd, apply 'path.Localroot' settings,
7414 /// if any.
7415 /// The final path via the server is dsrv+path.
7416 
7417 void TProofServ::FilterLocalroot(TString &path, const char *dsrv)
7418 {
7419  TUrl u(path, kTRUE);
7420  if (!strcmp(u.GetProtocol(), "file")) {
7421  // Remove prefix, if any, if included and if Xrootd
7422  TString pfx = gEnv->GetValue("Path.Localroot","");
7423  if (!pfx.IsNull() && !strncmp(u.GetFile(), pfx.Data(), pfx.Length())) {
7424  TString srvp = TUrl(dsrv).GetProtocol();
7425  if (srvp == "root" || srvp == "xrd") path.Remove(0, pfx.Length());
7426  }
7427  }
7428 
7429  // Done
7430  return;
7431 }
7432 
7433 ////////////////////////////////////////////////////////////////////////////////
7434 /// Locks the directory. Waits if lock is hold by an other process.
7435 /// Returns 0 on success, -1 in case of error.
7436 
7438 {
7439  const char *pname = GetName();
7440 
7441  if (gSystem->AccessPathName(pname))
7442  fLockId = open(pname, O_CREAT|O_RDWR, 0644);
7443  else
7444  fLockId = open(pname, O_RDWR);
7445 
7446  if (fLockId == -1) {
7447  SysError("Lock", "cannot open lock file %s", pname);
7448  return -1;
7449  }
7450 
7451  PDB(kPackage, 2)
7452  Info("Lock", "%d: locking file %s ...", gSystem->GetPid(), pname);
7453  // lock the file
7454 #if !defined(R__WIN32) && !defined(R__WINGCC)
7455  if (lockf(fLockId, F_LOCK, (off_t) 1) == -1) {
7456  SysError("Lock", "error locking %s", pname);
7457  close(fLockId);
7458  fLockId = -1;
7459  return -1;
7460  }
7461 #endif
7462 
7463  PDB(kPackage, 2)
7464  Info("Lock", "%d: file %s locked", gSystem->GetPid(), pname);
7465 
7466  return 0;
7467 }
7468 
7469 ////////////////////////////////////////////////////////////////////////////////
7470 /// Unlock the directory. Returns 0 in case of success,
7471 /// -1 in case of error.
7472 
7474 {
7475  if (!IsLocked())
7476  return 0;
7477 
7478  PDB(kPackage, 2)
7479  Info("Lock", "%d: unlocking file %s ...", gSystem->GetPid(), GetName());
7480  // unlock the file
7481  lseek(fLockId, 0, SEEK_SET);
7482 #if !defined(R__WIN32) && !defined(R__WINGCC)
7483  if (lockf(fLockId, F_ULOCK, (off_t)1) == -1) {
7484  SysError("Unlock", "error unlocking %s", GetName());
7485  close(fLockId);
7486  fLockId = -1;
7487  return -1;
7488  }
7489 #endif
7490 
7491  PDB(kPackage, 2)
7492  Info("Unlock", "%d: file %s unlocked", gSystem->GetPid(), GetName());
7493 
7494  close(fLockId);
7495  fLockId = -1;
7496 
7497  return 0;
7498 }
virtual void HandleException(Int_t sig)
Exception handler: we do not try to recover here, just exit.
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
TClass * GetClass() const
Definition: TMessage.h:76
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 const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:932
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
Long64_t GetEntries() const
Definition: TQueryResult.h:130
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:1264
static Int_t GetCmdRtn()
Static method to get the return code from the execution of a command via the pipe.
Definition: TProofServ.cxx:345
TList * GetListOfLines() const
Definition: TMacro.h:53
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
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition: TError.cxx:106
TList * GetListOfBadSlaves() const
Definition: TProof.h:692
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 "...
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
Int_t fActSessions
Definition: TProofServ.h:133
virtual Int_t GetLearnEntries()=0
Int_t UnloadPackages()
Unload all packages.
Definition: TProof.cxx:8600
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:1647
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
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
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
Long64_t GetBytesRead() const
Definition: TProof.h:962
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
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 &#39;server&#39;.
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition: TSystem.cxx:3686
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.
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition: TMonitor.cxx:438
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 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
static TSQLServer * Connect(const char *db, const char *uid, const char *pw)
The db should be of the form: <dbms>://<host>[:<port>][/<database>], e.g.
Definition: TSQLServer.cxx:61
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.
const char *const kLS
Definition: TProof.h:166
TLine * line
const double pi
virtual TSeqCollection * GetListOfFileHandlers() const
Definition: TSystem.h:374
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
Long64_t fHWMBoxSize
Definition: TProofServ.h:168
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:520
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
void SetWriteV3(Bool_t on=kTRUE)
Set/Reset the &#39;OldStreamer&#39; bit in this instance and its elements.
Definition: TDSet.cxx:1846
static void FilterLocalroot(TString &path, const char *url="root://dum/")
If &#39;path&#39; is local and &#39;dsrv&#39; is Xrootd, apply &#39;path.Localroot&#39; 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:1362
TString fSessionTag
Definition: TProofServ.h:92
void SetPlayer(TVirtualProofPlayer *player)
Set a new PROOF player.
Definition: TProof.cxx:10766
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition: TProof.cxx:10485
#define gDirectory
Definition: TDirectory.h:218
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:818
const char * GetProtocol() const
Definition: TUrl.h:73
Definition: TDSet.h:153
TStopwatch fLatency
Definition: TProofServ.h:127
const char * GetGroup() const
Definition: TProofServ.h:254
void TerminateWorker(TSlave *wrk)
Ask an active worker &#39;wrk&#39; 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.
virtual void MakePlayer()
Make player instance.
TH1 * h
Definition: legend2.C:5
TObject * Value() const
Definition: TMap.h:125
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
TSocket * GetSocket() const
Definition: TProofServ.h:269
const char *const kPROOF_WorkDir
Definition: TProof.h:147
Bool_t NoLogOpt() const
Definition: TApplication.h:144
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
virtual Int_t GetEntries() const
Definition: TCollection.h:92
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:580
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
TObject * GetInputObject(const char *classname) const
Return first instance of class &#39;classname&#39; in the input list.
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
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&#39;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
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
TString ferr
Definition: pq2main.cxx:38
#define gROOT
Definition: TROOT.h:352
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
R__EXTERN Int_t gErrorAbortLevel
Definition: TError.h:108
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor&#39;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
TList * GetListOfInactiveSlaves() const
Definition: TProof.h:690
Int_t LoadPlugin()
Load the plugin library for this handler.
TList * GetListOfSlaves() const
Definition: TProof.h:689
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:1817
virtual void SetCurrentQuery(TQueryResult *q)=0
TList * Queries() const
Basic string class.
Definition: TString.h:137
TDataSetManagerFile * fDataSetStgRepo
Definition: TProofServ.h:157
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
void SetQueryRunning(TProofQueryResult *pq)
Set query in running state.
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1088
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
time_t GetSec() const
Definition: TTimeStamp.h:140
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
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:1510
TString fImage
Definition: TProofServ.h:91
Int_t GetProtocol() const
Definition: TProofServ.h:264
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 &#39;uri&#39;.
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
Option_t * GetOption() const
Definition: TSocket.h:128
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
TProofServ * gProofServ
Definition: TProofServ.cxx:116
STL namespace.
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:594
Int_t GetSeqNum() const
Definition: TQueryResult.h:123
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
Bool_t IsTopMaster() const
Definition: TProofServ.h:307
Bool_t UseDynamicStartup() const
Definition: TProof.h:954
static volatile Int_t gProofServDebug
Definition: TProofServ.cxx:119
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:212
TMonitor * fMergingMonitor
Definition: TProofServ.h:162
Long64_t GetEntries() const
void ScanPreviousQueries(const char *dir)
Scan the queries directory for the results of previous queries.
Int_t AddIncludePath(const char *incpath, Bool_t onClient=kFALSE, TList *wrks=0, Bool_t doCollect=kTRUE)
Add &#39;incpath&#39; to the inc path search.
Definition: TProof.cxx:9455
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
static void ResolveKeywords(TString &fname, const char *path=0)
Replace <ord>, <user>, <u>, <group>, <stag>, <qnum>, <file>, <rver> and <build> placeholders in fname...
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
void Print(Option_t *option="") const
Dump the content.
const char * GetOptions() const
Definition: TQueryResult.h:127
static Float_t GetMemHWM()
MemHWM getter.
TString fPrefix
Definition: TProofServ.h:146
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
const char * GetName() const
Returns name of object.
Definition: TMap.h:120
virtual TFileHandler * RemoveFileHandler(TFileHandler *fh)
Remove a file handler from the list of file handlers.
Definition: TSystem.cxx:568
TList * GetListOfElements() const
Definition: TDSet.h:231
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
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.
void SendParallel(Bool_t async=kFALSE)
Send number of parallel nodes to master or client.
Int_t fMaxQueries
Definition: TProofServ.h:166
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:496
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:2395
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:3847
Int_t Length() const
Definition: TBuffer.h:94
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 &#39;incpath&#39; 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
const char * GetFile() const
Definition: TUrl.h:78
virtual TObject * ReadObject(const TClass *cl)
Read object from I/O buffer.
Int_t fGroupId
Definition: TProofServ.h:117
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:449
virtual TList * GetOutputList() const =0
virtual int Unlink(const char *name)
Unlink, i.e. remove, a file.
Definition: TSystem.cxx:1345
Int_t GetQuerySeqNum() const
Definition: TProofServ.h:272
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
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.
Int_t GetCompressionLevel() const
Definition: TProofServ.h:476
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition: TProof.cxx:4793
void StopProcess(Bool_t abort, Int_t timeout=-1)
Send STOPPROCESS message to master and workers.
Definition: TProof.cxx:6211
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition: TMacro.cxx:299
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 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:2399
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:1461
#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
virtual void MergeOutput(Bool_t=kFALSE)=0
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.
TList * PreviousQueries() const
const char *const kPROOF_QueryDir
Definition: TProof.h:151
TMacro * GetSelecHdr() const
Definition: TQueryResult.h:135
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2450
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Definition: TFile.cxx:4315
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
TDSetElement * GetNextPacket(Long64_t totalEntries=-1)
Get next range of entries to be processed on this server.
Long64_t GetBytes() const
Definition: TQueryResult.h:132
virtual void Start(Long_t milliSec=-1, Bool_t singleShot=kFALSE)
Starts the timer with a milliSec timeout.
Definition: TTimer.cxx:209
Bool_t IsEndMaster() const
Definition: TProof.h:699
void Init(const TFunction *func)
Initialize the method invocation environment based on the TFunction object.
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:1756
const char * GetGroup() const
Definition: TProof.h:940
Long64_t fLogFileMaxSize
Definition: TProofServ.h:113
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.
Int_t CompLength() const
Definition: TMessage.h:95
const char * AsString(const Option_t *option="") const
Return the date & time as a string.
Definition: TTimeStamp.cxx:269
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1626
static Int_t RegisterDataSets(TList *in, TList *out, TDataSetManager *dsm, TString &e)
Register TFileCollections in &#39;out&#39; as datasets according to the rules in &#39;in&#39;.
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
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2220
virtual void ExitLoop()
Exit from event loop.
Definition: TSystem.cxx:396
virtual Bool_t IsValid() const
const char * GetSessionTag() const
Definition: TProof.h:942
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1562
TProofQueryResult * NextQuery()
Get the next query from the waiting list.
TString fDataDir
Definition: TProofServ.h:100
void FlushLogFile()
Reposition the read pointer in the log file to the very end.
virtual ~TProofServ()
Cleanup.
Int_t GetPort() const
Definition: TInetAddress.h:77
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.
virtual TSocket * Accept(UChar_t Opt=0)
Accept a connection on a server socket.
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1446
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
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 &#39;ord&#39; is in the active list...
Definition: TProof.cxx:11920
TString fOrdinal
Definition: TProofServ.h:116
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo&#39;s. In case of error return 0.
Definition: TProof.cxx:2316
const char *const kPROOF_DataDir
Definition: TProof.h:153
Int_t fGid
Definition: TSystem.h:140
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.
ELogLevel
Definition: TSystem.h:66
virtual Bool_t Load() const
Load the macro into the interpreter.
Definition: TMacro.cxx:245
static TVirtualProofPlayer * Create(const char *player, TProof *p, TSocket *s=0)
Create a PROOF player.
TString fAdminPath
Definition: TProofServ.h:102
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
const char * GetSessionTag() const
Definition: TProofServ.h:257
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.
const char * GetName() const
Returns name of object.
Definition: TObjString.h:42
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition: TEnv.cxx:581
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
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.
Bool_t IsEndMaster() const
Definition: TProofServ.h:304
Int_t fProtocol
Definition: TProofServ.h:115
TString fUser
Definition: TSystem.h:152
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3670
virtual void Close(Option_t *opt="")
Close the socket.
Definition: TSocket.cxx:388
Int_t GetNargs() const
Number of function arguments.
Definition: TFunction.cxx:164
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:1610
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:556
ROOT::R::TRInterface & r
Definition: Object.C:4
Int_t DisablePackages()
Remove all packages.
Definition: TProof.cxx:7982
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
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 &#39;dsrv&#39;.
const char *const kPROOF_DataSetDir
Definition: TProof.h:152
THashList * GetList()
TApplication * GetTProofServ(Int_t *argc, char **argv, FILE *flog)
Definition: TProofServ.cxx:551
void SetLearnTime(Double_t learnTime)
Long_t ExecPlugin(int nargs, const T &... params)
Long64_t GetNFiles() const
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:480
void Print(Option_t *option="") const
Prints the contents of the TFileCollection.
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.
Bool_t IsDraw() const
Definition: TQueryResult.h:152
Long_t fMemVirtual
Definition: TSystem.h:207
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:487
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.
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
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:536
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition: TSystem.cxx:1767
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 QueueQuery(TProofQueryResult *pq)
Add a query to the waiting list Returns the number of queries in the list.
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
unsigned int UInt_t
Definition: RtypesCore.h:42
TList * GetInputList()
Definition: TQueryResult.h:128
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 &#39;uri&#39; following the &#39;opts&#39; directives.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Ssiz_t Length() const
Definition: TString.h:390
virtual int Umask(Int_t mask)
Set the process file creation mode mask.
Definition: TSystem.cxx:1479
void SetRunning(Int_t startlog, const char *par, Int_t nwrks)
Call when running starts.
TString fDataDirOpts
Definition: TProofServ.h:101
const char * GetConfDir() const
Definition: TProofServ.h:251
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.
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1069
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
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
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 TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:310
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.
Int_t RemoveWorkers(TList *wrks)
Used for shuting down the workres after a query is finished.
Definition: TProof.cxx:1591
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,...)
TString fDataSetDir
Definition: TProofServ.h:99
TShutdownTimer * fShutdownTimer
Definition: TProofServ.h:150
Float_t GetUsedCPU() const
Definition: TQueryResult.h:133
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.
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:675
TString GetString() const
Definition: TObjString.h:50
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition: TProof.cxx:9947
#define Printf
Definition: TGeoToOCC.h:18
Long64_t GetFirst() const
Definition: TQueryResult.h:131
void AddPid(Int_t pid)
Add an entry for &#39;pid&#39; 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 &#39;libpath&#39; from the lib path search.
Definition: TProof.cxx:9500
virtual void RemoveQueryResult(const char *ref)=0
virtual void HandleRetrieve(TMessage *mess, TString *slb=0)
Handle retrieve request.
UInt_t What() const
Definition: TMessage.h:80
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 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:1676
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
TMacro * GetSelecImp() const
Definition: TQueryResult.h:136
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:1470
R__EXTERN TProof * gProof
Definition: TProof.h:1110
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.
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2240
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3760
Bool_t Notify()
Handle available message in the open file.
Definition: TProofServ.cxx:304
virtual void SendLogFile(Int_t status=0, Int_t start=-1, Int_t end=-1)
Send log file to master.
#define ClassImp(name)
Definition: Rtypes.h:279
double f(double x)
static Int_t fgCmdRtn
Definition: TProofServ.h:394
Bool_t IsZombie() const
Definition: TObject.h:141
void ResetParam()
Reset parameter list. To be used before the first call the SetParam().
virtual Long64_t GetEventsProcessed() const =0
TString fTopSessionTag
Definition: TProofServ.h:93
const char * GetService() const
Definition: TProofServ.h:250
void SetSysInfo(SysInfo_t si)
Setter for fSysInfo.
Definition: TProof.cxx:248
TVirtualProofPlayer * GetPlayer() const
Definition: TProof.h:751
virtual Func_t DynFindSymbol(const char *module, const char *entry)
Find specific entry point in specified library.
Definition: TSystem.cxx:1969
Int_t Counter() const
Definition: TStopwatch.h:52
TList * GetListOfMethodArgs()
Return list containing the TMethodArgs of a TFunction.
Definition: TFunction.cxx:126
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&#39;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:1336
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:864
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:1945
TList * GetListOfDeActives() const
Returns a list with all de-active sockets.
Definition: TMonitor.cxx:515
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
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
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition: TProof.cxx:2299
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
virtual Long64_t GetSize() const
Returns the current file size.
Definition: TFile.cxx:1279
Int_t fMergedWorkers
Definition: TProofServ.h:163
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.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
virtual Int_t GetGid(const char *group=0)
Returns the group&#39;s id. If group = 0, returns current user&#39;s group.
Definition: TSystem.cxx:1542
#define R__LOCKGUARD(mutex)
virtual TQueryResult * GetCurrentQuery() const =0
void SetRunStatus(ERunStatus rst)
Definition: TProof.h:707
Float_t fRealTime
Definition: TProofServ.h:125
Int_t BufferSize() const
Definition: TBuffer.h:92
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:385
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:2250
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&#39;s id. If user = 0, returns current user&#39;s id.
Definition: TSystem.cxx:1523
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
Int_t GetPort() const
Definition: TUrl.h:87
static TMap * GetDataSetNodeMap(TFileCollection *fc, TString &emsg)
Get a map {server-name, list-of-files} for collection &#39;fc&#39; to be used in TPacketizerFile.
Bool_t IsNull() const
Definition: TString.h:387
void SaveQuery(TProofQueryResult *qr, const char *fout=0)
Save current status of query &#39;qr&#39; to file name fout.
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex &#39;this&#39; 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
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:30
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 IsValid() const
Definition: TInetAddress.h:80
const char * GetImage() const
Definition: TProofServ.h:256
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.
TObject * FindObject(const char *keyname) const
Check if a (key,value) pair exists with keyname as name of the key.
Definition: TMap.cxx:213
TTime fTime
Definition: TTimer.h:60
Float_t GetCpuTime() const
Definition: TProof.h:964
Long64_t GetBytesRead() const
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:1638
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
const TString & GetWorkDir() const
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 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&#39;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
const char * GetWorkDir() const
Definition: TProofServ.h:255
virtual void SetOutputFilePath(const char *fp)=0
virtual TList * GetListOfKeys() const
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.
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.
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 &#39;cmd&#39; 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
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition: TSystem.cxx:2430
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 &#39;cachedir&#39; into the sandbox or create a the file with input data objects...
Definition: TProof.cxx:12879
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7127
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:830
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:234
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1964
virtual void DeletePlayer()
Delete player instance.
Int_t AddDynamicPath(const char *libpath, Bool_t onClient=kFALSE, TList *wrks=0, Bool_t doCollect=kTRUE)
Add &#39;libpath&#39; to the lib path search.
Definition: TProof.cxx:9410
virtual TProofProgressStatus * GetProgressStatus() const =0
void Reset()
Definition: TStopwatch.h:54
Bool_t IsParallel() const
Definition: TProof.h:972
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:3927
const char * GetUser() const
Definition: TProof.h:939
virtual Int_t AddOutputObject(TObject *obj)=0
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1806
virtual void Stop()
Definition: TTimer.h:99
const AParamType & GetVal() const
Definition: TParameter.h:77
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 const TString & GetBinDir()
Get the binary directory in the installation. Static utility function.
Definition: TROOT.cxx:2538
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
Bool_t IsValid() const
Definition: TProof.h:970
void RestartComputeTime()
Reset the compute time.
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1242
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
Int_t fTotSessions
Definition: TProofServ.h:132
virtual ~TProofServLogHandlerGuard()
Close a guard for executing a command in a pipe.
Definition: TProofServ.cxx:393
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:946
const Bool_t kIterBackward
Definition: TCollection.h:44
virtual Int_t SavePartialResults(Bool_t queryend=kFALSE, Bool_t force=kFALSE)=0
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
void Print(Option_t *option="") const
Print status of slave server.
void SendStatistics()
Send statistics of slave server to master or client.
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
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
virtual Int_t GetSize() const
Definition: TCollection.h:95
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
const char * GetDataDir() const
Definition: TProofServ.h:262
const char * GetUser() const
Definition: TProofServ.h:253
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.
const char * GetObjName() const
Definition: TDSet.h:229
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
Bool_t IsParallel() const
True if in parallel mode.
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
Int_t DeactivateWorker(const char *ord, Bool_t save=kTRUE)
Remove the worker identified by the ordinal number &#39;ord&#39; from the the active list.
Definition: TProof.cxx:11937
TList * GetListOfActiveSlaves() const
Definition: TProof.h:758
virtual TMap * GetDataSets(const char *uri, UInt_t=TDataSetManager::kExport)
Returns all datasets for the <group> and <user> specified by <uri>.
Int_t fQuerySeqNum
Definition: TProofServ.h:130
static TString fgSysLogService
Definition: TProofServ.h:185
const char * GetOrdinal() const
Definition: TProofServ.h:265
const Int_t n
Definition: legend1.C:16
Int_t fLogFileDes
Definition: TProofServ.h:112
Bool_t IsMaster() const
Definition: TProofServ.h:305
TProofServ(Int_t *argc, char **argv, FILE *flog=0)
Main constructor.
Definition: TProofServ.cxx:561
Int_t GetNanoSec() const
Definition: TTimeStamp.h:141
TProofLockPath * fCacheLock
Definition: TProofServ.h:105
double log(double)
Long_t fMemResident
Definition: TSystem.h:206
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904
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:3962
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
TQueryResultManager * fQMgr
Definition: TProofServ.h:138
const char * GetPrefix() const
Definition: TProofServ.h:288
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 * Data() const
Definition: TString.h:349
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