Logo ROOT   6.16/01
Reference Guide
TProofServ.cxx
Go to the documentation of this file.
1// @(#)root/proof:$Id$
2// Author: Fons Rademakers 16/02/97
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TProofServ
13\ingroup proofkernel
14
15Class providing the PROOF server. It can act either as the master
16server or as a slave server, depending on its startup arguments. It
17receives and handles message coming from the client or from the
18master server.
19
20*/
21
22#include "RConfigure.h"
23#include <ROOT/RConfig.hxx>
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
46using 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"
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#include "TPackMgr.h"
113
114// global proofserv handle
116
117// debug hook
118static volatile Int_t gProofServDebug = 1;
119
120// Syslog control
122TString TProofServ::fgSysLogService("proof");
123TString TProofServ::fgSysLogEntity("undef:default");
124
125// File where to log: default stderr
127
128// Integrate with crash reporter.
129#ifdef __APPLE__
130extern "C" {
131static const char *__crashreporter_info__ = 0;
132asm(".desc ___crashreporter_info__, 0x10");
133}
134#endif
135
136// To control allowed actions while processing
138
139// Last message and entry before exceptions
140TString TProofServ::fgLastMsg("<undef>");
142
143// Memory controllers
148
149// Async Logger
150static void SendAsynMsg(const char *msg) {
152}
153
154//----- Termination signal handler ---------------------------------------------
155////////////////////////////////////////////////////////////////////////////////
156
157class TProofServTerminationHandler : public TSignalHandler {
158 TProofServ *fServ;
159public:
160 TProofServTerminationHandler(TProofServ *s)
161 : TSignalHandler(kSigTermination, kFALSE) { fServ = s; }
162 Bool_t Notify();
163};
164
165////////////////////////////////////////////////////////////////////////////////
166/// Handle this interrupt
167
168Bool_t TProofServTerminationHandler::Notify()
169{
170 Printf("Received SIGTERM: terminating");
171 fServ->HandleTermination();
172 return kTRUE;
173}
174
175//----- Interrupt signal handler -----------------------------------------------
176////////////////////////////////////////////////////////////////////////////////
177
178class TProofServInterruptHandler : public TSignalHandler {
179 TProofServ *fServ;
180public:
181 TProofServInterruptHandler(TProofServ *s)
182 : TSignalHandler(kSigUrgent, kFALSE) { fServ = s; }
183 Bool_t Notify();
184};
185
186////////////////////////////////////////////////////////////////////////////////
187/// Handle this interrupt
188
189Bool_t TProofServInterruptHandler::Notify()
190{
191 fServ->HandleUrgentData();
192 if (TROOT::Initialized()) {
193 Throw(GetSignal());
194 }
195 return kTRUE;
196}
197
198//----- SigPipe signal handler -------------------------------------------------
199////////////////////////////////////////////////////////////////////////////////
200
201class TProofServSigPipeHandler : public TSignalHandler {
202 TProofServ *fServ;
203public:
204 TProofServSigPipeHandler(TProofServ *s) : TSignalHandler(kSigPipe, kFALSE)
205 { fServ = s; }
206 Bool_t Notify();
207};
208
209////////////////////////////////////////////////////////////////////////////////
210/// Handle this signal
211
212Bool_t TProofServSigPipeHandler::Notify()
213{
214 fServ->HandleSigPipe();
215 return kTRUE;
216}
217
218//----- Input handler for messages from parent or master -----------------------
219////////////////////////////////////////////////////////////////////////////////
220
221class TProofServInputHandler : public TFileHandler {
222 TProofServ *fServ;
223public:
224 TProofServInputHandler(TProofServ *s, Int_t fd) : TFileHandler(fd, 1)
225 { fServ = s; }
226 Bool_t Notify();
227 Bool_t ReadNotify() { return Notify(); }
228};
229
230////////////////////////////////////////////////////////////////////////////////
231/// Handle this input
232
233Bool_t TProofServInputHandler::Notify()
234{
235 fServ->HandleSocketInput();
236 return kTRUE;
237}
238
239TString TProofServLogHandler::fgPfx = ""; // Default prefix to be prepended to messages
240Int_t TProofServLogHandler::fgCmdRtn = 0; // Return code of the command execution (available only
241 // after closing the pipe)
242////////////////////////////////////////////////////////////////////////////////
243/// Execute 'cmd' in a pipe and handle output messages from the related file
244
246 TSocket *s, const char *pfx)
247 : TFileHandler(-1, 1), fSocket(s), fPfx(pfx)
248{
250 fgCmdRtn = 0;
251 fFile = 0;
252 if (s && cmd) {
253 fFile = gSystem->OpenPipe(cmd, "r");
254 if (fFile) {
255 SetFd(fileno(fFile));
256 // Notify what already in the file
257 Notify();
258 // Used in the destructor
260 } else {
261 fSocket = 0;
262 Error("TProofServLogHandler", "executing command in pipe");
263 fgCmdRtn = -1;
264 }
265 } else {
266 Error("TProofServLogHandler",
267 "undefined command (%p) or socket (%p)", (int *)cmd, s);
268 }
269}
270////////////////////////////////////////////////////////////////////////////////
271/// Handle available message from the open file 'f'
272
274 : TFileHandler(-1, 1), fSocket(s), fPfx(pfx)
275{
277 fgCmdRtn = 0;
278 fFile = 0;
279 if (s && f) {
280 fFile = f;
281 SetFd(fileno(fFile));
282 // Notify what already in the file
283 Notify();
284 } else {
285 Error("TProofServLogHandler", "undefined file (%p) or socket (%p)", f, s);
286 }
287}
288////////////////////////////////////////////////////////////////////////////////
289/// Handle available message in the open file
290
292{
293 if (TestBit(kFileIsPipe) && fFile) {
295#ifdef WIN32
296 fgCmdRtn = rc;
297#else
298 fgCmdRtn = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
299#endif
300 }
301 fFile = 0;
302 fSocket = 0;
304}
305////////////////////////////////////////////////////////////////////////////////
306/// Handle available message in the open file
307
309{
310 if (IsValid()) {
312 // Read buffer
313 char line[4096];
314 char *plf = 0;
315 while (fgets(line, sizeof(line), fFile)) {
316 if ((plf = strchr(line, '\n')))
317 *plf = 0;
318 // Create log string
319 TString log;
320 if (fPfx.Length() > 0) {
321 // Prepend prefix specific to this instance
322 log.Form("%s: %s", fPfx.Data(), line);
323 } else if (fgPfx.Length() > 0) {
324 // Prepend default prefix
325 log.Form("%s: %s", fgPfx.Data(), line);
326 } else {
327 // Nothing to prepend
328 log = line;
329 }
330 // Send the message one level up
331 m.Reset(kPROOF_MESSAGE);
332 m << log;
333 fSocket->Send(m);
334 }
335 }
336 return kTRUE;
337}
338////////////////////////////////////////////////////////////////////////////////
339/// Static method to set the default prefix
340
342{
343 fgPfx = pfx;
344}
345////////////////////////////////////////////////////////////////////////////////
346/// Static method to get the return code from the execution of a command via
347/// the pipe. This is always 0 when the log handler is not used with a pipe
348
350{
351 return fgCmdRtn;
352}
353
354////////////////////////////////////////////////////////////////////////////////
355/// Init a guard for executing a command in a pipe
356
358 const char *pfx, Bool_t on)
359{
360 fExecHandler = 0;
361 if (cmd && on) {
362 fExecHandler = new TProofServLogHandler(cmd, s, pfx);
363 if (fExecHandler->IsValid()) {
365 } else {
366 Error("TProofServLogHandlerGuard","invalid handler");
367 }
368 } else {
369 if (on)
370 Error("TProofServLogHandlerGuard","undefined command");
371 }
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// Init a guard for executing a command in a pipe
376
378 const char *pfx, Bool_t on)
379{
380 fExecHandler = 0;
381 if (f && on) {
383 if (fExecHandler->IsValid()) {
385 } else {
386 Error("TProofServLogHandlerGuard","invalid handler");
387 }
388 } else {
389 if (on)
390 Error("TProofServLogHandlerGuard","undefined file");
391 }
392}
393
394////////////////////////////////////////////////////////////////////////////////
395/// Close a guard for executing a command in a pipe
396
398{
402 }
403}
404
405//--- Special timer to control delayed shutdowns ----------------------------//
406////////////////////////////////////////////////////////////////////////////////
407/// Construtor
408
410 : TTimer(delay, kFALSE), fProofServ(p)
411{
412 fTimeout = gEnv->GetValue("ProofServ.ShutdownTimeout", 20);
413 // Backward compaitibility: until 5.32 the variable was called ProofServ.ShutdonwTimeout
414 fTimeout = gEnv->GetValue("ProofServ.ShutdonwTimeout", fTimeout);
415}
416
417////////////////////////////////////////////////////////////////////////////////
418/// Handle expiration of the shutdown timer. In the case of low activity the
419/// process will be aborted.
420
422{
423 if (gDebug > 0)
424 printf("TShutdownTimer::Notify: checking activity on the input socket\n");
425
426 // Check activity on the socket
427 TSocket *xs = 0;
428 if (fProofServ && (xs = fProofServ->GetSocket())) {
429 TTimeStamp now;
430 TTimeStamp ts = xs->GetLastUsage();
431 Long_t dt = (Long_t)(now.GetSec() - ts.GetSec()) * 1000 +
432 (Long_t)(now.GetNanoSec() - ts.GetNanoSec()) / 1000000 ;
433 if (dt > fTimeout * 60000) {
434 printf("TShutdownTimer::Notify: input socket: %p: did not show any activity"
435 " during the last %d mins: aborting\n", xs, fTimeout);
436 // At this point we lost our controller: we need to abort to avoid
437 // hidden timeouts or loops
438 gSystem->Abort();
439 } else {
440 if (gDebug > 0)
441 printf("TShutdownTimer::Notify: input socket: %p: show activity"
442 " %ld secs ago\n", xs, dt / 60000);
443 }
444 }
445 // Needed for the next shot
446 Reset();
447 return kTRUE;
448}
449
450//--- Synchronous timer used to reap children processes change of state ------//
451////////////////////////////////////////////////////////////////////////////////
452/// Destructor
453
455{
456 if (fChildren) {
458 delete fChildren;
459 fChildren = 0;
460 }
461}
462
463////////////////////////////////////////////////////////////////////////////////
464/// Add an entry for 'pid' in the internal list
465
467{
468 if (pid > 0) {
469 if (!fChildren)
470 fChildren = new TList;
471 TString spid;
472 spid.Form("%d", pid);
473 fChildren->Add(new TParameter<Int_t>(spid.Data(), pid));
474 TurnOn();
475 }
476}
477
478////////////////////////////////////////////////////////////////////////////////
479/// Check if any of the registered children has changed its state.
480/// Unregister those that are gone.
481
483{
484 if (fChildren) {
485 TIter nxp(fChildren);
486 TParameter<Int_t> *p = 0;
487 while ((p = (TParameter<Int_t> *)nxp())) {
488 int status;
489#ifndef WIN32
490 pid_t pid;
491 do {
492 pid = waitpid(p->GetVal(), &status, WNOHANG);
493 } while (pid < 0 && errno == EINTR);
494#else
495 intptr_t pid;
496 pid = _cwait(&status, (intptr_t)p->GetVal(), 0);
497#endif
498 if (pid > 0 && pid == p->GetVal()) {
499 // Remove from the list
500 fChildren->Remove(p);
501 delete p;
502 }
503 }
504 }
505
506 // Stop the timer if no children
507 if (!fChildren || fChildren->GetSize() <= 0) {
508 Stop();
509 } else {
510 // Needed for the next shot
511 Reset();
512 }
513 return kTRUE;
514}
515
516//--- Special timer to terminate idle sessions ----------------------------//
517////////////////////////////////////////////////////////////////////////////////
518/// Handle expiration of the idle timer. The session will just be terminated.
519
521{
522 Info ("Notify", "session idle for more then %lld secs: terminating", Long64_t(fTime)/1000);
523
524 if (fProofServ) {
525 // Set the status to timed-out
526 Int_t uss_rc = -1;
527 if ((uss_rc = fProofServ->UpdateSessionStatus(4)) != 0)
528 Warning("Notify", "problems updating session status (errno: %d)", -uss_rc);
529 // Send a terminate request
530 TString msg;
531 if (fProofServ->GetProtocol() < 29) {
532 msg.Form("\n//\n// PROOF session at %s (%s) terminated because idle for more than %lld secs\n"
533 "// Please IGNORE any error message possibly displayed below\n//",
535 } else {
536 msg.Form("\n//\n// PROOF session at %s (%s) terminated because idle for more than %lld secs\n//",
538 }
539 fProofServ->SendAsynMessage(msg.Data());
541 Reset();
542 Stop();
543 } else {
544 Warning("Notify", "fProofServ undefined!");
545 Start(-1, kTRUE);
546 }
547 return kTRUE;
548}
549
551
552// Hook to the constructor. This is needed to avoid using the plugin manager
553// which may create problems in multi-threaded environments.
554extern "C" {
555 TApplication *GetTProofServ(Int_t *argc, char **argv, FILE *flog)
556 { return new TProofServ(argc, argv, flog); }
557}
558
559////////////////////////////////////////////////////////////////////////////////
560/// Main constructor. Create an application environment. The TProofServ
561/// environment provides an eventloop via inheritance of TApplication.
562/// Actual server creation work is done in CreateServer() to allow
563/// overloading.
564
565TProofServ::TProofServ(Int_t *argc, char **argv, FILE *flog)
566 : TApplication("proofserv", argc, argv, 0, -1)
567{
568 // If test and tty, we are done
569 Bool_t xtest = (argc && *argc == 1) ? kTRUE : kFALSE;
570 if (xtest) {
571 Printf("proofserv: command line testing: OK");
572 exit(0);
573 }
574
575 // Read session specific rootrc file
576 TString rcfile = gSystem->Getenv("ROOTRCFILE") ? gSystem->Getenv("ROOTRCFILE")
577 : "session.rootrc";
579 gEnv->ReadFile(rcfile, kEnvChange);
580
581 // Upper limit on Virtual Memory (in kB)
582 fgVirtMemMax = gEnv->GetValue("Proof.VirtMemMax",-1);
583 if (fgVirtMemMax < 0 && gSystem->Getenv("PROOF_VIRTMEMMAX")) {
584 Long_t mmx = strtol(gSystem->Getenv("PROOF_VIRTMEMMAX"), 0, 10);
585 if (mmx < kMaxLong && mmx > 0)
586 fgVirtMemMax = mmx * 1024;
587 }
588 // Old variable for backward compatibility
589 if (fgVirtMemMax < 0 && gSystem->Getenv("ROOTPROOFASHARD")) {
590 Long_t mmx = strtol(gSystem->Getenv("ROOTPROOFASHARD"), 0, 10);
591 if (mmx < kMaxLong && mmx > 0)
592 fgVirtMemMax = mmx * 1024;
593 }
594 // Upper limit on Resident Memory (in kB)
595 fgResMemMax = gEnv->GetValue("Proof.ResMemMax",-1);
596 if (fgResMemMax < 0 && gSystem->Getenv("PROOF_RESMEMMAX")) {
597 Long_t mmx = strtol(gSystem->Getenv("PROOF_RESMEMMAX"), 0, 10);
598 if (mmx < kMaxLong && mmx > 0)
599 fgResMemMax = mmx * 1024;
600 }
601 // Thresholds for warnings and stop processing
602 fgMemStop = gEnv->GetValue("Proof.MemStop", 0.95);
603 fgMemHWM = gEnv->GetValue("Proof.MemHWM", 0.80);
604 if (fgVirtMemMax > 0 || fgResMemMax > 0) {
605 if ((fgMemStop < 0.) || (fgMemStop > 1.)) {
606 Warning("TProofServ", "requested memory fraction threshold to stop processing"
607 " (MemStop) out of range [0,1] - ignoring");
608 fgMemStop = 0.95;
609 }
610 if ((fgMemHWM < 0.) || (fgMemHWM > fgMemStop)) {
611 Warning("TProofServ", "requested memory fraction threshold for warning and finer monitoring"
612 " (MemHWM) out of range [0,MemStop] - ignoring");
613 fgMemHWM = 0.80;
614 }
615 }
616
617 // Wait (loop) to allow debugger to connect
618 Bool_t test = (argc && *argc >= 4 && !strcmp(argv[3], "test")) ? kTRUE : kFALSE;
619 if ((gEnv->GetValue("Proof.GdbHook",0) == 3 && !test) ||
620 (gEnv->GetValue("Proof.GdbHook",0) == 4 && test)) {
621 while (gProofServDebug)
622 ;
623 }
624
625 // Test instance
626 if (argc && *argc >= 4)
627 if (!strcmp(argv[3], "test"))
628 fService = "prooftest";
629
630 // crude check on number of arguments
631 if (argc && *argc < 2) {
632 Error("TProofServ", "Must have at least 1 arguments (see proofd).");
633 exit(1);
634 }
635
636 // Set global to this instance
637 gProofServ = this;
638
639 // Log control flags
641
642 // Abort on higher than kSysError's and set error handler
644 SetErrorHandlerFile(stderr);
646
647 fNcmd = 0;
648 fGroupPriority = 100;
650 fProtocol = 0;
651 fOrdinal = gEnv->GetValue("ProofServ.Ordinal", "-1");
652 fGroupId = -1;
653 fGroupSize = 0;
654 fRealTime = 0.0;
655 fCpuTime = 0.0;
656 fProof = 0;
657 fPlayer = 0;
658 fSocket = 0;
659
660 fTotSessions = -1;
661 fActSessions = -1;
662 fEffSessions = -1.;
663 fPackMgr = 0;
664
665 fLogFile = flog;
666 fLogFileDes = -1;
667
668 fArchivePath = "";
669 // Init lockers
670 fCacheLock = 0;
671 fQueryLock = 0;
672
673 fQMgr = 0;
675 fIdle = kTRUE;
676 fQuerySeqNum = -1;
677
678 fQueuedMsg = new TList;
679
681
682 fShutdownTimer = 0;
683 fReaperTimer = 0;
684 fIdleTOTimer = 0;
685
686 fDataSetManager = 0; // Initialized in Setup()
687 fDataSetStgRepo = 0; // Initialized in Setup()
688
689 fInputHandler = 0;
690
691 // Quotas disabled by default
692 fMaxQueries = -1;
693 fMaxBoxSize = -1;
694 fHWMBoxSize = -1;
695
696 // Submerger quantities
697 fMergingSocket = 0;
698 fMergingMonitor = 0;
699 fMergedWorkers = 0;
700
701 // Bit to flg high-memory footprint
703
704 // Max message size
705 fMsgSizeHWM = gEnv->GetValue("ProofServ.MsgSizeHWM", 1000000);
706
707 // Message compression
708 fCompressMsg = gEnv->GetValue("ProofServ.CompressMessage", 0);
709
710 gProofDebugLevel = gEnv->GetValue("Proof.DebugLevel",0);
712
714 if (gProofDebugLevel > 0)
715 Info("TProofServ", "DebugLevel %d Mask 0x%x", gProofDebugLevel, gProofDebugMask);
716
717 // Max log file size
718 fLogFileMaxSize = -1;
719 TString logmx = gEnv->GetValue("ProofServ.LogFileMaxSize", "");
720 if (!logmx.IsNull()) {
721 Long64_t xf = 1;
722 if (!logmx.IsDigit()) {
723 if (logmx.EndsWith("K")) {
724 xf = 1024;
725 logmx.Remove(TString::kTrailing, 'K');
726 } else if (logmx.EndsWith("M")) {
727 xf = 1024*1024;
728 logmx.Remove(TString::kTrailing, 'M');
729 } if (logmx.EndsWith("G")) {
730 xf = 1024*1024*1024;
731 logmx.Remove(TString::kTrailing, 'G');
732 }
733 }
734 if (logmx.IsDigit()) {
735 fLogFileMaxSize = logmx.Atoi() * xf;
736 if (fLogFileMaxSize > 0)
737 Info("TProofServ", "keeping the log file size within %lld bytes", fLogFileMaxSize);
738 } else {
739 logmx = gEnv->GetValue("ProofServ.LogFileMaxSize", "");
740 Warning("TProofServ", "bad formatted log file size limit ignored: '%s'", logmx.Data());
741 }
742 }
743
744 // Parse options
745 GetOptions(argc, argv);
746
747 // Default prefix in the form '<role>-<ordinal>'
748 fPrefix = (IsMaster() ? "Mst-" : "Wrk-");
749 if (test) fPrefix = "Test";
750 if (fOrdinal != "-1")
751 fPrefix += fOrdinal;
753
754 // Syslog control
755 TString slog = gEnv->GetValue("ProofServ.LogToSysLog", "");
756 if (!(slog.IsNull())) {
757 if (slog.IsDigit()) {
758 fgLogToSysLog = slog.Atoi();
759 } else {
760 char c = (slog[0] == 'M' || slog[0] == 'm') ? 'm' : 'a';
761 c = (slog[0] == 'W' || slog[0] == 'w') ? 'w' : c;
762 Bool_t dosyslog = ((c == 'm' && IsMaster()) ||
763 (c == 'w' && !IsMaster()) || c == 'a') ? kTRUE : kFALSE;
764 if (dosyslog) {
765 slog.Remove(0,1);
766 if (slog.IsDigit()) fgLogToSysLog = slog.Atoi();
767 if (fgLogToSysLog <= 0)
768 Warning("TProofServ", "request for syslog logging ineffective!");
769 }
770 }
771 }
772 // Initialize proper service if required
773 if (fgLogToSysLog > 0) {
774 fgSysLogService = (IsMaster()) ? "proofm" : "proofw";
775 if (fOrdinal != "-1") fgSysLogService += TString::Format("-%s", fOrdinal.Data());
777 }
778
779 // Enable optimized sending of streamer infos to use embedded backward/forward
780 // compatibility support between different ROOT versions and different versions of
781 // users classes
782 Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
783 if (enableSchemaEvolution) {
785 } else {
786 Info("TProofServ", "automatic schema evolution in TMessage explicitly disabled");
787 }
788}
789
790////////////////////////////////////////////////////////////////////////////////
791/// Finalize the server setup. If master, create the TProof instance to talk
792/// to the worker or submaster nodes.
793/// Return 0 on success, -1 on error
794
796{
797 // Get socket to be used (setup in proofd)
798 TString opensock = gSystem->Getenv("ROOTOPENSOCK");
799 if (opensock.Length() <= 0)
800 opensock = gEnv->GetValue("ProofServ.OpenSock", "-1");
801 Int_t sock = opensock.Atoi();
802 if (sock <= 0) {
803 Fatal("CreateServer", "Invalid socket descriptor number (%d)", sock);
804 return -1;
805 }
806 fSocket = new TSocket(sock);
807
808 // Set compression level, if any
810
811 // debug hooks
812 if (IsMaster()) {
813 // wait (loop) in master to allow debugger to connect
814 if (gEnv->GetValue("Proof.GdbHook",0) == 1) {
815 while (gProofServDebug)
816 ;
817 }
818 } else {
819 // wait (loop) in slave to allow debugger to connect
820 if (gEnv->GetValue("Proof.GdbHook",0) == 2) {
821 while (gProofServDebug)
822 ;
823 }
824 }
825
826 if (gProofDebugLevel > 0)
827 Info("CreateServer", "Service %s ConfDir %s IsMaster %d\n",
829
830 if (Setup() != 0) {
831 // Setup failure
832 LogToMaster();
833 SendLogFile();
834 Terminate(0);
835 return -1;
836 }
837
838 // Set the default prefix in the form '<role>-<ordinal>' (it was already done
839 // in the constructor, but for standard PROOF the ordinal number is only set in
840 // Setup(), so we need to do it again here)
841 TString pfx = (IsMaster() ? "Mst-" : "Wrk-");
842 pfx += GetOrdinal();
844
845 if (!fLogFile) {
847 // If for some reason we failed setting a redirection file for the logs
848 // we cannot continue
849 if (!fLogFile || (fLogFileDes = fileno(fLogFile)) < 0) {
850 LogToMaster();
851 SendLogFile(-98);
852 Terminate(0);
853 return -1;
854 }
855 } else {
856 // Use the file already open by pmain
857 if ((fLogFileDes = fileno(fLogFile)) < 0) {
858 LogToMaster();
859 SendLogFile(-98);
860 Terminate(0);
861 return -1;
862 }
863 }
864
865 // Send message of the day to the client
866 if (IsMaster()) {
867 if (CatMotd() == -1) {
868 LogToMaster();
869 SendLogFile(-99);
870 Terminate(0);
871 return -1;
872 }
873 }
874
875 // Everybody expects std::iostream to be available, so load it...
876 ProcessLine("#include <iostream>", kTRUE);
877 ProcessLine("#include <string>",kTRUE); // for std::string std::iostream.
878
879 // The following libs are also useful to have, make sure they are loaded...
880 //gROOT->LoadClass("TMinuit", "Minuit");
881 //gROOT->LoadClass("TPostScript", "Postscript");
882
883 // Load user functions
884 const char *logon;
885 logon = gEnv->GetValue("Proof.Load", (char *)0);
886 if (logon) {
887 char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
888 if (mac)
889 ProcessLine(TString::Format(".L %s", logon), kTRUE);
890 delete [] mac;
891 }
892
893 // Execute logon macro
894 logon = gEnv->GetValue("Proof.Logon", (char *)0);
895 if (logon && !NoLogOpt()) {
896 char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
897 if (mac)
898 ProcessFile(logon);
899 delete [] mac;
900 }
901
902 // Save current interpreter context
903 gInterpreter->SaveContext();
904 gInterpreter->SaveGlobalsContext();
905
906 // Install interrupt and message input handlers
907 gSystem->AddSignalHandler(new TProofServTerminationHandler(this));
908 gSystem->AddSignalHandler(new TProofServInterruptHandler(this));
909 fInputHandler = new TProofServInputHandler(this, sock);
911
912 // if master, start slave servers
913 if (IsMaster()) {
914 TString master = "proof://__master__";
916 if (a.IsValid()) {
917 master += ":";
918 master += a.GetPort();
919 }
920
921 // Get plugin manager to load appropriate TProof from
922 TPluginManager *pm = gROOT->GetPluginManager();
923 if (!pm) {
924 Error("CreateServer", "no plugin manager found");
925 SendLogFile(-99);
926 Terminate(0);
927 return -1;
928 }
929
930 // Find the appropriate handler
931 TPluginHandler *h = pm->FindHandler("TProof", fConfFile);
932 if (!h) {
933 Error("CreateServer", "no plugin found for TProof with a"
934 " config file of '%s'", fConfFile.Data());
935 SendLogFile(-99);
936 Terminate(0);
937 return -1;
938 }
939
940 // load the plugin
941 if (h->LoadPlugin() == -1) {
942 Error("CreateServer", "plugin for TProof could not be loaded");
943 SendLogFile(-99);
944 Terminate(0);
945 return -1;
946 }
947
948 // make instance of TProof
949 fProof = reinterpret_cast<TProof*>(h->ExecPlugin(5, master.Data(),
950 fConfFile.Data(),
951 GetConfDir(),
952 fLogLevel, 0));
953 if (!fProof || !fProof->IsValid()) {
954 Error("CreateServer", "plugin for TProof could not be executed");
956 SendLogFile(-99);
957 Terminate(0);
958 return -1;
959 }
960 // Find out if we are a master in direct contact only with workers
962
963 SendLogFile();
964 }
965
966 // Setup the shutdown timer
967 if (!fShutdownTimer) {
968 // Check activity on socket every 5 mins
969 fShutdownTimer = new TShutdownTimer(this, 300000);
971 }
972
973 // Check if schema evolution is effective: clients running versions <=17 do not
974 // support that: send a warning message
975 if (fProtocol <= 17) {
976 TString msg;
977 msg.Form("Warning: client version is too old: automatic schema evolution is ineffective.\n"
978 " This may generate compatibility problems between streamed objects.\n"
979 " The advise is to move to ROOT >= 5.21/02 .");
980 SendAsynMessage(msg.Data());
981 }
982
983 // Setup the idle timer
984 if (IsMaster() && !fIdleTOTimer) {
985 // Check activity on socket every 5 mins
986 Int_t idle_to = gEnv->GetValue("ProofServ.IdleTimeout", -1);
987 if (idle_to > 0) {
988 fIdleTOTimer = new TIdleTOTimer(this, idle_to * 1000);
990 if (gProofDebugLevel > 0)
991 Info("CreateServer", " idle timer started (%d secs)", idle_to);
992 } else if (gProofDebugLevel > 0) {
993 Info("CreateServer", " idle timer not started (no idle timeout requested)");
994 }
995 }
996
997 // Done
998 return 0;
999}
1000
1001////////////////////////////////////////////////////////////////////////////////
1002/// Cleanup. Not really necessary since after this dtor there is no
1003/// live anyway.
1004
1006{
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
1097TObject *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
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) {
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
1286void 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")) {
1303 fEndMaster = kTRUE;
1304 } else if (!strcmp(argv[1], "proofslave")) {
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)
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",
1402 fgLastMsg.Data(), fgLastEntry);
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",
1418 fgLastMsg.Data(), fgLastEntry);
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())
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:
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
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 FlushLogFile(); // Avoid sending (error) messages at next action
1774 }
1775 break;
1776
1777 case kPROOF_SENDFILE:
1778 if (!all && fProtocol <= 19) {
1779 // Come back later
1780 rc = 2;
1781 } else {
1782 mess->ReadString(str, sizeof(str));
1783 Long_t size;
1784 Int_t bin, fw = 1;
1785 char name[1024];
1786 if (fProtocol > 5) {
1787 sscanf(str, "%1023s %d %ld %d", name, &bin, &size, &fw);
1788 } else {
1789 sscanf(str, "%1023s %d %ld", name, &bin, &size);
1790 }
1791 TString fnam(name);
1792 Bool_t copytocache = kTRUE;
1793 if (fnam.BeginsWith("cache:")) {
1794 fnam.ReplaceAll("cache:", TString::Format("%s/", fCacheDir.Data()));
1795 copytocache = kFALSE;
1796 }
1797
1798 Int_t rfrc = 0;
1799 if (size > 0) {
1800 rfrc = ReceiveFile(fnam, bin ? kTRUE : kFALSE, size);
1801 } else {
1802 // Take it from the cache
1803 if (!fnam.BeginsWith(fCacheDir.Data())) {
1804 fnam.Insert(0, TString::Format("%s/", fCacheDir.Data()));
1805 }
1806 }
1807 if (rfrc == 0) {
1808 // copy file to cache if not a PAR file
1809 if (copytocache && size > 0 && !fPackMgr->IsInDir(name))
1810 gSystem->Exec(TString::Format("%s %s %s", kCP, fnam.Data(), fCacheDir.Data()));
1811 if (IsMaster() && fw == 1) {
1813 if (bin)
1814 opt |= TProof::kBinary;
1815 PDB(kGlobal, 1)
1816 Info("HandleSocketInput","forwarding file: %s", fnam.Data());
1817 if (fProof->SendFile(fnam, opt, (copytocache ? "cache" : "")) < 0) {
1818 Error("HandleSocketInput", "forwarding file: %s", fnam.Data());
1819 }
1820 }
1822 } else {
1823 // There was an error
1824 SendLogFile(1);
1825 }
1826 }
1827 break;
1828
1829 case kPROOF_LOGFILE:
1830 {
1831 Int_t start, end;
1832 (*mess) >> start >> end;
1833 PDB(kGlobal, 1)
1834 Info("HandleSocketInput:kPROOF_LOGFILE",
1835 "Logfile request - byte range: %d - %d", start, end);
1836
1837 LogToMaster();
1838 SendLogFile(0, start, end);
1839 }
1840 break;
1841
1842 case kPROOF_PARALLEL:
1843 if (all) {
1844 if (IsMaster()) {
1845 Int_t nodes;
1846 Bool_t random = kFALSE;
1847 (*mess) >> nodes;
1848 if ((mess->BufferSize() > mess->Length()))
1849 (*mess) >> random;
1850 if (fProof) fProof->SetParallel(nodes, random);
1851 rc = 1;
1852 }
1853 } else {
1854 rc = -1;
1855 }
1856 // Notify
1857 SendLogFile();
1858 break;
1859
1860 case kPROOF_CACHE:
1861 if (!all && fProtocol <= 19) {
1862 // Come back later
1863 rc = 2;
1864 } else {
1866 PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_CACHE","enter");
1867 Int_t hcrc = HandleCache(mess, pslb);
1868 // Notify
1869 SendLogFile(hcrc);
1870 }
1871 break;
1872
1873 case kPROOF_WORKERLISTS:
1874 { Int_t wlrc = -1;
1875 if (all) {
1876 if (IsMaster())
1877 wlrc = HandleWorkerLists(mess);
1878 else
1879 Warning("HandleSocketInput:kPROOF_WORKERLISTS",
1880 "Action meaning-less on worker nodes: protocol error?");
1881 } else {
1882 rc = -1;
1883 }
1884 // Notify
1885 SendLogFile(wlrc);
1886 }
1887 break;
1888
1890 if (all) {
1891 PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETSLAVEINFO", "Enter");
1892 if (IsMaster()) {
1893
1894 Bool_t ok = kTRUE;
1895 // if the session does not have workers and is in the dynamic mode
1896 if (fProof->UseDynamicStartup()) {
1897 ok = kFALSE;
1898 // get the a list of workers and start them
1899 Int_t pc = 0;
1900 TList* workerList = new TList();
1901 EQueryAction retVal = GetWorkers(workerList, pc);
1902 if (retVal != TProofServ::kQueryStop && retVal != TProofServ::kQueryEnqueued) {
1903 if (Int_t ret = fProof->AddWorkers(workerList) < 0) {
1904 Error("HandleSocketInput:kPROOF_GETSLAVEINFO",
1905 "adding a list of worker nodes returned: %d", ret);
1906 }
1907 } else {
1908 Error("HandleSocketInput:kPROOF_GETSLAVEINFO",
1909 "getting list of worker nodes returned: %d", retVal);
1910 }
1911 ok = kTRUE;
1912 }
1913 if (ok) {
1914 TList *info = fProof->GetListOfSlaveInfos();
1916 answ << info;
1917 fSocket->Send(answ);
1918 // stop the workers
1920 }
1921 } else {
1923 TList *info = new TList;
1925 SysInfo_t si;
1926 gSystem->GetSysInfo(&si);
1927 wi->SetSysInfo(si);
1928 info->Add(wi);
1929 answ << (TList *)info;
1930 fSocket->Send(answ);
1931 info->SetOwner(kTRUE);
1932 delete info;
1933 }
1934
1935 PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETSLAVEINFO", "Done");
1936 } else {
1938 answ << (TList *)0;
1939 fSocket->Send(answ);
1940 rc = -1;
1941 }
1942 break;
1943
1945 if (all) {
1946 PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETTREEHEADER", "Enter");
1947
1949 if (p) {
1950 p->HandleGetTreeHeader(mess);
1951 delete p;
1952 } else {
1953 Error("HandleSocketInput:kPROOF_GETTREEHEADER", "could not create TProofPlayer instance!");
1954 }
1955
1956 PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETTREEHEADER", "Done");
1957 } else {
1959 answ << TString("Failed") << (TObject *)0;
1960 fSocket->Send(answ);
1961 rc = -1;
1962 }
1963 break;
1964
1966 { PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETOUTPUTLIST", "Enter");
1967 TList* outputList = 0;
1968 if (IsMaster()) {
1969 outputList = fProof->GetOutputList();
1970 if (!outputList)
1971 outputList = new TList();
1972 } else {
1973 outputList = new TList();
1974 if (fProof->GetPlayer()) {
1975 TList *olist = fProof->GetPlayer()->GetOutputList();
1976 TIter next(olist);
1977 TObject *o;
1978 while ( (o = next()) ) {
1979 outputList->Add(new TNamed(o->GetName(), ""));
1980 }
1981 }
1982 }
1983 outputList->SetOwner();
1985 answ << outputList;
1986 fSocket->Send(answ);
1987 delete outputList;
1988 PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_GETOUTPUTLIST", "Done");
1989 }
1990 break;
1991
1993 if (all) {
1994 PDB(kGlobal, 1)
1995 Info("HandleSocketInput:kPROOF_VALIDATE_DSET", "Enter");
1996
1997 TDSet* dset = 0;
1998 (*mess) >> dset;
1999
2000 if (IsMaster()) fProof->ValidateDSet(dset);
2001 else dset->Validate();
2002
2004 answ << dset;
2005 fSocket->Send(answ);
2006 delete dset;
2007 PDB(kGlobal, 1)
2008 Info("HandleSocketInput:kPROOF_VALIDATE_DSET", "Done");
2009 } else {
2010 rc = -1;
2011 }
2012 // Notify
2013 SendLogFile();
2014 break;
2015
2016 case kPROOF_DATA_READY:
2017 if (all) {
2018 PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_DATA_READY", "Enter");
2020 if (IsMaster()) {
2021 Long64_t totalbytes = 0, bytesready = 0;
2022 Bool_t dataready = fProof->IsDataReady(totalbytes, bytesready);
2023 answ << dataready << totalbytes << bytesready;
2024 } else {
2025 Error("HandleSocketInput:kPROOF_DATA_READY",
2026 "This message should not be sent to slaves");
2027 answ << kFALSE << Long64_t(0) << Long64_t(0);
2028 }
2029 fSocket->Send(answ);
2030 PDB(kGlobal, 1) Info("HandleSocketInput:kPROOF_DATA_READY", "Done");
2031 } else {
2033 answ << kFALSE << Long64_t(0) << Long64_t(0);
2034 fSocket->Send(answ);
2035 rc = -1;
2036 }
2037 // Notify
2038 SendLogFile();
2039 break;
2040
2041 case kPROOF_DATASETS:
2042 { Int_t dsrc = -1;
2043 if (fProtocol > 16) {
2044 dsrc = HandleDataSets(mess, pslb);
2045 } else {
2046 Error("HandleSocketInput", "old client: no or incompatible dataset support");
2047 }
2048 SendLogFile(dsrc);
2049 }
2050 break;
2051
2052 case kPROOF_SUBMERGER:
2053 { HandleSubmerger(mess);
2054 }
2055 break;
2056
2058 if (all) {
2059 lirc = HandleLibIncPath(mess);
2060 } else {
2061 rc = -1;
2062 }
2063 // Notify the client
2064 if (lirc > 0) SendLogFile();
2065 break;
2066
2067 case kPROOF_REALTIMELOG:
2068 { Bool_t on;
2069 (*mess) >> on;
2070 PDB(kGlobal, 1)
2071 Info("HandleSocketInput:kPROOF_REALTIMELOG",
2072 "setting real-time logging %s", (on ? "ON" : "OFF"));
2073 fRealTimeLog = on;
2074 // Forward the request to lower levels
2075 if (IsMaster())
2077 }
2078 break;
2079
2080 case kPROOF_FORK:
2081 if (all) {
2082 HandleFork(mess);
2083 LogToMaster();
2084 } else {
2085 rc = -1;
2086 }
2087 SendLogFile();
2088 break;
2089
2091 if (all) {
2092 // This message resumes the session; should not come during processing.
2093
2094 if (WaitingQueries() == 0) {
2095 Error("HandleSocketInput", "no queries enqueued");
2096 break;
2097 }
2098
2099 // Similar to handle process
2100 // get the list of workers and start them
2101 TList *workerList = (fProof->UseDynamicStartup()) ? new TList : (TList *)0;
2102 Int_t pc = 0;
2103 EQueryAction retVal = GetWorkers(workerList, pc, kTRUE);
2104
2105 if (retVal == TProofServ::kQueryOK) {
2106 Int_t ret = 0;
2107 if (workerList && (ret = fProof->AddWorkers(workerList)) < 0) {
2108 Error("HandleSocketInput", "adding a list of worker nodes returned: %d", ret);
2109 } else {
2110 ProcessNext(pslb);
2111 // Set idle
2112 SetIdle(kTRUE);
2113 // Signal the client that we are idle
2115 Bool_t waiting = (WaitingQueries() > 0) ? kTRUE : kFALSE;
2116 m << waiting;
2117 fSocket->Send(m);
2118 }
2119 } else {
2120 if (retVal == TProofServ::kQueryStop) {
2121 Error("HandleSocketInput", "error getting list of worker nodes");
2122 } else if (retVal != TProofServ::kQueryEnqueued) {
2123 Warning("HandleSocketInput", "query was re-queued!");
2124 } else {
2125 Error("HandleSocketInput", "unexpected answer: %d", retVal);
2126 break;
2127 }
2128 }
2129
2130 }
2131 break;
2132
2133 case kPROOF_GOASYNC:
2134 { // The client requested to switch to asynchronous mode:
2135 // communicate the sequential number of the running query for later
2136 // identification, if any
2137 if (!IsIdle() && fPlayer) {
2138 // Get query currently being processed
2141 m << pq->GetSeqNum() << kFALSE;
2142 fSocket->Send(m);
2143 } else {
2144 // Idle or undefined: nothing to do; ignore
2145 SendAsynMessage("Processing request to go asynchronous:"
2146 " idle or undefined player - ignoring");
2147 }
2148 }
2149 break;
2150
2151 case kPROOF_ECHO:
2152 { // Echo request: an object has been sent along. If the object is a
2153 // string, it is simply echoed back to the client from the master
2154 // and each worker. Elsewhere, the output of TObject::Print() is
2155 // sent. Received object is disposed after usage.
2156
2157 TObject *obj = mess->ReadObject(0x0); // class type ignored
2158
2159 if (IsMaster()) {
2160 // We are on master
2161 // dbTODO: forward on dynamic startup when wrks are up
2162 if (IsParallel() && fProof && !fProof->UseDynamicStartup()) {
2163 fProof->Echo(obj); // forward to lower layer
2164 }
2165 }
2166
2168 TString smsg;
2169
2170 if (obj->InheritsFrom(TObjString::Class())) {
2171 // It's a string: echo it
2172 smsg.Form("Echo response from %s:%s: %s",
2174 ((TObjString *)obj)->String().Data());
2175 }
2176 else {
2177 // Not a string: collect Print() output and send it
2178
2179 // Output to tempfile
2180 TString tmpfn = "echo-out-";
2181 FILE *tf = gSystem->TempFileName(tmpfn, fDataDir);
2182 if (!tf || (gSystem->RedirectOutput(tmpfn.Data()) == -1)) {
2183 Error("HandleSocketInput", "Can't redirect output");
2184 if (tf) {
2185 fclose(tf);
2186 gSystem->Unlink(tmpfn);
2187 }
2188 rc = -1;
2189 delete obj;
2190 break;
2191 }
2192 //cout << obj->ClassName() << endl;
2193 obj->Print();
2194 gSystem->RedirectOutput(0x0); // restore
2195 fclose(tf);
2196
2197 // Read file back and send it via message
2198 smsg.Form("*** Echo response from %s:%s ***\n",
2200 TMacro *fr = new TMacro();
2201 fr->ReadFile(tmpfn);
2202 TIter nextLine(fr->GetListOfLines());
2204 while (( line = (TObjString *)nextLine() )) {
2205 smsg.Append( line->String() );
2206 }
2207
2208 // Close the reader (TMacro) and remove file
2209 delete fr;
2210 gSystem->Unlink(tmpfn);
2211 }
2212
2213 // Send message and dispose object
2214 rmsg << smsg;
2215 GetSocket()->Send(rmsg);
2216 delete obj;
2217 }
2218 break;
2219
2220 default:
2221 Error("HandleSocketInput", "unknown command %d", what);
2222 rc = -2;
2223 break;
2224 }
2225
2226 fRealTime += (Float_t)timer.RealTime();
2227 fCpuTime += (Float_t)timer.CpuTime();
2228
2229 if (!(slb.IsNull()) || fgLogToSysLog > 1) {
2230 TString s;
2231 s.Form("%s %d %.3f %.3f %s", fgSysLogEntity.Data(),
2232 what, timer.RealTime(), timer.CpuTime(), slb.Data());
2233 gSystem->Syslog(kLogNotice, s.Data());
2234 }
2235
2236 // Done
2237 return rc;
2238}
2239
2240////////////////////////////////////////////////////////////////////////////////
2241/// Accept and merge results from a set of workers
2242
2244{
2245 TMessage *mess = new TMessage();
2246 Int_t mergedWorkers = 0;
2247
2248 PDB(kSubmerger, 1) Info("AcceptResults", "enter");
2249
2250 // Overall result of this procedure
2251 Bool_t result = kTRUE;
2252
2253 fMergingMonitor = new TMonitor();
2255
2256 Int_t numworkers = 0;
2257 while (fMergingMonitor->GetActive() > 0 && mergedWorkers < connections) {
2258
2260 if (!s) {
2261 Info("AcceptResults", "interrupt!");
2262 result = kFALSE;
2263 break;
2264 }
2265
2266 if (s == fMergingSocket) {
2267 // New incoming connection
2268 TSocket *sw = fMergingSocket->Accept();
2269 if (sw && sw != (TSocket *)(-1)) {
2270 fMergingMonitor->Add(sw);
2271
2272 PDB(kSubmerger, 2)
2273 Info("AcceptResults", "connection from a worker accepted on merger %s ",
2274 fOrdinal.Data());
2275 // All assigned workers are connected
2276 if (++numworkers >= connections)
2278 } else {
2279 PDB(kSubmerger, 1)
2280 Info("AcceptResults", "spurious signal found of merging socket");
2281 }
2282 } else {
2283 if (s->Recv(mess) < 0) {
2284 Error("AcceptResults", "problems receiving message");
2285 continue;
2286 }
2287 PDB(kSubmerger, 2)
2288 Info("AcceptResults", "message received: %d ", (mess ? mess->What() : 0));
2289 if (!mess) {
2290 Error("AcceptResults", "message received: %p ", mess);
2291 continue;
2292 }
2293 Int_t type = 0;
2294
2295 // Read output objec(s) from the received message
2296 while ((mess->BufferSize() > mess->Length())) {
2297 (*mess) >> type;
2298
2299 PDB(kSubmerger, 2) Info("AcceptResults", " type %d ", type);
2300 if (type == 2) {
2301 mergedWorkers++;
2302 PDB(kSubmerger, 2)
2303 Info("AcceptResults",
2304 "a new worker has been mergerd. Total merged workers: %d",
2305 mergedWorkers);
2306 }
2307 TObject *o = mess->ReadObject(TObject::Class());
2308 if (mergerPlayer->AddOutputObject(o) == 1) {
2309 // Remove the object if it has been merged
2310 PDB(kSubmerger, 2) Info("AcceptResults", "removing %p (has been merged)", o);
2311 SafeDelete(o);
2312 } else
2313 PDB(kSubmerger, 2) Info("AcceptResults", "%p not merged yet", o);
2314 }
2315 }
2316 }
2318
2320 Int_t size = sockets->GetSize();
2321 for (Int_t i =0; i< size; ++i){
2322 ((TSocket*)(sockets->At(i)))->Close();
2323 PDB(kSubmerger, 2) Info("AcceptResults", "closing socket");
2324 delete ((TSocket*)(sockets->At(i)));
2325 }
2326
2329
2330 PDB(kSubmerger, 2) Info("AcceptResults", "exit: %d", result);
2331 return result;
2332}
2333
2334////////////////////////////////////////////////////////////////////////////////
2335/// Handle Out-Of-Band data sent by the master or client.
2336
2338{
2339 char oob_byte;
2340 Int_t n, nch, wasted = 0;
2341
2342 const Int_t kBufSize = 1024;
2343 char waste[kBufSize];
2344
2345 // Real-time notification of messages
2347
2348 PDB(kGlobal, 5)
2349 Info("HandleUrgentData", "handling oob...");
2350
2351 // Receive the OOB byte
2352 while ((n = fSocket->RecvRaw(&oob_byte, 1, kOob)) < 0) {
2353 if (n == -2) { // EWOULDBLOCK
2354 //
2355 // The OOB data has not yet arrived: flush the input stream
2356 //
2357 // In some systems (Solaris) regular recv() does not return upon
2358 // receipt of the oob byte, which makes the below call to recv()
2359 // block indefinitely if there are no other data in the queue.
2360 // FIONREAD ioctl can be used to check if there are actually any
2361 // data to be flushed. If not, wait for a while for the oob byte
2362 // to arrive and try to read it again.
2363 //
2365 if (nch == 0) {
2366 gSystem->Sleep(1000);
2367 continue;
2368 }
2369
2370 if (nch > kBufSize) nch = kBufSize;
2371 n = fSocket->RecvRaw(waste, nch);
2372 if (n <= 0) {
2373 Error("HandleUrgentData", "error receiving waste");
2374 break;
2375 }
2376 wasted = 1;
2377 } else {
2378 Error("HandleUrgentData", "error receiving OOB");
2379 return;
2380 }
2381 }
2382
2383 PDB(kGlobal, 5)
2384 Info("HandleUrgentData", "got OOB byte: %d\n", oob_byte);
2385
2386 if (fProof) fProof->SetActive();
2387
2388 switch (oob_byte) {
2389
2391 Info("HandleUrgentData", "*** Hard Interrupt");
2392
2393 // If master server, propagate interrupt to slaves
2394 if (IsMaster())
2396
2397 // Flush input socket
2398 while (1) {
2399 Int_t atmark;
2400
2401 fSocket->GetOption(kAtMark, atmark);
2402
2403 if (atmark) {
2404 // Send the OOB byte back so that the client knows where
2405 // to stop flushing its input stream of obsolete messages
2406 n = fSocket->SendRaw(&oob_byte, 1, kOob);
2407 if (n <= 0)
2408 Error("HandleUrgentData", "error sending OOB");
2409 break;
2410 }
2411
2412 // find out number of bytes to read before atmark
2414 if (nch == 0) {
2415 gSystem->Sleep(1000);
2416 continue;
2417 }
2418
2419 if (nch > kBufSize) nch = kBufSize;
2420 n = fSocket->RecvRaw(waste, nch);
2421 if (n <= 0) {
2422 Error("HandleUrgentData", "error receiving waste (2)");
2423 break;
2424 }
2425 }
2426
2427 SendLogFile();
2428
2429 break;
2430
2432 Info("HandleUrgentData", "Soft Interrupt");
2433
2434 // If master server, propagate interrupt to slaves
2435 if (IsMaster())
2437
2438 if (wasted) {
2439 Error("HandleUrgentData", "soft interrupt flushed stream");
2440 break;
2441 }
2442
2443 Interrupt();
2444
2445 SendLogFile();
2446
2447 break;
2448
2450 Info("HandleUrgentData", "Shutdown Interrupt");
2451
2452 // If master server, propagate interrupt to slaves
2453 if (IsMaster())
2455
2456 Terminate(0);
2457
2458 break;
2459
2460 default:
2461 Error("HandleUrgentData", "unexpected OOB byte");
2462 break;
2463 }
2464
2466}
2467
2468////////////////////////////////////////////////////////////////////////////////
2469/// Called when the client is not alive anymore (i.e. when kKeepAlive
2470/// has failed).
2471
2473{
2474 // Real-time notification of messages
2476
2477 if (IsMaster()) {
2478 // Check if we are here because client is closed. Try to ping client,
2479 // if that works it we are here because some slave died
2480 if (fSocket->Send(kPROOF_PING | kMESS_ACK) < 0) {
2481 Info("HandleSigPipe", "keepAlive probe failed");
2482 // Tell slaves we are going to close since there is no client anymore
2483
2484 fProof->SetActive();
2487 Terminate(0);
2488 }
2489 } else {
2490 Info("HandleSigPipe", "keepAlive probe failed");
2491 Terminate(0); // will not return from here....
2492 }
2493}
2494
2495////////////////////////////////////////////////////////////////////////////////
2496/// True if in parallel mode.
2497
2499{
2500 if (IsMaster() && fProof)
2501 return fProof->IsParallel() || fProof->UseDynamicStartup() ;
2502
2503 // false in case we are a slave
2504 return kFALSE;
2505}
2506
2507////////////////////////////////////////////////////////////////////////////////
2508/// Print status of slave server.
2509
2510void TProofServ::Print(Option_t *option) const
2511{
2512 if (IsMaster() && fProof)
2513 fProof->Print(option);
2514 else
2515 Printf("This is worker %s", gSystem->HostName());
2516}
2517
2518////////////////////////////////////////////////////////////////////////////////
2519/// Redirect stdout to a log file. This log file will be flushed to the
2520/// client or master after each command.
2521
2522void TProofServ::RedirectOutput(const char *dir, const char *mode)
2523{
2524 char logfile[512];
2525
2526 TString sdir = (dir && strlen(dir) > 0) ? dir : fSessionDir.Data();
2527 if (IsMaster()) {
2528 snprintf(logfile, 512, "%s/master-%s.log", sdir.Data(), fOrdinal.Data());
2529 } else {
2530 snprintf(logfile, 512, "%s/worker-%s.log", sdir.Data(), fOrdinal.Data());
2531 }
2532
2533 if ((freopen(logfile, mode, stdout)) == 0)
2534 SysError("RedirectOutput", "could not freopen stdout (%s)", logfile);
2535
2536 if ((dup2(fileno(stdout), fileno(stderr))) < 0)
2537 SysError("RedirectOutput", "could not redirect stderr");
2538
2539 if ((fLogFile = fopen(logfile, "r")) == 0)
2540 SysError("RedirectOutput", "could not open logfile '%s'", logfile);
2541
2542 // from this point on stdout and stderr are properly redirected
2543 if (fProtocol < 4 && fWorkDir != TString::Format("~/%s", kPROOF_WorkDir)) {
2544 Warning("RedirectOutput", "no way to tell master (or client) where"
2545 " to upload packages");
2546 }
2547}
2548
2549////////////////////////////////////////////////////////////////////////////////
2550/// Reset PROOF environment to be ready for execution of next command.
2551
2552void TProofServ::Reset(const char *dir)
2553{
2554 // First go to new directory. Check first that we got a reasonable path;
2555 // in PROOF-Lite it may not be the case
2556 TString dd(dir);
2557 if (!dd.BeginsWith("proofserv")) {
2558 Int_t ic = dd.Index(":");
2559 if (ic != kNPOS)
2560 dd.Replace(0, ic, "proofserv");
2561 }
2562 gDirectory->cd(dd.Data());
2563
2564 // Clear interpreter environment.
2565 gROOT->Reset();
2566
2567 // Make sure current directory is empty (don't delete anything when
2568 // we happen to be in the ROOT memory only directory!?)
2569 if (gDirectory != gROOT) {
2570 gDirectory->Delete();
2571 }
2572
2574}
2575
2576////////////////////////////////////////////////////////////////////////////////
2577/// Receive a file, either sent by a client or a master server.
2578/// If bin is true it is a binary file, other wise it is an ASCII
2579/// file and we need to check for Windows \r tokens. Returns -1 in
2580/// case of error, 0 otherwise.
2581
2583{
2584 if (size <= 0) return 0;
2585
2586 // open file, overwrite already existing file
2587 Int_t fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
2588 if (fd < 0) {
2589 SysError("ReceiveFile", "error opening file %s", file);
2590 return -1;
2591 }
2592
2593 const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
2594 char buf[kMAXBUF], cpy[kMAXBUF];
2595
2596 Int_t left, r;
2597 Long64_t filesize = 0;
2598
2599 while (filesize < size) {
2600 left = Int_t(size - filesize);
2601 if (left > kMAXBUF)
2602 left = kMAXBUF;
2603 r = fSocket->RecvRaw(&buf, left);
2604 if (r > 0) {
2605 char *p = buf;
2606
2607 filesize += r;
2608 while (r) {
2609 Int_t w;
2610
2611 if (!bin) {
2612 Int_t k = 0, i = 0, j = 0;
2613 char *q;
2614 while (i < r) {
2615 if (p[i] == '\r') {
2616 i++;
2617 k++;
2618 }
2619 cpy[j++] = buf[i++];
2620 }
2621 q = cpy;
2622 r -= k;
2623 w = write(fd, q, r);
2624 } else {
2625 w = write(fd, p, r);
2626 }
2627
2628 if (w < 0) {
2629 SysError("ReceiveFile", "error writing to file %s", file);
2630 close(fd);
2631 return -1;
2632 }
2633 r -= w;
2634 p += w;
2635 }
2636 } else if (r < 0) {
2637 Error("ReceiveFile", "error during receiving file %s", file);
2638 close(fd);
2639 return -1;
2640 }
2641 }
2642
2643 close(fd);
2644
2645 if (chmod(file, 0644) != 0)
2646 Warning("ReceiveFile", "error setting mode 0644 on file %s", file);
2647
2648 return 0;
2649}
2650
2651////////////////////////////////////////////////////////////////////////////////
2652/// Main server eventloop.
2653
2655{
2656 // Setup the server
2657 if (CreateServer() == 0) {
2658
2659 // Run the main event loop
2660 TApplication::Run(retrn);
2661 }
2662}
2663
2664////////////////////////////////////////////////////////////////////////////////
2665/// Send log file to master.
2666/// If start > -1 send only bytes in the range from start to end,
2667/// if end <= start send everything from start.
2668
2670{
2671 // Determine the number of bytes left to be read from the log file.
2672 fflush(stdout);
2673
2674 // On workers we do not send the logs to masters (to avoid duplication of
2675 // text) unless asked explicitly, e.g. after an Exec(...) request.
2676 if (!IsMaster()) {
2677 if (!fSendLogToMaster) {
2678 FlushLogFile();
2679 } else {
2680 // Decide case by case
2682 }
2683 }
2684
2685 off_t ltot=0, lnow=0;
2686 Int_t left = -1;
2687 Bool_t adhoc = kFALSE;
2688
2689 if (fLogFileDes > -1) {
2690 ltot = lseek(fileno(stdout), (off_t) 0, SEEK_END);
2691 lnow = lseek(fLogFileDes, (off_t) 0, SEEK_CUR);
2692
2693 if (ltot >= 0 && lnow >= 0) {
2694 if (start > -1) {
2695 lseek(fLogFileDes, (off_t) start, SEEK_SET);
2696 if (end <= start || end > ltot)
2697 end = ltot;
2698 left = (Int_t)(end - start);
2699 if (end < ltot)
2700 left++;
2701 adhoc = kTRUE;
2702 } else {
2703 left = (Int_t)(ltot - lnow);
2704 }
2705 }
2706 }
2707
2708 if (left > 0) {
2709 if (fSocket->Send(left, kPROOF_LOGFILE) < 0) {
2710 SysError("SendLogFile", "error sending kPROOF_LOGFILE");
2711 return;
2712 }
2713
2714 const Int_t kMAXBUF = 32768; //16384 //65536;
2715 char buf[kMAXBUF];
2716 Int_t wanted = (left > kMAXBUF) ? kMAXBUF : left;
2717 Int_t len;
2718 do {
2719 while ((len = read(fLogFileDes, buf, wanted)) < 0 &&
2720 TSystem::GetErrno() == EINTR)
2722
2723 if (len < 0) {
2724 SysError("SendLogFile", "error reading log file");
2725 break;
2726 }
2727
2728 if (end == ltot && len == wanted)
2729 buf[len-1] = '\n';
2730
2731 if (fSocket->SendRaw(buf, len) < 0) {
2732 SysError("SendLogFile", "error sending log file");
2733 break;
2734 }
2735
2736 // Update counters
2737 left -= len;
2738 wanted = (left > kMAXBUF) ? kMAXBUF : left;
2739
2740 } while (len > 0 && left > 0);
2741 }
2742
2743 // Restore initial position if partial send
2744 if (adhoc && lnow >=0 )
2745 lseek(fLogFileDes, lnow, SEEK_SET);
2746
2748 if (IsMaster())
2749 mess << status << (fProof ? fProof->GetParallel() : 0);
2750 else
2751 mess << status << (Int_t) 1;
2752
2753 if (fSocket->Send(mess) < 0) {
2754 SysError("SendLogFile", "error sending kPROOF_LOGDONE");
2755 return;
2756 }
2757
2758 PDB(kGlobal, 1) Info("SendLogFile", "kPROOF_LOGDONE sent");
2759}
2760
2761////////////////////////////////////////////////////////////////////////////////
2762/// Send statistics of slave server to master or client.
2763
2765{
2766 Long64_t bytesread = TFile::GetFileBytesRead();
2767 Float_t cputime = fCpuTime, realtime = fRealTime;
2768 if (IsMaster()) {
2769 bytesread = fProof->GetBytesRead();
2770 cputime = fProof->GetCpuTime();
2771 }
2772
2774 TString workdir = gSystem->WorkingDirectory(); // expect TString on other side
2775 mess << bytesread << realtime << cputime << workdir;
2776 if (fProtocol >= 4) mess << TString(gProofServ->GetWorkDir());
2777 mess << TString(gProofServ->GetImage());
2778 fSocket->Send(mess);
2779}
2780
2781////////////////////////////////////////////////////////////////////////////////
2782/// Send number of parallel nodes to master or client.
2783
2785{
2786 Int_t nparallel = 0;
2787 if (IsMaster()) {
2788 PDB(kGlobal, 2)
2789 Info("SendParallel", "Will invoke AskParallel()");
2791 PDB(kGlobal, 2)
2792 Info("SendParallel", "Will invoke GetParallel()");
2793 nparallel = fProof->GetParallel();
2794 } else {
2795 nparallel = 1;
2796 }
2797
2799 mess << nparallel << async;
2800 fSocket->Send(mess);
2801}
2802
2803////////////////////////////////////////////////////////////////////////////////
2804/// Print the ProofServ logo on standard output.
2805/// Return 0 on success, -1 on failure
2806
2808{
2809 char str[512];
2810
2811 if (IsMaster()) {
2812 snprintf(str, 512, "**** Welcome to the PROOF server @ %s ****", gSystem->HostName());
2813 } else {
2814 snprintf(str, 512, "**** PROOF slave server @ %s started ****", gSystem->HostName());
2815 }
2816
2817 if (fSocket->Send(str) != 1+static_cast<Int_t>(strlen(str))) {
2818 Error("Setup", "failed to send proof server startup message");
2819 return -1;
2820 }
2821
2822 // exchange protocol level between client and master and between
2823 // master and slave
2824 Int_t what;
2825 if (fSocket->Recv(fProtocol, what) != 2*sizeof(Int_t)) {
2826 Error("Setup", "failed to receive remote proof protocol");
2827 return -1;
2828 }
2829 if (fSocket->Send(kPROOF_Protocol, kROOTD_PROTOCOL) != 2*sizeof(Int_t)) {
2830 Error("Setup", "failed to send local proof protocol");
2831 return -1;
2832 }
2833
2834 // If old version, setup authentication related stuff
2835 if (fProtocol < 5) {
2836 TString wconf;
2837 if (OldAuthSetup(wconf) != 0) {
2838 Error("Setup", "OldAuthSetup: failed to setup authentication");
2839 return -1;
2840 }
2841 if (IsMaster()) {
2842 fConfFile = wconf;
2843 fWorkDir.Form("~/%s", kPROOF_WorkDir);
2844 } else {
2845 if (fProtocol < 4) {
2846 fWorkDir.Form("~/%s", kPROOF_WorkDir);
2847 } else {
2848 fWorkDir = wconf;
2849 if (fWorkDir.IsNull()) fWorkDir.Form("~/%s", kPROOF_WorkDir);
2850 }
2851 }
2852 } else {
2853
2854 // Receive some useful information
2855 TMessage *mess;
2856 if ((fSocket->Recv(mess) <= 0) || !mess) {
2857 Error("Setup", "failed to receive ordinal and config info");
2858 return -1;
2859 }
2860 if (IsMaster()) {
2861 (*mess) >> fUser >> fOrdinal >> fConfFile;
2862 fWorkDir = gEnv->GetValue("ProofServ.Sandbox", TString::Format("~/%s", kPROOF_WorkDir));
2863 } else {
2864 (*mess) >> fUser >> fOrdinal >> fWorkDir;
2865 if (fWorkDir.IsNull())
2866 fWorkDir = gEnv->GetValue("ProofServ.Sandbox", TString::Format("~/%s", kPROOF_WorkDir));
2867 }
2868 // Set the correct prefix
2869 if (fOrdinal != "-1")
2870 fPrefix += fOrdinal;
2872 delete mess;
2873 }
2874
2875 if (IsMaster()) {
2876
2877 // strip off any prooftype directives
2878 TString conffile = fConfFile;
2879 conffile.Remove(0, 1 + conffile.Index(":"));
2880
2881 // parse config file to find working directory
2882 TProofResourcesStatic resources(fConfDir, conffile);
2883 if (resources.IsValid()) {
2884 if (resources.GetMaster()) {
2885 TString tmpWorkDir = resources.GetMaster()->GetWorkDir();
2886 if (tmpWorkDir != "")
2887 fWorkDir = tmpWorkDir;
2888 }
2889 } else {
2890 Info("Setup", "invalid config file %s (missing or unreadable",
2891 resources.GetFileName().Data());
2892 }
2893 }
2894
2895 // Set $HOME and $PATH. The HOME directory was already set to the
2896 // user's home directory by proofd.
2897 gSystem->Setenv("HOME", gSystem->HomeDirectory());
2898
2899 // Add user name in case of non default workdir
2900 if (fWorkDir.BeginsWith("/") &&
2901 !fWorkDir.BeginsWith(gSystem->HomeDirectory())) {
2902 if (!fWorkDir.EndsWith("/"))
2903 fWorkDir += "/";
2905 if (u) {
2906 fWorkDir += u->fUser;
2907 delete u;
2908 }
2909 }
2910
2911 // Goto to the main PROOF working directory
2912 char *workdir = gSystem->ExpandPathName(fWorkDir.Data());
2913 fWorkDir = workdir;
2914 delete [] workdir;
2915 if (gProofDebugLevel > 0)
2916 Info("Setup", "working directory set to %s", fWorkDir.Data());
2917
2918 // host first name
2919 TString host = gSystem->HostName();
2920 if (host.Index(".") != kNPOS)
2921 host.Remove(host.Index("."));
2922
2923 // Session tag
2924 fSessionTag.Form("%s-%s-%ld-%d", fOrdinal.Data(), host.Data(),
2925 (Long_t)TTimeStamp().GetSec(),gSystem->GetPid());
2927
2928 // create session directory and make it the working directory
2930 if (IsMaster())
2931 fSessionDir += "/master-";
2932 else
2933 fSessionDir += "/slave-";
2935
2936 // Common setup
2937 if (SetupCommon() != 0) {
2938 Error("Setup", "common setup failed");
2939 return -1;
2940 }
2941
2942 // Incoming OOB should generate a SIGURG
2944
2945 // Send packets off immediately to reduce latency
2947
2948 // Check every two hours if client is still alive
2950
2951 // Done
2952 return 0;
2953}
2954
2955////////////////////////////////////////////////////////////////////////////////
2956/// Common part (between TProofServ and TXProofServ) of the setup phase.
2957/// Return 0 on success, -1 on error
2958
2960{
2961 // deny write access for group and world
2962 gSystem->Umask(022);
2963
2964#ifdef R__UNIX
2965 // Add bindir to PATH
2966 TString path(gSystem->Getenv("PATH"));
2967 TString bindir(TROOT::GetBinDir());
2968 // Augment PATH, if required
2969 // ^<compiler>, <compiler>, ^<sysbin>, <sysbin>
2970 TString paths = gEnv->GetValue("ProofServ.BinPaths", "");
2971 if (paths.Length() > 0) {
2972 Int_t icomp = 0;
2973 if (paths.Contains("^<compiler>"))
2974 icomp = 1;
2975 else if (paths.Contains("<compiler>"))
2976 icomp = -1;
2977 if (icomp != 0) {
2978# ifdef COMPILER
2979 TString compiler = COMPILER;
2980 if (compiler.Index("is ") != kNPOS)
2981 compiler.Remove(0, compiler.Index("is ") + 3);
2982 compiler = gSystem->DirName(compiler);
2983 if (icomp == 1) {
2984 if (!bindir.IsNull()) bindir += ":";
2985 bindir += compiler;
2986 } else if (icomp == -1) {
2987 if (!path.IsNull()) path += ":";
2988 path += compiler;
2989 }
2990#endif
2991 }
2992 Int_t isysb = 0;
2993 if (paths.Contains("^<sysbin>"))
2994 isysb = 1;
2995 else if (paths.Contains("<sysbin>"))
2996 isysb = -1;
2997 if (isysb != 0) {
2998 if (isysb == 1) {
2999 if (!bindir.IsNull()) bindir += ":";
3000 bindir += "/bin:/usr/bin:/usr/local/bin";
3001 } else if (isysb == -1) {
3002 if (!path.IsNull()) path += ":";
3003 path += "/bin:/usr/bin:/usr/local/bin";
3004 }
3005 }
3006 }
3007 // Final insert
3008 if (!bindir.IsNull()) bindir += ":";
3009 path.Insert(0, bindir);
3010 gSystem->Setenv("PATH", path);
3011#endif
3012
3016 Error("SetupCommon", "can not change to PROOF directory %s",
3017 fWorkDir.Data());
3018 return -1;
3019 }
3020 } else {
3025 Error("SetupCommon", "can not change to PROOF directory %s",
3026 fWorkDir.Data());
3027 return -1;
3028 }
3029 }
3030 }
3031
3032 // Set group
3033 fGroup = gEnv->GetValue("ProofServ.ProofGroup", "default");
3034
3035 // Check and make sure "cache" directory exists
3036 fCacheDir = gEnv->GetValue("ProofServ.CacheDir",
3037 TString::Format("%s/%s", fWorkDir.Data(), kPROOF_CacheDir));
3041 if (gProofDebugLevel > 0)
3042 Info("SetupCommon", "cache directory set to %s", fCacheDir.Data());
3043 fCacheLock =
3044 new TProofLockPath(TString::Format("%s/%s%s",
3046 TString(fCacheDir).ReplaceAll("/","%").Data()));
3047 // Make also sure the cache path is in the macro path
3049
3050 // Check and make sure "packages" directory exists
3051 TString packdir = gEnv->GetValue("ProofServ.PackageDir",
3052 TString::Format("%s/%s", fWorkDir.Data(), kPROOF_PackDir));
3053 ResolveKeywords(packdir);
3054 if (gSystem->AccessPathName(packdir))
3055 gSystem->mkdir(packdir, kTRUE);
3056 fPackMgr = new TPackMgr(packdir);
3058 // Notification message
3059 TString noth;
3060 const char *k = (IsMaster()) ? "Mst" : "Wrk";
3061 noth.Form("%s-%s", k, fOrdinal.Data());
3062 fPackMgr->SetPrefix(noth.Data());
3063 if (gProofDebugLevel > 0)
3064 Info("SetupCommon", "package directory set to %s", packdir.Data());
3065
3066 // Check and make sure "data" directory exists
3067 fDataDir = gEnv->GetValue("ProofServ.DataDir","");
3068 Ssiz_t isep = kNPOS;
3069 if (fDataDir.IsNull()) {
3070 // Use default
3071 fDataDir.Form("%s/%s/<ord>/<stag>", fWorkDir.Data(), kPROOF_DataDir);
3072 } else if ((isep = fDataDir.Last(' ')) != kNPOS) {
3073 fDataDirOpts = fDataDir(isep + 1, fDataDir.Length());
3074 fDataDir.Remove(isep);
3075 }
3078 if (gSystem->mkdir(fDataDir, kTRUE) != 0) {
3079 Warning("SetupCommon", "problems creating path '%s' (errno: %d)",
3080 fDataDir.Data(), TSystem::GetErrno());
3081 }
3082 if (gProofDebugLevel > 0)
3083 Info("SetupCommon", "data directory set to %s", fDataDir.Data());
3084
3085 // Check and apply possible options
3086 // (see http://root.cern.ch/drupal/content/configuration-reference-guide#datadir)
3087 TString dataDirOpts = gEnv->GetValue("ProofServ.DataDirOpts","");
3088 if (!dataDirOpts.IsNull()) {
3089 // Do they apply to this server type
3090 Bool_t doit = kTRUE;
3091 if ((IsMaster() && !dataDirOpts.Contains("M")) ||
3092 (!IsMaster() && !dataDirOpts.Contains("W"))) doit = kFALSE;
3093 if (doit) {
3094 // Get the wanted mode
3095 UInt_t m = 0755;
3096 if (dataDirOpts.Contains("g")) m = 0775;
3097 if (dataDirOpts.Contains("a") || dataDirOpts.Contains("o")) m = 0777;
3098 if (gProofDebugLevel > 0)
3099 Info("SetupCommon", "requested mode for data directories is '%o'", m);
3100 // Loop over paths
3101 FileStat_t st;
3102 TString p, subp;
3103 Int_t from = 0;
3104 if (fDataDir.BeginsWith("/")) p = "/";
3105 while (fDataDir.Tokenize(subp, from, "/")) {
3106 if (subp.IsNull()) continue;
3107 p += subp;
3108 if (gSystem->GetPathInfo(p, st) == 0) {
3109 if (st.fUid == (Int_t) gSystem->GetUid() && st.fGid == (Int_t) gSystem->GetGid()) {
3110 if (gSystem->Chmod(p.Data(), m) != 0) {
3111 Warning("SetupCommon", "problems setting mode '%o' on path '%s' (errno: %d)",
3112 m, p.Data(), TSystem::GetErrno());
3113 break;
3114 }
3115 }
3116 p += "/";
3117 } else {
3118 Warning("SetupCommon", "problems stat-ing path '%s' (errno: %d; datadir: %s)",
3119 p.Data(), TSystem::GetErrno(), fDataDir.Data());
3120 break;
3121 }
3122 }
3123 }
3124 }
3125
3126 // List of directories where to look for global packages
3127 TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
3128
3129 ResolveKeywords(globpack);
3130 Int_t nglb = TPackMgr::RegisterGlobalPath(globpack);
3131 Info("SetupCommon", " %d global package directories registered", nglb);
3132 FlushLogFile();
3133
3134 // Check the session dir
3140 Error("SetupCommon", "can not change to working directory '%s'",
3141 fSessionDir.Data());
3142 return -1;
3143 }
3144 }
3145 gSystem->Setenv("PROOF_SANDBOX", fSessionDir);
3146 if (gProofDebugLevel > 0)
3147 Info("SetupCommon", "session dir is '%s'", fSessionDir.Data());
3148
3149 // On masters, check and make sure that "queries" and "datasets"
3150 // directories exist
3151 if (IsMaster()) {
3152
3153 // Make sure that the 'queries' dir exist
3155 fQueryDir += TString("/") + kPROOF_QueryDir;
3159 fQueryDir += TString("/session-") + fTopSessionTag;
3162 if (gProofDebugLevel > 0)
3163 Info("SetupCommon", "queries dir is %s", fQueryDir.Data());
3164
3165 // Create 'queries' locker instance and lock it
3166 fQueryLock = new TProofLockPath(TString::Format("%s/%s%s-%s",
3169 TString(fQueryDir).ReplaceAll("/","%").Data()));
3170 fQueryLock->Lock();
3171 // Create the query manager
3173 fQueryLock, 0);
3174 }
3175
3176 // Server image
3177 fImage = gEnv->GetValue("ProofServ.Image", "");
3178
3179 // Get the group priority
3180 if (IsMaster()) {
3181 // Send session tag to client
3183 m << fTopSessionTag << fGroup << fUser;
3184 fSocket->Send(m);
3185 // Group priority
3187 // Dataset manager instance via plug-in
3188 TPluginHandler *h = 0;
3189 TString dsms = gEnv->GetValue("Proof.DataSetManager", "");
3190 if (!dsms.IsNull()) {
3191 TString dsm;
3192 Int_t from = 0;
3193 while (dsms.Tokenize(dsm, from, ",")) {
3195 Warning("SetupCommon", "a valid dataset manager already initialized");
3196 Warning("SetupCommon", "support for multiple managers not yet available");
3197 break;
3198 }
3199 // Get plugin manager to load the appropriate TDataSetManager
3200 if (gROOT->GetPluginManager()) {
3201 // Find the appropriate handler
3202 h = gROOT->GetPluginManager()->FindHandler("TDataSetManager", dsm);
3203 if (h && h->LoadPlugin() != -1) {
3204 // make instance of the dataset manager
3206 reinterpret_cast<TDataSetManager*>(h->ExecPlugin(3, fGroup.Data(),
3207 fUser.Data(), dsm.Data()));
3208 }
3209 }
3210 }
3211 // Check the result of the dataset manager initialization
3213 Warning("SetupCommon", "dataset manager plug-in initialization failed");
3214 SendAsynMessage("TXProofServ::SetupCommon: dataset manager plug-in initialization failed");
3216 }
3217 } else {
3218 // Initialize the default dataset manager
3219 TString opts("Av:");
3220 TString dsetdir = gEnv->GetValue("ProofServ.DataSetDir", "");
3221 if (dsetdir.IsNull()) {
3222 // Use the default in the sandbox
3223 dsetdir.Form("%s/%s", fWorkDir.Data(), kPROOF_DataSetDir);
3226 opts += "Sb:";
3227 }
3228 // Find the appropriate handler
3229 if (!h) {
3230 h = gROOT->GetPluginManager()->FindHandler("TDataSetManager", "file");
3231 if (h && h->LoadPlugin() == -1) h = 0;
3232 }
3233 if (h) {
3234 // make instance of the dataset manager
3235 TString oo = TString::Format("dir:%s opt:%s", dsetdir.Data(), opts.Data());
3236 fDataSetManager = reinterpret_cast<TDataSetManager*>(h->ExecPlugin(3,
3237 fGroup.Data(), fUser.Data(), oo.Data()));
3238 }
3240 Warning("SetupCommon", "default dataset manager plug-in initialization failed");
3242 }
3243 }
3244 // Dataset manager for staging requests
3245 TString dsReqCfg = gEnv->GetValue("Proof.DataSetStagingRequests", "");
3246 if (!dsReqCfg.IsNull()) {
3247 TPMERegexp reReqDir("(^| )(dir:)?([^ ]+)( |$)");
3248
3249 if (reReqDir.Match(dsReqCfg) == 5) {
3250 TString dsDirFmt;
3251 dsDirFmt.Form("dir:%s perms:open", reReqDir[3].Data());
3252 fDataSetStgRepo = new TDataSetManagerFile("_stage_", "_stage_",
3253 dsDirFmt);
3254 if (fDataSetStgRepo &&
3256 Warning("SetupCommon",
3257 "failed init of dataset staging requests repository");
3259 }
3260 } else {
3261 Warning("SetupCommon",
3262 "specify, with [dir:]<path>, a valid path for staging requests");
3263 }
3264 } else if (gProofDebugLevel > 0) {
3265 Warning("SetupCommon", "no repository for staging requests available");
3266 }
3267 }
3268
3269 // Quotas
3270 TString quotas = gEnv->GetValue(TString::Format("ProofServ.UserQuotas.%s", fUser.Data()),"");
3271 if (quotas.IsNull())
3272 quotas = gEnv->GetValue(TString::Format("ProofServ.UserQuotasByGroup.%s", fGroup.Data()),"");
3273 if (quotas.IsNull())
3274 quotas = gEnv->GetValue("ProofServ.UserQuotas", "");
3275 if (!quotas.IsNull()) {
3276 // Parse it; format ("maxquerykept=10 hwmsz=800m maxsz=1g")
3277 TString tok;
3278 Ssiz_t from = 0;
3279 while (quotas.Tokenize(tok, from, " ")) {
3280 // Set max number of query results to keep
3281 if (tok.BeginsWith("maxquerykept=")) {
3282 tok.ReplaceAll("maxquerykept=","");
3283 if (tok.IsDigit())
3284 fMaxQueries = tok.Atoi();
3285 else
3286 Info("SetupCommon",
3287 "parsing 'maxquerykept' :ignoring token %s : not a digit", tok.Data());
3288 }
3289 // Set High-Water-Mark or max on the sandbox size
3290 const char *ksz[2] = {"hwmsz=", "maxsz="};
3291 for (Int_t j = 0; j < 2; j++) {
3292 if (tok.BeginsWith(ksz[j])) {
3293 tok.ReplaceAll(ksz[j],"");
3294 Long64_t fact = -1;
3295 if (!tok.IsDigit()) {
3296 // Parse (k, m, g)
3297 tok.ToLower();
3298 const char *s[3] = {"k", "m", "g"};
3299 Int_t i = 0, ki = 1024;
3300 while (fact < 0) {
3301 if (tok.EndsWith(s[i++]))
3302 fact = ki;
3303 else
3304 ki *= 1024;
3305 }
3306 tok.Remove(tok.Length()-1);
3307 }
3308 if (tok.IsDigit()) {
3309 if (j == 0)
3310 fHWMBoxSize = (fact > 0) ? tok.Atoi() * fact : tok.Atoi();
3311 else
3312 fMaxBoxSize = (fact > 0) ? tok.Atoi() * fact : tok.Atoi();
3313 } else {
3314 TString ssz(ksz[j], strlen(ksz[j])-1);
3315 Info("SetupCommon", "parsing '%s' : ignoring token %s", ssz.Data(), tok.Data());
3316 }
3317 }
3318 }
3319 }
3320 }
3321
3322 // Apply quotas, if any
3323 if (IsMaster() && fQMgr)
3325 Warning("SetupCommon", "problems applying fMaxQueries");
3326
3327 // Send "ROOTversion|ArchCompiler" flag
3328 if (fProtocol > 12) {
3329 TString vac = gROOT->GetVersion();
3330 vac += TString::Format(":%s", gROOT->GetGitCommit());
3331 TString rtag = gEnv->GetValue("ProofServ.RootVersionTag", "");
3332 if (rtag.Length() > 0)
3333 vac += TString::Format(":%s", rtag.Data());
3336 m << vac;
3337 fSocket->Send(m);
3338 }
3339
3340 // Set user vars in TProof
3341 TString all_vars(gSystem->Getenv("PROOF_ALLVARS"));
3342 TString name;
3343 Int_t from = 0;
3344 while (all_vars.Tokenize(name, from, ",")) {
3345 if (!name.IsNull()) {
3346 TString value = gSystem->Getenv(name);
3347 TProof::AddEnvVar(name, value);
3348 }
3349 }
3350
3351 if (fgLogToSysLog > 0) {
3352 // Set the syslog entity (all the information is available now)
3353 if (!(fUser.IsNull()) && !(fGroup.IsNull())) {
3354 fgSysLogEntity.Form("%s:%s", fUser.Data(), fGroup.Data());
3355 } else if (!(fUser.IsNull()) && fGroup.IsNull()) {
3356 fgSysLogEntity.Form("%s:default", fUser.Data());
3357 } else if (fUser.IsNull() && !(fGroup.IsNull())) {
3358 fgSysLogEntity.Form("undef:%s", fGroup.Data());
3359 }
3360 // Log the beginning of this session
3361 TString s;
3362 s.Form("%s 0 %.3f %.3f", fgSysLogEntity.Data(), fRealTime, fCpuTime);
3363 gSystem->Syslog(kLogNotice, s.Data());
3364 }
3365
3366 if (gProofDebugLevel > 0)
3367 Info("SetupCommon", "successfully completed");
3368
3369 // Done
3370 return 0;
3371}
3372
3373////////////////////////////////////////////////////////////////////////////////
3374/// Terminate the proof server.
3375
3377{
3378 if (fgLogToSysLog > 0) {
3379 TString s;
3380 s.Form("%s -1 %.3f %.3f %d", fgSysLogEntity.Data(), fRealTime, fCpuTime, status);
3381 gSystem->Syslog(kLogNotice, s.Data());
3382 }
3383
3384 // Notify the memory footprint
3385 ProcInfo_t pi;
3386 if (!gSystem->GetProcInfo(&pi)){
3387 Info("Terminate", "process memory footprint: %ld/%ld kB virtual, %ld/%ld kB resident ",
3388 pi.fMemVirtual, fgVirtMemMax, pi.fMemResident, fgResMemMax);
3389 }
3390
3391 // Cleanup session directory
3392 if (status == 0) {
3393 // make sure we remain in a "connected" directory
3395 // needed in case fSessionDir is on NFS ?!
3396 gSystem->MakeDirectory(fSessionDir+"/.delete");
3397 gSystem->Exec(TString::Format("%s %s", kRM, fSessionDir.Data()));
3398 }
3399
3400 // Cleanup queries directory if empty
3401 if (IsMaster()) {
3402 if (!(fQMgr && fQMgr->Queries() && fQMgr->Queries()->GetSize())) {
3403 // make sure we remain in a "connected" directory
3405 // needed in case fQueryDir is on NFS ?!
3406 gSystem->MakeDirectory(fQueryDir+"/.delete");
3407 gSystem->Exec(TString::Format("%s %s", kRM, fQueryDir.Data()));
3408 // Remove lock file
3409 if (fQueryLock)
3411 }
3412
3413 // Unlock the query dir owned by this session
3414 if (fQueryLock)
3415 fQueryLock->Unlock();
3416 }
3417
3418 // Cleanup data directory if empty
3421 Info("Terminate", "data directory '%s' has been removed", fDataDir.Data());
3422 }
3423
3424 // Remove input handler to avoid spurious signals in socket
3425 // selection for closing activities executed upon exit()
3427 TObject *fh = 0;
3428 while ((fh = next())) {
3429 TProofServInputHandler *ih = dynamic_cast<TProofServInputHandler *>(fh);
3430 if (ih)
3432 }
3433
3434 // Stop processing events
3435 gSystem->ExitLoop();
3436
3437 // Exit() is called in pmain
3438}
3439
3440////////////////////////////////////////////////////////////////////////////////
3441/// Scan recursively the datadir and unlink it if empty
3442/// Return kTRUE if it can be unlinked, kFALSE otherwise
3443
3445{
3446 if (!path || strlen(path) <= 0) return kFALSE;
3447
3448 Bool_t dorm = kTRUE;
3449 void *dirp = gSystem->OpenDirectory(path);
3450 if (dirp) {
3451 TString fpath;
3452 const char *ent = 0;
3453 while (dorm && (ent = gSystem->GetDirEntry(dirp))) {
3454 if (!strcmp(ent, ".") || !strcmp(ent, "..")) continue;
3455 fpath.Form("%s/%s", path, ent);
3456 FileStat_t st;
3457 if (gSystem->GetPathInfo(fpath, st) == 0 && R_ISDIR(st.fMode)) {
3458 dorm = UnlinkDataDir(fpath);
3459 } else {
3460 dorm = kFALSE;
3461 }
3462 }
3463 // Close the directory
3464 gSystem->FreeDirectory(dirp);
3465 } else {
3466 // Cannot open the directory
3467 dorm = kFALSE;
3468 }
3469
3470 // Do remove, if required
3471 if (dorm && gSystem->Unlink(path) != 0)
3472 Warning("UnlinkDataDir", "data directory '%s' is empty but could not be removed", path);
3473 // done
3474 return dorm;
3475}
3476
3477////////////////////////////////////////////////////////////////////////////////
3478/// Static function that returns kTRUE in case we are a PROOF server.
3479
3481{
3482 return gProofServ ? kTRUE : kFALSE;
3483}
3484
3485////////////////////////////////////////////////////////////////////////////////
3486/// Static function returning pointer to global object gProofServ.
3487/// Mainly for use via CINT, where the gProofServ symbol might be
3488/// deleted from the symbol table.
3489
3491{
3492 return gProofServ;
3493}
3494
3495////////////////////////////////////////////////////////////////////////////////
3496/// Setup authentication related stuff for old versions.
3497/// Provided for backward compatibility.
3498
3500{
3501 OldProofServAuthSetup_t oldAuthSetupHook = 0;
3502
3503 if (!oldAuthSetupHook) {
3504 // Load libraries needed for (server) authentication ...
3505 TString authlib = "libRootAuth";
3506 char *p = 0;
3507 // The generic one
3508 if ((p = gSystem->DynamicPathName(authlib, kTRUE))) {
3509 delete[] p;
3510 if (gSystem->Load(authlib) == -1) {
3511 Error("OldAuthSetup", "can't load %s",authlib.Data());
3512 return kFALSE;
3513 }
3514 } else {
3515 Error("OldAuthSetup", "can't locate %s",authlib.Data());
3516 return -1;
3517 }
3518 //
3519 // Locate OldProofServAuthSetup
3520 Func_t f = gSystem->DynFindSymbol(authlib,"OldProofServAuthSetup");
3521 if (f)
3522 oldAuthSetupHook = (OldProofServAuthSetup_t)(f);
3523 else {
3524 Error("OldAuthSetup", "can't find OldProofServAuthSetup");
3525 return -1;
3526 }
3527 }
3528 //
3529 // Setup
3530 return (*oldAuthSetupHook)(fSocket, IsMaster(), fProtocol,
3531 fUser, fOrdinal, conf);
3532}
3533
3534////////////////////////////////////////////////////////////////////////////////
3535/// Create a TProofQueryResult instance for this query.
3536
3538 const char *opt,
3539 TList *inlist, Long64_t fst,
3540 TDSet *dset, const char *selec,
3541 TObject *elist)
3542{
3543 // Increment sequential number
3544 Int_t seqnum = -1;
3545 if (fQMgr) {
3547 seqnum = fQMgr->SeqNum();
3548 }
3549
3550 // Locally we always use the current streamer
3551 Bool_t olds = (dset && dset->TestBit(TDSet::kWriteV3)) ? kTRUE : kFALSE;
3552 if (olds)
3553 dset->SetWriteV3(kFALSE);
3554
3555 // Create the instance and add it to the list
3556 TProofQueryResult *pqr = new TProofQueryResult(seqnum, opt, inlist, nent,
3557 fst, dset, selec, elist);
3558 // Title is the session identifier
3560
3561 // Restore old streamer info
3562 if (olds)
3563 dset->SetWriteV3(kTRUE);
3564
3565 return pqr;
3566}
3567
3568////////////////////////////////////////////////////////////////////////////////
3569/// Set query in running state.
3570
3572{
3573 // Record current position in the log file at start
3574 fflush(stdout);
3575 Int_t startlog = lseek(fileno(stdout), (off_t) 0, SEEK_END);
3576
3577 // Add some header to logs
3578 Printf(" ");
3579 Info("SetQueryRunning", "starting query: %d", pq->GetSeqNum());
3580
3581 // Build the list of loaded PAR packages
3582 TString parlist = "";
3583 fPackMgr->GetEnabledPackages(parlist);
3584
3585 if (fProof) {
3586 // Set in running state
3587 pq->SetRunning(startlog, parlist, fProof->GetParallel());
3588
3589 // Bytes and CPU at start (we will calculate the differential at end)
3590 pq->SetProcessInfo(pq->GetEntries(),
3592 } else {
3593 // Set in running state
3594 pq->SetRunning(startlog, parlist, -1);
3595
3596 // Bytes and CPU at start (we will calculate the differential at end)
3597 pq->SetProcessInfo(pq->GetEntries(), float(0.), 0);
3598 }
3599}
3600
3601////////////////////////////////////////////////////////////////////////////////
3602/// Handle archive request.
3603
3604void TProofServ::HandleArchive(TMessage *mess, TString *slb)
3605{
3606 PDB(kGlobal, 1)
3607 Info("HandleArchive", "Enter");
3608
3609 TString queryref;
3610 TString path;
3611 (*mess) >> queryref >> path;
3612
3613 if (slb) slb->Form("%s %s", queryref.Data(), path.Data());
3614
3615 // If this is a set default action just save the default
3616 if (queryref == "Default") {
3617 fArchivePath = path;
3618 Info("HandleArchive",
3619 "default path set to %s", fArchivePath.Data());
3620 return;
3621 }
3622
3623 Int_t qry = -1;
3624 TString qdir;
3625 TProofQueryResult *pqr = fQMgr ? fQMgr->LocateQuery(queryref, qry, qdir) : 0;
3626 TProofQueryResult *pqm = pqr;
3627
3628 if (path.Length() <= 0) {
3629 if (fArchivePath.Length() <= 0) {
3630 Info("HandleArchive",
3631 "archive paths are not defined - do nothing");
3632 return;
3633 }
3634 if (qry > 0) {
3635 path.Form("%s/session-%s-%d.root",
3636 fArchivePath.Data(), fTopSessionTag.Data(), qry);
3637 } else {
3638 path = queryref;
3639 path.ReplaceAll(":q","-");
3640 path.Insert(0, TString::Format("%s/",fArchivePath.Data()));
3641 path += ".root";
3642 }
3643 }
3644
3645 // Build file name for specific query
3646 if (!pqr || qry < 0) {
3647 TString fout = qdir;
3648 fout += "/query-result.root";
3649
3650 TFile *f = TFile::Open(fout,"READ");
3651 pqr = 0;
3652 if (f) {
3653 f->ReadKeys();
3654 TIter nxk(f->GetListOfKeys());
3655 TKey *k = 0;
3656 while ((k = (TKey *)nxk())) {
3657 if (!strcmp(k->GetClassName(), "TProofQueryResult")) {
3658 pqr = (TProofQueryResult *) f->Get(k->GetName());
3659 if (pqr)
3660 break;
3661 }
3662 }
3663 f->Close();
3664 delete f;
3665 } else {
3666 Info("HandleArchive",
3667 "file cannot be open (%s)",fout.Data());
3668 return;
3669 }
3670 }
3671
3672 if (pqr) {
3673
3674 PDB(kGlobal, 1) Info("HandleArchive",
3675 "archive path for query #%d: %s",
3676 qry, path.Data());
3677 TFile *farc = 0;
3678 if (gSystem->AccessPathName(path))
3679 farc = TFile::Open(path,"NEW");
3680 else
3681 farc = TFile::Open(path,"UPDATE");
3682 if (!farc || !(farc->IsOpen())) {
3683 Info("HandleArchive",
3684 "archive file cannot be open (%s)",path.Data());
3685 return;
3686 }
3687 farc->cd();
3688
3689 // Update query status
3690 pqr->SetArchived(path);
3691 if (pqm)
3692 pqm->SetArchived(path);
3693
3694 // Write to file
3695 pqr->Write();
3696
3697 // Update temporary files too
3698 if (qry > -1 && fQMgr)
3699 fQMgr->SaveQuery(pqr);
3700
3701 // Notify
3702 Info("HandleArchive",
3703 "results of query %s archived to file %s",
3704 queryref.Data(), path.Data());
3705 }
3706
3707 // Done
3708 return;
3709}
3710
3711////////////////////////////////////////////////////////////////////////////////
3712/// Get a map {server-name, list-of-files} for collection 'fc' to be used in
3713/// TPacketizerFile. Returns a pointer to the map (ownership of the caller).
3714/// Or (TMap *)0 and an error message in emsg.
3715
3717{
3718 TMap *fcmap = 0;
3719 emsg = "";
3720
3721 // Sanity checks
3722 if (!fc) {
3723 emsg.Form("file collection undefined!");
3724 return fcmap;
3725 }
3726
3727 // Prepare data set map
3728 fcmap = new TMap();
3729
3730 TIter nxf(fc->GetList());
3731 TFileInfo *fiind = 0;
3732 TString key;
3733 while ((fiind = (TFileInfo *)nxf())) {
3734 TUrl *xurl = fiind->GetCurrentUrl();
3735 // Find the key for this server
3736 key.Form("%s://%s", xurl->GetProtocol(), xurl->GetHostFQDN());
3737 if (xurl->GetPort() > 0)
3738 key += TString::Format(":%d", xurl->GetPort());
3739 // Get the map entry for this key
3740 TPair *ent = 0;
3741 THashList* l = 0;
3742 if ((ent = (TPair *) fcmap->FindObject(key.Data()))) {
3743 // Attach to the list
3744 l = (THashList *) ent->Value();
3745 } else {
3746 // Create list
3747 l = new THashList;
3748 l->SetOwner(kTRUE);
3749 // Add it to the map
3750 fcmap->Add(new TObjString(key.Data()), l);
3751 }
3752 // Add fileinfo with index to list
3753 l->Add(fiind);
3754 }
3755
3756 // Done
3757 return fcmap;
3758}
3759
3760////////////////////////////////////////////////////////////////////////////////
3761/// Handle processing request.
3762
3763void TProofServ::HandleProcess(TMessage *mess, TString *slb)
3764{
3765 PDB(kGlobal, 1)
3766 Info("HandleProcess", "Enter");
3767
3768 // Nothing to do for slaves if we are not idle
3769 if (!IsTopMaster() && !IsIdle())
3770 return;
3771
3772 TDSet *dset;
3773 TString filename, opt;
3774 TList *input;
3776 TEventList *evl = 0;
3777 TEntryList *enl = 0;
3778 Bool_t sync;
3779
3780 (*mess) >> dset >> filename >> input >> opt >> nentries >> first >> evl >> sync;
3781 // Get entry list information, if any (support started with fProtocol == 15)
3782 if ((mess->BufferSize() > mess->Length()) && fProtocol > 14)
3783 (*mess) >> enl;
3784 Bool_t hasNoData = (!dset || dset->TestBit(TDSet::kEmpty)) ? kTRUE : kFALSE;
3785
3786 // Priority to the entry list
3787 TObject *elist = (enl) ? (TObject *)enl : (TObject *)evl;
3788 if (enl && evl)
3789 // Cannot specify both at the same time
3790 SafeDelete(evl);
3791 if ((!hasNoData) && elist)
3792 dset->SetEntryList(elist);
3793
3794 if (IsTopMaster()) {
3795
3796 TString emsg;
3797 // Make sure the dataset contains the information needed
3798 if ((!hasNoData) && dset->GetListOfElements()->GetSize() == 0) {
3799 if (TProof::AssertDataSet(dset, input, fDataSetManager, emsg) != 0) {
3800 SendAsynMessage(TString::Format("AssertDataSet on %s: %s",
3801 fPrefix.Data(), emsg.Data()));
3802 Error("HandleProcess", "AssertDataSet: %s", emsg.Data());
3803 // To terminate collection
3804 if (sync) SendLogFile();
3805 return;
3806 }
3807 } else if (hasNoData) {
3808 // Check if we are required to process with TPacketizerFile a registered dataset
3809 TNamed *ftp = dynamic_cast<TNamed *>(input->FindObject("PROOF_FilesToProcess"));
3810 if (ftp) {
3811 TString dsn(ftp->GetTitle());
3812 if (!dsn.Contains(":") || dsn.BeginsWith("dataset:")) {
3813 dsn.ReplaceAll("dataset:", "");
3814 // Get the map for TPacketizerFile
3815 // Make sure we have something in input and a dataset manager
3816 if (!fDataSetManager) {
3817 emsg.Form("dataset manager not initialized!");
3818 } else {
3819 TFileCollection *fc = 0;
3820 // Get the dataset
3821 if (!(fc = fDataSetManager->GetDataSet(dsn))) {
3822 emsg.Form("requested dataset '%s' does not exists", dsn.Data());
3823 } else {
3824 TMap *fcmap = GetDataSetNodeMap(fc, emsg);
3825 if (fcmap) {
3826 input->Remove(ftp);
3827 delete ftp;
3828 fcmap->SetOwner(kTRUE);
3829 fcmap->SetName("PROOF_FilesToProcess");
3830 input->Add(fcmap);
3831 }
3832 }
3833 }
3834 if (!emsg.IsNull()) {
3835 SendAsynMessage(TString::Format("HandleProcess on %s: %s",
3836 fPrefix.Data(), emsg.Data()));
3837 Error("HandleProcess", "%s", emsg.Data());
3838 // To terminate collection
3839 if (sync) SendLogFile();
3840 return;
3841 }
3842 }
3843 }
3844 }
3845
3846 TProofQueryResult *pq = 0;
3847
3848 // Create instance of query results; we set ownership of the input list
3849 // to the TQueryResult object, to avoid too many instantiations
3850 pq = MakeQueryResult(nentries, opt, 0, first, 0, filename, 0);
3851
3852 // Prepare the input list and transfer it into the TQueryResult object
3853 if (dset) input->Add(dset);
3854 if (elist) input->Add(elist);
3855 pq->SetInputList(input, kTRUE);
3856
3857 // Clear the list
3858 input->Clear("nodelete");
3859 SafeDelete(input);
3860
3861 // Save input data, if any
3862 if (TProof::SaveInputData(pq, fCacheDir.Data(), emsg) != 0)
3863 Warning("HandleProcess", "could not save input data: %s", emsg.Data());
3864
3865 // If not a draw action add the query to the main list
3866 if (!(pq->IsDraw())) {
3867 if (fQMgr) {
3868 if (fQMgr->Queries()) fQMgr->Queries()->Add(pq);
3869 // Also save it to queries dir
3870 fQMgr->SaveQuery(pq);
3871 }
3872 }
3873
3874 // Add anyhow to the waiting lists
3875 QueueQuery(pq);
3876
3877 // Call get Workers
3878 // if we are not idle the scheduler will just enqueue the query and
3879 // send a resume message later.
3880
3881 Bool_t enqueued = kFALSE;
3882 Int_t pc = 0;
3883 // if the session does not have workers and is in the dynamic mode
3884 if (fProof->UseDynamicStartup()) {
3885 // get the a list of workers and start them
3886 TList* workerList = new TList();
3887 EQueryAction retVal = GetWorkers(workerList, pc);
3888 if (retVal == TProofServ::kQueryStop) {
3889 Error("HandleProcess", "error getting list of worker nodes");
3890 // To terminate collection
3891 if (sync) SendLogFile();
3892 return;
3893 } else if (retVal == TProofServ::kQueryEnqueued) {
3894 // change to an asynchronous query
3895 enqueued = kTRUE;
3896 Info("HandleProcess", "query %d enqueued", pq->GetSeqNum());
3897 } else if (Int_t ret = fProof->AddWorkers(workerList) < 0) {
3898 Error("HandleProcess", "Adding a list of worker nodes returned: %d",
3899 ret);
3900 // To terminate collection
3901 if (sync) SendLogFile();
3902 return;
3903 }
3904 } else {
3905 EQueryAction retVal = GetWorkers(0, pc);
3906 if (retVal == TProofServ::kQueryStop) {
3907 Error("HandleProcess", "error getting list of worker nodes");
3908 // To terminate collection
3909 if (sync) SendLogFile();
3910 return;
3911 } else if (retVal == TProofServ::kQueryEnqueued) {
3912 // change to an asynchronous query
3913 enqueued = kTRUE;
3914 Info("HandleProcess", "query %d enqueued", pq->GetSeqNum());
3915 } else if (retVal != TProofServ::kQueryOK) {
3916 Error("HandleProcess", "unknown return value: %d", retVal);
3917 // To terminate collection
3918 if (sync) SendLogFile();
3919 return;
3920 }
3921 }
3922
3923 // If the client submission was asynchronous, signal the submission of
3924 // the query and communicate the assigned sequential number for later
3925 // identification
3927 if (!sync || enqueued) {
3928 m << pq->GetSeqNum() << kFALSE;
3929 fSocket->Send(m);
3930 }
3931
3932 // Nothing more to do if we are not idle
3933 if (!IsIdle()) {
3934 // Notify submission
3935 Info("HandleProcess",
3936 "query \"%s:%s\" submitted", pq->GetTitle(), pq->GetName());
3937 return;
3938 }
3939
3940 // Process
3941 // in the static mode, if a session is enqueued it will be processed after current query
3942 // (there is no way to enqueue if idle).
3943 // in the dynamic mode we will process here only if the session was idle and got workers!
3944 Bool_t doprocess = kFALSE;
3945 while (WaitingQueries() > 0 && !enqueued) {
3946 doprocess = kTRUE;
3947 //
3948 ProcessNext(slb);
3949 // avoid processing async queries sent during processing in dyn mode
3951 enqueued = kTRUE;
3952
3953 } // Loop on submitted queries
3954
3955 // Set idle
3956 SetIdle(kTRUE);
3957
3958 // Reset mergers
3960
3961 // kPROOF_SETIDLE sets the client to idle; in asynchronous mode clients monitor
3962 // TProof::IsIdle for to check the readiness of a query, so we need to send this
3963 // before to be sure thatn everything about a query is received by the client
3964 if (!sync) SendLogFile();
3965
3966 // Signal the client that we are idle
3967 if (doprocess) {
3968 m.Reset(kPROOF_SETIDLE);
3969 Bool_t waiting = (WaitingQueries() > 0) ? kTRUE : kFALSE;
3970 m << waiting;
3971 fSocket->Send(m);
3972 }
3973
3974 // In synchronous mode TProof::Collect is terminated by the reception of the
3975 // log file and subsequent submissions are controlled by TProof::IsIdle(), so
3976 // this must be last one to be sent
3977 if (sync) SendLogFile();
3978
3979 // Set idle
3980 SetIdle(kTRUE);
3981
3982 } else {
3983
3984 // Reset compute stopwatch: we include all what done from now on
3985 fCompute.Reset();
3986 fCompute.Start();
3987
3988 // Set not idle
3989 SetIdle(kFALSE);
3990
3991 // Cleanup the player
3992 Bool_t deleteplayer = kTRUE;
3993 MakePlayer();
3994
3995 // Setup data set
3996 if (dset && (dset->IsA() == TDSetProxy::Class()))
3997 ((TDSetProxy*)dset)->SetProofServ(this);
3998
3999 // Get input data, if any
4000 TString emsg;
4001 if (TProof::GetInputData(input, fCacheDir.Data(), emsg) != 0)
4002 Warning("HandleProcess", "could not get input data: %s", emsg.Data());
4003
4004 // Get query sequential number
4005 if (TProof::GetParameter(input, "PROOF_QuerySeqNum", fQuerySeqNum) != 0)
4006 Warning("HandleProcess", "could not get query sequential number!");
4007
4008 // Make the ordinal number available in the selector
4009 TObject *nord = 0;
4010 while ((nord = input->FindObject("PROOF_Ordinal")))
4011 input->Remove(nord);
4012 input->Add(new TNamed("PROOF_Ordinal", GetOrdinal()));
4013
4014 // Set input
4015 TIter next(input);
4016 TObject *o = 0;
4017 while ((o = next())) {
4018 PDB(kGlobal, 2) Info("HandleProcess", "adding: %s", o->GetName());
4019 fPlayer->AddInput(o);
4020 }
4021
4022 // Check if a TSelector object is passed via input list
4023 TObject *obj = 0;
4024 TSelector *selector_obj = 0;
4025 TIter nxt(input);
4026 while ((obj = nxt())){
4027 if (obj->InheritsFrom("TSelector")) {
4028 selector_obj = (TSelector *) obj;
4029 filename = selector_obj->ClassName();
4030 Info("HandleProcess", "selector obj for '%s' found", selector_obj->ClassName());
4031 break;
4032 }
4033 }
4034
4035 // Signal the master that we are starting processing
4037
4038 // Reset latency stopwatch
4039 fLatency.Reset();
4041
4042 // Process
4043 PDB(kGlobal, 1) Info("HandleProcess", "calling %s::Process()", fPlayer->IsA()->GetName());
4044
4045 if (selector_obj){
4046 Info("HandleProcess", "calling fPlayer->Process() with selector object: %s", selector_obj->ClassName());
4047 fPlayer->Process(dset, selector_obj, opt, nentries, first);
4048 }
4049 else {
4050 Info("HandleProcess", "calling fPlayer->Process() with selector name: %s", filename.Data());
4051 fPlayer->Process(dset, filename, opt, nentries, first);
4052 }
4053
4054 // Return number of events processed
4057 if (fProtocol > 18) {
4058 TProofProgressStatus* status =
4060 gPerfStats?gPerfStats->GetBytesRead():0);
4061 if (status)
4062 m << status << abort;
4063 if (slb)
4064 slb->Form("%d %lld %lld", fPlayer->GetExitStatus(),
4065 status->GetEntries(), status->GetBytesRead());
4066 SafeDelete(status);
4067 } else {
4068 m << fPlayer->GetEventsProcessed() << abort;
4069 if (slb)
4070 slb->Form("%d %lld -1", fPlayer->GetExitStatus(), fPlayer->GetEventsProcessed());
4071 }
4072
4073 fSocket->Send(m);
4074 PDB(kGlobal, 2)
4075 Info("TProofServ::Handleprocess",
4076 "worker %s has finished processing with %d objects in output list",
4078
4079 // Cleanup the input data set info
4080 SafeDelete(dset);
4081 SafeDelete(enl);
4082 SafeDelete(evl);
4083
4086 if (outok) {
4087 // Check if in controlled output sending mode or submerging
4088 Int_t cso = 0;
4089 Bool_t isSubMerging = kFALSE;
4090
4091 // Check if we are in merging mode (i.e. parameter PROOF_UseMergers exists)
4092 Int_t nm = 0;
4093 if (TProof::GetParameter(input, "PROOF_UseMergers", nm) == 0) {
4094 isSubMerging = (nm >= 0) ? kTRUE : kFALSE;
4095 }
4096 if (!isSubMerging) {
4097 cso = gEnv->GetValue("Proof.ControlSendOutput", 1);
4098 if (TProof::GetParameter(input, "PROOF_ControlSendOutput", cso) != 0)
4099 cso = gEnv->GetValue("Proof.ControlSendOutput", 1);
4100 }
4101
4102 if (cso > 0) {
4103
4104 // Control output sending mode: wait for the master to ask for the objects.
4105 // Allows controls of memory usage on the master.
4107 fSocket->Send(msg);
4108
4109 // Set idle
4110 SetIdle(kTRUE);
4111
4112 // Do not cleanup the player yet: it will be used in sending output activities
4113 deleteplayer = kFALSE;
4114
4115 PDB(kGlobal, 1)
4116 Info("HandleProcess", "controlled mode: worker %s has finished,"
4117 " sizes sent to master", fOrdinal.Data());
4118 } else {
4119
4120 // Check if we are in merging mode (i.e. parameter PROOF_UseMergers exists)
4122 if (isSubMerging)
4123 Info("HandleProcess", "submerging disabled because of high-memory case");
4124 isSubMerging = kFALSE;
4125 } else {
4126 PDB(kGlobal, 2) Info("HandleProcess", "merging mode check: %d", isSubMerging);
4127 }
4128
4129 if (!IsMaster() && isSubMerging) {
4130 // Worker in merging mode.
4131 //----------------------------
4132 // First, it reports only the size of its output to the master
4133 // + port on which it can possibly accept outputs from other workers if it becomes a merger
4134 // Master will later tell it where it should send the output (either to the master or to some merger)
4135 // or if it should become a merger
4136
4137 TMessage msg_osize(kPROOF_SUBMERGER);
4138 msg_osize << Int_t(TProof::kOutputSize);
4139 msg_osize << fPlayer->GetOutputList()->GetEntries();
4140
4142 Int_t merge_port = 0;
4143 if (fMergingSocket) {
4144 PDB(kGlobal, 2)
4145 Info("HandleProcess", "possible port for merging connections: %d",
4147 merge_port = fMergingSocket->GetLocalPort();
4148 }
4149 msg_osize << merge_port;
4150 fSocket->Send(msg_osize);
4151
4152 // Set idle
4153 SetIdle(kTRUE);
4154
4155 // Do not cleanup the player yet: it will be used in sub-merging activities
4156 deleteplayer = kFALSE;
4157
4158 PDB(kSubmerger, 2) Info("HandleProcess", "worker %s has finished", fOrdinal.Data());
4159
4160 } else {
4161 // Sub-master OR worker not in merging mode
4162 // ---------------------------------------------
4163 PDB(kGlobal, 2) Info("HandleProcess", "sending result directly to master");
4165 Warning("HandleProcess","problems sending output list");
4166
4167 // Masters reset the mergers, if any
4168 if (IsMaster()) fProof->ResetMergers();
4169
4170 // Signal the master that we are idle
4172
4173 // Set idle
4174 SetIdle(kTRUE);
4175
4176 // Notify the user
4177 SendLogFile();
4178 }
4179
4180
4181
4182 }
4183
4184 } else {
4185 // No output list
4187 Warning("HandleProcess","the output list is empty!");
4188 if (SendResults(fSocket) != 0)
4189 Warning("HandleProcess", "problems sending output list");
4190
4191 // Masters reset the mergers, if any
4192 if (IsMaster()) fProof->ResetMergers();
4193
4194 // Signal the master that we are idle
4196
4197 // Set idle
4198 SetIdle(kTRUE);
4199
4200 // Notify the user
4201 SendLogFile();
4202 }
4203
4204 // Prevent from double-deleting in input
4205 TIter nex(input);
4206 while ((obj = nex())) {
4207 if (obj->InheritsFrom("TSelector")) input->Remove(obj);
4208 }
4209
4210 // Make also sure the input list objects are deleted
4212
4213 // Remove possible inputs from a file and the file, if any
4214 TList *added = dynamic_cast<TList *>(input->FindObject("PROOF_InputObjsFromFile"));
4215 if (added) {
4216 if (added->GetSize() > 0) {
4217 // The file must be the last one
4218 TFile *f = dynamic_cast<TFile *>(added->Last());
4219 if (f) {
4220 added->Remove(f);
4221 TIter nxo(added);
4222 while ((o = nxo())) { input->Remove(o); }
4223 input->Remove(added);
4224 added->SetOwner(kFALSE);
4225 added->Clear();
4226 f->Close();
4227 delete f;
4228 }
4229 }
4230 SafeDelete(added);
4231 }
4232 input->SetOwner();
4233 SafeDelete(input);
4234
4235 // Cleanup if required
4236 if (deleteplayer) DeletePlayer();
4237 }
4238
4239 PDB(kGlobal, 1) Info("HandleProcess", "done");
4240
4241 // Done
4242 return;
4243}
4244
4245////////////////////////////////////////////////////////////////////////////////
4246/// Sends all objects from the given list to the specified socket
4247
4249{
4250 PDB(kOutput, 2) Info("SendResults", "enter");
4251
4252 TString msg;
4253 if (fProtocol > 23 && outlist) {
4254 // Send objects in bunches of max fMsgSizeHWM bytes to optimize transfer
4255 // Objects are merged one-by-one by the client
4256 // Messages for objects
4258 // Objects in the output list
4259 Int_t olsz = outlist->GetSize();
4260 if (IsTopMaster() && pq) {
4261 msg.Form("%s: merging output objects ... done ",
4262 fPrefix.Data());
4263 SendAsynMessage(msg.Data());
4264 // Message for the client
4265 msg.Form("%s: objects merged; sending output: %d objs", fPrefix.Data(), olsz);
4266 SendAsynMessage(msg.Data(), kFALSE);
4267 // Send light query info
4268 mbuf << (Int_t) 0;
4269 mbuf.WriteObject(pq);
4270 if (sock->Send(mbuf) < 0) return -1;
4271 }
4272 // Objects in the output list
4273 Int_t ns = 0, np = 0;
4274 TIter nxo(outlist);
4275 TObject *o = 0;
4276 Int_t totsz = 0, objsz = 0;
4277 mbuf.Reset();
4278 while ((o = nxo())) {
4279 if (mbuf.Length() > fMsgSizeHWM) {
4280 PDB(kOutput, 1)
4281 Info("SendResults",
4282 "message has %d bytes: limit of %lld bytes reached - sending ...",
4283 mbuf.Length(), fMsgSizeHWM);
4284 // Compress the message, if required; for these messages we do it already
4285 // here so we get the size; TXSocket does not do it twice.
4286 if (GetCompressionLevel() > 0) {
4288 mbuf.Compress();
4289 objsz = mbuf.CompLength();
4290 } else {
4291 objsz = mbuf.Length();
4292 }
4293 totsz += objsz;
4294 if (IsTopMaster()) {
4295 msg.Form("%s: objects merged; sending obj %d/%d (%d bytes) ",
4296 fPrefix.Data(), ns, olsz, objsz);
4297 SendAsynMessage(msg.Data(), kFALSE);
4298 }
4299 if (sock->Send(mbuf) < 0) return -1;
4300 // Reset the message
4301 mbuf.Reset();
4302 np = 0;
4303 }
4304 ns++;
4305 np++;
4306 mbuf << (Int_t) ((ns >= olsz) ? 2 : 1);
4307 mbuf << o;
4308 }
4309 if (np > 0) {
4310 // Compress the message, if required; for these messages we do it already
4311 // here so we get the size; TXSocket does not do it twice.
4312 if (GetCompressionLevel() > 0) {
4314 mbuf.Compress();
4315 objsz = mbuf.CompLength();
4316 } else {
4317 objsz = mbuf.Length();
4318 }
4319 totsz += objsz;
4320 if (IsTopMaster()) {
4321 msg.Form("%s: objects merged; sending obj %d/%d (%d bytes) ",
4322 fPrefix.Data(), ns, olsz, objsz);
4323 SendAsynMessage(msg.Data(), kFALSE);
4324 }
4325 if (sock->Send(mbuf) < 0) return -1;
4326 }
4327 if (IsTopMaster()) {
4328 // Send total size
4329 msg.Form("%s: grand total: sent %d objects, size: %d bytes ",
4330 fPrefix.Data(), olsz, totsz);
4331 SendAsynMessage(msg.Data());
4332 }
4333 } else if (fProtocol > 10 && outlist) {
4334
4335 // Send objects one-by-one to optimize transfer and merging
4336 // Messages for objects
4338 // Objects in the output list
4339 Int_t olsz = outlist->GetSize();
4340 if (IsTopMaster() && pq) {
4341 msg.Form("%s: merging output objects ... done ",
4342 fPrefix.Data());
4343 SendAsynMessage(msg.Data());
4344 // Message for the client
4345 msg.Form("%s: objects merged; sending output: %d objs", fPrefix.Data(), olsz);
4346 SendAsynMessage(msg.Data(), kFALSE);
4347 // Send light query info
4348 mbuf << (Int_t) 0;
4349 mbuf.WriteObject(pq);
4350 if (sock->Send(mbuf) < 0) return -1;
4351 }
4352
4353 Int_t ns = 0;
4354 Int_t totsz = 0, objsz = 0;
4355 TIter nxo(fPlayer->GetOutputList());
4356 TObject *o = 0;
4357 while ((o = nxo())) {
4358 ns++;
4359 mbuf.Reset();
4360 Int_t type = (Int_t) ((ns >= olsz) ? 2 : 1);
4361 mbuf << type;
4362 mbuf.WriteObject(o);
4363 // Compress the message, if required; for these messages we do it already
4364 // here so we get the size; TXSocket does not do it twice.
4365 if (GetCompressionLevel() > 0) {
4367 mbuf.Compress();
4368 objsz = mbuf.CompLength();
4369 } else {
4370 objsz = mbuf.Length();
4371 }
4372 totsz += objsz;
4373 if (IsTopMaster()) {
4374 msg.Form("%s: objects merged; sending obj %d/%d (%d bytes) ",
4375 fPrefix.Data(), ns, olsz, objsz);
4376 SendAsynMessage(msg.Data(), kFALSE);
4377 }
4378 if (sock->Send(mbuf) < 0) return -1;
4379 }
4380 // Total size
4381 if (IsTopMaster()) {
4382 // Send total size
4383 msg.Form("%s: grand total: sent %d objects, size: %d bytes ",
4384 fPrefix.Data(), olsz, totsz);
4385 SendAsynMessage(msg.Data());
4386 }
4387
4388 } else if (IsTopMaster() && fProtocol > 6 && outlist) {
4389
4390 // Buffer to be sent
4392 mbuf.WriteObject(pq);
4393 // Sizes
4394 Int_t blen = mbuf.CompLength();
4395 Int_t olsz = outlist->GetSize();
4396 // Message for the client
4397 msg.Form("%s: sending output: %d objs, %d bytes", fPrefix.Data(), olsz, blen);
4398 SendAsynMessage(msg.Data(), kFALSE);
4399 if (sock->Send(mbuf) < 0) return -1;
4400
4401 } else {
4402 if (outlist) {
4403 PDB(kGlobal, 2) Info("SendResults", "sending output list");
4404 } else {
4405 PDB(kGlobal, 2) Info("SendResults", "notifying failure or abort");
4406 }
4407 if (sock->SendObject(outlist, kPROOF_OUTPUTLIST) < 0) return -1;
4408 }
4409
4410 PDB(kOutput,2) Info("SendResults", "done");
4411
4412 // Done
4413 return 0;
4414}
4415
4416////////////////////////////////////////////////////////////////////////////////
4417/// process the next query from the queue of submitted jobs.
4418/// to be called on the top master only.
4419
4420void TProofServ::ProcessNext(TString *slb)
4421{
4422 TDSet *dset = 0;
4423 TString filename, opt;
4424 TList *input = 0;
4425 Long64_t nentries = -1, first = 0;
4426
4427 // TObject *elist = 0;
4428 TProofQueryResult *pq = 0;
4429
4430 TObject* obj = 0;
4431 TSelector* selector_obj = 0;
4432
4433 // Process
4434
4435 // Reset compute stopwatch: we include all what done from now on
4436 fCompute.Reset();
4437 fCompute.Start();
4438
4439 // Get next query info (also removes query from the list)
4440 pq = NextQuery();
4441 if (pq) {
4442
4443 // Set not idle
4444 SetIdle(kFALSE);
4445 opt = pq->GetOptions();
4446 input = pq->GetInputList();
4447 nentries = pq->GetEntries();
4448 first = pq->GetFirst();
4449 filename = pq->GetSelecImp()->GetName();
4450 Ssiz_t id = opt.Last('#');
4451 if (id != kNPOS && id < opt.Length() - 1) {
4452 filename += opt(id + 1, opt.Length());
4453 // Remove it from 'opt' so user found on the workers what they specified
4454 opt.Remove(id);
4455 }
4456 // Attach to data set and entry- (or event-) list (if any)
4457 TObject *o = 0;
4458 if ((o = pq->GetInputObject("TDSet"))) {
4459 dset = (TDSet *) o;
4460 } else {
4461 // Should never get here
4462 Error("ProcessNext", "no TDset object: cannot continue");
4463 return;
4464 }
4465 // elist = 0;
4466 // if ((o = pq->GetInputObject("TEntryList")))
4467 // elist = o;
4468 // else if ((o = pq->GetInputObject("TEventList")))
4469 // elist = o;
4470
4471 // Expand selector files
4472 if (pq->GetSelecImp()) {
4473 gSystem->Exec(TString::Format("%s %s", kRM, pq->GetSelecImp()->GetName()));
4474 pq->GetSelecImp()->SaveSource(pq->GetSelecImp()->GetName());
4475 }
4476 if (pq->GetSelecHdr() &&
4477 !strstr(pq->GetSelecHdr()->GetName(), "TProofDrawHist")) {
4478 gSystem->Exec(TString::Format("%s %s", kRM, pq->GetSelecHdr()->GetName()));
4479 pq->GetSelecHdr()->SaveSource(pq->GetSelecHdr()->GetName());
4480 }
4481
4482 // Taking out a TSelector object from input list
4483 TIter nxt(input);
4484 while ((obj = nxt())){
4485 if (obj->InheritsFrom("TSelector") &&
4486 !strcmp(pq->GetSelecImp()->GetName(), obj->ClassName())) {
4487 selector_obj = (TSelector *) obj;
4488 Info("ProcessNext", "found object for selector '%s'", obj->ClassName());
4489 break;
4490 }
4491 }
4492
4493 } else {
4494 // Should never get here
4495 Error("ProcessNext", "empty waiting queries list!");
4496 return;
4497 }
4498
4499 // Set in running state
4500 SetQueryRunning(pq);
4501
4502 // Save to queries dir, if not standard draw
4503 if (fQMgr) {
4504 if (!(pq->IsDraw()))
4505 fQMgr->SaveQuery(pq);
4506 else
4508 fQMgr->ResetTime();
4509 }
4510
4511 // Signal the client that we are starting a new query
4513 m << TString(pq->GetSelecImp()->GetName())
4514 << dset->GetNumOfFiles()
4515 << pq->GetFirst() << pq->GetEntries();
4516 fSocket->Send(m);
4517
4518 // Create player
4519 MakePlayer();
4520
4521 // Add query results to the player lists
4523
4524 // Set query currently processed
4526
4527 // Setup data set
4528 if (dset->IsA() == TDSetProxy::Class())
4529 ((TDSetProxy*)dset)->SetProofServ(this);
4530
4531 // Add the unique query tag as TNamed object to the input list
4532 // so that it is available in TSelectors for monitoring
4533 TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
4534 input->Add(new TNamed("PROOF_QueryTag", qid.Data()));
4535 // ... and the sequential number
4536 fQuerySeqNum = pq->GetSeqNum();
4537 input->Add(new TParameter<Int_t>("PROOF_QuerySeqNum", fQuerySeqNum));
4538
4539 // Check whether we have to enforce the use of submergers, but only if the user did
4540 // not express itself on the subject
4541 if (gEnv->Lookup("Proof.UseMergers") && !input->FindObject("PROOF_UseMergers")) {
4542 Int_t smg = gEnv->GetValue("Proof.UseMergers",-1);
4543 if (smg >= 0) {
4544 input->Add(new TParameter<Int_t>("PROOF_UseMergers", smg));
4545 PDB(kSubmerger, 2) Info("ProcessNext", "PROOF_UseMergers set to %d", smg);
4546 if (gEnv->Lookup("Proof.MergersByHost")) {
4547 Int_t mbh = gEnv->GetValue("Proof.MergersByHost", 0);
4548 if (mbh != 0) {
4549 // Administrator settings have the priority
4550 TObject *o = 0;
4551 if ((o = input->FindObject("PROOF_MergersByHost"))) { input->Remove(o); delete o; }
4552 input->Add(new TParameter<Int_t>("PROOF_MergersByHost", mbh));
4553 PDB(kSubmerger, 2) Info("ProcessNext", "submergers setup by host/node");
4554 }
4555 }
4556 }
4557 }
4558
4559 // Set input
4560 TIter next(input);
4561 TObject *o = 0;
4562 while ((o = next())) {
4563 PDB(kGlobal, 2) Info("ProcessNext", "adding: %s", o->GetName());
4564 fPlayer->AddInput(o);
4565 }
4566
4567 // Remove the list of the missing files from the original list, if any
4568 if ((o = input->FindObject("MissingFiles"))) input->Remove(o);
4569
4570 // Process
4571 PDB(kGlobal, 1) Info("ProcessNext", "calling %s::Process()", fPlayer->IsA()->GetName());
4572 if (selector_obj){
4573 Info("ProcessNext", "calling fPlayer->Process() with selector object: %s", selector_obj->ClassName());
4574 fPlayer->Process(dset, selector_obj, opt, nentries, first);
4575 }
4576 else {
4577 Info("ProcessNext", "calling fPlayer->Process() with selector name: %s", filename.Data());
4578 fPlayer->Process(dset, filename, opt, nentries, first);
4579 }
4580
4581 // This is the end of merging
4583
4584 // Return number of events processed
4585 Bool_t abort =
4588 m.Reset(kPROOF_STOPPROCESS);
4589 // message sent from worker to the master
4590 if (fProtocol > 18) {
4592 m << status << abort;
4593 status = 0; // the status belongs to the player.
4594 } else if (fProtocol > 8) {
4595 m << fPlayer->GetEventsProcessed() << abort;
4596 } else {
4598 }
4599 fSocket->Send(m);
4600 }
4601
4602 // Register any dataset produced during this processing, if required
4604 TNamed *psr = (TNamed *) fPlayer->GetOutputList()->FindObject("PROOFSERV_RegisterDataSet");
4605 if (psr) {
4606 TString emsg;
4607 if (RegisterDataSets(input, fPlayer->GetOutputList(), fDataSetManager, emsg) != 0)
4608 Warning("ProcessNext", "problems registering produced datasets: %s", emsg.Data());
4609 do {
4610 fPlayer->GetOutputList()->Remove(psr);
4611 delete psr;
4612 } while ((psr = (TNamed *) fPlayer->GetOutputList()->FindObject("PROOFSERV_RegisterDataSet")));
4613 }
4614 }
4615
4616 // Complete filling of the TQueryResult instance
4617 if (fQMgr && !pq->IsDraw()) {
4618 if (!abort) fProof->AskStatistics();
4619 if (fQMgr->FinalizeQuery(pq, fProof, fPlayer))
4621 }
4622
4623 // If we were requested to save results on the master and we are not in save-to-file mode
4624 // then we save the results
4625 if (IsTopMaster() && fPlayer->GetOutputList()) {
4626 Bool_t save = kTRUE;
4627 TIter nxo(fPlayer->GetOutputList());
4628 TObject *xo = 0;
4629 while ((xo = nxo())) {
4630 if (xo->InheritsFrom("TProofOutputFile") && xo->TestBit(TProofOutputFile::kSwapFile)) {
4631 save = kFALSE;
4632 break;
4633 }
4634 }
4635 if (save) {
4636 TNamed *nof = (TNamed *) input->FindObject("PROOF_DefaultOutputOption");
4637 if (nof) {
4638 TString oopt(nof->GetTitle());
4639 if (oopt.BeginsWith("of:")) {
4640 oopt.Replace(0, 3, "");
4641 if (!oopt.IsNull()) fPlayer->SetOutputFilePath(oopt);
4643 }
4644 }
4645 }
4646 }
4647
4648 // Send back the results
4649 TQueryResult *pqr = pq->CloneInfo();
4650 // At least the TDSet name in the light object
4651 Info("ProcessNext", "adding info about dataset '%s' in the light query result", dset->GetName());
4652 TList rin;
4653 TDSet *ds = new TDSet(dset->GetName(), dset->GetObjName());
4654 rin.Add(ds);
4655 if (pqr) pqr->SetInputList(&rin, kTRUE);
4657 PDB(kGlobal, 2)
4658 Info("ProcessNext", "sending results");
4659 TQueryResult *xpq = (pqr && fProtocol > 10) ? pqr : pq;
4660 if (SendResults(fSocket, fPlayer->GetOutputList(), xpq) != 0)
4661 Warning("ProcessNext", "problems sending output list");
4662 if (slb) slb->Form("%d %lld %lld %.3f", fPlayer->GetExitStatus(), pq->GetEntries(),
4663 pq->GetBytes(), pq->GetUsedCPU());
4664 } else {
4666 Warning("ProcessNext","the output list is empty!");
4668 Warning("ProcessNext", "problems sending output list");
4669 if (slb) slb->Form("%d -1 -1 %.3f", fPlayer->GetExitStatus(), pq->GetUsedCPU());
4670 }
4671
4672 // Remove aborted queries from the list
4674 SafeDelete(pqr);
4675 if (fQMgr) fQMgr->RemoveQuery(pq);
4676 } else {
4677 // Keep in memory only light infor about a query
4678 if (!(pq->IsDraw()) && pqr) {
4679 if (fQMgr && fQMgr->Queries()) {
4680 fQMgr->Queries()->Add(pqr);
4681 // Remove from the fQueries list
4682 fQMgr->Queries()->Remove(pq);
4683 }
4684 // These removes 'pq' from the internal player list and
4685 // deletes it; in this way we do not attempt a double delete
4686 // when destroying the player
4688 pq->GetTitle(), pq->GetName()));
4689 }
4690 }
4691
4692 DeletePlayer();
4693 if (IsMaster() && fProof->UseDynamicStartup())
4694 // stop the workers
4696}
4697
4698////////////////////////////////////////////////////////////////////////////////
4699/// Register TFileCollections in 'out' as datasets according to the rules in 'in'
4700
4702 TDataSetManager *dsm, TString &msg)
4703{
4704 PDB(kDataset, 1)
4705 ::Info("TProofServ::RegisterDataSets",
4706 "enter: %d objs in the output list", (out ? out->GetSize() : -1));
4707
4708 if (!in || !out || !dsm) {
4709 ::Error("TProofServ::RegisterDataSets", "invalid inputs: %p, %p, %p", in, out, dsm);
4710 return 0;
4711 }
4712 msg = "";
4713 THashList tags;
4714 TList torm;
4715 TIter nxo(out);
4716 TObject *o = 0;
4717 while ((o = nxo())) {
4718 // Only file collections TFileCollection
4719 TFileCollection *ds = dynamic_cast<TFileCollection*> (o);
4720 if (ds) {
4721 // Origin of this dataset
4722 ds->SetTitle(gSystem->HostName());
4723 // The tag and register option
4724 TNamed *fcn = 0;
4725 TString tag = TString::Format("DATASET_%s", ds->GetName());
4726 if (!(fcn = (TNamed *) out->FindObject(tag))) continue;
4727 // If this tag is in the list of processed tags, flag it for removal
4728 if (tags.FindObject(tag)) {
4729 torm.Add(o);
4730 continue;
4731 }
4732 // Register option
4733 TString regopt(fcn->GetTitle());
4734 // Sort according to the internal index, if required
4735 if (regopt.Contains(":sortidx:")) {
4736 ds->Sort(kTRUE);
4737 regopt.ReplaceAll(":sortidx:", "");
4738 }
4739 // Register this dataset
4741 // Extract the list
4742 if (ds->GetList()->GetSize() > 0) {
4743 // Register the dataset (quota checks are done inside here)
4744 const char *vfmsg = regopt.Contains("V") ? " and verifying" : "";
4745 msg.Form("Registering%s dataset '%s' ... ", vfmsg, ds->GetName());
4746 // Always allow verification for this action
4748 if (regopt.Contains("V") && !allowVerify) dsm->SetBit(TDataSetManager::kAllowVerify);
4749 // Main action
4750 Int_t rc = dsm->RegisterDataSet(ds->GetName(), ds, regopt);
4751 // Reset to the previous state if needed
4752 if (regopt.Contains("V") && !allowVerify) dsm->ResetBit(TDataSetManager::kAllowVerify);
4753 if (rc != 0) {
4754 ::Warning("TProofServ::RegisterDataSets",
4755 "failure registering or verifying dataset '%s'", ds->GetName());
4756 msg.Form("Registering%s dataset '%s' ... failed! See log for more details", vfmsg, ds->GetName());
4757 } else {
4758 ::Info("TProofServ::RegisterDataSets", "dataset '%s' successfully registered%s",
4759 ds->GetName(), (strlen(vfmsg) > 0) ? " and verified" : "");
4760 msg.Form("Registering%s dataset '%s' ... OK", vfmsg, ds->GetName());
4761 // Add tag to the list of processed tags to avoid double processing
4762 // (there may be more objects with the same name, created by each worker)
4763 tags.Add(new TObjString(tag));
4764 }
4765 // Notify
4766 PDB(kDataset, 2) {
4767 ::Info("TProofServ::RegisterDataSets", "printing collection");
4768 ds->Print("F");
4769 }
4770 } else {
4771 ::Warning("TProofServ::RegisterDataSets", "collection '%s' is empty", o->GetName());
4772 }
4773 } else {
4774 ::Info("TProofServ::RegisterDataSets", "dataset registration not allowed");
4775 return -1;
4776 }
4777 }
4778 }
4779 // Cleanup all temporary stuff possibly created by each worker
4780 TIter nxrm(&torm);
4781 while ((o = nxrm())) out->Remove(o);
4782 torm.SetOwner(kTRUE);
4783 // Remove tags
4784 TIter nxtg(&tags);
4785 while((o = nxtg())) {
4786 TObject *oo = 0;
4787 while ((oo = out->FindObject(o->GetName()))) { out->Remove(oo); }
4788 }
4789 tags.SetOwner(kTRUE);
4790
4791 PDB(kDataset, 1) ::Info("TProofServ::RegisterDataSets", "exit");
4792 // Done
4793 return 0;
4794}
4795
4796////////////////////////////////////////////////////////////////////////////////
4797/// Handle request for list of queries.
4798
4800{
4801 PDB(kGlobal, 1)
4802 Info("HandleQueryList", "Enter");
4803
4804 Bool_t all;
4805 (*mess) >> all;
4806
4807 TList *ql = new TList;
4808 Int_t ntot = 0, npre = 0, ndraw= 0;
4809 if (fQMgr) {
4810 if (all) {
4811 // Rescan
4812 TString qdir = fQueryDir;
4813 Int_t idx = qdir.Index("session-");
4814 if (idx != kNPOS)
4815 qdir.Remove(idx);
4817 // Send also information about previous queries, if any
4818 if (fQMgr->PreviousQueries()) {
4819 TIter nxq(fQMgr->PreviousQueries());
4820 TProofQueryResult *pqr = 0;
4821 while ((pqr = (TProofQueryResult *)nxq())) {
4822 ntot++;
4823 pqr->fSeqNum = ntot;
4824 ql->Add(pqr);
4825 }
4826 }
4827 }
4828
4829 npre = ntot;
4830 if (fQMgr->Queries()) {
4831 // Add info about queries in this session
4832 TIter nxq(fQMgr->Queries());
4833 TProofQueryResult *pqr = 0;
4834 TQueryResult *pqm = 0;
4835 while ((pqr = (TProofQueryResult *)nxq())) {
4836 ntot++;
4837 if ((pqm = pqr->CloneInfo())) {
4838 pqm->fSeqNum = ntot;
4839 ql->Add(pqm);
4840 } else {
4841 Warning("HandleQueryList", "unable to clone TProofQueryResult '%s:%s'",
4842 pqr->GetName(), pqr->GetTitle());
4843 }
4844 }
4845 }
4846 // Number of draw queries
4847 ndraw = fQMgr->DrawQueries();
4848 }
4849
4851 m << npre << ndraw << ql;
4852 fSocket->Send(m);
4853 delete ql;
4854
4855 // Done
4856 return;
4857}
4858
4859////////////////////////////////////////////////////////////////////////////////
4860/// Handle remove request.
4861
4862void TProofServ::HandleRemove(TMessage *mess, TString *slb)
4863{
4864 PDB(kGlobal, 1)
4865 Info("HandleRemove", "Enter");
4866
4867 TString queryref;
4868 (*mess) >> queryref;
4869
4870 if (slb) *slb = queryref;
4871
4872 if (queryref == "cleanupqueue") {
4873 // Remove pending requests
4875 // Notify
4876 Info("HandleRemove", "%d queries removed from the waiting list", pend);
4877 // We are done
4878 return;
4879 }
4880
4881 if (queryref == "cleanupdir") {
4882
4883 // Cleanup previous sessions results
4884 Int_t nd = (fQMgr) ? fQMgr->CleanupQueriesDir() : -1;
4885
4886 // Notify
4887 Info("HandleRemove", "%d directories removed", nd);
4888 // We are done
4889 return;
4890 }
4891
4892
4893 if (fQMgr) {
4894 TProofLockPath *lck = 0;
4895 if (fQMgr->LockSession(queryref, &lck) == 0) {
4896
4897 // Remove query
4898 TList qtorm;
4899 fQMgr->RemoveQuery(queryref, &qtorm);
4901
4902 // Unlock and remove the lock file
4903 if (lck) {
4904 gSystem->Unlink(lck->GetName());
4905 SafeDelete(lck);
4906 }
4907
4908 // We are done
4909 return;
4910 }
4911 } else {
4912 Warning("HandleRemove", "query result manager undefined!");
4913 }
4914
4915 // Notify failure
4916 Info("HandleRemove",
4917 "query %s could not be removed (unable to lock session)", queryref.Data());
4918
4919 // Done
4920 return;
4921}
4922
4923////////////////////////////////////////////////////////////////////////////////
4924/// Handle retrieve request.
4925
4926void TProofServ::HandleRetrieve(TMessage *mess, TString *slb)
4927{
4928 PDB(kGlobal, 1)
4929 Info("HandleRetrieve", "Enter");
4930
4931 TString queryref;
4932 (*mess) >> queryref;
4933
4934 if (slb) *slb = queryref;
4935
4936 // Parse reference string
4937 Int_t qry = -1;
4938 TString qdir;
4939 if (fQMgr) fQMgr->LocateQuery(queryref, qry, qdir);
4940
4941 TString fout = qdir;
4942 fout += "/query-result.root";
4943
4944 TFile *f = TFile::Open(fout,"READ");
4945 TProofQueryResult *pqr = 0;
4946 if (f) {
4947 f->ReadKeys();
4948 TIter nxk(f->GetListOfKeys());
4949 TKey *k = 0;
4950 while ((k = (TKey *)nxk())) {
4951 if (!strcmp(k->GetClassName(), "TProofQueryResult")) {
4952 pqr = (TProofQueryResult *) f->Get(k->GetName());
4953 // For backward compatibility
4954 if (pqr && fProtocol < 13) {
4955 TDSet *d = 0;
4956 TObject *o = 0;
4957 TIter nxi(pqr->GetInputList());
4958 while ((o = nxi()))
4959 if ((d = dynamic_cast<TDSet *>(o)))
4960 break;
4961 d->SetWriteV3(kTRUE);
4962 }
4963 if (pqr) {
4964
4965 // Message for the client
4966 Float_t qsz = (Float_t) f->GetSize();
4967 Int_t ilb = 0;
4968 static const char *clb[4] = { "bytes", "KB", "MB", "GB" };
4969 while (qsz > 1000. && ilb < 3) {
4970 qsz /= 1000.;
4971 ilb++;
4972 }
4973 SendAsynMessage(TString::Format("%s: sending result of %s:%s (%.1f %s)",
4974 fPrefix.Data(), pqr->GetTitle(), pqr->GetName(),
4975 qsz, clb[ilb]));
4977 } else {
4978 Info("HandleRetrieve",
4979 "query not found in file %s",fout.Data());
4980 // Notify not found
4982 }
4983 break;
4984 }
4985 }
4986 f->Close();
4987 delete f;
4988 } else {
4989 Info("HandleRetrieve",
4990 "file cannot be open (%s)",fout.Data());
4991 // Notify not found
4993 return;
4994 }
4995
4996 // Done
4997 return;
4998}
4999
5000////////////////////////////////////////////////////////////////////////////////
5001/// Handle lib, inc search paths modification request
5002
5004{
5005 TString type;
5006 Bool_t add;
5007 TString path;
5008 Int_t rc = 1;
5009 (*mess) >> type >> add >> path;
5010 if (mess->BufferSize() > mess->Length()) (*mess) >> rc;
5011
5012 // Check type of action
5013 if ((type != "lib") && (type != "inc")) {
5014 Error("HandleLibIncPath","unknown action type: %s", type.Data());
5015 return rc;
5016 }
5017
5018 // Separators can be either commas or blanks
5019 path.ReplaceAll(","," ");
5020
5021 // Decompose lists
5022 TObjArray *op = 0;
5023 if (path.Length() > 0 && path != "-") {
5024 if (!(op = path.Tokenize(" "))) {
5025 Error("HandleLibIncPath","decomposing path %s", path.Data());
5026 return rc;
5027 }
5028 }
5029
5030 if (add) {
5031
5032 if (type == "lib") {
5033
5034 // Add libs
5035 TIter nxl(op, kIterBackward);
5036 TObjString *lib = 0;
5037 while ((lib = (TObjString *) nxl())) {
5038 // Expand path
5039 TString xlib = lib->GetName();
5040 gSystem->ExpandPathName(xlib);
5041 // Add to the dynamic lib search path if it exists and can be read
5042 if (!gSystem->AccessPathName(xlib, kReadPermission)) {
5043 TString newlibpath = gSystem->GetDynamicPath();
5044 // In the first position after the working dir
5045 Int_t pos = 0;
5046 if (newlibpath.BeginsWith(".:"))
5047 pos = 2;
5048 if (newlibpath.Index(xlib) == kNPOS) {
5049 newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
5050 gSystem->SetDynamicPath(newlibpath);
5051 }
5052 } else {
5053 Info("HandleLibIncPath",
5054 "libpath %s does not exist or cannot be read - not added", xlib.Data());
5055 }
5056 }
5057
5058 // Forward the request, if required
5059 if (IsMaster())
5060 fProof->AddDynamicPath(path);
5061
5062 } else {
5063
5064 // Add incs
5065 TIter nxi(op);
5066 TObjString *inc = 0;
5067 while ((inc = (TObjString *) nxi())) {
5068 // Expand path
5069 TString xinc = inc->GetName();
5070 gSystem->ExpandPathName(xinc);
5071 // Add to the dynamic lib search path if it exists and can be read
5072 if (!gSystem->AccessPathName(xinc, kReadPermission)) {
5073 TString curincpath = gSystem->GetIncludePath();
5074 if (curincpath.Index(xinc) == kNPOS)
5075 gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
5076 } else
5077 Info("HandleLibIncPath",
5078 "incpath %s does not exist or cannot be read - not added", xinc.Data());
5079 }
5080
5081 // Forward the request, if required
5082 if (IsMaster())
5083 fProof->AddIncludePath(path);
5084 }
5085
5086
5087 } else {
5088
5089 if (type == "lib") {
5090
5091 // Remove libs
5092 TIter nxl(op);
5093 TObjString *lib = 0;
5094 while ((lib = (TObjString *) nxl())) {
5095 // Expand path
5096 TString xlib = lib->GetName();
5097 gSystem->ExpandPathName(xlib);
5098 // Remove from the dynamic lib search path
5099 TString newlibpath = gSystem->GetDynamicPath();
5100 newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
5101 gSystem->SetDynamicPath(newlibpath);
5102 }
5103
5104 // Forward the request, if required
5105 if (IsMaster())
5107
5108 } else {
5109
5110 // Remove incs
5111 TIter nxi(op);
5112 TObjString *inc = 0;
5113 while ((inc = (TObjString *) nxi())) {
5114 TString newincpath = gSystem->GetIncludePath();
5115 newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
5116 // Remove the interpreter path (added anyhow internally)
5117 newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
5118 gSystem->SetIncludePath(newincpath);
5119 }
5120
5121 // Forward the request, if required
5122 if (IsMaster())
5124 }
5125 }
5126 // Done
5127 return rc;
5128}
5129
5130////////////////////////////////////////////////////////////////////////////////
5131/// Handle file checking request.
5132
5133void TProofServ::HandleCheckFile(TMessage *mess, TString *slb)
5134{
5135 TString filenam;
5136 TMD5 md5;
5137 UInt_t opt = TProof::kUntar;
5138
5140
5141 // Parse message
5142 (*mess) >> filenam >> md5;
5143 if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8))
5144 (*mess) >> opt;
5145
5146 if (slb) *slb = filenam;
5147
5148 if (filenam.BeginsWith("-")) {
5149 // install package:
5150 // compare md5's, untar, store md5 in PROOF-INF, remove par file
5151 Int_t st = 0;
5152 Bool_t err = kFALSE;
5153 filenam = filenam.Strip(TString::kLeading, '-');
5154 TString packnam = filenam;
5155 packnam.Remove(packnam.Length() - 4); // strip off ".par"
5156 // compare md5's to check if transmission was ok
5157 TMD5 *md5local = fPackMgr->GetMD5(packnam);
5158 if (md5local && md5 == (*md5local)) {
5159 if ((opt & TProof::kRemoveOld)) {
5160 if ((st = fPackMgr->Clean(packnam)))
5161 Error("HandleCheckFile", "failure cleaning %s", packnam.Data());
5162 }
5163 // Unpack
5164 st = fPackMgr->Unpack(packnam, md5local);
5165 if (st == 0) {
5166 // Notify the client
5167 reply << (Int_t)1;
5168 PDB(kPackage, 1)
5169 Info("HandleCheckFile",
5170 "package %s installed on node", filenam.Data());
5171 } else {
5172 if (st == -2) {
5173 Error("HandleCheckFile", "gunzip not found");
5174 } else {
5175 Error("HandleCheckFile", "package %s did not unpack into %s",
5176 filenam.Data(), packnam.Data());
5177 }
5178 reply << (Int_t)0;
5179 if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5180 err = kTRUE;
5181 }
5182 } else {
5183 reply << (Int_t)0;
5184 if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5185 err = kTRUE;
5186 PDB(kPackage, 1)
5187 Error("HandleCheckFile",
5188 "package %s not yet on node", filenam.Data());
5189 }
5190
5191 // Note: Originally an fPackageLock->Unlock() call was made
5192 // after the if-else statement below. With multilevel masters,
5193 // submasters still check to make sure the package exists with
5194 // the correct md5 checksum and need to do a read lock there.
5195 // As yet locking is not that sophisicated so the lock must
5196 // be released below before the call to fProof->UploadPackage().
5197 if (err) {
5198 // delete par file in case of error
5199 fPackMgr->Remove(filenam);
5200 } else if (IsMaster()) {
5201 // forward to workers
5202 TString parpath;
5203 fPackMgr->GetParPath(filenam, parpath);
5204 if (fProof->UploadPackage(parpath,
5205 (TProof::EUploadPackageOpt)opt) != 0)
5206 Info("HandleCheckFile",
5207 "problems uploading package %s", parpath.Data());
5208 }
5209 delete md5local;
5210 fSocket->Send(reply);
5211
5212 } else if (filenam.BeginsWith("+") || filenam.BeginsWith("=")) {
5213 filenam.Remove(0,1);
5214
5215 TString parname = filenam;
5216 // If remote install it from there
5217 TFile::EFileType ft = TFile::GetType(filenam);
5218 if (ft == TFile::kWeb || ft == TFile::kNet) {
5219 parname = gSystem->BaseName(filenam);
5220 if (fPackMgr->Install(filenam) < 0) {
5221 Warning("HandleCheckFile",
5222 "problems installing package %s", filenam.Data());
5223
5224 }
5225 }
5226
5227 // check file in package directory
5228 TMD5 *md5local = fPackMgr->ReadMD5(parname);
5229
5230 if (md5local && md5 == (*md5local)) {
5231 // package already on server, unlock directory
5232 reply << (Int_t)1;
5233 PDB(kPackage, 1)
5234 Info("HandleCheckFile",
5235 "package %s already on node", parname.Data());
5236 if (IsMaster()) {
5237 Int_t xrc = 0;
5238 TString par = filenam;
5239 if (ft != TFile::kWeb && ft != TFile::kNet) {
5240 xrc = fPackMgr->GetParPath(filenam, par);
5241 }
5242 if (xrc == 0) {
5243 if (fProof->UploadPackage(par) != 0)
5244 Warning("HandleCheckFile",
5245 "problems uploading package %s", par.Data());
5246 }
5247 }
5248
5249 } else {
5250 reply << (Int_t)0;
5251 if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5252 PDB(kPackage, 1)
5253 Info("HandleCheckFile",
5254 "package %s not yet on node", filenam.Data());
5255 }
5256 delete md5local;
5257 fSocket->Send(reply);
5258
5259 } else {
5260 // check file in cache directory
5261 TString cachef = fCacheDir + "/" + filenam;
5262 fCacheLock->Lock();
5263 TMD5 *md5local = TMD5::FileChecksum(cachef);
5264
5265 if (md5local && md5 == (*md5local)) {
5266 reply << (Int_t)1;
5267 PDB(kCache, 1)
5268 Info("HandleCheckFile", "file %s already on node", filenam.Data());
5269 } else {
5270 reply << (Int_t)0;
5271 if (fProtocol <= 19) reply.Reset(kPROOF_FATAL);
5272 PDB(kCache, 1)
5273 Info("HandleCheckFile", "file %s not yet on node", filenam.Data());
5274 }
5275 delete md5local;
5276 fSocket->Send(reply);
5277 fCacheLock->Unlock();
5278 }
5279}
5280
5281////////////////////////////////////////////////////////////////////////////////
5282/// Handle here all cache and package requests.
5283
5285{
5286 PDB(kGlobal, 1)
5287 Info("HandleCache", "Enter");
5288
5289 Int_t status = 0;
5290 Int_t type = 0;
5291 Bool_t all = kFALSE;
5292 TMessage msg;
5293 Bool_t fromglobal = kFALSE;
5294 Int_t chkveropt = TPackMgr::kCheckROOT; // Default: check ROOT version
5295 TPackMgr *packmgr = 0;
5296
5297 // Notification message
5298 TString noth;
5299 const char *k = (IsMaster()) ? "Mst" : "Wrk";
5300 noth.Form("%s-%s", k, fOrdinal.Data());
5301
5302 TList *optls = 0;
5303 TString packagedir, package, pdir, ocwd, file;
5304 (*mess) >> type;
5305 switch (type) {
5306 case TProof::kShowCache:
5307 (*mess) >> all;
5308 printf("*** File cache %s:%s ***\n", gSystem->HostName(),
5309 fCacheDir.Data());
5310 fflush(stdout);
5311 PDB(kCache, 1) {
5312 gSystem->Exec(TString::Format("%s -a %s", kLS, fCacheDir.Data()));
5313 } else {
5314 gSystem->Exec(TString::Format("%s %s", kLS, fCacheDir.Data()));
5315 }
5316 if (IsMaster() && all)
5317 fProof->ShowCache(all);
5318 LogToMaster();
5319 if (slb) slb->Form("%d %d", type, all);
5320 break;
5322 file = "";
5323 if ((mess->BufferSize() > mess->Length())) (*mess) >> file;
5324 fCacheLock->Lock();
5325 if (file.IsNull() || file == "*") {
5326 gSystem->Exec(TString::Format("%s %s/* %s/.*.binversion", kRM, fCacheDir.Data(), fCacheDir.Data()));
5327 } else {
5328 gSystem->Exec(TString::Format("%s %s/%s", kRM, fCacheDir.Data(), file.Data()));
5329 }
5330 fCacheLock->Unlock();
5331 if (IsMaster())
5333 if (slb) slb->Form("%d %s", type, file.Data());
5334 break;
5336 (*mess) >> all;
5337 fPackMgr->Show();
5338 if (IsMaster() && all)
5339 fProof->ShowPackages(all);
5340 LogToMaster();
5341 if (slb) slb->Form("%d %d", type, all);
5342 break;
5344 if ((status = fPackMgr->Unload(0)) == 0) {
5345 fPackMgr->Remove();
5346 if (IsMaster())
5347 status = fProof->ClearPackages();
5348 }
5349 if (slb) slb->Form("%d %d", type, status);
5350 break;
5352 (*mess) >> package;
5353 if ((status = fPackMgr->Unload(package)) == 0) {
5354 fPackMgr->Remove(package);
5355 if (IsMaster())
5356 status = fProof->ClearPackage(package);
5357 }
5358 if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5359 break;
5361 (*mess) >> package;
5362 if ((mess->BufferSize() > mess->Length())) (*mess) >> chkveropt;
5363
5364 if (!(packmgr = TPackMgr::GetPackMgr(package.Data(), fPackMgr))) {
5365 // Package not found
5366 SendAsynMessage(TString::Format("%s: kBuildPackage: failure locating %s ...",
5367 noth.Data(), package.Data()));
5368 status = -1;
5369 break;
5370 }
5371 fromglobal = (packmgr == fPackMgr) ? kFALSE : kTRUE;
5372 packagedir = packmgr->GetTitle();
5373
5374 if (IsMaster() && !fromglobal) {
5375 // Make sure package is available on all slaves, even new ones
5376 TString par;
5377 Int_t xrc = packmgr->GetParPath(package, par);
5378 if (xrc != 0 || fProof->UploadPackage(par) != 0) {
5379 Warning("HandleCache",
5380 "kBuildPackage: problems forwarding package %s to workers", package.Data());
5381 SendAsynMessage(TString::Format("%s: kBuildPackage: problems forwarding package %s to workers ...",
5382 noth.Data(), package.Data()));
5383 }
5384 }
5385
5386 if (!status) {
5387
5388 PDB(kPackage, 1)
5389 Info("HandleCache",
5390 "kBuildPackage: package %s exists and has PROOF-INF directory", package.Data());
5391
5392 // Forward build command to slaves, but don't wait for results
5393 if (IsMaster())
5395
5396 // Build here
5397 status = packmgr->Build(package.Data(), chkveropt);
5398 }
5399
5400 if (status) {
5401 // Notify the upper level
5402 SendAsynMessage(TString::Format("%s: failure building %s ... (status: %d)", noth.Data(), package.Data(), status));
5403 } else {
5404 // collect built results from slaves
5405 if (IsMaster())
5407 PDB(kPackage, 1)
5408 Info("HandleCache", "package %s successfully built", package.Data());
5409 }
5410 if (slb) slb->Form("%d %s %d %d", type, package.Data(), status, chkveropt);
5411 break;
5412
5414 (*mess) >> package;
5415
5416 // Get argument, if any
5417 if ((mess->BufferSize() > mess->Length())) (*mess) >> optls;
5418 // Load the package
5419 if ((status = fPackMgr->Load(package.Data(), optls)) < 0) {
5420
5421 // Notify the upper level
5422 SendAsynMessage(TString::Format("%s: failure loading %s, args: %p (%d) ...",
5423 noth.Data(), package.Data(), optls,
5424 (optls && optls->GetSize() > 0) ? optls->GetSize() : 0));
5425
5426 } else {
5427
5428 if (IsMaster()) {
5429 if (optls && optls->GetSize() > 0) {
5430 // List argument
5431 status = fProof->LoadPackage(package, kFALSE, optls);
5432 } else {
5433 // No argument
5434 status = fProof->LoadPackage(package);
5435 }
5436 }
5437
5438 PDB(kPackage, 1)
5439 Info("HandleCache", "package %s successfully loaded", package.Data());
5440 }
5441
5442 if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5443 break;
5444
5446 (*mess) >> all;
5447 { TString title("*** Enabled packages ***");
5448 if (!IsMaster() || all) {
5449 title.Form("*** Enabled packages on %s %s on %s",
5450 (IsMaster()) ? "master" : "worker",
5451 fOrdinal.Data(), gSystem->HostName());
5452 }
5453 fPackMgr->ShowEnabled(title);
5454 }
5455 if (IsMaster() && all)
5457 LogToMaster();
5458 if (slb) slb->Form("%d %d", type, all);
5459 break;
5461 (*mess) >> all;
5462 if (IsMaster() && all)
5463 fProof->ShowCache(all);
5464 LogToMaster();
5465 if (slb) slb->Form("%d %d", type, all);
5466 break;
5468 file = "";
5469 if ((mess->BufferSize() > mess->Length())) (*mess) >> file;
5470 if (IsMaster())
5472 if (slb) slb->Form("%d %s", type, file.Data());
5473 break;
5475 (*mess) >> all;
5476 if (IsMaster() && all)
5477 fProof->ShowPackages(all);
5478 LogToMaster();
5479 if (slb) slb->Form("%d %d", type, all);
5480 break;
5482 if (IsMaster())
5484 if (slb) slb->Form("%d", type);
5485 break;
5487 (*mess) >> package;
5488 if (IsMaster())
5489 fProof->DisablePackage(package);
5490 if (slb) slb->Form("%d %s", type, package.Data());
5491 break;
5493 (*mess) >> package;
5494 if ((mess->BufferSize() > mess->Length())) (*mess) >> chkveropt;
5495 if (IsMaster())
5496 fProof->BuildPackage(package, TProof::kBuildAll, chkveropt);
5497 if (slb) slb->Form("%d %s %d", type, package.Data(), chkveropt);
5498 break;
5500 (*mess) >> package;
5501 status = fPackMgr->Unload(package);
5502 if (IsMaster() && status == 0)
5503 status = fProof->UnloadPackage(package);
5504 if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5505 break;
5507 (*mess) >> package;
5508 fPackMgr->Remove(package);
5509 if (IsMaster())
5510 fProof->DisablePackage(package);
5511 if (slb) slb->Form("%d %s", type, package.Data());
5512 break;
5514 status = fPackMgr->Unload(0);
5515 if (IsMaster() && status == 0)
5516 status = fProof->UnloadPackages();
5517 if (slb) slb->Form("%d %s %d", type, package.Data(), status);
5518 break;
5520 fPackMgr->Remove();
5521 if (IsMaster())
5523 if (slb) slb->Form("%d %s", type, package.Data());
5524 break;
5527 { TList *epl = fPackMgr->GetListOfEnabled();
5528 msg << type << epl;
5529 fSocket->Send(msg);
5530 epl->SetOwner();
5531 delete epl;
5532 }
5533 if (slb) slb->Form("%d", type);
5534 break;
5536 {
5537 TList *pack = fPackMgr->GetList();
5539 msg << type << pack;
5540 fSocket->Send(msg);
5541 pack->SetOwner(kTRUE);
5542 delete pack;
5543 }
5544 if (slb) slb->Form("%d", type);
5545 break;
5546 case TProof::kLoadMacro:
5547 {
5548 (*mess) >> package;
5549
5550 // By first forwarding the load command to the unique workers
5551 // and only then loading locally we load/build in parallel
5552 if (IsMaster())
5553 fProof->Load(package, kFALSE, kTRUE);
5554
5555 // Atomic action
5556 fCacheLock->Lock();
5557
5558 TString originalCwd = gSystem->WorkingDirectory();
5560
5561 // Load the macro
5562 TString pack(package);
5563 Ssiz_t from = 0;
5564 if ((from = pack.Index(",")) != kNPOS) pack.Remove(from);
5565 Info("HandleCache", "loading macro %s ...", pack.Data());
5566 gROOT->ProcessLine(TString::Format(".L %s", pack.Data()));
5567
5568 // Release atomicity
5569 gSystem->ChangeDirectory(originalCwd.Data());
5570 fCacheLock->Unlock();
5571
5572 // Now we collect the result from the unique workers and send the load request
5573 // to the other workers (no compilation)
5574 if (IsMaster())
5575 fProof->Load(package, kFALSE, kFALSE);
5576
5577 // Notify the upper level
5578 LogToMaster();
5579
5580 if (slb) slb->Form("%d %s", type, package.Data());
5581 }
5582 break;
5583 default:
5584 Error("HandleCache", "unknown type %d", type);
5585 break;
5586 }
5587
5588 // We are done
5589 return status;
5590}
5591
5592////////////////////////////////////////////////////////////////////////////////
5593/// Handle here all requests to modify worker lists
5594
5596{
5597 PDB(kGlobal, 1)
5598 Info("HandleWorkerLists", "Enter");
5599
5600 Int_t type = 0, rc = 0;
5601 TString ord;
5602
5603 (*mess) >> type;
5604
5605 switch (type) {
5607 (*mess) >> ord;
5608 if (ord != "*" && !ord.BeginsWith(GetOrdinal()) && ord != "restore") break;
5609 if (fProof) {
5611 Int_t nactmax = fProof->GetListOfSlaves()->GetSize() -
5613 if (nact < nactmax || !IsEndMaster()) {
5614 Int_t nwc = fProof->ActivateWorker(ord);
5615 Int_t nactnew = fProof->GetListOfActiveSlaves()->GetSize();
5616 if (ord == "*") {
5617 if (nactnew == nactmax) {
5618 PDB(kGlobal, 1) Info("HandleWorkerList", "all workers (re-)activated");
5619 } else {
5620 if (IsEndMaster())
5621 PDB(kGlobal, 1) Info("HandleWorkerList", "%d workers could not be (re-)activated", nactmax - nactnew);
5622 }
5623 } else if (ord == "restore") {
5624 if (nwc > 0) {
5625 PDB(kGlobal, 1) Info("HandleWorkerList","active worker(s) restored");
5626 } else {
5627 Error("HandleWorkerList", "some active worker(s) could not be restored; check logs");
5628 }
5629 } else {
5630 if (nactnew == (nact + nwc)) {
5631 if (nwc > 0)
5632 PDB(kGlobal, 1) Info("HandleWorkerList","worker(s) %s (re-)activated", ord.Data());
5633 } else {
5634 if (nwc != -2 && IsEndMaster()) {
5635 Error("HandleWorkerList", "some worker(s) could not be (re-)activated;"
5636 " # of actives: %d --> %d (nwc: %d)",
5637 nact, nactnew, nwc);
5638 }
5639 rc = (nwc < 0) ? nwc : -1;
5640 }
5641 }
5642 } else {
5643 PDB(kGlobal, 1) Info("HandleWorkerList","all workers are already active");
5644 }
5645 } else {
5646 Warning("HandleWorkerList","undefined PROOF session: protocol error?");
5647 }
5648 break;
5650 (*mess) >> ord;
5651 if (ord != "*" && !ord.BeginsWith(GetOrdinal()) && ord != "restore") break;
5652 if (fProof) {
5654 if (nact > 0) {
5655 Int_t nwc = fProof->DeactivateWorker(ord);
5656 Int_t nactnew = fProof->GetListOfActiveSlaves()->GetSize();
5657 if (ord == "*") {
5658 if (nactnew == 0) {
5659 PDB(kGlobal, 1) Info("HandleWorkerList","all workers deactivated");
5660 } else {
5661 if (IsEndMaster())
5662 PDB(kGlobal, 1) Info("HandleWorkerList","%d workers could not be deactivated", nactnew);
5663 }
5664 } else {
5665 if (nactnew == (nact - nwc)) {
5666 if (nwc > 0)
5667 PDB(kGlobal, 1) Info("HandleWorkerList","worker(s) %s deactivated", ord.Data());
5668 } else {
5669 if (nwc != -2 && IsEndMaster()) {
5670 Error("HandleWorkerList", "some worker(s) could not be deactivated:"
5671 " # of actives: %d --> %d (nwc: %d)",
5672 nact, nactnew, nwc);
5673 }
5674 rc = (nwc < 0) ? nwc : -1;
5675 }
5676 }
5677 } else {
5678 PDB(kGlobal, 1) Info("HandleWorkerList","all workers are already inactive");
5679 }
5680 } else {
5681 Warning("HandleWorkerList","undefined PROOF session: protocol error?");
5682 }
5683 break;
5684 default:
5685 Warning("HandleWorkerList","unknown action type (%d)", type);
5686 rc = -1;
5687 }
5688 // Done
5689 return rc;
5690}
5691
5692////////////////////////////////////////////////////////////////////////////////
5693/// Get list of workers to be used from now on.
5694/// The list must be provided by the caller.
5695
5697 Int_t & /* prioritychange */,
5698 Bool_t /* resume */)
5699{
5700 // Parse the config file
5701 TProofResourcesStatic *resources =
5703 fConfFile = resources->GetFileName(); // Update the global file name (with path)
5704 PDB(kGlobal,1)
5705 Info("GetWorkers", "using PROOF config file: %s", fConfFile.Data());
5706
5707 // Get the master
5708 TProofNodeInfo *master = resources->GetMaster();
5709 if (!master) {
5710 PDB(kAll,1)
5711 Info("GetWorkers",
5712 "no appropriate master line found in %s", fConfFile.Data());
5713 return kQueryStop;
5714 } else {
5715 // Set image if not yet done and available
5716 if (fImage.IsNull() && strlen(master->GetImage()) > 0)
5717 fImage = master->GetImage();
5718 }
5719
5720 // Fill submaster or worker list
5721 if (workers) {
5722 if (resources->GetSubmasters() && resources->GetSubmasters()->GetSize() > 0) {
5723 PDB(kAll,1)
5724 resources->GetSubmasters()->Print();
5725 TProofNodeInfo *ni = 0;
5726 TIter nw(resources->GetSubmasters());
5727 while ((ni = (TProofNodeInfo *) nw()))
5728 workers->Add(new TProofNodeInfo(*ni));
5729 } else if (resources->GetWorkers() && resources->GetWorkers()->GetSize() > 0) {
5730 PDB(kAll,1)
5731 resources->GetWorkers()->Print();
5732 TProofNodeInfo *ni = 0;
5733 TIter nw(resources->GetWorkers());
5734 while ((ni = (TProofNodeInfo *) nw()))
5735 workers->Add(new TProofNodeInfo(*ni));
5736 }
5737 }
5738
5739 // We are done
5740 return kQueryOK;
5741}
5742
5743////////////////////////////////////////////////////////////////////////////////
5744/// Set the file stream where to log (default stderr).
5745/// If ferr == 0 the default is restored.
5746/// Returns current setting.
5747
5749{
5750 FILE *oldferr = fgErrorHandlerFile;
5751 fgErrorHandlerFile = (ferr) ? ferr : stderr;
5752 return oldferr;
5753}
5754
5755////////////////////////////////////////////////////////////////////////////////
5756/// The PROOF error handler function. It prints the message on fgErrorHandlerFile and
5757/// if abort is set it aborts the application.
5758
5759void TProofServ::ErrorHandler(Int_t level, Bool_t abort, const char *location,
5760 const char *msg)
5761{
5762 if (gErrorIgnoreLevel == kUnset) {
5764 if (gEnv) {
5765 TString lvl = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
5766 if (!lvl.CompareTo("Print", TString::kIgnoreCase))
5768 else if (!lvl.CompareTo("Info", TString::kIgnoreCase))
5770 else if (!lvl.CompareTo("Warning", TString::kIgnoreCase))
5772 else if (!lvl.CompareTo("Error", TString::kIgnoreCase))
5774 else if (!lvl.CompareTo("Break", TString::kIgnoreCase))
5776 else if (!lvl.CompareTo("SysError", TString::kIgnoreCase))
5778 else if (!lvl.CompareTo("Fatal", TString::kIgnoreCase))
5780 }
5781 }
5782
5783 if (level < gErrorIgnoreLevel)
5784 return;
5785
5786 // Always communicate errors via SendLogFile
5787 if (level >= kError && gProofServ)
5789
5790 Bool_t tosyslog = (fgLogToSysLog > 2) ? kTRUE : kFALSE;
5791
5792 const char *type = 0;
5793 ELogLevel loglevel = kLogInfo;
5794
5795 Int_t ipos = (location) ? strlen(location) : 0;
5796
5797 if (level >= kPrint) {
5798 loglevel = kLogInfo;
5799 type = "Print";
5800 }
5801 if (level >= kInfo) {
5802 loglevel = kLogInfo;
5803 char *ps = location ? (char *) strrchr(location, '|') : (char *)0;
5804 if (ps) {
5805 ipos = (int)(ps - (char *)location);
5806 type = "SvcMsg";
5807 } else {
5808 type = "Info";
5809 }
5810 }
5811 if (level >= kWarning) {
5812 loglevel = kLogWarning;
5813 type = "Warning";
5814 }
5815 if (level >= kError) {
5816 loglevel = kLogErr;
5817 type = "Error";
5818 }
5819 if (level >= kBreak) {
5820 loglevel = kLogErr;
5821 type = "*** Break ***";
5822 }
5823 if (level >= kSysError) {
5824 loglevel = kLogErr;
5825 type = "SysError";
5826 }
5827 if (level >= kFatal) {
5828 loglevel = kLogErr;
5829 type = "Fatal";
5830 }
5831
5832
5833 TString buf;
5834
5835 // Time stamp
5836 TTimeStamp ts;
5837 TString st(ts.AsString("lc"),19);
5838
5839 if (!location || ipos == 0 ||
5840 (level >= kPrint && level < kInfo) ||
5841 (level >= kBreak && level < kSysError)) {
5842 fprintf(fgErrorHandlerFile, "%s %5d %s | %s: %s\n", st(11,8).Data(),
5843 gSystem->GetPid(),
5844 (gProofServ ? gProofServ->GetPrefix() : "proof"),
5845 type, msg);
5846 if (tosyslog)
5847 buf.Form("%s: %s:%s", fgSysLogEntity.Data(), type, msg);
5848 } else {
5849 fprintf(fgErrorHandlerFile, "%s %5d %s | %s in <%.*s>: %s\n", st(11,8).Data(),
5850 gSystem->GetPid(),
5851 (gProofServ ? gProofServ->GetPrefix() : "proof"),
5852 type, ipos, location, msg);
5853 if (tosyslog)
5854 buf.Form("%s: %s:<%.*s>: %s", fgSysLogEntity.Data(), type, ipos, location, msg);
5855 }
5856 fflush(fgErrorHandlerFile);
5857
5858 if (tosyslog)
5859 gSystem->Syslog(loglevel, buf);
5860
5861#ifdef __APPLE__
5862 if (__crashreporter_info__)
5863 delete [] __crashreporter_info__;
5864 __crashreporter_info__ = StrDup(buf);
5865#endif
5866
5867 if (abort) {
5868
5869 static Bool_t recursive = kFALSE;
5870
5871 if (gProofServ != 0 && !recursive) {
5872 recursive = kTRUE;
5874 recursive = kFALSE;
5875 }
5876
5877 fprintf(fgErrorHandlerFile, "aborting\n");
5878 fflush(fgErrorHandlerFile);
5880 gSystem->Abort();
5881 }
5882}
5883
5884////////////////////////////////////////////////////////////////////////////////
5885/// Make player instance.
5886
5888{
5889 TVirtualProofPlayer *p = 0;
5890
5891 // Cleanup first
5892 DeletePlayer();
5893
5894 if (IsParallel()) {
5895 // remote mode
5896 p = fProof->MakePlayer();
5897 } else {
5898 // slave or sequential mode
5899 p = TVirtualProofPlayer::Create("slave", 0, fSocket);
5900 if (IsMaster())
5901 fProof->SetPlayer(p);
5902 }
5903
5904 // set player
5905 fPlayer = p;
5906}
5907
5908////////////////////////////////////////////////////////////////////////////////
5909/// Delete player instance.
5910
5912{
5913 if (IsMaster()) {
5914 PDB(kGlobal, 1) {
5915 fCompute.Stop();
5916 Printf(" +++ Latest processing times: %f s (CPU: %f s)",
5918 }
5919 if (fProof) fProof->SetPlayer(0);
5920 } else {
5922 }
5923 fPlayer = 0;
5924}
5925
5926////////////////////////////////////////////////////////////////////////////////
5927/// Get the processing priority for the group the user belongs too. This
5928/// priority is a number (0 - 100) determined by a scheduler (third
5929/// party process) based on some basic priority the group has, e.g.
5930/// we might want to give users in a specific group (e.g. promptana)
5931/// a higher priority than users in other groups, and on the analysis
5932/// of historical logging data (i.e. usage of CPU by the group in a
5933/// previous time slot, as recorded in TPerfStats::WriteQueryLog()).
5934///
5935/// Currently the group priority is obtained by a query in a SQL DB
5936/// table proofpriority, which has the format:
5937/// CREATE TABLE proofpriority (
5938/// id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
5939/// group VARCHAR(32) NOT NULL,
5940/// priority INT
5941///)
5942
5944{
5945 TString sqlserv = gEnv->GetValue("ProofServ.QueryLogDB","");
5946 TString sqluser = gEnv->GetValue("ProofServ.QueryLogUser","");
5947 TString sqlpass = gEnv->GetValue("ProofServ.QueryLogPasswd","");
5948
5949 Int_t priority = 100;
5950
5951 if (sqlserv == "")
5952 return priority;
5953
5954 TString sql;
5955 sql.Form("SELECT priority WHERE group='%s' FROM proofpriority", fGroup.Data());
5956
5957 // open connection to SQL server
5958 TSQLServer *db = TSQLServer::Connect(sqlserv, sqluser, sqlpass);
5959
5960 if (!db || db->IsZombie()) {
5961 Error("GetPriority", "failed to connect to SQL server %s as %s %s",
5962 sqlserv.Data(), sqluser.Data(), sqlpass.Data());
5963 printf("%s\n", sql.Data());
5964 } else {
5965 TSQLResult *res = db->Query(sql);
5966
5967 if (!res) {
5968 Error("GetPriority", "query into proofpriority failed");
5969 Printf("%s", sql.Data());
5970 } else {
5971 TSQLRow *row = res->Next(); // first row is header
5972 if (row) {
5973 priority = atoi(row->GetField(0));
5974 delete row;
5975 } else {
5976 Error("GetPriority", "first row is header is NULL");
5977 }
5978 }
5979 delete res;
5980 }
5981 delete db;
5982
5983 return priority;
5984}
5985
5986////////////////////////////////////////////////////////////////////////////////
5987/// Send an asychronous message to the master / client .
5988/// Masters will forward up the message to the client.
5989/// The client prints 'msg' of stderr and adds a '\n'/'\r' depending on
5990/// 'lf' being kTRUE (default) or kFALSE.
5991/// Returns the return value from TSocket::Send(TMessage &) .
5992
5993void TProofServ::SendAsynMessage(const char *msg, Bool_t lf)
5994{
5995 static TMessage m(kPROOF_MESSAGE);
5996
5997 // To leave a track in the output file ... if requested
5998 // (clients will be notified twice)
5999 PDB(kAsyn,1)
6000 Info("SendAsynMessage","%s", (msg ? msg : "(null)"));
6001
6002 if (fSocket && msg) {
6003 m.Reset(kPROOF_MESSAGE);
6004 m << TString(msg) << lf;
6005 if (fSocket->Send(m) <= 0)
6006 Warning("SendAsynMessage", "could not send message '%s'", msg);
6007 }
6008
6009 return;
6010}
6011
6012////////////////////////////////////////////////////////////////////////////////
6013/// Reposition the read pointer in the log file to the very end.
6014/// This allows to "hide" useful debug messages during normal operations
6015/// while preserving the possibility to have them in case of problems.
6016
6018{
6019 off_t lend = lseek(fileno(stdout), (off_t)0, SEEK_END);
6020 if (lend >= 0) lseek(fLogFileDes, lend, SEEK_SET);
6021}
6022
6023////////////////////////////////////////////////////////////////////////////////
6024/// Truncate the log file to the 80% of the required max size if this
6025/// is set.
6026
6028{
6029#ifndef WIN32
6030 TString emsg;
6031 if (fLogFileMaxSize > 0 && fLogFileDes > 0) {
6032 fflush(stdout);
6033 struct stat st;
6034 if (fstat(fLogFileDes, &st) == 0) {
6035 if (st.st_size >= fLogFileMaxSize) {
6036 off_t truncsz = (off_t) (( fLogFileMaxSize * 80 ) / 100 );
6037 if (truncsz < 100) {
6038 emsg.Form("+++ WARNING +++: %s: requested truncate size too small"
6039 " (%lld,%lld) - ignore ", fPrefix.Data(), (Long64_t) truncsz, fLogFileMaxSize);
6040 SendAsynMessage(emsg.Data());
6041 return;
6042 }
6044 while (ftruncate(fileno(stdout), truncsz) != 0 &&
6045 (TSystem::GetErrno() == EINTR)) {
6047 }
6048 if (TSystem::GetErrno() > 0) {
6049 Error("TruncateLogFile", "truncating to %lld bytes; file size is %lld bytes (errno: %d)",
6050 (Long64_t)truncsz, (Long64_t)st.st_size, TSystem::GetErrno());
6051 emsg.Form("+++ WARNING +++: %s: problems truncating log file to %lld bytes; file size is %lld bytes"
6052 " (errno: %d)", fPrefix.Data(), (Long64_t)truncsz, (Long64_t)st.st_size, TSystem::GetErrno());
6053 SendAsynMessage(emsg.Data());
6054 } else {
6055 Info("TruncateLogFile", "file truncated to %lld bytes (80%% of %lld); file size was %lld bytes ",
6056 (Long64_t)truncsz, fLogFileMaxSize, (Long64_t)st.st_size);
6057 emsg.Form("+++ WARNING +++: %s: log file truncated to %lld bytes (80%% of %lld)",
6058 fPrefix.Data(), (Long64_t)truncsz, fLogFileMaxSize);
6059 SendAsynMessage(emsg.Data());
6060 }
6061 }
6062 } else {
6063 emsg.Form("+++ WARNING +++: %s: could not stat log file descriptor"
6064 " for truncation (errno: %d)", fPrefix.Data(), TSystem::GetErrno());
6065 SendAsynMessage(emsg.Data());
6066 }
6067 }
6068#endif
6069}
6070
6071////////////////////////////////////////////////////////////////////////////////
6072/// Exception handler: we do not try to recover here, just exit.
6073
6075{
6076 Error("HandleException", "caugth exception triggered by signal '%d' %s %lld",
6077 sig, fgLastMsg.Data(), fgLastEntry);
6078 // Description
6079 TString emsg;
6080 emsg.Form("%s: caught exception triggered by signal '%d' %s %lld",
6081 GetOrdinal(), sig, fgLastMsg.Data(), fgLastEntry);
6082 // Try to warn the user
6083 SendAsynMessage(emsg.Data());
6084
6085 gSystem->Exit(sig);
6086}
6087
6088////////////////////////////////////////////////////////////////////////////////
6089/// Handle here requests about datasets.
6090
6092{
6093 if (gDebug > 0)
6094 Info("HandleDataSets", "enter");
6095
6096 // We need a dataset manager
6097 if (!fDataSetManager) {
6098 Warning("HandleDataSets", "no data manager is available to fullfil the request");
6099 return -1;
6100 }
6101
6102 // Used in most cases
6103 TString dsUser, dsGroup, dsName, dsTree, uri, opt;
6104 Int_t rc = 0;
6105
6106 // Invalid characters in dataset URI
6107 TPMERegexp reInvalid("[^A-Za-z0-9._-]"); // from ParseUri
6108
6109 // Message type
6110 Int_t type = 0;
6111 (*mess) >> type;
6112
6113 switch (type) {
6115 //
6116 // Check whether this dataset exist
6117 {
6118 (*mess) >> uri;
6119 if (slb) slb->Form("%d %s", type, uri.Data());
6121 // Dataset name does exist
6122 return -1;
6123 }
6124 break;
6126 // list size must be above 0
6127 {
6129 (*mess) >> uri;
6130 (*mess) >> opt;
6131 if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6132 // Extract the list
6133 TFileCollection *dataSet =
6134 dynamic_cast<TFileCollection*> ((mess->ReadObject(TFileCollection::Class())));
6135 if (!dataSet || dataSet->GetList()->GetSize() == 0) {
6136 Error("HandleDataSets", "can not save an empty list.");
6137 return -1;
6138 }
6139 // Register the dataset (quota checks are done inside here)
6140 rc = fDataSetManager->RegisterDataSet(uri, dataSet, opt);
6141 delete dataSet;
6142 return rc;
6143 } else {
6144 Info("HandleDataSets", "dataset registration not allowed");
6145 if (slb) slb->Form("%d notallowed", type);
6146 return -1;
6147 }
6148 }
6149 break;
6150
6152 {
6153 (*mess) >> uri; // TString
6154
6155 if (!fDataSetStgRepo) {
6156 Error("HandleDataSets",
6157 "no dataset staging request repository available");
6158 return -1;
6159 }
6160
6161 // Transform input URI in a valid dataset name
6162 TString validUri = uri;
6163 while (reInvalid.Substitute(validUri, "_")) {}
6164
6165 // Check if dataset exists beforehand: if it does, staging has
6166 // already been requested
6167 if (fDataSetStgRepo->ExistsDataSet(validUri.Data())) {
6168 Warning("HandleDataSets", "staging of %s already requested",
6169 uri.Data());
6170 return -1;
6171 }
6172
6173 // Try to get dataset from current manager
6175 if (!fc || (fc->GetNFiles() == 0)) {
6176 Error("HandleDataSets", "empty dataset or no dataset returned");
6177 if (fc) delete fc;
6178 return -1;
6179 }
6180
6181 // Reset all staged bits and remove unnecessary URLs (all but last)
6182 TIter it(fc->GetList());
6183 TFileInfo *fi;
6184 while ((fi = dynamic_cast<TFileInfo *>(it.Next()))) {
6186 Int_t nToErase = fi->GetNUrls() - 1;
6187 for (Int_t i=0; i<nToErase; i++)
6188 fi->RemoveUrlAt(0);
6189 }
6190
6191 fc->Update(); // absolutely necessary
6192
6193 // Save request
6194 fDataSetStgRepo->ParseUri(validUri, &dsGroup, &dsUser, &dsName);
6195 if (fDataSetStgRepo->WriteDataSet(dsGroup, dsUser,
6196 dsName, fc) == 0) {
6197 // Error, can't save dataset
6198 Error("HandleDataSets",
6199 "can't register staging request for %s", uri.Data());
6200 delete fc;
6201 return -1;
6202 }
6203
6204 Info("HandleDataSets",
6205 "Staging request registered for %s", uri.Data());
6206
6207 delete fc;
6208 return 0; // success (-1 == failure)
6209 }
6210 break;
6211
6213 {
6214 if (!fDataSetStgRepo) {
6215 Error("HandleDataSets",
6216 "no dataset staging request repository available");
6217 return -1;
6218 }
6219
6220 (*mess) >> uri; // TString
6221
6222 // Transform URI in a valid dataset name
6223 while (reInvalid.Substitute(uri, "_")) {}
6224
6225 // Get the list
6227 if (fc) {
6229 delete fc;
6230 return 0;
6231 }
6232 else {
6233 // No such dataset: not an error, but don't send message
6234 Info("HandleDataSets", "no pending staging request for %s",
6235 uri.Data());
6236 return 0;
6237 }
6238 }
6239 break;
6240
6242 {
6243 if (!fDataSetStgRepo) {
6244 Error("HandleDataSets",
6245 "no dataset staging request repository available");
6246 return -1;
6247 }
6248
6249 (*mess) >> uri;
6250
6251 // Transform URI in a valid dataset name
6252 while (reInvalid.Substitute(uri, "_")) {}
6253
6254 if (!fDataSetStgRepo->RemoveDataSet(uri.Data()))
6255 return -1; // failure
6256
6257 return 0; // success
6258 }
6259 break;
6260
6262 {
6263 (*mess) >> uri >> opt;
6264 if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6265 // Show content
6266 fDataSetManager->ShowDataSets(uri, opt);
6267 }
6268 break;
6269
6271 {
6272 (*mess) >> uri >> opt;
6273 if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6274 // Get the datasets and fill a map
6276 Ssiz_t kLite = opt.Index(":lite:", 0, TString::kIgnoreCase);
6277 if (kLite != kNPOS) {
6279 opt.Remove(kLite, strlen(":lite:"));
6280 }
6281 TMap *returnMap = fDataSetManager->GetDataSets(uri, omsk);
6282 // If defines, option gives the name of a server for which to extract the information
6283 if (returnMap && !opt.IsNull()) {
6284 // The return map will be in the form </group/user/datasetname> --> <dataset>
6285 TMap *rmap = new TMap;
6286 TObject *k = 0;
6287 TFileCollection *fc = 0, *xfc = 0;
6288 TIter nxd(returnMap);
6289 while ((k = nxd()) && (fc = (TFileCollection *) returnMap->GetValue(k))) {
6290 // Get subset on specified server, if any
6291 if ((xfc = fc->GetFilesOnServer(opt.Data()))) {
6292 rmap->Add(new TObjString(k->GetName()), xfc);
6293 }
6294 }
6295 returnMap->DeleteAll();
6296 if (rmap->GetSize() > 0) {
6297 returnMap = rmap;
6298 } else {
6299 Info("HandleDataSets", "no dataset found on server '%s'", opt.Data());
6300 delete rmap;
6301 returnMap = 0;
6302 }
6303 }
6304 if (returnMap) {
6305 // Send them back
6306 fSocket->SendObject(returnMap, kMESS_OK);
6307 returnMap->DeleteAll();
6308 } else {
6309 // Failure
6310 return -1;
6311 }
6312 }
6313 break;
6315 {
6316 (*mess) >> uri >> opt;
6317 if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6318 // Get the list
6319 TFileCollection *fileList = fDataSetManager->GetDataSet(uri,opt);
6320 if (fileList) {
6321 fSocket->SendObject(fileList, kMESS_OK);
6322 delete fileList;
6323 } else {
6324 // Failure
6325 return -1;
6326 }
6327 }
6328 break;
6330 {
6332 (*mess) >> uri;
6333 if (slb) slb->Form("%d %s", type, uri.Data());
6334 if (!fDataSetManager->RemoveDataSet(uri)) {
6335 // Failure
6336 return -1;
6337 }
6338 } else {
6339 Info("HandleDataSets", "dataset creation / removal not allowed");
6340 if (slb) slb->Form("%d notallowed", type);
6341 return -1;
6342 }
6343 }
6344 break;
6346 {
6348 (*mess) >> uri >> opt;
6349 if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6351 rc = fDataSetManager->ScanDataSet(uri, opt);
6352 // TODO: verify in parallel:
6353 // - dataset = GetDataSet(uri)
6354 // - TList flist; TDataSetManager::ScanDataSet(dataset, ..., &flist)
6355 // - fPlayer->Process( ... flist ...) // needs to be developed
6356 // - dataset->Integrate(flist) (perhaps automatic; flist object owned by dataset)
6357 // - RegisterDataSet(uri, dataset, "OT")
6358 } else {
6359 Info("HandleDataSets", "dataset verification not allowed");
6360 return -1;
6361 }
6362 }
6363 break;
6364 case TProof::kGetQuota:
6365 {
6367 if (slb) slb->Form("%d", type);
6368 TMap *groupQuotaMap = fDataSetManager->GetGroupQuotaMap();
6369 if (groupQuotaMap) {
6370 // Send result
6371 fSocket->SendObject(groupQuotaMap, kMESS_OK);
6372 } else {
6373 return -1;
6374 }
6375 } else {
6376 Info("HandleDataSets", "quota control disabled");
6377 if (slb) slb->Form("%d disabled", type);
6378 return -1;
6379 }
6380 }
6381 break;
6382 case TProof::kShowQuota:
6383 {
6385 if (slb) slb->Form("%d", type);
6386 (*mess) >> opt;
6387 // Display quota information
6389 } else {
6390 Info("HandleDataSets", "quota control disabled");
6391 if (slb) slb->Form("%d disabled", type);
6392 }
6393 }
6394 break;
6396 {
6398 (*mess) >> uri;
6399 if (slb) slb->Form("%d %s", type, uri.Data());
6401 } else {
6402 Info("HandleDataSets", "kSetDefaultTreeName: modification of dataset info not allowed");
6403 if (slb) slb->Form("%d notallowed", type);
6404 return -1;
6405 }
6406 }
6407 break;
6408 case TProof::kCache:
6409 {
6410 (*mess) >> uri >> opt;
6411 if (slb) slb->Form("%d %s %s", type, uri.Data(), opt.Data());
6412 if (opt == "show") {
6413 // Show cache content
6415 } else if (opt == "clear") {
6416 // Clear cache content
6418 } else {
6419 Error("HandleDataSets", "kCache: unknown action: %s", opt.Data());
6420 }
6421 }
6422 break;
6423 default:
6424 rc = -1;
6425 Error("HandleDataSets", "unknown type %d", type);
6426 break;
6427 }
6428
6429 // We are done
6430 return rc;
6431}
6432
6433////////////////////////////////////////////////////////////////////////////////
6434/// Handle a message of type kPROOF_SUBMERGER
6435
6437{
6438 // Message type
6439 Int_t type = 0;
6440 (*mess) >> type;
6441
6442 TString msg;
6443 switch (type) {
6445 break;
6446
6448 {
6449 Bool_t deleteplayer = kTRUE;
6450 if (!IsMaster()) {
6451 if (fMergingMonitor) {
6452 Info("HandleSubmerger", "kSendOutput: interrupting ...");
6454 }
6455 if (fMergingSocket) {
6459 }
6460
6461 TString name;
6462 Int_t port = 0;
6463 Int_t merger_id = -1;
6464 (*mess) >> merger_id >> name >> port;
6465 PDB(kSubmerger, 1)
6466 Info("HandleSubmerger","worker %s redirected to merger #%d %s:%d", fOrdinal.Data(), merger_id, name.Data(), port);
6467
6468 TSocket *t = 0;
6469 if (name.Length() > 0 && port > 0 && (t = new TSocket(name, port)) && t->IsValid()) {
6470
6471 PDB(kSubmerger, 2) Info("HandleSubmerger",
6472 "kSendOutput: worker asked for sending output to merger #%d %s:%d",
6473 merger_id, name.Data(), port);
6474
6475 if (SendResults(t, fPlayer->GetOutputList()) != 0) {
6476 msg.Form("worker %s cannot send results to merger #%d at %s:%d", GetPrefix(), merger_id, name.Data(), port);
6477 PDB(kSubmerger, 2) Info("HandleSubmerger",
6478 "kSendOutput: %s - inform the master", msg.Data());
6479 SendAsynMessage(msg);
6480 // Results not send
6482 answ << Int_t(TProof::kMergerDown);
6483 answ << merger_id;
6484 fSocket->Send(answ);
6485 } else {
6486 // Worker informs master that it had sent its output to the merger
6488 answ << Int_t(TProof::kOutputSent);
6489 answ << merger_id;
6490 fSocket->Send(answ);
6491
6492 PDB(kSubmerger, 2) Info("HandleSubmerger", "kSendOutput: worker sent its output");
6494 SetIdle(kTRUE);
6495 SendLogFile();
6496 }
6497 } else {
6498
6499 if (name == "master") {
6500 PDB(kSubmerger, 2) Info("HandleSubmerger",
6501 "kSendOutput: worker was asked for sending output to master");
6503 Warning("HandleSubmerger", "problems sending output list");
6504 // Signal the master that we are idle
6506 SetIdle(kTRUE);
6507 SendLogFile();
6508
6509 } else if (!t || !(t->IsValid())) {
6510 msg.Form("worker %s could not open a valid socket to merger #%d at %s:%d",
6511 GetPrefix(), merger_id, name.Data(), port);
6512 PDB(kSubmerger, 2) Info("HandleSubmerger",
6513 "kSendOutput: %s - inform the master", msg.Data());
6514 SendAsynMessage(msg);
6515 // Results not send
6517 answ << Int_t(TProof::kMergerDown);
6518 answ << merger_id;
6519 fSocket->Send(answ);
6520 deleteplayer = kFALSE;
6521 }
6522
6523 SafeDelete(t);
6524
6525 }
6526
6527 } else {
6528 Error("HandleSubmerger", "kSendOutput: received not on worker");
6529 }
6530
6531 // Cleanup
6532 if (deleteplayer) DeletePlayer();
6533 }
6534 break;
6535 case TProof::kBeMerger:
6536 {
6537 Bool_t deleteplayer = kTRUE;
6538 if (!IsMaster()) {
6539 Int_t merger_id = -1;
6540 //Int_t merger_port = 0;
6541 Int_t connections = 0;
6542 (*mess) >> merger_id >> connections;
6543 PDB(kSubmerger, 2)
6544 Info("HandleSubmerger", "worker %s established as merger", fOrdinal.Data());
6545
6546 PDB(kSubmerger, 2)
6547 Info("HandleSubmerger",
6548 "kBeMerger: worker asked for being merger #%d for %d connections",
6549 merger_id, connections);
6550
6551 TVirtualProofPlayer *mergerPlayer = TVirtualProofPlayer::Create("remote",fProof,0);
6552
6553 if (mergerPlayer) {
6554 PDB(kSubmerger, 2) Info("HandleSubmerger",
6555 "kBeMerger: mergerPlayer created (%p) ", mergerPlayer);
6556
6557 // This may be used internally
6559
6560 // Accept results from assigned workers
6561 if (AcceptResults(connections, mergerPlayer)) {
6562 PDB(kSubmerger, 2)
6563 Info("HandleSubmerger", "kBeMerger: all outputs from workers accepted");
6564
6565 PDB(kSubmerger, 2)
6566 Info("","adding own output to the list on %s", fOrdinal.Data());
6567
6568 // Add own results to the output list.
6569 // On workers the player does not own the output list, which is owned
6570 // by the selector and deleted in there
6571 // On workers the player does not own the output list, which is owned
6572 // by the selector and deleted in there
6573 TIter nxo(fPlayer->GetOutputList());
6574 TObject * o = 0;
6575 while ((o = nxo())) {
6576 if ((mergerPlayer->AddOutputObject(o) != 1)) {
6577 // Remove the object if it has not been merged: it is owned
6578 // now by the merger player (in its output list)
6579 if (fPlayer->GetOutputList()) {
6580 PDB(kSubmerger, 2)
6581 Info("HandleSocketInput", "removing merged object (%p)", o);
6583 }
6584 }
6585 }
6586 PDB(kSubmerger, 2) Info("HandleSubmerger","kBeMerger: own outputs added");
6587 PDB(kSubmerger, 2) Info("HandleSubmerger","starting delayed merging on %s", fOrdinal.Data());
6588
6589 // Delayed merging if neccessary
6590 mergerPlayer->MergeOutput(kTRUE);
6591
6592 PDB(kSubmerger, 2) mergerPlayer->GetOutputList()->Print("all");
6593
6594 PDB(kSubmerger, 2) Info("HandleSubmerger", "delayed merging on %s finished ", fOrdinal.Data());
6595 PDB(kSubmerger, 2) Info("HandleSubmerger", "%s sending results to master ", fOrdinal.Data());
6596 // Send merged results to master
6597 if (SendResults(fSocket, mergerPlayer->GetOutputList()) != 0)
6598 Warning("HandleSubmerger","kBeMerger: problems sending output list");
6599 if (mergerPlayer->GetOutputList())
6600 mergerPlayer->GetOutputList()->SetOwner(kTRUE);
6601
6602 PDB(kSubmerger, 2) Info("HandleSubmerger","kBeMerger: results sent to master");
6603 // Signal the master that we are idle
6605 SetIdle(kTRUE);
6606 SendLogFile();
6607 } else {
6608 // Results from all assigned workers not accepted
6610 answ << Int_t(TProof::kMergerDown);
6611 answ << merger_id;
6612 fSocket->Send(answ);
6613 deleteplayer = kFALSE;
6614 }
6615 // Reset
6616 SafeDelete(mergerPlayer);
6617
6618 } else {
6619 Warning("HandleSubmerger","kBeMerger: problems craeting the merger player!");
6620 // Results from all assigned workers not accepted
6622 answ << Int_t(TProof::kMergerDown);
6623 answ << merger_id;
6624 fSocket->Send(answ);
6625 deleteplayer = kFALSE;
6626 }
6627 } else {
6628 Error("HandleSubmerger","kSendOutput: received not on worker");
6629 }
6630
6631 // Cleanup
6632 if (deleteplayer) DeletePlayer();
6633 }
6634 break;
6635
6637 break;
6638
6640 {
6641 // Received only in case of forced termination of merger by master
6642 PDB(kSubmerger, 2) Info("HandleSubmerger", "kStopMerging");
6643 if (fMergingMonitor) {
6644 Info("HandleSubmerger", "kStopMerging: interrupting ...");
6646 }
6647 }
6648 break;
6649
6651 break;
6652 }
6653}
6654
6655////////////////////////////////////////////////////////////////////////////////
6656/// Cloning itself via fork. Not implemented
6657
6659{
6660 Info("HandleFork", "fork cloning not implemented");
6661}
6662
6663////////////////////////////////////////////////////////////////////////////////
6664/// Fork a child.
6665/// If successful, return 0 in the child process and the child pid in the parent
6666/// process. The child pid is registered for reaping.
6667/// Return <0 in the parent process in case of failure.
6668
6670{
6671#ifndef WIN32
6672 // Fork
6673 pid_t pid;
6674 if ((pid = fork()) < 0) {
6675 Error("Fork", "failed to fork");
6676 return pid;
6677 }
6678
6679 // Nothing else to do in the child
6680 if (!pid) return pid;
6681
6682 // Make sure that the reaper timer is started
6683 if (!fReaperTimer) {
6684 fReaperTimer = new TReaperTimer(1000);
6685 fReaperTimer->Start(-1);
6686 }
6687
6688 // Register the new child
6689 fReaperTimer->AddPid(pid);
6690
6691 // Done
6692 return pid;
6693#else
6694 Warning("Fork", "Functionality not provided under windows");
6695 return -1;
6696#endif
6697}
6698
6699////////////////////////////////////////////////////////////////////////////////
6700/// Replace <ord>, <user>, <u>, <group>, <stag>, <qnum>, <file>, <rver> and
6701/// <build> placeholders in fname.
6702/// Here, <rver> is the root version in integer form, e.g. 53403, and <build> a
6703/// string includign version, architecture and compiler version, e.g.
6704/// '53403_linuxx8664gcc_gcc46' .
6705
6706void TProofServ::ResolveKeywords(TString &fname, const char *path)
6707{
6708 // Replace <user>, if any
6709 if (fname.Contains("<user>")) {
6710 if (gProofServ && gProofServ->GetUser() && strlen(gProofServ->GetUser())) {
6711 fname.ReplaceAll("<user>", gProofServ->GetUser());
6712 } else if (gProof && gProof->GetUser() && strlen(gProof->GetUser())) {
6713 fname.ReplaceAll("<user>", gProof->GetUser());
6714 } else {
6715 fname.ReplaceAll("<user>", "nouser");
6716 }
6717 }
6718 // Replace <us>, if any
6719 if (fname.Contains("<u>")) {
6720 if (gProofServ && gProofServ->GetUser() && strlen(gProofServ->GetUser())) {
6721 TString u(gProofServ->GetUser()[0]);
6722 fname.ReplaceAll("<u>", u);
6723 } else if (gProof && gProof->GetUser() && strlen(gProof->GetUser())) {
6724 TString u(gProof->GetUser()[0]);
6725 fname.ReplaceAll("<u>", u);
6726 } else {
6727 fname.ReplaceAll("<u>", "n");
6728 }
6729 }
6730 // Replace <group>, if any
6731 if (fname.Contains("<group>")) {
6732 if (gProofServ && gProofServ->GetGroup() && strlen(gProofServ->GetGroup())) {
6733 fname.ReplaceAll("<group>", gProofServ->GetGroup());
6734 } else if (gProof && gProof->GetGroup() && strlen(gProof->GetGroup())) {
6735 fname.ReplaceAll("<group>", gProof->GetGroup());
6736 } else {
6737 fname.ReplaceAll("<group>", "default");
6738 }
6739 }
6740 // Replace <stag>, if any
6741 if (fname.Contains("<stag>")) {
6743 fname.ReplaceAll("<stag>", gProofServ->GetSessionTag());
6744 } else if (gProof && gProof->GetSessionTag() && strlen(gProof->GetSessionTag())) {
6745 fname.ReplaceAll("<stag>", gProof->GetSessionTag());
6746 } else {
6747 ::Warning("TProofServ::ResolveKeywords", "session tag undefined: ignoring");
6748 }
6749 }
6750 // Replace <ord>, if any
6751 if (fname.Contains("<ord>")) {
6752 if (gProofServ && gProofServ->GetOrdinal() && strlen(gProofServ->GetOrdinal()))
6753 fname.ReplaceAll("<ord>", gProofServ->GetOrdinal());
6754 else
6755 ::Warning("TProofServ::ResolveKeywords", "ordinal number undefined: ignoring");
6756 }
6757 // Replace <qnum>, if any
6758 if (fname.Contains("<qnum>")) {
6760 fname.ReplaceAll("<qnum>", TString::Format("%d", gProofServ->GetQuerySeqNum()).Data());
6761 else
6762 ::Warning("TProofServ::ResolveKeywords", "query seqeuntial number undefined: ignoring");
6763 }
6764 // Replace <file>, if any
6765 if (fname.Contains("<file>") && path && strlen(path) > 0) {
6766 fname.ReplaceAll("<file>", path);
6767 }
6768 // Replace <rver>, if any
6769 if (fname.Contains("<rver>")) {
6770 TString v = TString::Format("%d", gROOT->GetVersionInt());
6771 fname.ReplaceAll("<rver>", v);
6772 }
6773 // Replace <build>, if any
6774 if (fname.Contains("<build>")) {
6775 TString b = TString::Format("%d_%s_%s", gROOT->GetVersionInt(), gSystem->GetBuildArch(),
6777 fname.ReplaceAll("<build>", b);
6778 }
6779}
6780
6781////////////////////////////////////////////////////////////////////////////////
6782/// Return the status of this session:
6783/// 0 idle
6784/// 1 running
6785/// 2 being terminated (currently unused)
6786/// 3 queued
6787/// 4 idle timed-out (not set in here but in TIdleTOTimer::Notify)
6788/// This is typically run in the reader thread, so access needs to be protected
6789
6791{
6792 std::lock_guard<std::recursive_mutex> lock(fQMtx);
6793 Int_t st = (fIdle) ? 0 : 1;
6794 if (fIdle && fWaitingQueries->GetSize() > 0) st = 3;
6795 return st;
6796}
6797
6798////////////////////////////////////////////////////////////////////////////////
6799/// Update the session status in the relevant file. The status is taken from
6800/// GetSessionStatus() unless xst >= 0, in which case xst is used.
6801/// Return 0 on success, -errno if the file could not be opened.
6802
6804{
6805 FILE *fs = fopen(fAdminPath.Data(), "w");
6806 if (fs) {
6807 Int_t st = (xst < 0) ? GetSessionStatus() : xst;
6808 fprintf(fs, "%d", st);
6809 fclose(fs);
6810 PDB(kGlobal, 2)
6811 Info("UpdateSessionStatus", "status (=%d) update in path: %s", st, fAdminPath.Data());
6812 } else {
6813 return -errno;
6814 }
6815 // Done
6816 return 0;
6817}
6818
6819////////////////////////////////////////////////////////////////////////////////
6820/// Return the idle status
6821
6823{
6824 std::lock_guard<std::recursive_mutex> lock(fQMtx);
6825 return fIdle;
6826}
6827
6828////////////////////////////////////////////////////////////////////////////////
6829/// Change the idle status
6830
6832{
6833 std::lock_guard<std::recursive_mutex> lock(fQMtx);
6834 fIdle = st;
6835}
6836
6837////////////////////////////////////////////////////////////////////////////////
6838/// Return kTRUE if the session is waiting for the OK to start processing
6839
6841{
6842 std::lock_guard<std::recursive_mutex> lock(fQMtx);
6843 if (fIdle && fWaitingQueries->GetSize() > 0) return kTRUE;
6844 return kFALSE;
6845}
6846
6847////////////////////////////////////////////////////////////////////////////////
6848/// Return the number of waiting queries
6849
6851{
6852 std::lock_guard<std::recursive_mutex> lock(fQMtx);
6853 return fWaitingQueries->GetSize();
6854}
6855
6856////////////////////////////////////////////////////////////////////////////////
6857/// Add a query to the waiting list
6858/// Returns the number of queries in the list
6859
6861{
6862 std::lock_guard<std::recursive_mutex> lock(fQMtx);
6863 fWaitingQueries->Add(pq);
6864 return fWaitingQueries->GetSize();
6865}
6866
6867////////////////////////////////////////////////////////////////////////////////
6868/// Get the next query from the waiting list.
6869/// The query is removed from the list.
6870
6872{
6873 std::lock_guard<std::recursive_mutex> lock(fQMtx);
6876 return pq;
6877}
6878
6879////////////////////////////////////////////////////////////////////////////////
6880/// Cleanup the waiting queries list. The objects are deleted if 'del' is true.
6881/// If 'qls' is non null, only objects in 'qls' are removed.
6882/// Returns the number of cleanup queries
6883
6885{
6886 std::lock_guard<std::recursive_mutex> lock(fQMtx);
6887 Int_t ncq = 0;
6888 if (qls) {
6889 TIter nxq(qls);
6890 TObject *o = 0;
6891 while ((o = nxq())) {
6892 if (fWaitingQueries->FindObject(o)) ncq++;
6894 if (del) delete o;
6895 }
6896 } else {
6897 ncq = fWaitingQueries->GetSize();
6900 }
6901 // Done
6902 return ncq;
6903}
6904
6905////////////////////////////////////////////////////////////////////////////////
6906/// Set the message to be sent back in case of exceptions
6907
6908void TProofServ::SetLastMsg(const char *lastmsg)
6909{
6910 fgLastMsg = lastmsg;
6911}
6912
6913////////////////////////////////////////////////////////////////////////////////
6914/// Set the last entry before exception
6915
6917{
6918 fgLastEntry = entry;
6919}
6920
6921////////////////////////////////////////////////////////////////////////////////
6922/// VirtMemMax getter
6923
6925{
6926 return fgVirtMemMax;
6927}
6928////////////////////////////////////////////////////////////////////////////////
6929/// ResMemMax getter
6930
6932{
6933 return fgResMemMax;
6934}
6935////////////////////////////////////////////////////////////////////////////////
6936/// MemHWM getter
6937
6939{
6940 return fgMemHWM;
6941}
6942////////////////////////////////////////////////////////////////////////////////
6943/// MemStop getter
6944
6946{
6947 return fgMemStop;
6948}
6949
6950////////////////////////////////////////////////////////////////////////////////
6951/// Extract LOCALDATASERVER info in 'dsrv'
6952
6954{
6955 // Check if a local data server has been specified
6956 if (gSystem->Getenv("LOCALDATASERVER")) {
6957 dsrv = gSystem->Getenv("LOCALDATASERVER");
6958 if (!dsrv.EndsWith("/")) dsrv += "/";
6959 }
6960
6961 // Done
6962 return;
6963}
6964
6965////////////////////////////////////////////////////////////////////////////////
6966/// If 'path' is local and 'dsrv' is Xrootd, apply 'path.Localroot' settings,
6967/// if any.
6968/// The final path via the server is dsrv+path.
6969
6970void TProofServ::FilterLocalroot(TString &path, const char *dsrv)
6971{
6972 TUrl u(path, kTRUE);
6973 if (!strcmp(u.GetProtocol(), "file")) {
6974 // Remove prefix, if any, if included and if Xrootd
6975 TString pfx = gEnv->GetValue("Path.Localroot","");
6976 if (!pfx.IsNull() && !strncmp(u.GetFile(), pfx.Data(), pfx.Length())) {
6977 TString srvp = TUrl(dsrv).GetProtocol();
6978 if (srvp == "root" || srvp == "xrd") path.Remove(0, pfx.Length());
6979 }
6980 }
6981
6982 // Done
6983 return;
6984}
6985
6986////////////////////////////////////////////////////////////////////////////////
6987/// Locks the directory. Waits if lock is hold by an other process.
6988/// Returns 0 on success, -1 in case of error.
6989
6991{
6992 const char *pname = GetName();
6993
6994 if (gSystem->AccessPathName(pname))
6995 fLockId = open(pname, O_CREAT|O_RDWR, 0644);
6996 else
6997 fLockId = open(pname, O_RDWR);
6998
6999 if (fLockId == -1) {
7000 SysError("Lock", "cannot open lock file %s", pname);
7001 return -1;
7002 }
7003
7004 PDB(kPackage, 2)
7005 Info("Lock", "%d: locking file %s ...", gSystem->GetPid(), pname);
7006 // lock the file
7007#if !defined(R__WIN32) && !defined(R__WINGCC)
7008 if (lockf(fLockId, F_LOCK, (off_t) 1) == -1) {
7009 SysError("Lock", "error locking %s", pname);
7010 close(fLockId);
7011 fLockId = -1;
7012 return -1;
7013 }
7014#endif
7015
7016 PDB(kPackage, 2)
7017 Info("Lock", "%d: file %s locked", gSystem->GetPid(), pname);
7018
7019 return 0;
7020}
7021
7022////////////////////////////////////////////////////////////////////////////////
7023/// Unlock the directory. Returns 0 in case of success,
7024/// -1 in case of error.
7025
7027{
7028 if (!IsLocked())
7029 return 0;
7030
7031 PDB(kPackage, 2)
7032 Info("Lock", "%d: unlocking file %s ...", gSystem->GetPid(), GetName());
7033 // unlock the file
7034 lseek(fLockId, 0, SEEK_SET);
7035#if !defined(R__WIN32) && !defined(R__WINGCC)
7036 if (lockf(fLockId, F_ULOCK, (off_t)1) == -1) {
7037 SysError("Unlock", "error unlocking %s", GetName());
7038 close(fLockId);
7039 fLockId = -1;
7040 return -1;
7041 }
7042#endif
7043
7044 PDB(kPackage, 2)
7045 Info("Unlock", "%d: file %s unlocked", gSystem->GetPid(), GetName());
7046
7047 close(fLockId);
7048 fLockId = -1;
7049
7050 return 0;
7051}
void Class()
Definition: Class.C:29
SVector< double, 2 > v
Definition: Dict.h:5
@ kPROOF_PROCESS
Definition: MessageTypes.h:56
@ kPROOF_VALIDATE_DSET
Definition: MessageTypes.h:70
@ kPROOF_PING
Definition: MessageTypes.h:48
@ kMESS_OK
Definition: MessageTypes.h:32
@ kPROOF_DATA_READY
Definition: MessageTypes.h:71
@ kMESS_STRING
Definition: MessageTypes.h:34
@ kPROOF_GETSTATS
Definition: MessageTypes.h:68
@ kPROOF_GETTREEHEADER
Definition: MessageTypes.h:66
@ kPROOF_STATUS
Definition: MessageTypes.h:47
@ kPROOF_QUERYLIST
Definition: MessageTypes.h:72
@ kPROOF_CHECKFILE
Definition: MessageTypes.h:53
@ kPROOF_GOASYNC
Definition: MessageTypes.h:96
@ kPROOF_PARALLEL
Definition: MessageTypes.h:55
@ kPROOF_LOGLEVEL
Definition: MessageTypes.h:44
@ kPROOF_SENDOUTPUT
Definition: MessageTypes.h:99
@ kPROOF_SESSIONTAG
Definition: MessageTypes.h:79
@ kPROOF_RETRIEVE
Definition: MessageTypes.h:73
@ kPROOF_GETOBJECT
Definition: MessageTypes.h:51
@ kMESS_OBJECT
Definition: MessageTypes.h:35
@ kPROOF_STOPPROCESS
Definition: MessageTypes.h:63
@ kPROOF_VERSARCHCOMP
Definition: MessageTypes.h:92
@ kPROOF_LOGFILE
Definition: MessageTypes.h:45
@ kPROOF_REMOVE
Definition: MessageTypes.h:75
@ kMESS_ACK
Definition: MessageTypes.h:29
@ kPROOF_FATAL
Definition: MessageTypes.h:43
@ kPROOF_OUTPUTOBJECT
Definition: MessageTypes.h:89
@ kPROOF_REALTIMELOG
Definition: MessageTypes.h:91
@ kPROOF_SUBMERGER
Definition: MessageTypes.h:97
@ kROOTD_PROTOCOL
Definition: MessageTypes.h:114
@ kPROOF_QUERYSUBMITTED
Definition: MessageTypes.h:78
@ kPROOF_ARCHIVE
Definition: MessageTypes.h:74
@ kPROOF_SENDFILE
Definition: MessageTypes.h:54
@ kPROOF_GETENTRIES
Definition: MessageTypes.h:60
@ kPROOF_ECHO
Definition: MessageTypes.h:98
@ kPROOF_GETPACKET
Definition: MessageTypes.h:52
@ kPROOF_WORKERLISTS
Definition: MessageTypes.h:87
@ kPROOF_OUTPUTLIST
Definition: MessageTypes.h:57
@ kPROOF_RESET
Definition: MessageTypes.h:50
@ kPROOF_GETPARALLEL
Definition: MessageTypes.h:69
@ kPROOF_PRINT
Definition: MessageTypes.h:49
@ kPROOF_LIB_INC_PATH
Definition: MessageTypes.h:86
@ kPROOF_FORK
Definition: MessageTypes.h:95
@ kPROOF_CACHE
Definition: MessageTypes.h:59
@ kPROOF_MESSAGE
Definition: MessageTypes.h:85
@ kPROOF_LOGDONE
Definition: MessageTypes.h:46
@ kPROOF_DATASETS
Definition: MessageTypes.h:83
@ kMESS_CINT
Definition: MessageTypes.h:36
@ kPROOF_PACKAGE_LIST
Definition: MessageTypes.h:84
@ kPROOF_GETOUTPUTLIST
Definition: MessageTypes.h:67
@ kPROOF_SETIDLE
Definition: MessageTypes.h:77
@ kPROOF_STARTPROCESS
Definition: MessageTypes.h:76
@ kPROOF_GETSLAVEINFO
Definition: MessageTypes.h:65
@ kPROOF_MAXQUERIES
Definition: MessageTypes.h:80
@ kPROOF_CLEANUPSESSION
Definition: MessageTypes.h:81
@ kPROOF_STOP
Definition: MessageTypes.h:42
@ kPROOF_GROUPVIEW
Definition: MessageTypes.h:41
ROOT::R::TRInterface & r
Definition: Object.C:4
#define SafeDelete(p)
Definition: RConfig.hxx:529
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
int Ssiz_t
Definition: RtypesCore.h:63
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:363
R__EXTERN Int_t gDebug
Definition: Rtypes.h:90
const Bool_t kIterBackward
Definition: TCollection.h:41
#define gDirectory
Definition: TDirectory.h:213
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
@ kEnvChange
Definition: TEnv.h:74
const Int_t kPrint
Definition: TError.h:36
const Int_t kError
Definition: TError.h:39
const Int_t kSysError
Definition: TError.h:41
const Int_t kUnset
Definition: TError.h:35
const Int_t kFatal
Definition: TError.h:42
void Error(const char *location, const char *msgfmt,...)
const Int_t kBreak
Definition: TError.h:40
R__EXTERN Int_t gErrorAbortLevel
Definition: TError.h:106
const Int_t kWarning
Definition: TError.h:38
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:105
void Warning(const char *location, const char *msgfmt,...)
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition: TError.cxx:106
const Int_t kInfo
Definition: TError.h:37
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
int type
Definition: TGX11.cxx:120
#define Printf
Definition: TGeoToOCC.h:18
int nentries
Definition: THbookFile.cxx:89
float * q
Definition: THbookFile.cxx:87
#define gInterpreter
Definition: TInterpreter.h:538
double log(double)
R__EXTERN TProofDebug::EProofDebugMask gProofDebugMask
Definition: TProofDebug.h:53
#define PDB(mask, level)
Definition: TProofDebug.h:56
R__EXTERN Int_t gProofDebugLevel
Definition: TProofDebug.h:54
TApplication * GetTProofServ(Int_t *argc, char **argv, FILE *flog)
Definition: TProofServ.cxx:555
static volatile Int_t gProofServDebug
Definition: TProofServ.cxx:118
static void SendAsynMsg(const char *msg)
Definition: TProofServ.cxx:150
TProofServ * gProofServ
Definition: TProofServ.cxx:115
Int_t(* OldProofServAuthSetup_t)(TSocket *, Bool_t, Int_t, TString &, TString &, TString &)
Definition: TProofServ.h:62
const char *const kPROOF_QueryDir
Definition: TProof.h:128
const char *const kPROOF_DataSetDir
Definition: TProof.h:129
const char *const kPROOF_DataDir
Definition: TProof.h:130
const char *const kRM
Definition: TProof.h:142
const char *const kPROOF_CacheLockFile
Definition: TProof.h:131
const char *const kCP
Definition: TProof.h:141
const char *const kPROOF_CacheDir
Definition: TProof.h:125
const char *const kPROOF_PackDir
Definition: TProof.h:126
const char *const kLS
Definition: TProof.h:143
const char *const kPROOF_WorkDir
Definition: TProof.h:124
const char *const kPROOF_QueryLockFile
Definition: TProof.h:133
R__EXTERN TProof * gProof
Definition: TProof.h:1077
const Int_t kPROOF_Protocol
Definition: TProof.h:120
#define gROOT
Definition: TROOT.h:410
@ kKeepAlive
Definition: TSocket.h:41
@ kBytesToRead
Definition: TSocket.h:47
@ kNoDelay
Definition: TSocket.h:43
@ kProcessGroup
Definition: TSocket.h:45
@ kAtMark
Definition: TSocket.h:46
@ kOob
Definition: TSocket.h:52
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2465
@ kSigTermination
@ kSigPipe
@ kSigUrgent
@ kReadPermission
Definition: TSystem.h:48
@ kWritePermission
Definition: TSystem.h:47
@ kLogLocal5
Definition: TSystem.h:73
ELogLevel
Definition: TSystem.h:56
@ kLogWarning
Definition: TSystem.h:61
@ kLogNotice
Definition: TSystem.h:62
@ kLogInfo
Definition: TSystem.h:63
@ kLogErr
Definition: TSystem.h:60
Bool_t R_ISDIR(Int_t mode)
Definition: TSystem.h:116
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
@ kLogPid
Definition: TSystem.h:52
@ kLogCons
Definition: TSystem.h:53
#define gPerfStats
#define snprintf
Definition: civetweb.c:1540
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:3728
This class creates the ROOT Application Environment that interfaces to the windowing system eventloop...
Definition: TApplication.h:39
virtual Long_t ProcessFile(const char *file, Int_t *error=0, Bool_t keep=kFALSE)
Bool_t NoLogOpt() const
Definition: TApplication.h:138
virtual Long_t ProcessLine(const char *line, Bool_t sync=kFALSE, Int_t *error=0)
virtual void Run(Bool_t retrn=kFALSE)
virtual TObject * ReadObject(const TClass *cl)
Read object from I/O buffer.
virtual char * ReadString(char *s, Int_t max)
Read string from I/O buffer.
virtual void WriteObject(const TObject *obj, Bool_t cacheReuse=kTRUE)
Write object to I/O buffer.
Definition: TBufferIO.cxx:530
Int_t BufferSize() const
Definition: TBuffer.h:94
Int_t Length() const
Definition: TBuffer.h:96
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
void SetName(const char *name)
Definition: TCollection.h:204
virtual Int_t GetEntries() const
Definition: TCollection.h:177
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
Manages an element of a TDSet.
Definition: TDSet.h:66
This class implements a data set to be used for PROOF processing.
Definition: TDSet.h:153
virtual void SetEntryList(TObject *aList)
Set entry (or event) list for this data set.
Definition: TDSet.cxx:1894
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:1382
Int_t GetNumOfFiles()
Return the number of files in the dataset.
Definition: TDSet.cxx:2019
void Validate()
Validate the TDSet by opening files.
Definition: TDSet.cxx:1590
void SetWriteV3(Bool_t on=kTRUE)
Set/Reset the 'OldStreamer' bit in this instance and its elements.
Definition: TDSet.cxx:1875
TList * GetListOfElements() const
Definition: TDSet.h:231
const char * GetObjName() const
Definition: TDSet.h:229
@ kEmpty
Definition: TDSet.h:159
@ kWriteV3
Definition: TDSet.h:158
Int_t WriteDataSet(const char *group, const char *user, const char *dsName, TFileCollection *dataset, UInt_t option=0, TMD5 *checksum=0)
Writes indicated dataset.
TFileCollection * GetDataSet(const char *uri, const char *srv=0)
Utility function used in various methods for user dataset upload.
Bool_t ExistsDataSet(const char *group, const char *user, const char *dsName)
Checks if the indicated dataset exits.
Bool_t RemoveDataSet(const char *group, const char *user, const char *dsName)
Removes the indicated dataset.
virtual TFileCollection * GetDataSet(const char *uri, const char *server=0)
Utility function used in various methods for user dataset upload.
Int_t ScanDataSet(const char *uri, const char *opt)
Scans the dataset indicated by 'uri' following the 'opts' directives.
virtual TMap * GetDataSets(const char *uri, UInt_t=TDataSetManager::kExport)
Returns all datasets for the <group> and <user> specified by <uri>.
virtual Bool_t ExistsDataSet(const char *uri)
Checks if the indicated dataset exits.
virtual TMap * GetGroupQuotaMap()
virtual void ShowDataSets(const char *uri="*", const char *opt="")
Prints formatted information about the dataset 'uri'.
virtual void ShowQuota(const char *opt)
Display quota information.
virtual Bool_t RemoveDataSet(const char *uri)
Removes the indicated dataset.
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.
virtual Int_t ClearCache(const char *uri)
Clear cached information matching uri.
virtual Int_t RegisterDataSet(const char *uri, TFileCollection *dataSet, const char *opt)
Register a dataset, perfoming quota checkings, if needed.
virtual Int_t ShowCache(const char *uri)
Show cached information matching uri.
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:26
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition: TEnv.cxx:592
virtual TEnvRec * Lookup(const char *n) const
Loop over all resource records and return the one with name.
Definition: TEnv.cxx:547
A TEventList object is a list of selected events (entries) in a TTree.
Definition: TEventList.h:31
Class that contains a list of TFileInfo's and accumulated meta data information about its entries.
THashList * GetList()
void Sort(Bool_t useindex=kFALSE)
Sort the collection.
void Print(Option_t *option="") const
Prints the contents of the TFileCollection.
virtual Bool_t Notify()
Notify when event occurred on descriptor associated with this handler.
void SetFd(int fd)
virtual Bool_t ReadNotify()
Notify when something can be read from the descriptor associated with this handler.
Class describing a generic file including meta information.
Definition: TFileInfo.h:38
Bool_t RemoveUrlAt(Int_t i)
Remove URL at given position. Returns kTRUE on success, kFALSE on error.
Definition: TFileInfo.cxx:336
Int_t GetNUrls() const
Definition: TFileInfo.h:74
TUrl * GetCurrentUrl() const
Return the current url.
Definition: TFileInfo.cxx:248
static EFileType GetType(const char *name, Option_t *option="", TString *prefix=0)
Resolve the file type as a function of the protocol field in 'name'.
Definition: TFile.cxx:4690
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Definition: TFile.cxx:4443
EFileType
File type.
Definition: TFile.h:187
@ kWeb
Definition: TFile.h:187
@ kNet
Definition: TFile.h:187
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseGeneralPurpose, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3975
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:262
Bool_t Notify()
Handle expiration of the idle timer. The session will just be terminated.
Definition: TProofServ.cxx:520
TProofServ * fProofServ
Definition: TProofServ.h:445
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:36
TObject * Next()
Definition: TCollection.h:249
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
virtual const char * GetClassName() const
Definition: TKey.h:71
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:689
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:655
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:399
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:44
static TMD5 * FileChecksum(const char *file)
Returns checksum of specified file.
Definition: TMD5.cxx:474
Class supporting a collection of lines with C++ code.
Definition: TMacro.h:31
virtual Int_t ReadFile(const char *filename)
Read lines in filename in this macro.
Definition: TMacro.cxx:336
void SaveSource(FILE *fp)
Save macro source in file pointer fp.
Definition: TMacro.cxx:381
TList * GetListOfLines() const
Definition: TMacro.h:51
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:40
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
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
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:235
TObject * FindObject(const char *keyname) const
Check if a (key,value) pair exists with keyname as name of the key.
Definition: TMap.cxx:214
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition: TMessage.cxx:116
UInt_t What() const
Definition: TMessage.h:75
void Reset()
Reset the message buffer so we can use (i.e. fill) it again.
Definition: TMessage.cxx:178
void SetCompressionSettings(Int_t settings=ROOT::RCompressionSetting::EDefaults::kUseGeneralPurpose)
Definition: TMessage.cxx:284
Int_t Compress()
Compress the message.
Definition: TMessage.cxx:302
Int_t CompLength() const
Definition: TMessage.h:90
TClass * GetClass() const
Definition: TMessage.h:71
virtual void RemoveAll()
Remove all sockets from the monitor.
Definition: TMonitor.cxx:241
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition: TMonitor.cxx:322
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor's active list.
Definition: TMonitor.cxx:168
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition: TMonitor.cxx:438
virtual void DeActivateAll()
De-activate all activated sockets.
Definition: TMonitor.cxx:302
TList * GetListOfDeActives() const
Returns a list with all de-active sockets.
Definition: TMonitor.cxx:515
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition: TMonitor.cxx:214
void Interrupt()
Definition: TMonitor.h:71
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
Collectable string class.
Definition: TObjString.h:28
const char * GetName() const
Returns name of object.
Definition: TObjString.h:39
Mother of all ROOT objects.
Definition: TObject.h:37
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:785
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:894
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:908
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:550
void ResetBit(UInt_t f)
Definition: TObject.h:171
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition: TObject.h:68
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:97
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:874
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:708
The PROOF package manager contains tools to manage packages.
Definition: TPackMgr.h:37
void SetLogger(TPackMgrLog_t logger)
Definition: TPackMgr.h:67
Bool_t IsInDir(const char *path)
Method to check if 'path' is in the managed directory Return kTRUE or kFALSE.
Definition: TPackMgr.cxx:478
@ kCheckROOT
Definition: TPackMgr.h:39
void Show(const char *title=0)
Show available packages.
Definition: TPackMgr.cxx:548
void GetEnabledPackages(TString &packlist)
Method to get a semi-colon separated list with the names of the enabled packages.
Definition: TPackMgr.cxx:501
Int_t Build(const char *pack, Int_t opt=TPackMgr::kCheckROOT)
Method to build a package.
Definition: TPackMgr.cxx:87
Int_t Install(const char *par, Bool_t rmold=kFALSE)
Install package from par (unpack the file in the directory); par can be an URL for remote retrieval.
Definition: TPackMgr.cxx:766
Int_t GetParPath(const char *pack, TString &path)
Method to get the path of the PAR file for package 'pack'.
Definition: TPackMgr.cxx:521
Int_t Unpack(const char *pack, TMD5 *sum=0)
Read MD5 checksum of the PAR file from the PROOF-INF/md5.txt file.
Definition: TPackMgr.cxx:723
TMD5 * GetMD5(const char *pack)
Get MD5 checksum of the PAR file corresponding to given package Returns a pointer to a TMD5 object,...
Definition: TPackMgr.cxx:692
void ShowEnabled(const char *title=0)
Show enabled packages.
Definition: TPackMgr.cxx:662
TList * GetList() const
Get list of available packages Returns a pointer to a TList object, transferring ownership to the cal...
Definition: TPackMgr.cxx:621
Int_t Clean(const char *pack)
Clean dir for package 'pack' Return -1 in case of error, 0 otherwise.
Definition: TPackMgr.cxx:576
static Int_t RegisterGlobalPath(const char *paths)
Parse one or more paths as possible sources of packages Returns number of paths added; or -1 in case ...
Definition: TPackMgr.cxx:871
Int_t Load(const char *pack, TList *optls=0)
Method to load a package taking an option list Return -1 on error, 0 otherwise.
Definition: TPackMgr.cxx:220
Int_t Unload(const char *pack)
Method to unload a package.
Definition: TPackMgr.cxx:411
TList * GetListOfEnabled() const
Get list of enabled packages Returns a pointer to a TList object, transferring ownership to the calle...
Definition: TPackMgr.cxx:644
static TPackMgr * GetPackMgr(const char *pack, TPackMgr *packmgr=nullptr)
Get the package manager having 'pack'; priority is given to packmgr, if defined.
Definition: TPackMgr.cxx:911
void SetPrefix(const char *pfx)
Definition: TPackMgr.h:68
Int_t Remove(const char *pack=0, Bool_t dolock=kTRUE)
Remove package 'pack' If 'pack' is null or empty all packages are cleared.
Definition: TPackMgr.cxx:593
TMD5 * ReadMD5(const char *pack)
Read MD5 checksum of the PAR file from the PROOF-INF/md5.txt file.
Definition: TPackMgr.cxx:708
const char * GetTitle() const
Returns title of object.
Definition: TPackMgr.h:63
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:102
TObject * Value() const
Definition: TMap.h:121
Named parameter, streamable and storable.
Definition: TParameter.h:37
const AParamType & GetVal() const
Definition: TParameter.h:69
This class implements a plugin library manager.
TPluginHandler * FindHandler(const char *base, const char *uri=0)
Returns the handler if there exists a handler for the specified URI.
Bool_t IsLocked() const
Definition: TProofServ.h:360
Int_t Unlock()
Unlock the directory.
Int_t Lock()
Locks the directory.
The purpose of this class is to provide a complete node description for masters, submasters and worke...
const TString & GetImage() const
const TString & GetWorkDir() const
Container class for processing statistics.
void Print(Option_t *option="") const
Dump the content.
Long64_t GetEntries() const
void SetLearnTime(Double_t learnTime)
void IncCPUTime(Double_t procTime)
void IncProcTime(Double_t procTime)
Long64_t GetBytesRead() const
TQueryResult version adapted to PROOF neeeds.
void SetRunning(Int_t startlog, const char *par, Int_t nwrks)
Call when running starts.
The purpose of this class is to provide a standard interface to static config files.
TProofNodeInfo * GetMaster()
Get the master node.
TList * GetSubmasters()
Get the list of submaster nodes.
TList * GetWorkers()
Get the list of worker nodes.
virtual Bool_t IsValid() const
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:357
TProofServLogHandler * fExecHandler
Definition: TProofServ.h:404
virtual ~TProofServLogHandlerGuard()
Close a guard for executing a command in a pipe.
Definition: TProofServ.cxx:397
Bool_t Notify()
Handle available message in the open file.
Definition: TProofServ.cxx:308
virtual ~TProofServLogHandler()
Handle available message in the open file.
Definition: TProofServ.cxx:291
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:245
static Int_t fgCmdRtn
Definition: TProofServ.h:382
static TString fgPfx
Definition: TProofServ.h:381
static Int_t GetCmdRtn()
Static method to get the return code from the execution of a command via the pipe.
Definition: TProofServ.cxx:349
static void SetDefaultPrefix(const char *pfx)
Static method to set the default prefix.
Definition: TProofServ.cxx:341
Class providing the PROOF server.
Definition: TProofServ.h:66
Float_t fCpuTime
Definition: TProofServ.h:114
TString fQueryDir
Definition: TProofServ.h:88
const char * GetOrdinal() const
Definition: TProofServ.h:253
TPackMgr * fPackMgr
Definition: TProofServ.h:86
virtual ~TProofServ()
Cleanup.
void SetIdle(Bool_t st=kTRUE)
Change the idle status.
const char * GetConfDir() const
Definition: TProofServ.h:239
Int_t fProtocol
Definition: TProofServ.h:103
void Interrupt()
Definition: TProofServ.h:291
void TruncateLogFile()
Truncate the log file to the 80% of the required max size if this is set.
Int_t CatMotd()
Print message of the day (in the file pointed by the env PROOFMOTD or from fConfDir/etc/proof/motd).
TString fArchivePath
Definition: TProofServ.h:96
Int_t GetPriority()
Get the processing priority for the group the user belongs too.
Int_t fGroupId
Definition: TProofServ.h:105
void SendStatistics()
Send statistics of slave server to master or client.
const char * GetImage() const
Definition: TProofServ.h:244
virtual Int_t CreateServer()
Finalize the server setup.
Definition: TProofServ.cxx:795
Int_t fLogLevel
Definition: TProofServ.h:107
FILE * fLogFile
Definition: TProofServ.h:100
virtual EQueryAction GetWorkers(TList *workers, Int_t &prioritychange, Bool_t resume=kFALSE)
Get list of workers to be used from now on.
Int_t GetQuerySeqNum() const
Definition: TProofServ.h:260
Bool_t IsWaiting()
Return kTRUE if the session is waiting for the OK to start processing.
TString fDataDir
Definition: TProofServ.h:90
void Print(Option_t *option="") const
Print status of slave server.
static void ErrorHandler(Int_t level, Bool_t abort, const char *location, const char *msg)
The PROOF error handler function.
static Long_t fgResMemMax
Definition: TProofServ.h:160
TString fSessionDir
Definition: TProofServ.h:85
TMonitor * fMergingMonitor
Definition: TProofServ.h:150
TString fAdminPath
Definition: TProofServ.h:92
const char * GetUser() const
Definition: TProofServ.h:241
virtual void HandleProcess(TMessage *mess, TString *slb=0)
Handle processing request.
void FlushLogFile()
Reposition the read pointer in the log file to the very end.
Int_t CleanupWaitingQueries(Bool_t del=kTRUE, TList *qls=0)
Cleanup the waiting queries list.
static FILE * fgErrorHandlerFile
Definition: TProofServ.h:168
static Bool_t IsActive()
Static function that returns kTRUE in case we are a PROOF server.
static TProofServ * This()
Static function returning pointer to global object gProofServ.
TString fService
Definition: TProofServ.h:76
static void GetLocalServer(TString &dsrv)
Extract LOCALDATASERVER info in 'dsrv'.
virtual void HandleRemove(TMessage *mess, TString *slb=0)
Handle remove request.
static void SetLastEntry(Long64_t lastentry)
Set the last entry before exception.
virtual void HandleArchive(TMessage *mess, TString *slb=0)
Handle archive request.
static Float_t GetMemHWM()
MemHWM getter.
Int_t fLogFileDes
Definition: TProofServ.h:101
Bool_t IsParallel() const
True if in parallel mode.
TProofLockPath * fQueryLock
Definition: TProofServ.h:95
static void FilterLocalroot(TString &path, const char *url="root://dum/")
If 'path' is local and 'dsrv' is Xrootd, apply 'path.Localroot' settings, if any.
Long64_t fMsgSizeHWM
Definition: TProofServ.h:166
static FILE * SetErrorHandlerFile(FILE *ferr)
Set the file stream where to log (default stderr).
virtual void HandleFork(TMessage *mess)
Cloning itself via fork. Not implemented.
virtual void HandleSigPipe()
Called when the client is not alive anymore (i.e.
void RedirectOutput(const char *dir=0, const char *mode="w")
Redirect stdout to a log file.
static void SetLastMsg(const char *lastmsg)
Set the message to be sent back in case of exceptions.
TStopwatch fLatency
Definition: TProofServ.h:115
virtual void DeletePlayer()
Delete player instance.
virtual void ProcessNext(TString *slb=0)
process the next query from the queue of submitted jobs.
Bool_t fMasterServ
Definition: TProofServ.h:111
TSocket * GetSocket() const
Definition: TProofServ.h:257
virtual void HandleUrgentData()
Handle Out-Of-Band data sent by the master or client.
void SetQueryRunning(TProofQueryResult *pq)
Set query in running state.
TProofQueryResult * NextQuery()
Get the next query from the waiting list.
TSocket * fSocket
Definition: TProofServ.h:97
Int_t fCompressMsg
Definition: TProofServ.h:142
Int_t SetupCommon()
Common part (between TProofServ and TXProofServ) of the setup phase.
Int_t SendResults(TSocket *sock, TList *outlist=0, TQueryResult *pq=0)
Sends all objects from the given list to the specified socket.
TString fDataSetDir
Definition: TProofServ.h:89
TString fPrefix
Definition: TProofServ.h:134
const char * GetGroup() const
Definition: TProofServ.h:242
TDSetElement * GetNextPacket(Long64_t totalEntries=-1)
Get next range of entries to be processed on this server.
Bool_t IsEndMaster() const
Definition: TProofServ.h:292
void SendAsynMessage(const char *msg, Bool_t lf=kTRUE)
Send an asychronous message to the master / client .
static void ResolveKeywords(TString &fname, const char *path=0)
Replace <ord>, <user>, , <group>, <stag>, <qnum>, <file>, <rver> and <build> placeholders in fname.
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 Int_t HandleWorkerLists(TMessage *mess)
Handle here all requests to modify worker lists.
static Int_t RegisterDataSets(TList *in, TList *out, TDataSetManager *dsm, TString &e)
Register TFileCollections in 'out' as datasets according to the rules in 'in'.
TVirtualProofPlayer * fPlayer
Definition: TProofServ.h:99
TString fSessionTag
Definition: TProofServ.h:83
virtual void HandleQueryList(TMessage *mess)
Handle request for list of queries.
Bool_t IsMaster() const
Definition: TProofServ.h:293
const char * GetDataDir() const
Definition: TProofServ.h:250
Bool_t fSendLogToMaster
Definition: TProofServ.h:147
virtual void HandleCheckFile(TMessage *mess, TString *slb=0)
Handle file checking request.
static Float_t fgMemStop
Definition: TProofServ.h:163
TProofLockPath * fCacheLock
Definition: TProofServ.h:94
TProof * fProof
Definition: TProofServ.h:98
TString fOrdinal
Definition: TProofServ.h:104
TProofServ(Int_t *argc, char **argv, FILE *flog=0)
Main constructor.
Definition: TProofServ.cxx:565
Bool_t fEndMaster
Definition: TProofServ.h:110
Long64_t fLogFileMaxSize
Definition: TProofServ.h:102
virtual Int_t HandleCache(TMessage *mess, TString *slb=0)
Handle here all cache and package requests.
std::recursive_mutex fQMtx
Definition: TProofServ.h:130
virtual void HandleSocketInput()
Handle input coming from the client or from the master server.
TString fWorkDir
Definition: TProofServ.h:81
virtual void MakePlayer()
Make player instance.
virtual void HandleSubmerger(TMessage *mess)
Handle a message of type kPROOF_SUBMERGER.
virtual Int_t HandleLibIncPath(TMessage *mess)
Handle lib, inc search paths modification request.
TShutdownTimer * fShutdownTimer
Definition: TProofServ.h:138
TString fCacheDir
Definition: TProofServ.h:87
Bool_t IsIdle()
Return the idle status.
Int_t fNcmd
Definition: TProofServ.h:108
TDataSetManagerFile * fDataSetStgRepo
Definition: TProofServ.h:145
Int_t GetSessionStatus()
Return the status of this session: 0 idle 1 running 2 being terminated (currently unused) 3 queued 4 ...
virtual Int_t HandleDataSets(TMessage *mess, TString *slb=0)
Handle here requests about datasets.
TServerSocket * fMergingSocket
Definition: TProofServ.h:149
Bool_t fInterrupt
Definition: TProofServ.h:112
Int_t fActSessions
Definition: TProofServ.h:121
TList * fQueuedMsg
Definition: TProofServ.h:132
TString fGroup
Definition: TProofServ.h:78
Bool_t fRealTimeLog
Definition: TProofServ.h:136
void GetOptions(Int_t *argc, char **argv)
Get and handle command line options.
virtual Int_t Setup()
Print the ProofServ logo on standard output.
TStopwatch fCompute
Definition: TProofServ.h:116
static Long_t fgVirtMemMax
Definition: TProofServ.h:159
Int_t fMergedWorkers
Definition: TProofServ.h:151
TString fImage
Definition: TProofServ.h:82
@ kQueryEnqueued
Definition: TProofServ.h:73
TString fTopSessionTag
Definition: TProofServ.h:84
TFileHandler * fInputHandler
Definition: TProofServ.h:124
void SendParallel(Bool_t async=kFALSE)
Send number of parallel nodes to master or client.
Int_t GetCompressionLevel() const
Definition: TProofServ.h:464
static Float_t fgMemHWM
Definition: TProofServ.h:162
Float_t fEffSessions
Definition: TProofServ.h:122
static Long_t GetResMemMax()
ResMemMax getter.
Long64_t fHWMBoxSize
Definition: TProofServ.h:156
TString fConfDir
Definition: TProofServ.h:79
Int_t QueueQuery(TProofQueryResult *pq)
Add a query to the waiting list Returns the number of queries in the list.
TIdleTOTimer * fIdleTOTimer
Definition: TProofServ.h:140
static Int_t fgLogToSysLog
Definition: TProofServ.h:172
static TString fgLastMsg
Definition: TProofServ.h:228
virtual Int_t Fork()
Fork a child.
Int_t fMaxQueries
Definition: TProofServ.h:154
static Long_t GetVirtMemMax()
VirtMemMax getter.
Bool_t UnlinkDataDir(const char *path)
Scan recursively the datadir and unlink it if empty Return kTRUE if it can be unlinked,...
Int_t GetProtocol() const
Definition: TProofServ.h:252
TString fConfFile
Definition: TProofServ.h:80
Int_t fTotSessions
Definition: TProofServ.h:120
Int_t fGroupSize
Definition: TProofServ.h:106
Bool_t AcceptResults(Int_t connections, TVirtualProofPlayer *mergerPlayer)
Accept and merge results from a set of workers.
TDataSetManager * fDataSetManager
Definition: TProofServ.h:144
TString fUser
Definition: TProofServ.h:77
static Int_t fgRecursive
Definition: TProofServ.h:169
TQueryResultManager * fQMgr
Definition: TProofServ.h:126
TList * fWaitingQueries
Definition: TProofServ.h:128
void Reset(const char *dir)
Reset PROOF environment to be ready for execution of next command.
virtual void Terminate(Int_t status)
Terminate the proof server.
virtual void HandleException(Int_t sig)
Exception handler: we do not try to recover here, just exit.
Int_t OldAuthSetup(TString &wconf)
Setup authentication related stuff for old versions.
static TString fgSysLogEntity
Definition: TProofServ.h:174
TString fDataDirOpts
Definition: TProofServ.h:91
Int_t WaitingQueries()
Return the number of waiting queries.
void Run(Bool_t retrn=kFALSE)
Main server eventloop.
Long64_t fMaxBoxSize
Definition: TProofServ.h:155
const char * GetWorkDir() const
Definition: TProofServ.h:243
const char * GetPrefix() const
Definition: TProofServ.h:276
static TString fgSysLogService
Definition: TProofServ.h:173
void LogToMaster(Bool_t on=kTRUE)
Definition: TProofServ.h:322
Int_t fGroupPriority
Definition: TProofServ.h:109
TReaperTimer * fReaperTimer
Definition: TProofServ.h:139
static Long64_t fgLastEntry
Definition: TProofServ.h:229
const char * GetSessionTag() const
Definition: TProofServ.h:245
virtual void SendLogFile(Int_t status=0, Int_t start=-1, Int_t end=-1)
Send log file to master.
Float_t fRealTime
Definition: TProofServ.h:113
static Float_t GetMemStop()
MemStop getter.
Bool_t IsTopMaster() const
Definition: TProofServ.h:295
void RestartComputeTime()
Reset the compute time.
Int_t fQuerySeqNum
Definition: TProofServ.h:118
TProofQueryResult * MakeQueryResult(Long64_t nentries, const char *opt, TList *inl, Long64_t first, TDSet *dset, const char *selec, TObject *elist)
Create a TProofQueryResult instance for this query.
virtual void HandleRetrieve(TMessage *mess, TString *slb=0)
Handle retrieve request.
TStopwatch fSaveOutput
Definition: TProofServ.h:117
Int_t UpdateSessionStatus(Int_t xst=-1)
Update the session status in the relevant file.
Bool_t fIdle
Definition: TProofServ.h:129
TObject * Get(const char *namecycle)
Get object with name "name;cycle" (e.g.
static TMap * GetDataSetNodeMap(TFileCollection *fc, TString &emsg)
Get a map {server-name, list-of-files} for collection 'fc' to be used in TPacketizerFile.
const char * GetService() const
Definition: TProofServ.h:238
This class controls a Parallel ROOT Facility, PROOF, cluster.
Definition: TProof.h:316
const char * GetSessionTag() const
Definition: TProof.h:909
void ShowPackages(Bool_t all=kFALSE, Bool_t redirlog=kFALSE)
List contents of package directory.
Definition: TProof.cxx:7742
@ kShutdownInterrupt
Definition: TProof.h:398
@ kHardInterrupt
Definition: TProof.h:396
@ kSoftInterrupt
Definition: TProof.h:397
Bool_t IsEndMaster() const
Definition: TProof.h:664
Int_t UploadPackage(const char *par, EUploadPackageOpt opt=kUntar, TList *workers=0)
Upload a PROOF archive (PAR file).
Definition: TProof.cxx:8413
Int_t SendCurrentState(ESlaves list=kActive)
Transfer the current state of the master to the active slave servers.
Definition: TProof.cxx:6730
TList * GetListOfSlaves() const
Definition: TProof.h:654
@ kDeactivateWorker
Definition: TProof.h:451
@ kActivateWorker
Definition: TProof.h:450
Int_t DisablePackages()
Remove all packages.
Definition: TProof.cxx:7914
@ kCollectBuildResults
Definition: TProof.h:457
@ kBuildOnSlavesNoWait
Definition: TProof.h:455
@ kBuildAll
Definition: TProof.h:456
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:12284
Int_t BuildPackage(const char *package, EBuildPackageOpt opt=kBuildAll, Int_t chkveropt=TPackMgr::kCheckROOT, TList *workers=0)
Build specified package.
Definition: TProof.cxx:7962
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition: TProof.cxx:4775
TList * GetListOfInactiveSlaves() const
Definition: TProof.h:655
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:12386
Bool_t IsParallel() const
Definition: TProof.h:939
TVirtualProofPlayer * GetPlayer() const
Definition: TProof.h:716
void AskParallel()
Ask the for the number of parallel slaves.
Definition: TProof.cxx:2055
virtual void ClearCache(const char *file=0)
Remove file from all file caches.
Definition: TProof.cxx:7686
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:11325
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition: TProof.cxx:9890
void SetRunStatus(ERunStatus rst)
Definition: TProof.h:672
static void AssertMacroPath(const char *macro)
Make sure that the directory path contained by macro is in the macro path.
Definition: TProof.cxx:8571
@ kRunning
Definition: TProof.h:371
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:8860
virtual void ShowCache(Bool_t all=kFALSE)
List contents of file cache.
Definition: TProof.cxx:7663
Bool_t IsValid() const
Definition: TProof.h:937
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7112
@ kStopMerging
Definition: TProof.h:381
@ kOutputSent
Definition: TProof.h:382
@ kMergerDown
Definition: TProof.h:380
@ kSendOutput
Definition: TProof.h:378
@ kOutputSize
Definition: TProof.h:377
@ kBeMerger
Definition: TProof.h:379
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:11732
static Bool_t GetFileInCmd(const char *cmd, TString &fn)
Static method to extract the filename (if any) form a CINT command.
Definition: TProof.cxx:6467
Float_t GetCpuTime() const
Definition: TProof.h:931
void SetPlayer(TVirtualProofPlayer *player)
Set a new PROOF player.
Definition: TProof.cxx:10171
Int_t ClearPackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7829
Int_t AddWorkers(TList *wrks)
Works on the master node only.
Definition: TProof.cxx:1304
Int_t ClearPackages()
Remove all packages.
Definition: TProof.cxx:7812
void SetActive(Bool_t=kTRUE)
Definition: TProof.h:988
EUploadPackageOpt
Definition: TProof.h:366
@ kUntar
Definition: TProof.h:367
@ kRemoveOld
Definition: TProof.h:368
Int_t RemoveIncludePath(const char *incpath, Bool_t onClient=kFALSE)
Remove 'incpath' from the inc path search.
Definition: TProof.cxx:8939
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition: TProof.cxx:2282
Int_t UnloadPackage(const char *package)
Unload specified package.
Definition: TProof.cxx:8086
Long64_t GetBytesRead() const
Definition: TProof.h:929
void AskStatistics()
Ask the for the statistics of the slaves.
Definition: TProof.cxx:2000
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:11342
@ kRemoveDataSet
Definition: TProof.h:430
@ kRegisterDataSet
Definition: TProof.h:427
@ kShowQuota
Definition: TProof.h:434
@ kGetQuota
Definition: TProof.h:433
@ kStagingStatus
Definition: TProof.h:438
@ kShowDataSets
Definition: TProof.h:432
@ kCache
Definition: TProof.h:436
@ kSetDefaultTreeName
Definition: TProof.h:435
@ kRequestStaging
Definition: TProof.h:437
@ kGetDataSets
Definition: TProof.h:426
@ kCheckDataSetName
Definition: TProof.h:425
@ kVerifyDataSet
Definition: TProof.h:429
@ kCancelStaging
Definition: TProof.h:439
@ kGetDataSet
Definition: TProof.h:428
void SetRealTimeLog(Bool_t on=kTRUE)
Switch ON/OFF the real-time logging facility.
Definition: TProof.cxx:7068
Int_t Ping(ESlaves list)
Ping PROOF slaves. Returns the number of slaves that responded.
Definition: TProof.cxx:4724
Int_t UnloadPackages()
Unload all packages.
Definition: TProof.cxx:8119
virtual TVirtualProofPlayer * MakePlayer(const char *player=0, TSocket *s=0)
Construct a TProofPlayer object.
Definition: TProof.cxx:10183
TList * GetListOfActiveSlaves() const
Definition: TProof.h:723
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:8600
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:8815
Int_t RemoveWorkers(TList *wrks)
Used for shuting down the workres after a query is finished.
Definition: TProof.cxx:1575
Int_t RemoveDynamicPath(const char *libpath, Bool_t onClient=kFALSE)
Remove 'libpath' from the lib path search.
Definition: TProof.cxx:8905
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition: TProof.cxx:9780
void StopProcess(Bool_t abort, Int_t timeout=-1)
Send STOPPROCESS message to master and workers.
Definition: TProof.cxx:6196
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:6866
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:11987
void Interrupt(EUrgent type, ESlaves list=kActive)
Send interrupt to master or slave servers.
Definition: TProof.cxx:2254
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:7000
Int_t SendCommand(const char *cmd, ESlaves list=kActive)
Send command to be executed on the PROOF master and/or slaves.
Definition: TProof.cxx:6603
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo's. In case of error return 0.
Definition: TProof.cxx:2299
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition: TProof.cxx:9352
@ kDisableSubPackage
Definition: TProof.h:413
@ kClearPackages
Definition: TProof.h:404
@ kShowSubPackages
Definition: TProof.h:411
@ kShowEnabledPackages
Definition: TProof.h:408
@ kListEnabledPackages
Definition: TProof.h:420
@ kClearPackage
Definition: TProof.h:405
@ kLoadMacro
Definition: TProof.h:421
@ kShowSubCache
Definition: TProof.h:409
@ kDisablePackage
Definition: TProof.h:416
@ kDisablePackages
Definition: TProof.h:418
@ kLoadPackage
Definition: TProof.h:407
@ kBuildPackage
Definition: TProof.h:406
@ kListPackages
Definition: TProof.h:419
@ kUnloadPackages
Definition: TProof.h:417
@ kUnloadPackage
Definition: TProof.h:415
@ kShowCache
Definition: TProof.h:401
@ kClearSubCache
Definition: TProof.h:410
@ kBuildSubPackage
Definition: TProof.h:414
@ kClearCache
Definition: TProof.h:402
@ kShowPackages
Definition: TProof.h:403
@ kDisableSubPackages
Definition: TProof.h:412
const char * GetUser() const
Definition: TProof.h:906
void TerminateWorker(TSlave *wrk)
Ask an active worker 'wrk' to terminate, i.e. to shutdown.
Definition: TProof.cxx:4668
Int_t LoadPackage(const char *package, Bool_t notOnClient=kFALSE, TList *loadopts=0, TList *workers=0)
Load specified package.
Definition: TProof.cxx:8041
@ kBinary
Definition: TProof.h:443
@ kCp
Definition: TProof.h:447
@ kForward
Definition: TProof.h:445
void SetLogLevel(Int_t level, UInt_t mask=TProofDebug::kAll)
Set server logging level.
Definition: TProof.cxx:7051
TList * GetListOfBadSlaves() const
Definition: TProof.h:657
Int_t DisablePackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7857
void ShowEnabledPackages(Bool_t all=kFALSE)
List which packages are enabled.
Definition: TProof.cxx:7790
Bool_t UseDynamicStartup() const
Definition: TProof.h:921
void ResetMergers()
Definition: TProof.h:691
Bool_t IsDataReady(Long64_t &totalbytes, Long64_t &bytesready)
See if the data is ready to be analyzed.
Definition: TProof.cxx:2218
const char * GetGroup() const
Definition: TProof.h:907
Class managing the query-result area.
void SaveQuery(TProofQueryResult *qr, const char *fout=0)
Save current status of query 'qr' to file name fout.
Bool_t FinalizeQuery(TProofQueryResult *pq, TProof *proof, TVirtualProofPlayer *player)
Final steps after Process() to complete the TQueryResult instance.
void RemoveQuery(TQueryResult *qr, Bool_t soft=kFALSE)
Remove everything about query qr.
TList * PreviousQueries() const
Int_t CleanupQueriesDir()
Remove all queries results referring to previous sessions.
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...
TProofQueryResult * LocateQuery(TString queryref, Int_t &qry, TString &qdir)
Locate query referenced by queryref.
Int_t CleanupSession(const char *sessiontag)
Cleanup query dir qdir.
Int_t LockSession(const char *sessiontag, TProofLockPath **lck)
Try locking query area of session tagged sessiontag.
TList * Queries() const
void ScanPreviousQueries(const char *dir)
Scan the queries directory for the results of previous queries.
A container class for query results.
Definition: TQueryResult.h:36
Long64_t GetEntries() const
Definition: TQueryResult.h:122
Int_t GetSeqNum() const
Definition: TQueryResult.h:115
void SetArchived(const char *archfile)
Set (or update) query in archived state.
TMacro * GetSelecImp() const
Definition: TQueryResult.h:128
TQueryResult * CloneInfo()
Return an instance of TQueryResult containing only the local info fields, i.e.
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.
virtual void SetInputList(TList *in, Bool_t adopt=kTRUE)
Set / change the input list.
TObject * GetInputObject(const char *classname) const
Return first instance of class 'classname' in the input list.
TMacro * GetSelecHdr() const
Definition: TQueryResult.h:127
const char * GetOptions() const
Definition: TQueryResult.h:119
Long64_t GetFirst() const
Definition: TQueryResult.h:123
Bool_t IsDraw() const
Definition: TQueryResult.h:144
TList * GetInputList()
Definition: TQueryResult.h:120
Int_t fSeqNum
query unique sequential number
Definition: TQueryResult.h:52
Float_t GetUsedCPU() const
Definition: TQueryResult.h:125
Long64_t GetBytes() const
Definition: TQueryResult.h:124
static const TString & GetBinDir()
Get the binary directory in the installation. Static utility function.
Definition: TROOT.cxx:2947
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2764
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2859
Bool_t Notify()
Check if any of the registered children has changed its state.
Definition: TProofServ.cxx:482
TList * fChildren
Definition: TProofServ.h:431
void AddPid(Int_t pid)
Add an entry for 'pid' in the internal list.
Definition: TProofServ.cxx:466
virtual ~TReaperTimer()
Destructor.
Definition: TProofServ.cxx:454
virtual TSQLRow * Next()=0
virtual const char * GetField(Int_t field)=0
virtual TSQLResult * Query(const char *sql)=0
static TSQLServer * Connect(const char *db, const char *uid, const char *pw)
The db should be of the form: <dbms>://<host>[:<port>][/<database>], e.g.
Definition: TSQLServer.cxx:61
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition: TSelector.h:33
virtual Int_t GetLocalPort()
Get port # to which server socket is bound. In case of error returns -1.
virtual TSocket * Accept(UChar_t Opt=0)
Accept a connection on a server socket.
TShutdownTimer(TProofServ *p, Int_t delay)
Construtor.
Definition: TProofServ.cxx:409
Bool_t Notify()
Handle expiration of the shutdown timer.
Definition: TProofServ.cxx:421
TProofServ * fProofServ
Definition: TProofServ.h:418
virtual Bool_t Notify()
Notify when signal occurs.
void SetSysInfo(SysInfo_t si)
Setter for fSysInfo.
Definition: TProof.cxx:265
Option_t * GetOption() const
Definition: TSocket.h:118
virtual Int_t SetOption(ESockOptions opt, Int_t val)
Set socket options.
Definition: TSocket.cxx:1012
TTimeStamp GetLastUsage()
Definition: TSocket.h:149
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:817
virtual void Close(Option_t *opt="")
Close the socket.
Definition: TSocket.cxx:389
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:897
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:620
void SetCompressionSettings(Int_t settings=ROOT::RCompressionSetting::EDefaults::kUseGeneralPurpose)
Used to specify the compression level and algorithm: settings = 100 * algorithm + level.
Definition: TSocket.cxx:1097
virtual Int_t SendObject(const TObject *obj, Int_t kind=kMESS_OBJECT)
Send an object.
Definition: TSocket.cxx:600
virtual Bool_t IsValid() const
Definition: TSocket.h:152
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:522
Stopwatch class.
Definition: TStopwatch.h:28
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
Definition: TStopwatch.cxx:110
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
Definition: TStopwatch.cxx:58
Int_t Counter() const
Definition: TStopwatch.h:50
Double_t CpuTime()
Stop the stopwatch (if it is running) and return the cputime (in seconds) passed between the start an...
Definition: TStopwatch.cxx:125
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:77
void Reset()
Definition: TStopwatch.h:52
@ kLeading
Definition: TString.h:262
@ kTrailing
Definition: TString.h:262
@ kIgnoreCase
Definition: TString.h:263
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:2286
virtual int Umask(Int_t mask)
Set the process file creation mode mask.
Definition: TSystem.cxx:1505
virtual Int_t GetGid(const char *group=0)
Returns the group's id. If group = 0, returns current user's group.
Definition: TSystem.cxx:1568
virtual void AddFileHandler(TFileHandler *fh)
Add a file handler to the list of system file handlers.
Definition: TSystem.cxx:563
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition: TSystem.cxx:3820
virtual TInetAddress GetSockName(int sock)
Get Internet Protocol (IP) address of host and port #.
Definition: TSystem.cxx:2352
virtual Func_t DynFindSymbol(const char *module, const char *entry)
Find specific entry point in specified library.
Definition: TSystem.cxx:2044
virtual void Syslog(ELogLevel level, const char *mess)
Send mess to syslog daemon.
Definition: TSystem.cxx:1673
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:285
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1264
virtual void Openlog(const char *name, Int_t options, ELogFacility facility)
Open connection to system log daemon.
Definition: TSystem.cxx:1664
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:269
virtual void AddIncludePath(const char *includePath)
Add includePath to the already set include path.
Definition: TSystem.cxx:4061
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:1496
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1013
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:852
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:843
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:716
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1652
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3894
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:913
virtual int MakeDirectory(const char *name)
Make a directory.
Definition: TSystem.cxx:834
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:662
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:2501
virtual const char * HomeDirectory(const char *userName=0)
Return the user's home directory.
Definition: TSystem.cxx:894
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:4096
virtual TFileHandler * RemoveFileHandler(TFileHandler *fh)
Remove a file handler from the list of file handlers.
Definition: TSystem.cxx:573
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1843
virtual TSeqCollection * GetListOfFileHandlers() const
Definition: TSystem.h:364
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:671
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:1388
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:1286
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:860
virtual void ExitLoop()
Exit from event loop.
Definition: TSystem.cxx:401
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition: TSystem.cxx:869
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:1487
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition: TSystem.cxx:2532
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:680
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:941
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:541
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1782
virtual void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
Definition: TSystem.cxx:725
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:312
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition: TSystem.cxx:1793
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:446
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:878
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1536
virtual Int_t GetUid(const char *user=0)
Returns the user's id. If user = 0, returns current user's id.
Definition: TSystem.cxx:1549
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1636
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3804
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:733
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1371
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:741
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1588
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:1702
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1472
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition: TSystem.cxx:2020
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition: TTimeStamp.h:71
time_t GetSec() const
Definition: TTimeStamp.h:135
Int_t GetNanoSec() const
Definition: TTimeStamp.h:136
const char * AsString(const Option_t *option="") const
Return the date & time as a string.
Definition: TTimeStamp.cxx:271
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:51
virtual void Start(Long_t milliSec=-1, Bool_t singleShot=kFALSE)
Starts the timer with a milliSec timeout.
Definition: TTimer.cxx:211
virtual void TurnOn()
Add the timer to the system timer list.
Definition: TTimer.cxx:241
TTime fTime
Definition: TTimer.h:54
void Reset()
Reset the timer.
Definition: TTimer.cxx:157
virtual void Stop()
Definition: TTimer.h:93
This class represents a WWW compatible URL.
Definition: TUrl.h:35
const char * GetFile() const
Definition: TUrl.h:72
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
const char * GetProtocol() const
Definition: TUrl.h:67
Int_t GetPort() const
Definition: TUrl.h:81
Abstract interface for the PROOF player.
virtual void AddInput(TObject *inp)=0
virtual TQueryResult * GetCurrentQuery() const =0
virtual Int_t GetLearnEntries()=0
virtual TList * GetInputList() const =0
virtual void UpdateProgressInfo()=0
virtual Long64_t GetEventsProcessed() const =0
virtual void SetMerging(Bool_t on=kTRUE)=0
virtual EExitStatus GetExitStatus() const =0
virtual void AddQueryResult(TQueryResult *q)=0
virtual void MergeOutput(Bool_t=kFALSE)=0
static TVirtualProofPlayer * Create(const char *player, TProof *p, TSocket *s=0)
Create a PROOF player.
virtual Int_t AddOutputObject(TObject *obj)=0
virtual void HandleGetTreeHeader(TMessage *mess)=0
virtual void RemoveQueryResult(const char *ref)=0
virtual Int_t SavePartialResults(Bool_t queryend=kFALSE, Bool_t force=kFALSE)=0
virtual void StopProcess(Bool_t abort, Int_t timeout=-1)=0
virtual Long64_t Process(TDSet *set, const char *selector, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
virtual TProofProgressStatus * GetProgressStatus() const =0
virtual void SetOutputFilePath(const char *fp)=0
virtual TList * GetOutputList() const =0
virtual void SetCurrentQuery(TQueryResult *q)=0
virtual Long64_t GetCacheSize()=0
TLine * line
const Int_t n
Definition: legend1.C:16
static constexpr double nm
static constexpr double s
static constexpr double pc
static constexpr double pi
static constexpr double ps
static constexpr double ns
Definition: file.py:1
Definition: first.py:1
STL namespace.
Definition: test.py:1
const char * String
Definition: TXMLSetup.cxx:93
Int_t fMode
Definition: TSystem.h:128
Int_t fGid
Definition: TSystem.h:130
Int_t fUid
Definition: TSystem.h:129
TString fUser
Definition: TSystem.h:142
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12