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