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