00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <fcntl.h>
00025 #include <errno.h>
00026 #ifdef WIN32
00027 # include <io.h>
00028 # include <sys/stat.h>
00029 # include <sys/types.h>
00030 # include "snprintf.h"
00031 #else
00032 # include <unistd.h>
00033 #endif
00034 #include <vector>
00035
00036 #include "RConfigure.h"
00037 #include "Riostream.h"
00038 #include "Getline.h"
00039 #include "TBrowser.h"
00040 #include "TChain.h"
00041 #include "TCondor.h"
00042 #include "TDSet.h"
00043 #include "TError.h"
00044 #include "TEnv.h"
00045 #include "TEntryList.h"
00046 #include "TEventList.h"
00047 #include "TFile.h"
00048 #include "TFileInfo.h"
00049 #include "TFunction.h"
00050 #include "TFTP.h"
00051 #include "THashList.h"
00052 #include "TInterpreter.h"
00053 #include "TKey.h"
00054 #include "TMap.h"
00055 #include "TMath.h"
00056 #include "TMessage.h"
00057 #include "TMethodArg.h"
00058 #include "TMethodCall.h"
00059 #include "TMonitor.h"
00060 #include "TMutex.h"
00061 #include "TObjArray.h"
00062 #include "TObjString.h"
00063 #include "TParameter.h"
00064 #include "TProof.h"
00065 #include "TProofNodeInfo.h"
00066 #include "TVirtualProofPlayer.h"
00067 #include "TVirtualPacketizer.h"
00068 #include "TProofServ.h"
00069 #include "TPluginManager.h"
00070 #include "TQueryResult.h"
00071 #include "TRandom.h"
00072 #include "TRegexp.h"
00073 #include "TROOT.h"
00074 #include "TSemaphore.h"
00075 #include "TSlave.h"
00076 #include "TSocket.h"
00077 #include "TSortedList.h"
00078 #include "TSystem.h"
00079 #include "TThread.h"
00080 #include "TTree.h"
00081 #include "TUrl.h"
00082 #include "TFileCollection.h"
00083 #include "TDataSetManager.h"
00084 #include "TMacro.h"
00085
00086 TProof *gProof = 0;
00087 TVirtualMutex *gProofMutex = 0;
00088
00089
00090 char TProofMergePrg::fgCr[4] = {'-', '\\', '|', '/'};
00091
00092 TList *TProof::fgProofEnvList = 0;
00093 TPluginHandler *TProof::fgLogViewer = 0;
00094
00095 ClassImp(TProof)
00096
00097
00098
00099 Bool_t TProofInterruptHandler::Notify()
00100 {
00101
00102
00103 if (isatty(0) == 0 || isatty(1) == 0 || fProof->GetRemoteProtocol() < 22) {
00104
00105
00106 fProof->StopProcess(kTRUE);
00107
00108 } else {
00109
00110 char *a = 0;
00111 if (fProof->GetRemoteProtocol() < 22) {
00112 a = Getline("\nSwith to asynchronous mode not supported remotely:"
00113 "\nEnter S/s to stop, Q/q to quit, any other key to continue: ");
00114 } else {
00115 a = Getline("\nEnter A/a to switch asynchronous, S/s to stop, Q/q to quit,"
00116 " any other key to continue: ");
00117 }
00118 if (a[0] == 'Q' || a[0] == 'S' || a[0] == 'q' || a[0] == 's') {
00119
00120 Info("Notify","Processing interrupt signal ... %c", a[0]);
00121
00122
00123 Bool_t abort = (a[0] == 'Q' || a[0] == 'q') ? kTRUE : kFALSE;
00124 fProof->StopProcess(abort);
00125
00126 } else if ((a[0] == 'A' || a[0] == 'a') && fProof->GetRemoteProtocol() >= 22) {
00127
00128 fProof->GoAsynchronous();
00129 }
00130 }
00131
00132 return kTRUE;
00133 }
00134
00135
00136
00137 TProofInputHandler::TProofInputHandler(TProof *p, TSocket *s)
00138 : TFileHandler(s->GetDescriptor(),1),
00139 fSocket(s), fProof(p)
00140 {
00141
00142 }
00143
00144
00145 Bool_t TProofInputHandler::Notify()
00146 {
00147
00148
00149 fProof->CollectInputFrom(fSocket);
00150 return kTRUE;
00151 }
00152
00153
00154
00155
00156 ClassImp(TSlaveInfo)
00157
00158
00159 Int_t TSlaveInfo::Compare(const TObject *obj) const
00160 {
00161
00162
00163 if (!obj) return 1;
00164
00165 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
00166
00167 if (!si) return fOrdinal.CompareTo(obj->GetName());
00168
00169 const char *myord = GetOrdinal();
00170 const char *otherord = si->GetOrdinal();
00171 while (myord && otherord) {
00172 Int_t myval = atoi(myord);
00173 Int_t otherval = atoi(otherord);
00174 if (myval < otherval) return 1;
00175 if (myval > otherval) return -1;
00176 myord = strchr(myord, '.');
00177 if (myord) myord++;
00178 otherord = strchr(otherord, '.');
00179 if (otherord) otherord++;
00180 }
00181 if (myord) return -1;
00182 if (otherord) return 1;
00183 return 0;
00184 }
00185
00186
00187 void TSlaveInfo::Print(Option_t *opt) const
00188 {
00189
00190
00191
00192
00193
00194 TString stat = fStatus == kActive ? "active" :
00195 fStatus == kBad ? "bad" :
00196 "not active";
00197
00198 Bool_t newfmt = kFALSE;
00199 TString oo(opt);
00200 if (oo.Contains("N")) {
00201 newfmt = kTRUE;
00202 oo.ReplaceAll("N","");
00203 }
00204 if (oo == "active" && fStatus != kActive) return;
00205 if (oo == "notactive" && fStatus != kNotActive) return;
00206 if (oo == "bad" && fStatus != kBad) return;
00207
00208 if (newfmt) {
00209 TString msd, si, datadir;
00210 if (!(fMsd.IsNull())) msd.Form("| msd: %s ", fMsd.Data());
00211 if (!(fDataDir.IsNull())) datadir.Form("| datadir: %s ", fDataDir.Data());
00212 if (fSysInfo.fCpus > 0) {
00213 si.Form("| %s, %d cores, %d MB ram", fHostName.Data(),
00214 fSysInfo.fCpus, fSysInfo.fPhysRam);
00215 } else {
00216 si.Form("| %s", fHostName.Data());
00217 }
00218 Printf("Worker: %9s %s %s%s| %s", fOrdinal.Data(), si.Data(), msd.Data(), datadir.Data(), stat.Data());
00219
00220 } else {
00221 TString msd = fMsd.IsNull() ? "<null>" : fMsd.Data();
00222
00223 cout << "Slave: " << fOrdinal
00224 << " hostname: " << fHostName
00225 << " msd: " << msd
00226 << " perf index: " << fPerfIndex
00227 << " " << stat
00228 << endl;
00229 }
00230 }
00231
00232
00233 void TSlaveInfo::SetSysInfo(SysInfo_t si)
00234 {
00235
00236
00237 fSysInfo.fOS = si.fOS;
00238 fSysInfo.fModel = si.fModel;
00239 fSysInfo.fCpuType = si.fCpuType;
00240 fSysInfo.fCpus = si.fCpus;
00241 fSysInfo.fCpuSpeed = si.fCpuSpeed;
00242 fSysInfo.fBusSpeed = si.fBusSpeed;
00243 fSysInfo.fL2Cache = si.fL2Cache;
00244 fSysInfo.fPhysRam = si.fPhysRam;
00245 }
00246
00247
00248
00249
00250 static char *CollapseSlashesInPath(const char *path)
00251 {
00252
00253
00254
00255 if (path) {
00256 Int_t i = 1;
00257 Int_t j = 0;
00258 char *newPath = new char [strlen(path) + 1];
00259 newPath[0] = path[0];
00260 while (path[i]) {
00261 if (path[i] != '/' || newPath[j] != '/') {
00262 j++;
00263 newPath[j] = path[i];
00264 }
00265 i++;
00266 }
00267 if (newPath[j] != '/')
00268 j++;
00269 newPath[j] = 0;
00270 return newPath;
00271 }
00272 return 0;
00273 }
00274
00275 ClassImp(TProof)
00276
00277 TSemaphore *TProof::fgSemaphore = 0;
00278
00279
00280
00281
00282 TMergerInfo::~TMergerInfo()
00283 {
00284
00285
00286
00287 if (fWorkers) {
00288 fWorkers->SetOwner(kFALSE);
00289 SafeDelete(fWorkers);
00290 }
00291 }
00292
00293 void TMergerInfo::SetMergedWorker()
00294 {
00295
00296
00297 if (AreAllWorkersMerged())
00298 Error("SetMergedWorker", "all workers have been already merged before!");
00299 else
00300 fMergedWorkers++;
00301 }
00302
00303
00304 void TMergerInfo::AddWorker(TSlave *sl)
00305 {
00306
00307
00308 if (!fWorkers)
00309 fWorkers = new TList();
00310 if (fWorkersToMerge == fWorkers->GetSize()) {
00311 Error("AddWorker", "all workers have been already assigned to this merger");
00312 return;
00313 }
00314 fWorkers->Add(sl);
00315 }
00316
00317
00318 Bool_t TMergerInfo::AreAllWorkersMerged()
00319 {
00320
00321
00322 return (fWorkersToMerge == fMergedWorkers);
00323 }
00324
00325
00326 Bool_t TMergerInfo::AreAllWorkersAssigned()
00327 {
00328
00329
00330 if (!fWorkers)
00331 return kFALSE;
00332
00333 return (fWorkers->GetSize() == fWorkersToMerge);
00334 }
00335
00336
00337 TProof::TProof(const char *masterurl, const char *conffile, const char *confdir,
00338 Int_t loglevel, const char *alias, TProofMgr *mgr)
00339 : fUrl(masterurl)
00340 {
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 InitMembers();
00354
00355
00356 fManager = mgr;
00357
00358
00359 fServType = TProofMgr::kXProofd;
00360
00361
00362 fQueryMode = kSync;
00363
00364
00365
00366 ResetBit(TProof::kIsClient);
00367 ResetBit(TProof::kIsMaster);
00368
00369
00370 if (!masterurl || strlen(masterurl) <= 0) {
00371 fUrl.SetProtocol("proof");
00372 fUrl.SetHost("__master__");
00373 } else if (!(strstr(masterurl, "://"))) {
00374 fUrl.SetProtocol("proof");
00375 }
00376 if (!strcmp(fUrl.GetHost(), "localhost") ||
00377 !strncmp(fUrl.GetHost(), "localhost.", strlen("localhost.")))
00378 fUrl.SetHost(gSystem->HostName());
00379
00380
00381 if (fUrl.GetPort() == TUrl(" ").GetPort())
00382 fUrl.SetPort(TUrl("proof:// ").GetPort());
00383
00384
00385 if (strlen(fUrl.GetUser()) <= 0) {
00386
00387 UserGroup_t *pw = gSystem->GetUserInfo();
00388 if (pw) {
00389 fUrl.SetUser(pw->fUser);
00390 delete pw;
00391 }
00392 }
00393
00394
00395 if (!strcmp(fUrl.GetHost(), "__master__"))
00396 fMaster = fUrl.GetHost();
00397 else if (!strlen(fUrl.GetHost()))
00398 fMaster = gSystem->GetHostByName(gSystem->HostName()).GetHostName();
00399 else
00400 fMaster = gSystem->GetHostByName(fUrl.GetHost()).GetHostName();
00401
00402
00403 if (strlen(fUrl.GetOptions()) > 0) {
00404 TString opts(fUrl.GetOptions());
00405 if (!(strncmp(fUrl.GetOptions(),"std",3))) {
00406 fServType = TProofMgr::kProofd;
00407 opts.Remove(0,3);
00408 fUrl.SetOptions(opts.Data());
00409 } else if (!(strncmp(fUrl.GetOptions(),"lite",4))) {
00410 fServType = TProofMgr::kProofLite;
00411 opts.Remove(0,4);
00412 fUrl.SetOptions(opts.Data());
00413 }
00414 }
00415
00416
00417 fMasterServ = kFALSE;
00418 SetBit(TProof::kIsClient);
00419 ResetBit(TProof::kIsMaster);
00420 if (fMaster == "__master__") {
00421 fMasterServ = kTRUE;
00422 ResetBit(TProof::kIsClient);
00423 SetBit(TProof::kIsMaster);
00424 } else if (fMaster == "prooflite") {
00425
00426 fMasterServ = kTRUE;
00427 SetBit(TProof::kIsMaster);
00428 }
00429
00430 if (TestBit(TProof::kIsClient))
00431 if (!gSystem->Getenv("ROOTPROOFCLIENT")) gSystem->Setenv("ROOTPROOFCLIENT","");
00432
00433 Init(masterurl, conffile, confdir, loglevel, alias);
00434
00435
00436
00437 if (mgr) {
00438 R__LOCKGUARD2(gROOTMutex);
00439 gROOT->GetListOfSockets()->Remove(mgr);
00440 gROOT->GetListOfSockets()->Add(mgr);
00441 }
00442
00443
00444 if (IsProofd() || TestBit(TProof::kIsMaster))
00445 if (!gROOT->GetListOfProofs()->FindObject(this))
00446 gROOT->GetListOfProofs()->Add(this);
00447
00448
00449 gProof = this;
00450 }
00451
00452
00453 TProof::TProof() : fUrl(""), fServType(TProofMgr::kXProofd)
00454 {
00455
00456
00457
00458
00459
00460
00461
00462
00463 InitMembers();
00464
00465 if (!gROOT->GetListOfProofs()->FindObject(this))
00466 gROOT->GetListOfProofs()->Add(this);
00467
00468 gProof = this;
00469 }
00470
00471
00472 void TProof::InitMembers()
00473 {
00474
00475
00476 fValid = kFALSE;
00477 fRecvMessages = 0;
00478 fSlaveInfo = 0;
00479 fMasterServ = kFALSE;
00480 fSendGroupView = kFALSE;
00481 fActiveSlaves = 0;
00482 fInactiveSlaves = 0;
00483 fUniqueSlaves = 0;
00484 fAllUniqueSlaves = 0;
00485 fNonUniqueMasters = 0;
00486 fActiveMonitor = 0;
00487 fUniqueMonitor = 0;
00488 fAllUniqueMonitor = 0;
00489 fCurrentMonitor = 0;
00490 fBytesRead = 0;
00491 fRealTime = 0;
00492 fCpuTime = 0;
00493 fIntHandler = 0;
00494 fProgressDialog = 0;
00495 fProgressDialogStarted = kFALSE;
00496 SetBit(kUseProgressDialog);
00497 fPlayer = 0;
00498 fFeedback = 0;
00499 fChains = 0;
00500 fDSet = 0;
00501 fNotIdle = 0;
00502 fSync = kTRUE;
00503 fRunStatus = kRunning;
00504 fIsWaiting = kFALSE;
00505 fRedirLog = kFALSE;
00506 fLogFileW = 0;
00507 fLogFileR = 0;
00508 fLogToWindowOnly = kFALSE;
00509
00510 fWaitingSlaves = 0;
00511 fQueries = 0;
00512 fOtherQueries = 0;
00513 fDrawQueries = 0;
00514 fMaxDrawQueries = 1;
00515 fSeqNum = 0;
00516
00517 fSessionID = -1;
00518 fEndMaster = kFALSE;
00519
00520 fGlobalPackageDirList = 0;
00521 fPackageLock = 0;
00522 fEnabledPackagesOnClient = 0;
00523
00524 fInputData = 0;
00525
00526 fPrintProgress = 0;
00527
00528 fLoadedMacros = 0;
00529
00530 fProtocol = -1;
00531 fSlaves = 0;
00532 fBadSlaves = 0;
00533 fAllMonitor = 0;
00534 fDataReady = kFALSE;
00535 fBytesReady = 0;
00536 fTotalBytes = 0;
00537 fAvailablePackages = 0;
00538 fEnabledPackages = 0;
00539 fRunningDSets = 0;
00540
00541 fCollectTimeout = -1;
00542
00543 fManager = 0;
00544 fQueryMode = kSync;
00545 fDynamicStartup = kFALSE;
00546
00547 fCloseMutex = 0;
00548
00549 fMergersSet = kFALSE;
00550 fMergers = 0;
00551 fMergersCount = -1;
00552 fLastAssignedMerger = 0;
00553 fWorkersToMerge = 0;
00554 fFinalizationRunning = kFALSE;
00555
00556
00557
00558 if (gSystem->Getenv("PROOF_ENVVARS")) {
00559 TString envs(gSystem->Getenv("PROOF_ENVVARS")), env, envsfound;
00560 Int_t from = 0;
00561 while (envs.Tokenize(env, from, ",")) {
00562 if (!env.IsNull()) {
00563 if (!gSystem->Getenv(env)) {
00564 Warning("Init", "request for sending over undefined environemnt variable '%s' - ignoring", env.Data());
00565 } else {
00566 if (!envsfound.IsNull()) envsfound += ",";
00567 envsfound += env;
00568 TProof::DelEnvVar(env);
00569 TProof::AddEnvVar(env, gSystem->Getenv(env));
00570 }
00571 }
00572 }
00573 if (envsfound.IsNull()) {
00574 Warning("Init", "none of the requested env variables were found: '%s'", envs.Data());
00575 } else {
00576 Info("Init", "the following environment variables have been added to the list to be sent to the nodes: '%s'", envsfound.Data());
00577 }
00578 }
00579
00580
00581 return;
00582 }
00583
00584
00585 TProof::~TProof()
00586 {
00587
00588
00589 if (fChains) {
00590 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
00591
00592 chain->SetProof(0);
00593 RemoveChain(chain);
00594 }
00595 }
00596
00597
00598 if (TestBit(TProof::kIsClient)) {
00599
00600 TIter nextpackage(fEnabledPackagesOnClient);
00601 while (TObjString *package = dynamic_cast<TObjString*>(nextpackage())) {
00602 FileStat_t stat;
00603 gSystem->GetPathInfo(package->String(), stat);
00604
00605
00606
00607 if (stat.fIsLink)
00608 gSystem->Unlink(package->String());
00609 }
00610 }
00611
00612 Close();
00613 SafeDelete(fIntHandler);
00614 SafeDelete(fSlaves);
00615 SafeDelete(fActiveSlaves);
00616 SafeDelete(fInactiveSlaves);
00617 SafeDelete(fUniqueSlaves);
00618 SafeDelete(fAllUniqueSlaves);
00619 SafeDelete(fNonUniqueMasters);
00620 SafeDelete(fBadSlaves);
00621 SafeDelete(fAllMonitor);
00622 SafeDelete(fActiveMonitor);
00623 SafeDelete(fUniqueMonitor);
00624 SafeDelete(fAllUniqueMonitor);
00625 SafeDelete(fSlaveInfo);
00626 SafeDelete(fChains);
00627 SafeDelete(fPlayer);
00628 SafeDelete(fFeedback);
00629 SafeDelete(fWaitingSlaves);
00630 SafeDelete(fAvailablePackages);
00631 SafeDelete(fEnabledPackages);
00632 SafeDelete(fEnabledPackagesOnClient);
00633 SafeDelete(fLoadedMacros);
00634 SafeDelete(fPackageLock);
00635 SafeDelete(fGlobalPackageDirList);
00636 SafeDelete(fRecvMessages);
00637 SafeDelete(fInputData);
00638 SafeDelete(fRunningDSets);
00639 SafeDelete(fCloseMutex);
00640
00641
00642 if (TestBit(TProof::kIsClient)) {
00643 if (fLogFileR)
00644 fclose(fLogFileR);
00645 if (fLogFileW)
00646 fclose(fLogFileW);
00647 if (fLogFileName.Length() > 0)
00648 gSystem->Unlink(fLogFileName);
00649 }
00650
00651
00652 gROOT->GetListOfProofs()->Remove(this);
00653
00654 if (fManager && fManager->IsValid())
00655 fManager->DiscardSession(this);
00656
00657 if (gProof && gProof == this) {
00658
00659 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
00660 while ((gProof = (TProof *)pvp())) {
00661 if (gProof->InheritsFrom(TProof::Class()))
00662 break;
00663 }
00664 }
00665
00666
00667 Emit("~TProof()");
00668 }
00669
00670
00671 Int_t TProof::Init(const char *, const char *conffile,
00672 const char *confdir, Int_t loglevel, const char *alias)
00673 {
00674
00675
00676
00677
00678
00679
00680
00681 R__ASSERT(gSystem);
00682
00683 fValid = kFALSE;
00684
00685
00686 Bool_t attach = kFALSE;
00687 if (strlen(fUrl.GetOptions()) > 0) {
00688 attach = kTRUE;
00689
00690 TString opts = fUrl.GetOptions();
00691 if (opts.Contains("GUI")) {
00692 SetBit(TProof::kUsingSessionGui);
00693 opts.Remove(opts.Index("GUI"));
00694 fUrl.SetOptions(opts);
00695 }
00696 }
00697
00698 if (TestBit(TProof::kIsMaster)) {
00699
00700 if (!conffile || strlen(conffile) == 0)
00701 fConfFile = kPROOF_ConfFile;
00702 if (!confdir || strlen(confdir) == 0)
00703 fConfDir = kPROOF_ConfDir;
00704
00705 if (gProofServ) fGroup = gProofServ->GetGroup();
00706 } else {
00707 fConfDir = confdir;
00708 fConfFile = conffile;
00709 }
00710
00711
00712 ParseConfigField(fConfFile);
00713
00714 fWorkDir = gSystem->WorkingDirectory();
00715 fLogLevel = loglevel;
00716 fProtocol = kPROOF_Protocol;
00717 fSendGroupView = kTRUE;
00718 fImage = fMasterServ ? "" : "<local>";
00719 fIntHandler = 0;
00720 fStatus = 0;
00721 fRecvMessages = new TList;
00722 fRecvMessages->SetOwner(kTRUE);
00723 fSlaveInfo = 0;
00724 fChains = new TList;
00725 fAvailablePackages = 0;
00726 fEnabledPackages = 0;
00727 fRunningDSets = 0;
00728 fEndMaster = TestBit(TProof::kIsMaster) ? kTRUE : kFALSE;
00729 fInputData = 0;
00730 ResetBit(TProof::kNewInputData);
00731 fPrintProgress = 0;
00732
00733
00734 fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
00735
00736
00737 fDynamicStartup = gEnv->GetValue("Proof.DynamicStartup", kFALSE);
00738
00739
00740 if (TestBit(TProof::kIsClient))
00741 fDataPoolUrl.Form("root://%s", fMaster.Data());
00742 else
00743 fDataPoolUrl = "";
00744
00745 fProgressDialog = 0;
00746 fProgressDialogStarted = kFALSE;
00747
00748
00749 TString al = (alias) ? alias : fMaster.Data();
00750 SetAlias(al);
00751
00752
00753 fRedirLog = kFALSE;
00754 if (TestBit(TProof::kIsClient)) {
00755 fLogFileName.Form("%s/ProofLog_%d", gSystem->TempDirectory(), gSystem->GetPid());
00756 if ((fLogFileW = fopen(fLogFileName, "w")) == 0)
00757 Error("Init", "could not create temporary logfile");
00758 if ((fLogFileR = fopen(fLogFileName, "r")) == 0)
00759 Error("Init", "could not open temp logfile for reading");
00760 }
00761 fLogToWindowOnly = kFALSE;
00762
00763
00764 fNotIdle = 0;
00765
00766 fSync = (attach) ? kFALSE : kTRUE;
00767
00768 fIsWaiting = kFALSE;
00769
00770
00771 fBytesRead = 0;
00772 fRealTime = 0;
00773 fCpuTime = 0;
00774
00775
00776 fQueries = 0;
00777 fOtherQueries = 0;
00778 fDrawQueries = 0;
00779 fMaxDrawQueries = 1;
00780 fSeqNum = 0;
00781
00782
00783 fSessionID = -1;
00784
00785
00786 fWaitingSlaves = 0;
00787
00788
00789 fPlayer = 0;
00790 MakePlayer();
00791
00792 fFeedback = new TList;
00793 fFeedback->SetOwner();
00794 fFeedback->SetName("FeedbackList");
00795 AddInput(fFeedback);
00796
00797
00798 fSlaves = new TSortedList(kSortDescending);
00799 fActiveSlaves = new TList;
00800 fInactiveSlaves = new TList;
00801 fUniqueSlaves = new TList;
00802 fAllUniqueSlaves = new TList;
00803 fNonUniqueMasters = new TList;
00804 fBadSlaves = new TList;
00805 fAllMonitor = new TMonitor;
00806 fActiveMonitor = new TMonitor;
00807 fUniqueMonitor = new TMonitor;
00808 fAllUniqueMonitor = new TMonitor;
00809 fCurrentMonitor = 0;
00810
00811 fPackageLock = 0;
00812 fEnabledPackagesOnClient = 0;
00813 fLoadedMacros = 0;
00814 fGlobalPackageDirList = 0;
00815
00816
00817
00818
00819 Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
00820 if (enableSchemaEvolution) {
00821 TMessage::EnableSchemaEvolutionForAll();
00822 } else {
00823 Info("TProof", "automatic schema evolution in TMessage explicitely disabled");
00824 }
00825
00826 if (IsMaster()) {
00827
00828 fPackageDir = gProofServ->GetPackageDir();
00829 } else {
00830
00831 TString sandbox = gEnv->GetValue("Proof.Sandbox", "");
00832 if (sandbox.IsNull()) sandbox.Form("~/%s", kPROOF_WorkDir);
00833 gSystem->ExpandPathName(sandbox);
00834 if (AssertPath(sandbox, kTRUE) != 0) {
00835 Error("Init", "failure asserting directory %s", sandbox.Data());
00836 return 0;
00837 }
00838
00839
00840 fPackageDir = gEnv->GetValue("Proof.PackageDir", "");
00841 if (fPackageDir.IsNull())
00842 fPackageDir.Form("%s/%s", sandbox.Data(), kPROOF_PackDir);
00843 if (AssertPath(fPackageDir, kTRUE) != 0) {
00844 Error("Init", "failure asserting directory %s", fPackageDir.Data());
00845 return 0;
00846 }
00847 }
00848
00849 if (!IsMaster()) {
00850
00851 TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
00852 if (globpack.Length() > 0) {
00853 Int_t ng = 0;
00854 Int_t from = 0;
00855 TString ldir;
00856 while (globpack.Tokenize(ldir, from, ":")) {
00857 if (gSystem->AccessPathName(ldir, kReadPermission)) {
00858 Warning("Init", "directory for global packages %s does not"
00859 " exist or is not readable", ldir.Data());
00860 } else {
00861
00862 TString key = Form("G%d", ng++);
00863 if (!fGlobalPackageDirList) {
00864 fGlobalPackageDirList = new THashList();
00865 fGlobalPackageDirList->SetOwner();
00866 }
00867 fGlobalPackageDirList->Add(new TNamed(key,ldir));
00868 }
00869 }
00870 }
00871
00872 TString lockpath(fPackageDir);
00873 lockpath.ReplaceAll("/", "%");
00874 lockpath.Insert(0, Form("%s/%s", gSystem->TempDirectory(), kPROOF_PackageLockFile));
00875 fPackageLock = new TProofLockPath(lockpath.Data());
00876
00877 fEnabledPackagesOnClient = new TList;
00878 fEnabledPackagesOnClient->SetOwner();
00879 }
00880
00881
00882 if (fDynamicStartup) {
00883 if (!IsMaster()) {
00884
00885 if (!StartSlaves(attach))
00886 return 0;
00887 }
00888 } else {
00889
00890
00891
00892 Bool_t masterOnly = gEnv->GetValue("Proof.MasterOnly", kFALSE);
00893 if (!IsMaster() || !masterOnly) {
00894
00895 if (!StartSlaves(attach))
00896 return 0;
00897 }
00898 }
00899
00900 if (fgSemaphore)
00901 SafeDelete(fgSemaphore);
00902
00903
00904 fValid = kTRUE;
00905
00906
00907 fAllMonitor->DeActivateAll();
00908
00909
00910 GoParallel(9999, attach);
00911
00912
00913 if (!attach)
00914 SendInitialState();
00915 else if (!IsIdle())
00916
00917 fRedirLog = kTRUE;
00918
00919
00920 if (TestBit(TProof::kIsClient))
00921 SetAlias(al);
00922
00923 SetActive(kFALSE);
00924
00925 if (IsValid()) {
00926
00927
00928 ActivateAsyncInput();
00929
00930 R__LOCKGUARD2(gROOTMutex);
00931 gROOT->GetListOfSockets()->Add(this);
00932 }
00933 return fActiveSlaves->GetSize();
00934 }
00935
00936
00937 void TProof::ParseConfigField(const char *config)
00938 {
00939
00940
00941
00942 TString sconf(config);
00943
00944
00945 const char *cq = (IsLite()) ? "\"" : "";
00946 Int_t ivg = kNPOS;
00947 if ((ivg = sconf.Index("valgrind")) != kNPOS) {
00948 Int_t jvg = sconf.Index(',', ivg);
00949 Int_t lvg = (jvg != kNPOS) ? (jvg-ivg) : sconf.Length();
00950 TString vgconf = sconf(ivg, lvg);
00951
00952
00953
00954
00955 TString mst, wrk, all;
00956 TList *envs = fgProofEnvList;
00957 TNamed *n = 0;
00958 if (envs) {
00959 if ((n = (TNamed *) envs->FindObject("PROOF_WRAPPERCMD")))
00960 all = n->GetTitle();
00961 if ((n = (TNamed *) envs->FindObject("PROOF_MASTER_WRAPPERCMD")))
00962 mst = n->GetTitle();
00963 if ((n = (TNamed *) envs->FindObject("PROOF_SLAVE_WRAPPERCMD")))
00964 wrk = n->GetTitle();
00965 }
00966 if (all != "" && mst == "") mst = all;
00967 if (all != "" && wrk == "") wrk = all;
00968 if (all != "" && all.BeginsWith("valgrind_opts:")) {
00969
00970 Info("ParseConfigField","valgrind run: resetting 'PROOF_WRAPPERCMD':"
00971 " must be set again for next run , if any");
00972 TProof::DelEnvVar("PROOF_WRAPPERCMD");
00973 }
00974 TString var, cmd;
00975 cmd.Form("%svalgrind -v --suppressions=<rootsys>/etc/valgrind-root.supp", cq);
00976 TString mstlab("NO"), wrklab("NO");
00977 if (vgconf == "valgrind" || vgconf.Contains("master")) {
00978 if (!IsLite()) {
00979
00980 if (mst == "" || mst.BeginsWith("valgrind_opts:")) {
00981 mst.ReplaceAll("valgrind_opts:","");
00982 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), mst.Data());
00983 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", var);
00984 mstlab = "YES";
00985 } else if (mst != "") {
00986 mstlab = "YES";
00987 }
00988 } else {
00989 if (vgconf.Contains("master")) {
00990 Warning("ParseConfigField",
00991 "master valgrinding does not make sense for PROOF-Lite: ignoring");
00992 vgconf.ReplaceAll("master", "");
00993 if (!vgconf.Contains("workers")) return;
00994 }
00995 if (vgconf == "valgrind" || vgconf == "valgrind=") vgconf = "valgrind=workers";
00996 }
00997 }
00998 if (vgconf.Contains("=workers") || vgconf.Contains("+workers")) {
00999
01000 if (wrk == "" || wrk.BeginsWith("valgrind_opts:")) {
01001 wrk.ReplaceAll("valgrind_opts:","");
01002 var.Form("%s --log-file=<logfilewrk>.valgrind.log %s%s", cmd.Data(), wrk.Data(), cq);
01003 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", var);
01004 TString nwrks("2");
01005 Int_t inw = vgconf.Index('#');
01006 if (inw != kNPOS) {
01007 nwrks = vgconf(inw+1, vgconf.Length());
01008 if (!nwrks.IsDigit()) nwrks = "2";
01009 }
01010
01011 if (!IsLite()) {
01012 TProof::AddEnvVar("PROOF_NWORKERS", nwrks);
01013 } else {
01014 gEnv->SetValue("ProofLite.Workers", nwrks.Atoi());
01015 }
01016 wrklab = nwrks;
01017
01018
01019 TProof::AddEnvVar("PROOF_ADDITIONALLOG", "valgrind.log*");
01020 } else if (wrk != "") {
01021 wrklab = "ALL";
01022 }
01023 }
01024
01025 if (!IsLite()) {
01026 TProof::AddEnvVar("PROOF_INTWAIT", "5000");
01027 gEnv->SetValue("Proof.SocketActivityTimeout", 6000);
01028 } else {
01029 gEnv->SetValue("ProofLite.StartupTimeOut", 5000);
01030 }
01031
01032 Printf(" ");
01033 if (!IsLite()) {
01034 Printf(" ---> Starting a debug run with valgrind (master:%s, workers:%s)", mstlab.Data(), wrklab.Data());
01035 } else {
01036 Printf(" ---> Starting a debug run with valgrind (workers:%s)", wrklab.Data());
01037 }
01038 Printf(" ---> Please be patient: startup may be VERY slow ...");
01039 Printf(" ---> Logs will be available as special tags in the log window (from the progress dialog or TProof::LogViewer()) ");
01040 Printf(" ---> (Reminder: this debug run makes sense only if you are running a debug version of ROOT)");
01041 Printf(" ");
01042
01043 } else if (sconf.BeginsWith("workers=")) {
01044
01045
01046
01047
01048
01049 sconf.ReplaceAll("workers=","");
01050 TProof::AddEnvVar("PROOF_NWORKERS", sconf);
01051 }
01052 }
01053
01054
01055 Int_t TProof::AssertPath(const char *inpath, Bool_t writable)
01056 {
01057
01058
01059
01060 if (!inpath || strlen(inpath) <= 0) {
01061 Error("AssertPath", "undefined input path");
01062 return -1;
01063 }
01064
01065 TString path(inpath);
01066 gSystem->ExpandPathName(path);
01067
01068 if (gSystem->AccessPathName(path, kFileExists)) {
01069 if (gSystem->mkdir(path, kTRUE) != 0) {
01070 Error("AssertPath", "could not create path %s", path.Data());
01071 return -1;
01072 }
01073 }
01074
01075 if (gSystem->AccessPathName(path, kWritePermission) && writable) {
01076 if (gSystem->Chmod(path, 0666) != 0) {
01077 Error("AssertPath", "could not make path %s writable", path.Data());
01078 return -1;
01079 }
01080 }
01081
01082
01083 return 0;
01084 }
01085
01086
01087 void TProof::SetManager(TProofMgr *mgr)
01088 {
01089
01090
01091
01092 fManager = mgr;
01093
01094 if (mgr) {
01095 R__LOCKGUARD2(gROOTMutex);
01096 gROOT->GetListOfSockets()->Remove(mgr);
01097 gROOT->GetListOfSockets()->Add(mgr);
01098 }
01099 }
01100
01101
01102 Int_t TProof::AddWorkers(TList *workerList)
01103 {
01104
01105
01106
01107
01108
01109
01110
01111 if (!IsMaster()) {
01112 Error("AddWorkers", "AddWorkers can only be called on the master!");
01113 return -1;
01114 }
01115
01116 if (!workerList || !(workerList->GetSize())) {
01117 Error("AddWorkers", "empty list of workers!");
01118 return -2;
01119 }
01120
01121
01122
01123 fImage = gProofServ->GetImage();
01124 if (fImage.IsNull())
01125 fImage.Form("%s:%s", TUrl(gSystem->HostName()).GetHostFQDN(), gProofServ->GetWorkDir());
01126
01127
01128 UInt_t nSlaves = workerList->GetSize();
01129 UInt_t nSlavesDone = 0;
01130 Int_t ord = 0;
01131
01132
01133
01134
01135 TList *addedWorkers = new TList();
01136 if (!addedWorkers) {
01137
01138 Error("AddWorkers", "cannot create new list for the workers to be added");
01139 return -2;
01140 }
01141 addedWorkers->SetOwner(kFALSE);
01142 TListIter next(workerList);
01143 TObject *to;
01144 TProofNodeInfo *worker;
01145 while ((to = next())) {
01146
01147 worker = (TProofNodeInfo *)to;
01148
01149
01150 const Char_t *image = worker->GetImage().Data();
01151 const Char_t *workdir = worker->GetWorkDir().Data();
01152 Int_t perfidx = worker->GetPerfIndex();
01153 Int_t sport = worker->GetPort();
01154 if (sport == -1)
01155 sport = fUrl.GetPort();
01156
01157
01158 TString fullord;
01159 if (worker->GetOrdinal().Length() > 0) {
01160 fullord.Form("%s.%s", gProofServ->GetOrdinal(), worker->GetOrdinal().Data());
01161 } else {
01162 fullord.Form("%s.%d", gProofServ->GetOrdinal(), ord);
01163 }
01164
01165
01166 TString wn(worker->GetNodeName());
01167 if (wn == "localhost" || wn.BeginsWith("localhost.")) wn = gSystem->HostName();
01168 TUrl u(TString::Format("%s:%d", wn.Data(), sport));
01169
01170 if (strlen(gProofServ->GetGroup()) > 0) {
01171
01172 if (strlen(u.GetUser()) <= 0)
01173 u.SetUser(gProofServ->GetUser());
01174 u.SetPasswd(gProofServ->GetGroup());
01175 }
01176 TSlave *slave = CreateSlave(u.GetUrl(), fullord, perfidx,
01177 image, workdir);
01178
01179
01180
01181 Bool_t slaveOk = kTRUE;
01182 if (slave->IsValid()) {
01183 fSlaves->Add(slave);
01184 addedWorkers->Add(slave);
01185 } else {
01186 slaveOk = kFALSE;
01187 fBadSlaves->Add(slave);
01188 }
01189
01190 PDB(kGlobal,3)
01191 Info("StartSlaves", "worker on host %s created"
01192 " and added to list", worker->GetNodeName().Data());
01193
01194
01195 nSlavesDone++;
01196 TMessage m(kPROOF_SERVERSTARTED);
01197 m << TString("Opening connections to workers") << nSlaves
01198 << nSlavesDone << slaveOk;
01199 gProofServ->GetSocket()->Send(m);
01200
01201 ord++;
01202 }
01203
01204
01205 SafeDelete(workerList);
01206
01207 nSlavesDone = 0;
01208
01209
01210
01211 TIter nxsl(addedWorkers);
01212 TSlave *sl = 0;
01213 while ((sl = (TSlave *) nxsl())) {
01214
01215
01216 if (sl->IsValid())
01217 sl->SetupServ(TSlave::kSlave, 0);
01218
01219
01220 Bool_t slaveOk = kTRUE;
01221 if (sl->IsValid()) {
01222 fAllMonitor->Add(sl->GetSocket());
01223 } else {
01224 slaveOk = kFALSE;
01225 fBadSlaves->Add(sl);
01226 }
01227
01228
01229 nSlavesDone++;
01230 TMessage m(kPROOF_SERVERSTARTED);
01231 m << TString("Setting up worker servers") << nSlaves
01232 << nSlavesDone << slaveOk;
01233 gProofServ->GetSocket()->Send(m);
01234 }
01235
01236
01237
01238
01239
01240
01241 SetParallel(99999, 0);
01242
01243 TList *tmpEnabledPackages = gProofServ->GetEnabledPackages();
01244
01245 if (tmpEnabledPackages && tmpEnabledPackages->GetSize() > 0) {
01246 TIter nxp(tmpEnabledPackages);
01247 TObjString *os = 0;
01248 while ((os = (TObjString *) nxp())) {
01249
01250
01251 UploadPackage(os->GetName());
01252 EnablePackage(os->GetName(), (TList *)0, kTRUE);
01253 }
01254 }
01255
01256
01257 if (fLoadedMacros) {
01258 TIter nxp(fLoadedMacros);
01259 TObjString *os = 0;
01260 while ((os = (TObjString *) nxp())) {
01261 Printf("Loading a macro : %s", os->GetName());
01262 Load(os->GetName(), kTRUE, kTRUE, addedWorkers);
01263 }
01264 }
01265
01266 TString dyn = gSystem->GetDynamicPath();
01267 dyn.ReplaceAll(":", " ");
01268 dyn.ReplaceAll("\"", " ");
01269 AddDynamicPath(dyn, kFALSE, addedWorkers);
01270 TString inc = gSystem->GetIncludePath();
01271 inc.ReplaceAll("-I", " ");
01272 inc.ReplaceAll("\"", " ");
01273 AddIncludePath(inc, kFALSE, addedWorkers);
01274
01275
01276 delete addedWorkers;
01277
01278
01279 if (fDynamicStartup && gProofServ)
01280 gProofServ->SendParallel(kTRUE);
01281
01282 return 0;
01283 }
01284
01285
01286 Int_t TProof::RemoveWorkers(TList *workerList)
01287 {
01288
01289
01290
01291
01292 if (!IsMaster()) {
01293 Error("RemoveWorkers", "RemoveWorkers can only be called on the master!");
01294 return -1;
01295 }
01296
01297 fFileMap.clear();
01298
01299 if (!workerList) {
01300
01301 TIter nxsl(fSlaves);
01302 TSlave *sl = 0;
01303 while ((sl = (TSlave *) nxsl())) {
01304
01305 TerminateWorker(sl);
01306 }
01307
01308 } else {
01309 if (!(workerList->GetSize())) {
01310 Error("RemoveWorkers", "The list of workers should not be empty!");
01311 return -2;
01312 }
01313
01314
01315 TListIter next(workerList);
01316 TObject *to;
01317 TProofNodeInfo *worker;
01318 while ((to = next())) {
01319 TSlave *sl = 0;
01320 if (!strcmp(to->ClassName(), "TProofNodeInfo")) {
01321
01322 worker = (TProofNodeInfo *)to;
01323 TIter nxsl(fSlaves);
01324 while ((sl = (TSlave *) nxsl())) {
01325
01326 if (sl->GetName() == worker->GetNodeName())
01327 break;
01328 }
01329 } else if (to->InheritsFrom(TSlave::Class())) {
01330 sl = (TSlave *) to;
01331 } else {
01332 Warning("RemoveWorkers","unknown object type: %s - it should be"
01333 " TProofNodeInfo or inheriting from TSlave", to->ClassName());
01334 }
01335
01336 if (sl) {
01337 if (gDebug > 0)
01338 Info("RemoveWorkers","terminating worker %s", sl->GetOrdinal());
01339 TerminateWorker(sl);
01340 }
01341 }
01342 }
01343
01344
01345 if (gProofServ && fSlaves->GetSize() <= 0) gProofServ->ReleaseWorker("master");
01346
01347 return 0;
01348 }
01349
01350
01351 Bool_t TProof::StartSlaves(Bool_t attach)
01352 {
01353
01354
01355
01356
01357 if (TestBit(TProof::kIsMaster)) {
01358
01359 Int_t pc = 0;
01360 TList *workerList = new TList;
01361
01362 if (gProofServ->GetWorkers(workerList, pc) == TProofServ::kQueryStop) {
01363 TString emsg("no resource currently available for this session: please retry later");
01364 if (gDebug > 0) Info("StartSlaves", "%s", emsg.Data());
01365 gProofServ->SendAsynMessage(emsg.Data());
01366 return kFALSE;
01367 }
01368
01369
01370 if (AddWorkers(workerList) < 0)
01371 return kFALSE;
01372
01373 } else {
01374
01375
01376 Printf("Starting master: opening connection ...");
01377 TSlave *slave = CreateSubmaster(fUrl.GetUrl(), "0", "master", 0);
01378
01379 if (slave->IsValid()) {
01380
01381
01382 fprintf(stderr,"Starting master:"
01383 " connection open: setting up server ... \r");
01384 StartupMessage("Connection to master opened", kTRUE, 1, 1);
01385
01386 if (!attach) {
01387
01388
01389 slave->SetInterruptHandler(kTRUE);
01390
01391
01392 slave->SetupServ(TSlave::kMaster, fConfFile);
01393
01394 if (slave->IsValid()) {
01395
01396
01397 Printf("Starting master: OK ");
01398 StartupMessage("Master started", kTRUE, 1, 1);
01399
01400
01401
01402 if (fProtocol == 1) {
01403 Error("StartSlaves",
01404 "client and remote protocols not compatible (%d and %d)",
01405 kPROOF_Protocol, fProtocol);
01406 slave->Close("S");
01407 delete slave;
01408 return kFALSE;
01409 }
01410
01411 fSlaves->Add(slave);
01412 fAllMonitor->Add(slave->GetSocket());
01413
01414
01415 slave->SetInterruptHandler(kFALSE);
01416
01417
01418 fIntHandler = new TProofInterruptHandler(this);
01419
01420
01421 Int_t rc = Collect(slave, 300);
01422 Int_t slStatus = slave->GetStatus();
01423 if (slStatus == -99 || slStatus == -98 || rc == 0) {
01424 fSlaves->Remove(slave);
01425 fAllMonitor->Remove(slave->GetSocket());
01426 if (slStatus == -99)
01427 Error("StartSlaves", "no resources available or problems setting up workers (check logs)");
01428 else if (slStatus == -98)
01429 Error("StartSlaves", "could not setup output redirection on master");
01430 else
01431 Error("StartSlaves", "setting up master");
01432 slave->Close("S");
01433 delete slave;
01434 return 0;
01435 }
01436
01437 if (!slave->IsValid()) {
01438 fSlaves->Remove(slave);
01439 fAllMonitor->Remove(slave->GetSocket());
01440 slave->Close("S");
01441 delete slave;
01442 Error("StartSlaves",
01443 "failed to setup connection with PROOF master server");
01444 return kFALSE;
01445 }
01446
01447 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
01448 if ((fProgressDialog =
01449 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
01450 if (fProgressDialog->LoadPlugin() == -1)
01451 fProgressDialog = 0;
01452 }
01453 } else {
01454
01455 Printf("Starting master: failure");
01456 }
01457 } else {
01458
01459
01460 Printf("Starting master: OK ");
01461 StartupMessage("Master attached", kTRUE, 1, 1);
01462
01463 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
01464 if ((fProgressDialog =
01465 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
01466 if (fProgressDialog->LoadPlugin() == -1)
01467 fProgressDialog = 0;
01468 }
01469
01470 fSlaves->Add(slave);
01471 fIntHandler = new TProofInterruptHandler(this);
01472 }
01473
01474 } else {
01475 delete slave;
01476
01477 if (gDebug > 0)
01478 Error("StartSlaves", "failed to create (or connect to) the PROOF master server");
01479 return kFALSE;
01480 }
01481 }
01482
01483 return kTRUE;
01484 }
01485
01486
01487 void TProof::Close(Option_t *opt)
01488 {
01489
01490
01491
01492
01493
01494 { R__LOCKGUARD2(fCloseMutex);
01495
01496 fValid = kFALSE;
01497 if (fSlaves) {
01498 if (fIntHandler)
01499 fIntHandler->Remove();
01500
01501 TIter nxs(fSlaves);
01502 TSlave *sl = 0;
01503 while ((sl = (TSlave *)nxs()))
01504 sl->Close(opt);
01505
01506 fActiveSlaves->Clear("nodelete");
01507 fUniqueSlaves->Clear("nodelete");
01508 fAllUniqueSlaves->Clear("nodelete");
01509 fNonUniqueMasters->Clear("nodelete");
01510 fBadSlaves->Clear("nodelete");
01511 fSlaves->Delete();
01512 }
01513 }
01514
01515 {
01516 R__LOCKGUARD2(gROOTMutex);
01517 gROOT->GetListOfSockets()->Remove(this);
01518
01519 if (IsProofd()) {
01520
01521 gROOT->GetListOfProofs()->Remove(this);
01522 if (gProof && gProof == this) {
01523
01524 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
01525 while ((gProof = (TProof *)pvp())) {
01526 if (gProof->IsProofd())
01527 break;
01528 }
01529 }
01530 }
01531 }
01532 }
01533
01534
01535 TSlave *TProof::CreateSlave(const char *url, const char *ord,
01536 Int_t perf, const char *image, const char *workdir)
01537 {
01538
01539
01540
01541
01542 TSlave* sl = TSlave::Create(url, ord, perf, image,
01543 this, TSlave::kSlave, workdir, 0);
01544
01545 if (sl->IsValid()) {
01546 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
01547
01548
01549 sl->fParallel = 1;
01550 }
01551
01552 return sl;
01553 }
01554
01555
01556
01557 TSlave *TProof::CreateSubmaster(const char *url, const char *ord,
01558 const char *image, const char *msd)
01559 {
01560
01561
01562
01563
01564 TSlave *sl = TSlave::Create(url, ord, 100, image, this,
01565 TSlave::kMaster, 0, msd);
01566
01567 if (sl->IsValid()) {
01568 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
01569 }
01570
01571 return sl;
01572 }
01573
01574
01575 TSlave *TProof::FindSlave(TSocket *s) const
01576 {
01577
01578
01579 TSlave *sl;
01580 TIter next(fSlaves);
01581
01582 while ((sl = (TSlave *)next())) {
01583 if (sl->IsValid() && sl->GetSocket() == s)
01584 return sl;
01585 }
01586 return 0;
01587 }
01588
01589
01590 void TProof::FindUniqueSlaves()
01591 {
01592
01593
01594
01595
01596
01597
01598
01599
01600 fUniqueSlaves->Clear();
01601 fUniqueMonitor->RemoveAll();
01602 fAllUniqueSlaves->Clear();
01603 fAllUniqueMonitor->RemoveAll();
01604 fNonUniqueMasters->Clear();
01605
01606 TIter next(fActiveSlaves);
01607
01608 while (TSlave *sl = dynamic_cast<TSlave*>(next())) {
01609 if (fImage == sl->fImage) {
01610 if (sl->GetSlaveType() == TSlave::kMaster) {
01611 fNonUniqueMasters->Add(sl);
01612 fAllUniqueSlaves->Add(sl);
01613 fAllUniqueMonitor->Add(sl->GetSocket());
01614 }
01615 continue;
01616 }
01617
01618 TIter next2(fUniqueSlaves);
01619 TSlave *replace_slave = 0;
01620 Bool_t add = kTRUE;
01621 while (TSlave *sl2 = dynamic_cast<TSlave*>(next2())) {
01622 if (sl->fImage == sl2->fImage) {
01623 add = kFALSE;
01624 if (sl->GetSlaveType() == TSlave::kMaster) {
01625 if (sl2->GetSlaveType() == TSlave::kSlave) {
01626
01627 replace_slave = sl2;
01628 add = kTRUE;
01629 } else if (sl2->GetSlaveType() == TSlave::kMaster) {
01630 fNonUniqueMasters->Add(sl);
01631 fAllUniqueSlaves->Add(sl);
01632 fAllUniqueMonitor->Add(sl->GetSocket());
01633 } else {
01634 Error("FindUniqueSlaves", "TSlave is neither Master nor Slave");
01635 R__ASSERT(0);
01636 }
01637 }
01638 break;
01639 }
01640 }
01641
01642 if (add) {
01643 fUniqueSlaves->Add(sl);
01644 fAllUniqueSlaves->Add(sl);
01645 fUniqueMonitor->Add(sl->GetSocket());
01646 fAllUniqueMonitor->Add(sl->GetSocket());
01647 if (replace_slave) {
01648 fUniqueSlaves->Remove(replace_slave);
01649 fAllUniqueSlaves->Remove(replace_slave);
01650 fUniqueMonitor->Remove(replace_slave->GetSocket());
01651 fAllUniqueMonitor->Remove(replace_slave->GetSocket());
01652 }
01653 }
01654 }
01655
01656
01657 fUniqueMonitor->DeActivateAll();
01658 fAllUniqueMonitor->DeActivateAll();
01659 }
01660
01661
01662 Int_t TProof::GetNumberOfSlaves() const
01663 {
01664
01665
01666 return fSlaves->GetSize();
01667 }
01668
01669
01670 Int_t TProof::GetNumberOfActiveSlaves() const
01671 {
01672
01673
01674
01675 return fActiveSlaves->GetSize();
01676 }
01677
01678
01679 Int_t TProof::GetNumberOfInactiveSlaves() const
01680 {
01681
01682
01683
01684 return fInactiveSlaves->GetSize();
01685 }
01686
01687
01688 Int_t TProof::GetNumberOfUniqueSlaves() const
01689 {
01690
01691
01692
01693 return fUniqueSlaves->GetSize();
01694 }
01695
01696
01697 Int_t TProof::GetNumberOfBadSlaves() const
01698 {
01699
01700
01701
01702 return fBadSlaves->GetSize();
01703 }
01704
01705
01706 void TProof::AskStatistics()
01707 {
01708
01709
01710 if (!IsValid()) return;
01711
01712 Broadcast(kPROOF_GETSTATS, kActive);
01713 Collect(kActive, fCollectTimeout);
01714 }
01715
01716
01717 void TProof::GetStatistics(Bool_t verbose)
01718 {
01719
01720
01721
01722
01723 if (fProtocol > 27) {
01724
01725 AskStatistics();
01726 } else {
01727
01728 RedirectHandle_t rh;
01729 gSystem->RedirectOutput(fLogFileName, "a", &rh);
01730 Print();
01731 gSystem->RedirectOutput(0, 0, &rh);
01732 TMacro *mp = GetLastLog();
01733 if (mp) {
01734
01735 TIter nxl(mp->GetListOfLines());
01736 TObjString *os = 0;
01737 while ((os = (TObjString *) nxl())) {
01738 TString s(os->GetName());
01739 if (s.Contains("Total MB's processed:")) {
01740 s.ReplaceAll("Total MB's processed:", "");
01741 if (s.IsFloat()) fBytesRead = (Long64_t) s.Atof() * (1024*1024);
01742 } else if (s.Contains("Total real time used (s):")) {
01743 s.ReplaceAll("Total real time used (s):", "");
01744 if (s.IsFloat()) fRealTime = s.Atof();
01745 } else if (s.Contains("Total CPU time used (s):")) {
01746 s.ReplaceAll("Total CPU time used (s):", "");
01747 if (s.IsFloat()) fCpuTime = s.Atof();
01748 }
01749 }
01750 delete mp;
01751 }
01752 }
01753
01754 if (verbose) {
01755 Printf(" Real/CPU time (s): %.3f / %.3f; workers: %d; processed: %.2f MBs",
01756 GetRealTime(), GetCpuTime(), GetParallel(), float(GetBytesRead())/(1024*1024));
01757 }
01758 }
01759
01760
01761 void TProof::AskParallel()
01762 {
01763
01764
01765 if (!IsValid()) return;
01766
01767 Broadcast(kPROOF_GETPARALLEL, kActive);
01768 Collect(kActive, fCollectTimeout);
01769 }
01770
01771
01772 TList *TProof::GetListOfQueries(Option_t *opt)
01773 {
01774
01775
01776 if (!IsValid() || TestBit(TProof::kIsMaster)) return (TList *)0;
01777
01778 Bool_t all = ((strchr(opt,'A') || strchr(opt,'a'))) ? kTRUE : kFALSE;
01779 TMessage m(kPROOF_QUERYLIST);
01780 m << all;
01781 Broadcast(m, kActive);
01782 Collect(kActive, fCollectTimeout);
01783
01784
01785 return fQueries;
01786 }
01787
01788
01789 Int_t TProof::GetNumberOfQueries()
01790 {
01791
01792
01793 if (fQueries)
01794 return fQueries->GetSize() - fOtherQueries;
01795 return 0;
01796 }
01797
01798
01799 void TProof::SetMaxDrawQueries(Int_t max)
01800 {
01801
01802
01803 if (max > 0) {
01804 if (fPlayer)
01805 fPlayer->SetMaxDrawQueries(max);
01806 fMaxDrawQueries = max;
01807 }
01808 }
01809
01810
01811 void TProof::GetMaxQueries()
01812 {
01813
01814
01815
01816 TMessage m(kPROOF_MAXQUERIES);
01817 m << kFALSE;
01818 Broadcast(m, kActive);
01819 Collect(kActive, fCollectTimeout);
01820 }
01821
01822
01823 TList *TProof::GetQueryResults()
01824 {
01825
01826
01827 return (fPlayer ? fPlayer->GetListOfResults() : (TList *)0);
01828 }
01829
01830
01831 TQueryResult *TProof::GetQueryResult(const char *ref)
01832 {
01833
01834
01835
01836 return (fPlayer ? fPlayer->GetQueryResult(ref) : (TQueryResult *)0);
01837 }
01838
01839
01840 void TProof::ShowQueries(Option_t *opt)
01841 {
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853 Bool_t help = ((strchr(opt,'H') || strchr(opt,'h'))) ? kTRUE : kFALSE;
01854 if (help) {
01855
01856
01857
01858 Printf("+++");
01859 Printf("+++ Options: \"A\" show all queries known to server");
01860 Printf("+++ \"L\" show retrieved queries");
01861 Printf("+++ \"F\" full listing of query info");
01862 Printf("+++ \"H\" print this menu");
01863 Printf("+++");
01864 Printf("+++ (case insensitive)");
01865 Printf("+++");
01866 Printf("+++ Use Retrieve(<#>) to retrieve the full"
01867 " query results from the master");
01868 Printf("+++ e.g. Retrieve(8)");
01869
01870 Printf("+++");
01871
01872 return;
01873 }
01874
01875 if (!IsValid()) return;
01876
01877 Bool_t local = ((strchr(opt,'L') || strchr(opt,'l'))) ? kTRUE : kFALSE;
01878
01879 TObject *pq = 0;
01880 if (!local) {
01881 GetListOfQueries(opt);
01882
01883 if (!fQueries) return;
01884
01885 TIter nxq(fQueries);
01886
01887
01888 if (fOtherQueries > 0) {
01889 Printf("+++");
01890 Printf("+++ Queries processed during other sessions: %d", fOtherQueries);
01891 Int_t nq = 0;
01892 while (nq++ < fOtherQueries && (pq = nxq()))
01893 pq->Print(opt);
01894 }
01895
01896
01897 Printf("+++");
01898 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
01899 GetNumberOfQueries(), fDrawQueries);
01900 while ((pq = nxq()))
01901 pq->Print(opt);
01902
01903 } else {
01904
01905
01906 Printf("+++");
01907 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
01908 GetNumberOfQueries(), fDrawQueries);
01909
01910
01911 TList *listlocal = fPlayer ? fPlayer->GetListOfResults() : (TList *)0;
01912 if (listlocal) {
01913 Printf("+++");
01914 Printf("+++ Queries available locally: %d", listlocal->GetSize());
01915 TIter nxlq(listlocal);
01916 while ((pq = nxlq()))
01917 pq->Print(opt);
01918 }
01919 }
01920 Printf("+++");
01921 }
01922
01923
01924 Bool_t TProof::IsDataReady(Long64_t &totalbytes, Long64_t &bytesready)
01925 {
01926
01927
01928 if (!IsValid()) return kFALSE;
01929
01930 TList submasters;
01931 TIter nextSlave(GetListOfActiveSlaves());
01932 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
01933 if (sl->GetSlaveType() == TSlave::kMaster) {
01934 submasters.Add(sl);
01935 }
01936 }
01937
01938 fDataReady = kTRUE;
01939 fBytesReady = 0;
01940 fTotalBytes = 0;
01941
01942 if (submasters.GetSize() > 0) {
01943 Broadcast(kPROOF_DATA_READY, &submasters);
01944 Collect(&submasters);
01945 }
01946
01947 bytesready = fBytesReady;
01948 totalbytes = fTotalBytes;
01949
01950 EmitVA("IsDataReady(Long64_t,Long64_t)", 2, totalbytes, bytesready);
01951
01952
01953 Info("IsDataReady", "%lld / %lld (%s)",
01954 bytesready, totalbytes, fDataReady?"READY":"NOT READY");
01955
01956 return fDataReady;
01957 }
01958
01959
01960 void TProof::Interrupt(EUrgent type, ESlaves list)
01961 {
01962
01963
01964 if (!IsValid()) return;
01965
01966 TList *slaves = 0;
01967 if (list == kAll) slaves = fSlaves;
01968 if (list == kActive) slaves = fActiveSlaves;
01969 if (list == kUnique) slaves = fUniqueSlaves;
01970 if (list == kAllUnique) slaves = fAllUniqueSlaves;
01971
01972 if (slaves->GetSize() == 0) return;
01973
01974 TSlave *sl;
01975 TIter next(slaves);
01976
01977 while ((sl = (TSlave *)next())) {
01978 if (sl->IsValid()) {
01979
01980
01981 sl->Interrupt((Int_t)type);
01982 }
01983 }
01984 }
01985
01986
01987 Int_t TProof::GetParallel() const
01988 {
01989
01990
01991
01992 if (!IsValid()) return -1;
01993
01994
01995 TIter nextSlave(GetListOfActiveSlaves());
01996 Int_t nparallel = 0;
01997 while (TSlave* sl = dynamic_cast<TSlave*>(nextSlave()))
01998 if (sl->GetParallel() >= 0)
01999 nparallel += sl->GetParallel();
02000
02001 return nparallel;
02002 }
02003
02004
02005 TList *TProof::GetListOfSlaveInfos()
02006 {
02007
02008
02009 if (!IsValid()) return 0;
02010
02011 if (fSlaveInfo == 0) {
02012 fSlaveInfo = new TSortedList(kSortDescending);
02013 fSlaveInfo->SetOwner();
02014 } else {
02015 fSlaveInfo->Delete();
02016 }
02017
02018 TList masters;
02019 TIter next(GetListOfSlaves());
02020 TSlave *slave;
02021
02022 while ((slave = (TSlave *) next()) != 0) {
02023 if (slave->GetSlaveType() == TSlave::kSlave) {
02024 const char *name = IsLite() ? gSystem->HostName() : slave->GetName();
02025 TSlaveInfo *slaveinfo = new TSlaveInfo(slave->GetOrdinal(),
02026 name,
02027 slave->GetPerfIdx());
02028 fSlaveInfo->Add(slaveinfo);
02029
02030 TIter nextactive(GetListOfActiveSlaves());
02031 TSlave *activeslave;
02032 while ((activeslave = (TSlave *) nextactive())) {
02033 if (TString(slaveinfo->GetOrdinal()) == activeslave->GetOrdinal()) {
02034 slaveinfo->SetStatus(TSlaveInfo::kActive);
02035 break;
02036 }
02037 }
02038
02039 TIter nextbad(GetListOfBadSlaves());
02040 TSlave *badslave;
02041 while ((badslave = (TSlave *) nextbad())) {
02042 if (TString(slaveinfo->GetOrdinal()) == badslave->GetOrdinal()) {
02043 slaveinfo->SetStatus(TSlaveInfo::kBad);
02044 break;
02045 }
02046 }
02047
02048 if (slave->IsValid()) {
02049 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
02050 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
02051 else
02052 masters.Add(slave);
02053 }
02054
02055 } else if (slave->GetSlaveType() == TSlave::kMaster) {
02056 if (slave->IsValid()) {
02057 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
02058 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
02059 else
02060 masters.Add(slave);
02061 }
02062 } else {
02063 Error("GetSlaveInfo", "TSlave is neither Master nor Slave");
02064 R__ASSERT(0);
02065 }
02066 }
02067 if (masters.GetSize() > 0) Collect(&masters);
02068
02069 return fSlaveInfo;
02070 }
02071
02072
02073 void TProof::Activate(TList *slaves)
02074 {
02075
02076
02077 TMonitor *mon = fAllMonitor;
02078 mon->DeActivateAll();
02079
02080 slaves = !slaves ? fActiveSlaves : slaves;
02081
02082 TIter next(slaves);
02083 TSlave *sl;
02084 while ((sl = (TSlave*) next())) {
02085 if (sl->IsValid())
02086 mon->Activate(sl->GetSocket());
02087 }
02088 }
02089
02090
02091 void TProof::SetMonitor(TMonitor *mon, Bool_t on)
02092 {
02093
02094
02095
02096 TMonitor *m = (mon) ? mon : fCurrentMonitor;
02097 if (m) {
02098 if (on)
02099 m->ActivateAll();
02100 else
02101 m->DeActivateAll();
02102 }
02103 }
02104
02105
02106 Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, TList *workers)
02107 {
02108
02109
02110
02111
02112 if (!IsValid()) return -1;
02113
02114 if (workers->GetSize() == 0) return 0;
02115
02116 int nsent = 0;
02117 TIter next(workers);
02118
02119 TSlave *wrk;
02120 while ((wrk = (TSlave *)next())) {
02121 if (wrk->IsValid()) {
02122 if (wrk->SendGroupPriority(grp, priority) == -1)
02123 MarkBad(wrk, "could not send group priority");
02124 else
02125 nsent++;
02126 }
02127 }
02128
02129 return nsent;
02130 }
02131
02132
02133 Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list)
02134 {
02135
02136
02137
02138
02139 TList *workers = 0;
02140 if (list == kAll) workers = fSlaves;
02141 if (list == kActive) workers = fActiveSlaves;
02142 if (list == kUnique) workers = fUniqueSlaves;
02143 if (list == kAllUnique) workers = fAllUniqueSlaves;
02144
02145 return BroadcastGroupPriority(grp, priority, workers);
02146 }
02147
02148
02149 void TProof::ResetMergePrg()
02150 {
02151
02152
02153 fMergePrg.Reset(fActiveSlaves->GetSize());
02154 }
02155
02156
02157 Int_t TProof::Broadcast(const TMessage &mess, TList *slaves)
02158 {
02159
02160
02161
02162
02163 if (!IsValid()) return -1;
02164
02165 if (!slaves || slaves->GetSize() == 0) return 0;
02166
02167 int nsent = 0;
02168 TIter next(slaves);
02169
02170 TSlave *sl;
02171 while ((sl = (TSlave *)next())) {
02172 if (sl->IsValid()) {
02173 if (sl->GetSocket()->Send(mess) == -1)
02174 MarkBad(sl, "could not broadcast request");
02175 else
02176 nsent++;
02177 }
02178 }
02179
02180 return nsent;
02181 }
02182
02183
02184 Int_t TProof::Broadcast(const TMessage &mess, ESlaves list)
02185 {
02186
02187
02188
02189
02190 TList *slaves = 0;
02191 if (list == kAll) slaves = fSlaves;
02192 if (list == kActive) slaves = fActiveSlaves;
02193 if (list == kUnique) slaves = fUniqueSlaves;
02194 if (list == kAllUnique) slaves = fAllUniqueSlaves;
02195
02196 return Broadcast(mess, slaves);
02197 }
02198
02199
02200 Int_t TProof::Broadcast(const char *str, Int_t kind, TList *slaves)
02201 {
02202
02203
02204
02205
02206 TMessage mess(kind);
02207 if (str) mess.WriteString(str);
02208 return Broadcast(mess, slaves);
02209 }
02210
02211
02212 Int_t TProof::Broadcast(const char *str, Int_t kind, ESlaves list)
02213 {
02214
02215
02216
02217
02218
02219 TMessage mess(kind);
02220 if (str) mess.WriteString(str);
02221 return Broadcast(mess, list);
02222 }
02223
02224
02225 Int_t TProof::BroadcastObject(const TObject *obj, Int_t kind, TList *slaves)
02226 {
02227
02228
02229
02230
02231 TMessage mess(kind);
02232 mess.WriteObject(obj);
02233 return Broadcast(mess, slaves);
02234 }
02235
02236
02237 Int_t TProof::BroadcastObject(const TObject *obj, Int_t kind, ESlaves list)
02238 {
02239
02240
02241
02242
02243 TMessage mess(kind);
02244 mess.WriteObject(obj);
02245 return Broadcast(mess, list);
02246 }
02247
02248
02249 Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, TList *slaves)
02250 {
02251
02252
02253
02254
02255 if (!IsValid()) return -1;
02256
02257 if (slaves->GetSize() == 0) return 0;
02258
02259 int nsent = 0;
02260 TIter next(slaves);
02261
02262 TSlave *sl;
02263 while ((sl = (TSlave *)next())) {
02264 if (sl->IsValid()) {
02265 if (sl->GetSocket()->SendRaw(buffer, length) == -1)
02266 MarkBad(sl, "could not send broadcast-raw request");
02267 else
02268 nsent++;
02269 }
02270 }
02271
02272 return nsent;
02273 }
02274
02275
02276 Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, ESlaves list)
02277 {
02278
02279
02280
02281
02282 TList *slaves = 0;
02283 if (list == kAll) slaves = fSlaves;
02284 if (list == kActive) slaves = fActiveSlaves;
02285 if (list == kUnique) slaves = fUniqueSlaves;
02286 if (list == kAllUnique) slaves = fAllUniqueSlaves;
02287
02288 return BroadcastRaw(buffer, length, slaves);
02289 }
02290
02291
02292 Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, TList *wrks)
02293 {
02294
02295
02296
02297
02298 if (!IsValid()) return -1;
02299
02300 if (wrks->GetSize() == 0) return 0;
02301
02302 int nsent = 0;
02303 TIter next(wrks);
02304
02305 TSlave *wrk;
02306 while ((wrk = (TSlave *)next())) {
02307 if (wrk->IsValid()) {
02308 if (SendFile(file, opt, rfile, wrk) < 0)
02309 Error("BroadcastFile",
02310 "problems sending file to worker %s (%s)",
02311 wrk->GetOrdinal(), wrk->GetName());
02312 else
02313 nsent++;
02314 }
02315 }
02316
02317 return nsent;
02318 }
02319
02320
02321 Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, ESlaves list)
02322 {
02323
02324
02325
02326
02327 TList *wrks = 0;
02328 if (list == kAll) wrks = fSlaves;
02329 if (list == kActive) wrks = fActiveSlaves;
02330 if (list == kUnique) wrks = fUniqueSlaves;
02331 if (list == kAllUnique) wrks = fAllUniqueSlaves;
02332
02333 return BroadcastFile(file, opt, rfile, wrks);
02334 }
02335
02336
02337 void TProof::ReleaseMonitor(TMonitor *mon)
02338 {
02339
02340
02341
02342 if (mon && (mon != fAllMonitor) && (mon != fActiveMonitor)
02343 && (mon != fUniqueMonitor) && (mon != fAllUniqueMonitor)) {
02344 delete mon;
02345 }
02346 }
02347
02348
02349 Int_t TProof::Collect(const TSlave *sl, Long_t timeout, Int_t endtype, Bool_t deactonfail)
02350 {
02351
02352
02353
02354
02355
02356
02357 Int_t rc = 0;
02358
02359 TMonitor *mon = 0;
02360 if (!sl->IsValid()) return 0;
02361
02362 if (fCurrentMonitor == fAllMonitor) {
02363 mon = new TMonitor;
02364 } else {
02365 mon = fAllMonitor;
02366 mon->DeActivateAll();
02367 }
02368 mon->Activate(sl->GetSocket());
02369
02370 rc = Collect(mon, timeout, endtype, deactonfail);
02371 ReleaseMonitor(mon);
02372 return rc;
02373 }
02374
02375
02376 Int_t TProof::Collect(TList *slaves, Long_t timeout, Int_t endtype, Bool_t deactonfail)
02377 {
02378
02379
02380
02381
02382
02383
02384 Int_t rc = 0;
02385
02386 TMonitor *mon = 0;
02387
02388 if (fCurrentMonitor == fAllMonitor) {
02389 mon = new TMonitor;
02390 } else {
02391 mon = fAllMonitor;
02392 mon->DeActivateAll();
02393 }
02394 TIter next(slaves);
02395 TSlave *sl;
02396 while ((sl = (TSlave*) next())) {
02397 if (sl->IsValid())
02398 mon->Activate(sl->GetSocket());
02399 }
02400
02401 rc = Collect(mon, timeout, endtype, deactonfail);
02402 ReleaseMonitor(mon);
02403 return rc;
02404 }
02405
02406
02407 Int_t TProof::Collect(ESlaves list, Long_t timeout, Int_t endtype, Bool_t deactonfail)
02408 {
02409
02410
02411
02412
02413
02414
02415 Int_t rc = 0;
02416 TMonitor *mon = 0;
02417
02418 if (list == kAll) mon = fAllMonitor;
02419 if (list == kActive) mon = fActiveMonitor;
02420 if (list == kUnique) mon = fUniqueMonitor;
02421 if (list == kAllUnique) mon = fAllUniqueMonitor;
02422 if (fCurrentMonitor == mon) {
02423
02424 mon = new TMonitor(*mon);
02425 }
02426 mon->ActivateAll();
02427
02428 rc = Collect(mon, timeout, endtype, deactonfail);
02429 ReleaseMonitor(mon);
02430 return rc;
02431 }
02432
02433
02434 Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deactonfail)
02435 {
02436
02437
02438
02439
02440
02441
02442
02443 fStatus = 0;
02444 fRecvMessages->Clear();
02445
02446 Long_t actto = (Long_t)(gEnv->GetValue("Proof.SocketActivityTimeout", -1) * 1000);
02447
02448 if (!mon->GetActive(actto)) return 0;
02449
02450 DeActivateAsyncInput();
02451
02452
02453 TMonitor *savedMonitor = 0;
02454 if (fCurrentMonitor) {
02455 savedMonitor = fCurrentMonitor;
02456 fCurrentMonitor = mon;
02457 } else {
02458 fCurrentMonitor = mon;
02459 fBytesRead = 0;
02460 fRealTime = 0.0;
02461 fCpuTime = 0.0;
02462 }
02463
02464
02465
02466 Bool_t saveRedirLog = fRedirLog;
02467 if (!IsIdle() && !IsSync())
02468 fRedirLog = kFALSE;
02469
02470 int cnt = 0, rc = 0;
02471
02472
02473 Long_t nto = timeout;
02474 PDB(kCollect, 2)
02475 Info("Collect","active: %d", mon->GetActive());
02476
02477
02478 if (fIntHandler)
02479 fIntHandler->Add();
02480
02481
02482 Int_t nact = 0;
02483 Long_t sto = -1;
02484 Int_t nsto = 60;
02485 mon->ResetInterrupt();
02486 while ((nact = mon->GetActive(sto)) && (nto < 0 || nto > 0)) {
02487
02488
02489 PDB(kCollect, 2) {
02490 if (nact < 4) {
02491 TList *al = mon->GetListOfActives();
02492 if (al && al->GetSize() > 0) {
02493 Info("Collect"," %d node(s) still active:", al->GetSize());
02494 TIter nxs(al);
02495 TSocket *xs = 0;
02496 while ((xs = (TSocket *)nxs())) {
02497 TSlave *wrk = FindSlave(xs);
02498 if (wrk)
02499 Info("Collect"," %s (%s)", wrk->GetName(), wrk->GetOrdinal());
02500 else
02501 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
02502 xs->GetInetAddress().GetPort());
02503 }
02504 }
02505 }
02506 }
02507
02508
02509 TSocket *s = mon->Select(1000);
02510
02511 if (s && s != (TSocket *)(-1)) {
02512
02513 rc = CollectInputFrom(s, endtype, deactonfail);
02514 if (rc == 1 || (rc == 2 && !savedMonitor)) {
02515
02516 mon->DeActivate(s);
02517 PDB(kCollect, 2)
02518 Info("Collect","deactivating %p (active: %d, %p)",
02519 s, mon->GetActive(),
02520 mon->GetListOfActives()->First());
02521 } else if (rc == 2) {
02522
02523
02524 if (savedMonitor) {
02525 savedMonitor->DeActivate(s);
02526 PDB(kCollect, 2)
02527 Info("Collect","save monitor: deactivating %p (active: %d, %p)",
02528 s, savedMonitor->GetActive(),
02529 savedMonitor->GetListOfActives()->First());
02530 }
02531 }
02532
02533
02534 if (rc >= 0)
02535 cnt++;
02536 } else {
02537
02538
02539
02540 if (!s)
02541 if (fPlayer && (fPlayer->GetExitStatus() == TVirtualProofPlayer::kFinished))
02542 mon->DeActivateAll();
02543
02544 if (s == (TSocket *)(-1) && nto > 0)
02545 nto--;
02546 }
02547
02548 sto = -1;
02549 if (--nsto <= 0) {
02550 sto = (Long_t) actto;
02551 nsto = 60;
02552 }
02553 }
02554
02555
02556 if (nto == 0) {
02557 TList *al = mon->GetListOfActives();
02558 if (al && al->GetSize() > 0) {
02559
02560 Info("Collect"," %d node(s) went in timeout:", al->GetSize());
02561 TIter nxs(al);
02562 TSocket *xs = 0;
02563 while ((xs = (TSocket *)nxs())) {
02564 TSlave *wrk = FindSlave(xs);
02565 if (wrk)
02566 Info("Collect"," %s", wrk->GetName());
02567 else
02568 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
02569 xs->GetInetAddress().GetPort());
02570 }
02571 }
02572 mon->DeActivateAll();
02573 }
02574
02575
02576 if (fIntHandler)
02577 fIntHandler->Remove();
02578
02579
02580 SendGroupView();
02581
02582
02583 fRedirLog = saveRedirLog;
02584
02585
02586 fCurrentMonitor = savedMonitor;
02587
02588 ActivateAsyncInput();
02589
02590 return cnt;
02591 }
02592
02593
02594 void TProof::CleanGDirectory(TList *ol)
02595 {
02596
02597
02598 if (ol) {
02599 TIter nxo(ol);
02600 TObject *o = 0;
02601 while ((o = nxo()))
02602 gDirectory->RecursiveRemove(o);
02603 }
02604 }
02605
02606
02607 Int_t TProof::CollectInputFrom(TSocket *s, Int_t endtype, Bool_t deactonfail)
02608 {
02609
02610
02611
02612 TMessage *mess;
02613
02614 Int_t recvrc = 0;
02615 if ((recvrc = s->Recv(mess)) < 0) {
02616 PDB(kCollect,2)
02617 Info("CollectInputFrom","%p: got %d from Recv()", s, recvrc);
02618 Bool_t bad = kTRUE;
02619 if (recvrc == -5) {
02620
02621 if (fCurrentMonitor) fCurrentMonitor->Remove(s);
02622 if (s->Reconnect() == 0) {
02623 if (fCurrentMonitor) fCurrentMonitor->Add(s);
02624 bad = kFALSE;
02625 }
02626 }
02627 if (bad)
02628 MarkBad(s, "problems receiving a message in TProof::CollectInputFrom(...)");
02629
02630 return -1;
02631 }
02632 if (!mess) {
02633
02634 MarkBad(s, "undefined message in TProof::CollectInputFrom(...)");
02635 return -1;
02636 }
02637 Int_t rc = 0;
02638
02639 Int_t what = mess->What();
02640 TSlave *sl = FindSlave(s);
02641 rc = HandleInputMessage(sl, mess, deactonfail);
02642 if (rc == 1 && (endtype >= 0) && (what != endtype))
02643
02644 rc = 2;
02645
02646
02647 return rc;
02648 }
02649
02650
02651 Int_t TProof::HandleInputMessage(TSlave *sl, TMessage *mess, Bool_t deactonfail)
02652 {
02653
02654
02655
02656
02657 char str[512];
02658 TObject *obj;
02659 Int_t rc = 0;
02660
02661 if (!mess || !sl) {
02662 Warning("HandleInputMessage", "given an empty message or undefined worker");
02663 return -1;
02664 }
02665 Bool_t delete_mess = kTRUE;
02666 TSocket *s = sl->GetSocket();
02667 if (!s) {
02668 Warning("HandleInputMessage", "worker socket is undefined");
02669 return -1;
02670 }
02671
02672
02673 Int_t what = mess->What();
02674
02675 PDB(kCollect,3)
02676 Info("HandleInputMessage", "got type %d from '%s'", what, sl->GetOrdinal());
02677
02678 switch (what) {
02679
02680 case kMESS_OK:
02681
02682 fRecvMessages->Add(mess);
02683 delete_mess = kFALSE;
02684 break;
02685
02686 case kMESS_OBJECT:
02687 if (fPlayer) fPlayer->HandleRecvHisto(mess);
02688 break;
02689
02690 case kPROOF_FATAL:
02691 { TString msg;
02692 if ((mess->BufferSize() > mess->Length()))
02693 (*mess) >> msg;
02694 if (msg.IsNull()) {
02695 MarkBad(s, "received kPROOF_FATAL");
02696 } else {
02697 MarkBad(s, msg);
02698 }
02699 }
02700 if (fProgressDialogStarted) {
02701
02702 Emit("StopProcess(Bool_t)", kTRUE);
02703 }
02704 break;
02705
02706 case kPROOF_STOP:
02707
02708 Info("HandleInputMessage", "received kPROOF_STOP from %s: disabling any further collection this worker",
02709 sl->GetOrdinal());
02710 rc = 1;
02711 break;
02712
02713 case kPROOF_GETTREEHEADER:
02714
02715 fRecvMessages->Add(mess);
02716 delete_mess = kFALSE;
02717 rc = 1;
02718 break;
02719
02720 case kPROOF_TOUCH:
02721
02722 {
02723 sl->Touch();
02724 }
02725 break;
02726
02727 case kPROOF_GETOBJECT:
02728
02729 mess->ReadString(str, sizeof(str));
02730 obj = gDirectory->Get(str);
02731 if (obj)
02732 s->SendObject(obj);
02733 else
02734 s->Send(kMESS_NOTOK);
02735 break;
02736
02737 case kPROOF_GETPACKET:
02738 {
02739 TDSetElement *elem = 0;
02740 elem = fPlayer ? fPlayer->GetNextPacket(sl, mess) : 0;
02741
02742 if (elem != (TDSetElement*) -1) {
02743 TMessage answ(kPROOF_GETPACKET);
02744 answ << elem;
02745 s->Send(answ);
02746
02747 while (fWaitingSlaves != 0 && fWaitingSlaves->GetSize()) {
02748 TPair *p = (TPair*) fWaitingSlaves->First();
02749 s = (TSocket*) p->Key();
02750 TMessage *m = (TMessage*) p->Value();
02751
02752 elem = fPlayer ? fPlayer->GetNextPacket(sl, m) : 0;
02753 if (elem != (TDSetElement*) -1) {
02754 TMessage a(kPROOF_GETPACKET);
02755 a << elem;
02756 s->Send(a);
02757
02758
02759
02760 fWaitingSlaves->Remove(fWaitingSlaves->FirstLink());
02761 delete p;
02762 delete m;
02763 } else {
02764 break;
02765 }
02766 }
02767 } else {
02768 if (fWaitingSlaves == 0) fWaitingSlaves = new TList;
02769 fWaitingSlaves->Add(new TPair(s, mess));
02770 delete_mess = kFALSE;
02771 }
02772 }
02773 break;
02774
02775 case kPROOF_LOGFILE:
02776 {
02777 Int_t size;
02778 (*mess) >> size;
02779 PDB(kGlobal,2)
02780 Info("HandleInputMessage","%s: kPROOF_LOGFILE: size: %d", sl->GetOrdinal(), size);
02781 RecvLogFile(s, size);
02782 }
02783 break;
02784
02785 case kPROOF_LOGDONE:
02786 (*mess) >> sl->fStatus >> sl->fParallel;
02787 PDB(kCollect,2)
02788 Info("HandleInputMessage","%s: kPROOF_LOGDONE: status %d parallel %d",
02789 sl->GetOrdinal(), sl->fStatus, sl->fParallel);
02790 if (sl->fStatus != 0) {
02791
02792 fStatus = sl->fStatus;
02793
02794 if (deactonfail) DeactivateWorker(sl->fOrdinal);
02795 }
02796 rc = 1;
02797 break;
02798
02799 case kPROOF_GETSTATS:
02800 {
02801 (*mess) >> sl->fBytesRead >> sl->fRealTime >> sl->fCpuTime
02802 >> sl->fWorkDir >> sl->fProofWorkDir;
02803 TString img;
02804 if ((mess->BufferSize() > mess->Length()))
02805 (*mess) >> img;
02806
02807 if (img.IsNull()) {
02808 if (sl->fImage.IsNull())
02809 sl->fImage = Form("%s:%s", TUrl(sl->fName).GetHostFQDN(),
02810 sl->fProofWorkDir.Data());
02811 } else {
02812 sl->fImage = img;
02813 }
02814 PDB(kGlobal,2)
02815 Info("HandleInputMessage",
02816 "kPROOF_GETSTATS:%s image: %s", sl->GetOrdinal(), sl->GetImage());
02817
02818 fBytesRead += sl->fBytesRead;
02819 fRealTime += sl->fRealTime;
02820 fCpuTime += sl->fCpuTime;
02821 rc = 1;
02822 }
02823 break;
02824
02825 case kPROOF_GETPARALLEL:
02826 {
02827 Bool_t async = kFALSE;
02828 (*mess) >> sl->fParallel;
02829 if ((mess->BufferSize() > mess->Length()))
02830 (*mess) >> async;
02831 rc = (async) ? 0 : 1;
02832 }
02833 break;
02834
02835 case kPROOF_CHECKFILE:
02836 {
02837 if ((mess->BufferSize() > mess->Length())) {
02838 (*mess) >> fCheckFileStatus;
02839 } else {
02840
02841
02842 fCheckFileStatus = 1;
02843 }
02844 rc = 1;
02845 }
02846 break;
02847
02848 case kPROOF_SENDFILE:
02849 {
02850 rc = 1;
02851 }
02852 break;
02853
02854 case kPROOF_PACKAGE_LIST:
02855 {
02856 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PACKAGE_LIST: enter");
02857 Int_t type = 0;
02858 (*mess) >> type;
02859 switch (type) {
02860 case TProof::kListEnabledPackages:
02861 SafeDelete(fEnabledPackages);
02862 fEnabledPackages = (TList *) mess->ReadObject(TList::Class());
02863 if (fEnabledPackages) {
02864 fEnabledPackages->SetOwner();
02865 } else {
02866 Error("HandleInputMessage",
02867 "kPROOF_PACKAGE_LIST: kListEnabledPackages: TList not found in message!");
02868 }
02869 break;
02870 case TProof::kListPackages:
02871 SafeDelete(fAvailablePackages);
02872 fAvailablePackages = (TList *) mess->ReadObject(TList::Class());
02873 if (fAvailablePackages) {
02874 fAvailablePackages->SetOwner();
02875 } else {
02876 Error("HandleInputMessage",
02877 "kPROOF_PACKAGE_LIST: kListPackages: TList not found in message!");
02878 }
02879 break;
02880 default:
02881 Error("HandleInputMessage", "kPROOF_PACKAGE_LIST: unknown type: %d", type);
02882 }
02883 }
02884 break;
02885
02886 case kPROOF_OUTPUTOBJECT:
02887 {
02888 PDB(kGlobal,2)
02889 Info("HandleInputMessage","kPROOF_OUTPUTOBJECT: enter");
02890 Int_t type = 0;
02891 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
02892 if (!TestBit(TProof::kIsClient) && !fMergersSet && !fFinalizationRunning) {
02893 Info("HandleInputMessage", "finalization on %s started ...", prefix);
02894 fFinalizationRunning = kTRUE;
02895 }
02896
02897 while ((mess->BufferSize() > mess->Length())) {
02898 (*mess) >> type;
02899
02900 if (fPlayer) {
02901 if (type == 0) {
02902
02903 TQueryResult *pq =
02904 (TQueryResult *) mess->ReadObject(TQueryResult::Class());
02905 if (pq) {
02906
02907 fPlayer->AddQueryResult(pq);
02908 fPlayer->SetCurrentQuery(pq);
02909
02910 if (fPlayer->GetOutputList())
02911 fPlayer->GetOutputList()->Clear();
02912
02913
02914 fPlayer->AddInput(new TNamed("PROOF_QueryTag",
02915 Form("%s:%s",pq->GetTitle(),pq->GetName())));
02916 } else {
02917 Warning("HandleInputMessage","kPROOF_OUTPUTOBJECT: query result missing");
02918 }
02919 } else if (type > 0) {
02920
02921 TObject *o = mess->ReadObject(TObject::Class());
02922
02923 fMergePrg.IncreaseIdx();
02924 TString msg;
02925 msg.Form("%s: merging output objects ... %s", prefix, fMergePrg.Export());
02926 if (gProofServ)
02927 gProofServ->SendAsynMessage(msg.Data(), kFALSE);
02928 else
02929 fprintf(stderr, "%s\r", msg.Data());
02930
02931 if ((fPlayer->AddOutputObject(o) == 1)) {
02932
02933 SafeDelete(o);
02934 }
02935 if (type > 1) {
02936
02937 fMergePrg.DecreaseNWrks();
02938 if (TestBit(TProof::kIsClient) && !IsLite()) {
02939
02940 TQueryResult *pq = fPlayer->GetCurrentQuery();
02941 pq->SetOutputList(fPlayer->GetOutputList(), kFALSE);
02942
02943 TObject *xo = 0;
02944 TIter nxin(fPlayer->GetInputList());
02945
02946 if (!pq->GetInputList()) pq->SetInputList(new TList());
02947 while ((xo = nxin()))
02948 if (!pq->GetInputList()->FindObject(xo->GetName())) pq->AddInput(xo->Clone());
02949
02950 QueryResultReady(Form("%s:%s", pq->GetTitle(), pq->GetName()));
02951
02952 UpdateDialog();
02953 }
02954 }
02955 }
02956 } else {
02957 Warning("HandleInputMessage", "kPROOF_OUTPUTOBJECT: player undefined!");
02958 }
02959 }
02960 }
02961 break;
02962
02963 case kPROOF_OUTPUTLIST:
02964 {
02965 PDB(kGlobal,2)
02966 Info("HandleInputMessage","%s: kPROOF_OUTPUTLIST: enter", sl->GetOrdinal());
02967 TList *out = 0;
02968 if (fPlayer) {
02969 if (TestBit(TProof::kIsMaster) || fProtocol < 7) {
02970 out = (TList *) mess->ReadObject(TList::Class());
02971 } else {
02972 TQueryResult *pq =
02973 (TQueryResult *) mess->ReadObject(TQueryResult::Class());
02974 if (pq) {
02975
02976 fPlayer->AddQueryResult(pq);
02977 fPlayer->SetCurrentQuery(pq);
02978
02979
02980 out = pq->GetOutputList();
02981 CleanGDirectory(out);
02982 out = (TList *) out->Clone();
02983
02984 QueryResultReady(Form("%s:%s", pq->GetTitle(), pq->GetName()));
02985 } else {
02986 PDB(kGlobal,2)
02987 Info("HandleInputMessage",
02988 "%s: kPROOF_OUTPUTLIST: query result missing", sl->GetOrdinal());
02989 }
02990 }
02991 if (out) {
02992 out->SetOwner();
02993 fPlayer->AddOutput(out);
02994 SafeDelete(out);
02995 } else {
02996 PDB(kGlobal,2)
02997 Info("HandleInputMessage",
02998 "%s: kPROOF_OUTPUTLIST: ouputlist is empty", sl->GetOrdinal());
02999 }
03000 } else {
03001 Warning("HandleInputMessage",
03002 "%s: kPROOF_OUTPUTLIST: player undefined!", sl->GetOrdinal());
03003 }
03004
03005 if (TestBit(TProof::kIsClient) && !IsLite())
03006 UpdateDialog();
03007 }
03008 break;
03009
03010 case kPROOF_QUERYLIST:
03011 {
03012 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYLIST: enter");
03013 (*mess) >> fOtherQueries >> fDrawQueries;
03014 if (fQueries) {
03015 fQueries->Delete();
03016 delete fQueries;
03017 fQueries = 0;
03018 }
03019 fQueries = (TList *) mess->ReadObject(TList::Class());
03020 }
03021 break;
03022
03023 case kPROOF_RETRIEVE:
03024 {
03025 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_RETRIEVE: enter");
03026 TQueryResult *pq =
03027 (TQueryResult *) mess->ReadObject(TQueryResult::Class());
03028 if (pq && fPlayer) {
03029 fPlayer->AddQueryResult(pq);
03030
03031 QueryResultReady(Form("%s:%s", pq->GetTitle(), pq->GetName()));
03032 } else {
03033 PDB(kGlobal,2)
03034 Info("HandleInputMessage","kPROOF_RETRIEVE: query result missing or player undefined");
03035 }
03036 }
03037 break;
03038
03039 case kPROOF_MAXQUERIES:
03040 {
03041 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MAXQUERIES: enter");
03042 Int_t max = 0;
03043
03044 (*mess) >> max;
03045 Printf("Number of queries fully kept remotely: %d", max);
03046 }
03047 break;
03048
03049 case kPROOF_SERVERSTARTED:
03050 {
03051 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SERVERSTARTED: enter");
03052
03053 UInt_t tot = 0, done = 0;
03054 TString action;
03055 Bool_t st = kTRUE;
03056
03057 (*mess) >> action >> tot >> done >> st;
03058
03059 if (TestBit(TProof::kIsClient)) {
03060 if (tot) {
03061 TString type = (action.Contains("submas")) ? "submasters"
03062 : "workers";
03063 Int_t frac = (Int_t) (done*100.)/tot;
03064 char msg[512] = {0};
03065 if (frac >= 100) {
03066 snprintf(msg, 512, "%s: OK (%d %s) \n",
03067 action.Data(),tot, type.Data());
03068 } else {
03069 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
03070 action.Data(), done, tot, frac);
03071 }
03072 if (fSync)
03073 fprintf(stderr,"%s", msg);
03074 else
03075 NotifyLogMsg(msg, 0);
03076 }
03077
03078 StartupMessage(action.Data(), st, (Int_t)done, (Int_t)tot);
03079 } else {
03080
03081
03082 TMessage m(kPROOF_SERVERSTARTED);
03083 m << action << tot << done << st;
03084 gProofServ->GetSocket()->Send(m);
03085 }
03086 }
03087 break;
03088
03089 case kPROOF_DATASET_STATUS:
03090 {
03091 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_DATASET_STATUS: enter");
03092
03093 UInt_t tot = 0, done = 0;
03094 TString action;
03095 Bool_t st = kTRUE;
03096
03097 (*mess) >> action >> tot >> done >> st;
03098
03099 if (TestBit(TProof::kIsClient)) {
03100 if (tot) {
03101 TString type = "files";
03102 Int_t frac = (Int_t) (done*100.)/tot;
03103 char msg[512] = {0};
03104 if (frac >= 100) {
03105 snprintf(msg, 512, "%s: OK (%d %s) \n",
03106 action.Data(),tot, type.Data());
03107 } else {
03108 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
03109 action.Data(), done, tot, frac);
03110 }
03111 if (fSync)
03112 fprintf(stderr,"%s", msg);
03113 else
03114 NotifyLogMsg(msg, 0);
03115 }
03116
03117 DataSetStatus(action.Data(), st, (Int_t)done, (Int_t)tot);
03118 } else {
03119
03120
03121 TMessage m(kPROOF_DATASET_STATUS);
03122 m << action << tot << done << st;
03123 gProofServ->GetSocket()->Send(m);
03124 }
03125 }
03126 break;
03127
03128 case kPROOF_STARTPROCESS:
03129 {
03130 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STARTPROCESS: enter");
03131
03132
03133
03134 if (!IsLite()) {
03135 fNotIdle = 1;
03136 fIsWaiting = kFALSE;
03137 }
03138
03139
03140 fRedirLog = (fSync) ? fRedirLog : kTRUE;
03141
03142
03143
03144
03145 if (!TestBit(TProof::kIsMaster)) {
03146 TString selec;
03147 Int_t dsz = -1;
03148 Long64_t first = -1, nent = -1;
03149 (*mess) >> selec >> dsz >> first >> nent;
03150
03151 if (!gROOT->IsBatch()) {
03152 if (fProgressDialog &&
03153 !TestBit(kUsingSessionGui) && TestBit(kUseProgressDialog)) {
03154 if (!fProgressDialogStarted) {
03155 fProgressDialog->ExecPlugin(5, this,
03156 selec.Data(), dsz, first, nent);
03157 fProgressDialogStarted = kTRUE;
03158 } else {
03159 ResetProgressDialog(selec, dsz, first, nent);
03160 }
03161 }
03162 ResetBit(kUsingSessionGui);
03163 }
03164 }
03165 }
03166 break;
03167
03168 case kPROOF_ENDINIT:
03169 {
03170 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_ENDINIT: enter");
03171
03172 if (TestBit(TProof::kIsMaster)) {
03173 if (fPlayer)
03174 fPlayer->SetInitTime();
03175 }
03176 }
03177 break;
03178
03179 case kPROOF_SETIDLE:
03180 {
03181 PDB(kGlobal,2)
03182 Info("HandleInputMessage","kPROOF_SETIDLE: enter");
03183
03184
03185 if (IsLite()) {
03186 if (fNotIdle > 0) {
03187 fNotIdle--;
03188 } else {
03189 Warning("HandleInputMessage", "got kPROOF_SETIDLE but no running workers ! protocol error?");
03190 }
03191 } else {
03192 fNotIdle = 0;
03193
03194 if ((mess->BufferSize() > mess->Length()))
03195 (*mess) >> fIsWaiting;
03196 }
03197 }
03198 break;
03199
03200 case kPROOF_QUERYSUBMITTED:
03201 {
03202 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYSUBMITTED: enter");
03203
03204
03205 (*mess) >> fSeqNum;
03206 Bool_t sync = fSync;
03207 if ((mess->BufferSize() > mess->Length()))
03208 (*mess) >> sync;
03209 if (sync != fSync && fSync) {
03210
03211 Activate();
03212 fSync = kFALSE;
03213 }
03214 DisableGoAsyn();
03215
03216 fIsWaiting = kTRUE;
03217
03218 if (!IsLite())
03219 fNotIdle = 1;
03220
03221 rc = 1;
03222 }
03223 break;
03224
03225 case kPROOF_SESSIONTAG:
03226 {
03227 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SESSIONTAG: enter");
03228
03229
03230 TString stag;
03231 (*mess) >> stag;
03232 SetName(stag);
03233
03234 sl->SetSessionTag(stag);
03235
03236 if ((mess->BufferSize() > mess->Length()))
03237 (*mess) >> fGroup;
03238 }
03239 break;
03240
03241 case kPROOF_FEEDBACK:
03242 {
03243 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_FEEDBACK: enter");
03244 TList *out = (TList *) mess->ReadObject(TList::Class());
03245 out->SetOwner();
03246 if (fPlayer)
03247 fPlayer->StoreFeedback(sl, out);
03248 else
03249
03250 rc = 1;
03251 }
03252 break;
03253
03254 case kPROOF_AUTOBIN:
03255 {
03256 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_AUTOBIN: enter");
03257
03258 TString name;
03259 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
03260
03261 (*mess) >> name >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax;
03262
03263 if (fPlayer) fPlayer->UpdateAutoBin(name,xmin,xmax,ymin,ymax,zmin,zmax);
03264
03265 TMessage answ(kPROOF_AUTOBIN);
03266
03267 answ << name << xmin << xmax << ymin << ymax << zmin << zmax;
03268
03269 s->Send(answ);
03270 }
03271 break;
03272
03273 case kPROOF_PROGRESS:
03274 {
03275 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PROGRESS: enter");
03276
03277 if (GetRemoteProtocol() > 25) {
03278
03279 TProofProgressInfo *pi = 0;
03280 (*mess) >> pi;
03281 fPlayer->Progress(sl,pi);
03282 } else if (GetRemoteProtocol() > 11) {
03283 Long64_t total, processed, bytesread;
03284 Float_t initTime, procTime, evtrti, mbrti;
03285 (*mess) >> total >> processed >> bytesread
03286 >> initTime >> procTime
03287 >> evtrti >> mbrti;
03288 if (fPlayer)
03289 fPlayer->Progress(sl, total, processed, bytesread,
03290 initTime, procTime, evtrti, mbrti);
03291
03292 } else {
03293
03294 Long64_t total, processed;
03295 (*mess) >> total >> processed;
03296 if (fPlayer)
03297 fPlayer->Progress(sl, total, processed);
03298 }
03299 }
03300 break;
03301
03302 case kPROOF_STOPPROCESS:
03303 {
03304
03305
03306
03307
03308
03309 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STOPPROCESS: enter");
03310
03311 Long64_t events = 0;
03312 Bool_t abort = kFALSE;
03313 TProofProgressStatus *status = 0;
03314
03315 if ((mess->BufferSize() > mess->Length()) && (fProtocol > 18)) {
03316 (*mess) >> status >> abort;
03317 } else if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8)) {
03318 (*mess) >> events >> abort;
03319 } else {
03320 (*mess) >> events;
03321 }
03322 if (!abort && fPlayer) {
03323 if (fProtocol > 18) {
03324 TList *listOfMissingFiles = 0;
03325 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
03326 listOfMissingFiles = new TList();
03327 listOfMissingFiles->SetName("MissingFiles");
03328 if (fPlayer)
03329 fPlayer->AddOutputObject(listOfMissingFiles);
03330 }
03331 if (fPlayer->GetPacketizer()) {
03332 Int_t ret =
03333 fPlayer->GetPacketizer()->AddProcessed(sl, status, 0, &listOfMissingFiles);
03334 if (ret > 0)
03335 fPlayer->GetPacketizer()->MarkBad(sl, status, &listOfMissingFiles);
03336
03337 status = 0;
03338 }
03339 } else {
03340 fPlayer->AddEventsProcessed(events);
03341 }
03342 }
03343 SafeDelete(status);
03344 if (!TestBit(TProof::kIsMaster))
03345 Emit("StopProcess(Bool_t)", abort);
03346 break;
03347 }
03348
03349 case kPROOF_SUBMERGER:
03350 {
03351 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_SUBMERGER: enter");
03352 HandleSubmerger(mess, sl);
03353 }
03354 break;
03355
03356 case kPROOF_GETSLAVEINFO:
03357 {
03358 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_GETSLAVEINFO: enter");
03359
03360 Bool_t active = (GetListOfActiveSlaves()->FindObject(sl) != 0);
03361 Bool_t bad = (GetListOfBadSlaves()->FindObject(sl) != 0);
03362 TList* tmpinfo = 0;
03363 (*mess) >> tmpinfo;
03364 if (tmpinfo == 0) {
03365 Error("HandleInputMessage", "kPROOF_GETSLAVEINFO: no list received!");
03366 } else {
03367 tmpinfo->SetOwner(kFALSE);
03368 Int_t nentries = tmpinfo->GetSize();
03369 for (Int_t i=0; i<nentries; i++) {
03370 TSlaveInfo* slinfo =
03371 dynamic_cast<TSlaveInfo*>(tmpinfo->At(i));
03372 if (slinfo) {
03373
03374 if (IsLite()) slinfo->fHostName = gSystem->HostName();
03375
03376 TIter nxw(fSlaveInfo);
03377 TSlaveInfo *ourwi = 0;
03378 while ((ourwi = (TSlaveInfo *)nxw())) {
03379 if (!strcmp(ourwi->GetOrdinal(), slinfo->GetOrdinal())) {
03380 ourwi->SetSysInfo(slinfo->GetSysInfo());
03381 ourwi->fHostName = slinfo->GetName();
03382 if (slinfo->GetDataDir() && (strlen(slinfo->GetDataDir()) > 0))
03383 ourwi->fDataDir = slinfo->GetDataDir();
03384 break;
03385 }
03386 }
03387 if (!ourwi) {
03388 fSlaveInfo->Add(slinfo);
03389 } else {
03390 slinfo = ourwi;
03391 }
03392 if (slinfo->fStatus != TSlaveInfo::kBad) {
03393 if (!active) slinfo->SetStatus(TSlaveInfo::kNotActive);
03394 if (bad) slinfo->SetStatus(TSlaveInfo::kBad);
03395 }
03396 if (sl->GetMsd() && (strlen(sl->GetMsd()) > 0))
03397 slinfo->fMsd = sl->GetMsd();
03398 }
03399 }
03400 delete tmpinfo;
03401 rc = 1;
03402 }
03403 }
03404 break;
03405
03406 case kPROOF_VALIDATE_DSET:
03407 {
03408 PDB(kGlobal,2)
03409 Info("HandleInputMessage", "kPROOF_VALIDATE_DSET: enter");
03410 TDSet* dset = 0;
03411 (*mess) >> dset;
03412 if (!fDSet)
03413 Error("HandleInputMessage", "kPROOF_VALIDATE_DSET: fDSet not set");
03414 else
03415 fDSet->Validate(dset);
03416 delete dset;
03417 }
03418 break;
03419
03420 case kPROOF_DATA_READY:
03421 {
03422 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_DATA_READY: enter");
03423 Bool_t dataready = kFALSE;
03424 Long64_t totalbytes, bytesready;
03425 (*mess) >> dataready >> totalbytes >> bytesready;
03426 fTotalBytes += totalbytes;
03427 fBytesReady += bytesready;
03428 if (dataready == kFALSE) fDataReady = dataready;
03429 }
03430 break;
03431
03432 case kPROOF_PING:
03433
03434 break;
03435
03436 case kPROOF_MESSAGE:
03437 {
03438 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MESSAGE: enter");
03439
03440
03441 TString msg;
03442 (*mess) >> msg;
03443 Bool_t lfeed = kTRUE;
03444 if ((mess->BufferSize() > mess->Length()))
03445 (*mess) >> lfeed;
03446
03447 if (TestBit(TProof::kIsClient)) {
03448
03449 if (fSync) {
03450
03451 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
03452 } else {
03453
03454 NotifyLogMsg(msg, (lfeed ? "\n" : "\r"));
03455 }
03456 } else {
03457
03458
03459 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
03460 if (gProofServ) {
03461
03462 gProofServ->FlushLogFile();
03463
03464
03465 gProofServ->SendAsynMessage(msg, lfeed);
03466 }
03467 }
03468 }
03469 break;
03470
03471 case kPROOF_VERSARCHCOMP:
03472 {
03473 TString vac;
03474 (*mess) >> vac;
03475 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_VERSARCHCOMP: %s", vac.Data());
03476 Int_t from = 0;
03477 TString vers, archcomp;
03478 if (vac.Tokenize(vers, from, "|"))
03479 vac.Tokenize(archcomp, from, "|");
03480 sl->SetArchCompiler(archcomp);
03481 vers.ReplaceAll(":","|");
03482 sl->SetROOTVersion(vers);
03483 }
03484 break;
03485
03486 default:
03487 {
03488 Error("HandleInputMessage", "unknown command received from '%s' (what = %d)",
03489 sl->GetOrdinal(), what);
03490 }
03491 break;
03492 }
03493
03494
03495 if (delete_mess)
03496 delete mess;
03497
03498
03499 return rc;
03500 }
03501
03502
03503 void TProof::HandleSubmerger(TMessage *mess, TSlave *sl)
03504 {
03505
03506
03507
03508 Int_t type = 0;
03509 (*mess) >> type;
03510 TSocket *s = sl->GetSocket();
03511
03512 switch (type) {
03513 case kOutputSent:
03514 {
03515 if (IsEndMaster()) {
03516 Int_t merger_id = -1;
03517 (*mess) >> merger_id;
03518
03519 PDB(kSubmerger, 2)
03520 Info("HandleSubmerger", "kOutputSent: Worker %s:%d:%s had sent its output to merger #%d",
03521 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), merger_id);
03522
03523 if (!fMergers || fMergers->GetSize() <= merger_id) {
03524 Error("HandleSubmerger", "kOutputSize: #%d not in list ", merger_id);
03525 break;
03526 }
03527 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
03528 mi->SetMergedWorker();
03529 if (mi->AreAllWorkersMerged()) {
03530 mi->Deactivate();
03531 if (GetActiveMergersCount() == 0) {
03532 fMergers->Clear();
03533 delete fMergers;
03534 fMergersSet = kFALSE;
03535 fMergersCount = -1;
03536 fLastAssignedMerger = 0;
03537 PDB(kSubmerger, 2) Info("HandleSubmerger", "all mergers removed ... ");
03538 }
03539 }
03540 } else {
03541 PDB(kSubmerger, 2) Error("HandleSubmerger","kOutputSent: received not on endmaster!");
03542 }
03543 }
03544 break;
03545
03546 case kMergerDown:
03547 {
03548 Int_t merger_id = -1;
03549 (*mess) >> merger_id;
03550
03551 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown: #%d ", merger_id);
03552
03553 if (!fMergers || fMergers->GetSize() <= merger_id) {
03554 Error("HandleSubmerger", "kMergerDown: #%d not in list ", merger_id);
03555 break;
03556 }
03557
03558 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
03559 if (!mi->IsActive()) {
03560 break;
03561 } else {
03562 mi->Deactivate();
03563 }
03564
03565
03566 TMessage stop(kPROOF_SUBMERGER);
03567 stop << Int_t(kStopMerging);
03568 stop << 0;
03569 s->Send(stop);
03570
03571
03572 AskForOutput(mi->GetMerger());
03573
03574
03575 TIter nxo(mi->GetWorkers());
03576 TObject * o = 0;
03577 while ((o = nxo())) {
03578 AskForOutput((TSlave *)o);
03579 }
03580 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown:%d: exit", merger_id);
03581 }
03582 break;
03583
03584 case kOutputSize:
03585 {
03586 if (IsEndMaster()) {
03587 PDB(kSubmerger, 2)
03588 Info("HandleSubmerger", "worker %s reported as finished ", sl->GetOrdinal());
03589
03590 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
03591 if (!fFinalizationRunning) {
03592 Info("HandleSubmerger", "finalization on %s started ...", prefix);
03593 fFinalizationRunning = kTRUE;
03594 }
03595
03596 Int_t output_size = 0;
03597 Int_t merging_port = 0;
03598 (*mess) >> output_size >> merging_port;
03599
03600 PDB(kSubmerger, 2) Info("HandleSubmerger",
03601 "kOutputSize: Worker %s:%d:%s reports %d output objects (+ available port %d)",
03602 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), output_size, merging_port);
03603 TString msg;
03604 if (!fMergersSet) {
03605
03606 Int_t activeWorkers = fCurrentMonitor ? fCurrentMonitor->GetActive() : GetNumberOfActiveSlaves();
03607
03608
03609 fMergersCount = -1;
03610 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
03611 if (mc) fMergersCount = mc->GetVal();
03612
03613
03614 if (fMergersCount < 0 || (fMergersCount > (activeWorkers/2) )) {
03615 msg.Form("%s: Invalid request: cannot start %d mergers for %d workers",
03616 prefix, fMergersCount, activeWorkers);
03617 if (gProofServ)
03618 gProofServ->SendAsynMessage(msg);
03619 else
03620 Printf("%s",msg.Data());
03621 fMergersCount = 0;
03622 }
03623
03624 if (fMergersCount == 0) {
03625 if (activeWorkers > 1) {
03626 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
03627 if (activeWorkers / fMergersCount < 2)
03628 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
03629 }
03630 if (fMergersCount > 1)
03631 msg.Form("%s: Number of mergers set dynamically to %d (for %d workers)",
03632 prefix, fMergersCount, activeWorkers);
03633 else {
03634 msg.Form("%s: No mergers will be used for %d workers",
03635 prefix, activeWorkers);
03636 fMergersCount = -1;
03637 }
03638 if (gProofServ)
03639 gProofServ->SendAsynMessage(msg);
03640 else
03641 Printf("%s",msg.Data());
03642 } else {
03643 msg.Form("%s: Number of mergers set by user to %d (for %d workers)",
03644 prefix, fMergersCount, activeWorkers);
03645 if (gProofServ)
03646 gProofServ->SendAsynMessage(msg);
03647 else
03648 Printf("%s",msg.Data());
03649 }
03650 if (fMergersCount > 0) {
03651
03652 fMergers = new TList();
03653 fLastAssignedMerger = 0;
03654
03655 fWorkersToMerge = (activeWorkers - fMergersCount);
03656
03657 if (!CreateMerger(sl, merging_port)) {
03658
03659 AskForOutput(sl);
03660 fWorkersToMerge--;
03661 fMergersCount--;
03662 }
03663 if (IsLite()) fMergePrg.SetNWrks(fMergersCount);
03664 } else {
03665 AskForOutput(sl);
03666 }
03667 fMergersSet = kTRUE;
03668 } else {
03669
03670 if (fMergersCount == -1) {
03671
03672 AskForOutput(sl);
03673 } else {
03674 if (fRedirectNext > 0 ) {
03675 RedirectWorker(s, sl, output_size);
03676 fRedirectNext--;
03677 } else {
03678 if (fMergersCount > fMergers->GetSize()) {
03679
03680 if (!CreateMerger(sl, merging_port)) {
03681
03682 AskForOutput(sl);
03683 fWorkersToMerge--;
03684 fMergersCount--;
03685 }
03686 } else
03687 RedirectWorker(s, sl, output_size);
03688 }
03689 }
03690 }
03691 } else {
03692 Error("HandleSubMerger","kOutputSize received not on endmaster!");
03693 }
03694 }
03695 break;
03696 }
03697 }
03698
03699
03700 void TProof::RedirectWorker(TSocket *s, TSlave * sl, Int_t output_size)
03701 {
03702
03703
03704 Int_t merger_id = FindNextFreeMerger();
03705 if (merger_id == -1) {
03706
03707 AskForOutput(sl);
03708 } else {
03709 TMessage sendoutput(kPROOF_SUBMERGER);
03710 sendoutput << Int_t(kSendOutput);
03711 PDB(kSubmerger, 2)
03712 Info("RedirectWorker", "redirecting worker %s to merger %d", sl->GetOrdinal(), merger_id);
03713
03714 PDB(kSubmerger, 2) Info("RedirectWorker", "redirecting output to merger #%d", merger_id);
03715 if (!fMergers || fMergers->GetSize() <= merger_id) {
03716 Error("RedirectWorker", "#%d not in list ", merger_id);
03717 return;
03718 }
03719 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
03720
03721 TString hname = (IsLite()) ? "localhost" : mi->GetMerger()->GetName();
03722 sendoutput << merger_id;
03723 sendoutput << hname;
03724 sendoutput << mi->GetPort();
03725 s->Send(sendoutput);
03726 mi->AddMergedObjects(output_size);
03727 mi->AddWorker(sl);
03728 }
03729 }
03730
03731
03732 Int_t TProof::FindNextFreeMerger()
03733 {
03734
03735
03736
03737 while (fLastAssignedMerger < fMergers->GetSize() &&
03738 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
03739 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
03740 fLastAssignedMerger++;
03741 }
03742
03743 if (fLastAssignedMerger == fMergers->GetSize()) {
03744 fLastAssignedMerger = 0;
03745 } else {
03746 return fLastAssignedMerger++;
03747 }
03748
03749 while (fLastAssignedMerger < fMergers->GetSize() &&
03750 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
03751 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
03752 fLastAssignedMerger++;
03753 }
03754
03755 if (fLastAssignedMerger == fMergers->GetSize()) {
03756 return -1;
03757 } else {
03758 return fLastAssignedMerger++;
03759 }
03760 }
03761
03762
03763 void TProof::AskForOutput(TSlave *sl)
03764 {
03765
03766
03767 TMessage sendoutput(kPROOF_SUBMERGER);
03768 sendoutput << Int_t(kSendOutput);
03769
03770 PDB(kSubmerger, 2) Info("AskForOutput",
03771 "worker %s was asked to send its output to master",
03772 sl->GetOrdinal());
03773
03774 sendoutput << -1;
03775 sendoutput << TString("master");
03776 sendoutput << -1;
03777 sl->GetSocket()->Send(sendoutput);
03778 if (IsLite()) fMergePrg.IncreaseNWrks();
03779 }
03780
03781
03782 void TProof::UpdateDialog()
03783 {
03784
03785
03786 if (!fPlayer) return;
03787
03788
03789 if (fPlayer->GetExitStatus() == TVirtualProofPlayer::kAborted) {
03790 if (fSync)
03791 Info("UpdateDialog",
03792 "processing was aborted - %lld events processed",
03793 fPlayer->GetEventsProcessed());
03794
03795 if (GetRemoteProtocol() > 11) {
03796
03797 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
03798 } else {
03799 Progress(-1, fPlayer->GetEventsProcessed());
03800 }
03801 Emit("StopProcess(Bool_t)", kTRUE);
03802 }
03803
03804
03805 if (fPlayer->GetExitStatus() == TVirtualProofPlayer::kStopped) {
03806 if (fSync)
03807 Info("UpdateDialog",
03808 "processing was stopped - %lld events processed",
03809 fPlayer->GetEventsProcessed());
03810
03811 if (GetRemoteProtocol() > 25) {
03812
03813 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1., -1, -1, -1.);
03814 } else if (GetRemoteProtocol() > 11) {
03815 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
03816 } else {
03817 Progress(-1, fPlayer->GetEventsProcessed());
03818 }
03819 Emit("StopProcess(Bool_t)", kFALSE);
03820 }
03821
03822
03823 if (GetRemoteProtocol() > 25) {
03824
03825 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
03826 10, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),(Float_t)(-1.),(Float_t)(-1.),
03827 (Float_t)(-1.),(Float_t)(-1.),(Int_t)(-1),(Int_t)(-1),(Float_t)(-1.));
03828 } else if (GetRemoteProtocol() > 11) {
03829
03830 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
03831 7, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),
03832 (Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.));
03833 } else {
03834 EmitVA("Progress(Long64_t,Long64_t)", 2, (Long64_t)(-1), (Long64_t)(-1));
03835 }
03836 }
03837
03838
03839 void TProof::ActivateAsyncInput()
03840 {
03841
03842
03843 TIter next(fSlaves);
03844 TSlave *sl;
03845
03846 while ((sl = (TSlave*) next()))
03847 if (sl->GetInputHandler())
03848 sl->GetInputHandler()->Add();
03849 }
03850
03851
03852 void TProof::DeActivateAsyncInput()
03853 {
03854
03855
03856 TIter next(fSlaves);
03857 TSlave *sl;
03858
03859 while ((sl = (TSlave*) next()))
03860 if (sl->GetInputHandler())
03861 sl->GetInputHandler()->Remove();
03862 }
03863
03864
03865 Int_t TProof::GetActiveMergersCount()
03866 {
03867
03868
03869 if (!fMergers) return 0;
03870
03871 Int_t active_mergers = 0;
03872
03873 TIter mergers(fMergers);
03874 TMergerInfo *mi = 0;
03875 while ((mi = (TMergerInfo *)mergers())) {
03876 if (mi->IsActive()) active_mergers++;
03877 }
03878
03879 return active_mergers;
03880 }
03881
03882
03883 Bool_t TProof::CreateMerger(TSlave *sl, Int_t port)
03884 {
03885
03886
03887 PDB(kSubmerger, 2)
03888 Info("CreateMerger", "worker %s will be merger ", sl->GetOrdinal());
03889
03890 PDB(kSubmerger, 2) Info("CreateMerger","Begin");
03891
03892 if (port <= 0) {
03893 PDB(kSubmerger,2)
03894 Info("CreateMerger", "cannot create merger on port %d - exit", port);
03895 return kFALSE;
03896 }
03897 Int_t mergersToCreate = fMergersCount - fMergers->GetSize();
03898
03899
03900 Int_t rest = fWorkersToMerge % mergersToCreate;
03901
03902
03903 if (rest > 0 && fMergers->GetSize() < rest) {
03904 rest = 1;
03905 } else {
03906 rest = 0;
03907 }
03908
03909 Int_t workers = (fWorkersToMerge / mergersToCreate) + rest;
03910
03911 TMergerInfo * merger = new TMergerInfo(sl, port, workers);
03912
03913 TMessage bemerger(kPROOF_SUBMERGER);
03914 bemerger << Int_t(kBeMerger);
03915 bemerger << fMergers->GetSize();
03916 bemerger << workers;
03917 sl->GetSocket()->Send(bemerger);
03918
03919 PDB(kSubmerger,2) Info("CreateMerger",
03920 "merger #%d (port: %d) for %d workers started",
03921 fMergers->GetSize(), port, workers);
03922
03923 fMergers->Add(merger);
03924 fWorkersToMerge = fWorkersToMerge - workers;
03925
03926 fRedirectNext = workers / 2;
03927
03928 PDB(kSubmerger, 2) Info("CreateMerger", "exit");
03929 return kTRUE;
03930 }
03931
03932
03933 void TProof::MarkBad(TSlave *wrk, const char *reason)
03934 {
03935
03936
03937
03938
03939 R__LOCKGUARD2(fCloseMutex);
03940
03941
03942
03943 if (!IsValid()) return;
03944
03945 if (!wrk) {
03946 Error("MarkBad", "worker instance undefined: protocol error? ");
03947 return;
03948 }
03949
03950
03951 static TString thisurl;
03952 if (thisurl.IsNull()) {
03953 if (IsMaster()) {
03954 Int_t port = gEnv->GetValue("ProofServ.XpdPort",-1);
03955 thisurl = (port > 0) ? Form("%s:%d", TUrl(gSystem->HostName()).GetHostFQDN(), port)
03956 : TUrl(gSystem->HostName()).GetHostFQDN();
03957 } else {
03958 thisurl = Form("%s@%s:%d", fUrl.GetUser(), fUrl.GetHost(), fUrl.GetPort());
03959 }
03960 }
03961
03962 if (!reason || (strcmp(reason, kPROOF_TerminateWorker) && strcmp(reason, kPROOF_WorkerIdleTO))) {
03963
03964 const char *mastertype = (gProofServ && gProofServ->IsTopMaster()) ? "top master" : "master";
03965 TString src = IsMaster() ? Form("%s at %s", mastertype, thisurl.Data()) : "local session";
03966 TString msg(Form("\n +++ Message from %s : ", src.Data()));
03967 msg += Form("marking %s:%d (%s) as bad\n +++ Reason: %s",
03968 wrk->GetName(), wrk->GetPort(), wrk->GetOrdinal(),
03969 (reason && strlen(reason)) ? reason : "unknown");
03970 Info("MarkBad", "%s", msg.Data());
03971
03972
03973 if (gProofServ) {
03974 msg += Form("\n\n +++ Most likely your code crashed on worker %s at %s:%d.\n",
03975 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
03976 } else {
03977 msg = Form("\n\n +++ Most likely your code crashed\n");
03978 }
03979 msg += Form(" +++ Please check the session logs for error messages either using\n");
03980 msg += Form(" +++ the 'Show logs' button or executing\n");
03981 msg += Form(" +++\n");
03982 if (gProofServ) {
03983 msg += Form(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->Display(\"%s\",0)\n\n",
03984 thisurl.Data(), wrk->GetOrdinal());
03985 gProofServ->SendAsynMessage(msg, kTRUE);
03986 } else {
03987 msg += Form(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->Display(\"*\")\n\n",
03988 thisurl.Data());
03989 Printf("%s", msg.Data());
03990 }
03991 } else if (reason) {
03992 if (gDebug > 0 && strcmp(reason, kPROOF_WorkerIdleTO)) {
03993 Info("MarkBad", "worker %s at %s:%d asked to terminate",
03994 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
03995 }
03996 }
03997
03998 if (IsMaster() && reason) {
03999 if (strcmp(reason, kPROOF_TerminateWorker)) {
04000
04001 TList *listOfMissingFiles = 0;
04002 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
04003 listOfMissingFiles = new TList();
04004 listOfMissingFiles->SetName("MissingFiles");
04005 if (fPlayer)
04006 fPlayer->AddOutputObject(listOfMissingFiles);
04007 }
04008
04009
04010 TVirtualPacketizer *packetizer = fPlayer ? fPlayer->GetPacketizer() : 0;
04011 if (packetizer) {
04012
04013 packetizer->MarkBad(wrk, 0, &listOfMissingFiles);
04014 }
04015 } else {
04016
04017 if (gProofServ) {
04018 TString ord(wrk->GetOrdinal());
04019 Int_t id = ord.Last('.');
04020 if (id != kNPOS) ord.Remove(0, id+1);
04021 gProofServ->ReleaseWorker(ord.Data());
04022 }
04023 }
04024 } else if (TestBit(TProof::kIsClient) && reason && !strcmp(reason, kPROOF_WorkerIdleTO)) {
04025
04026 fValid = kFALSE;
04027 }
04028
04029 fActiveSlaves->Remove(wrk);
04030 FindUniqueSlaves();
04031
04032 fAllMonitor->Remove(wrk->GetSocket());
04033 fActiveMonitor->Remove(wrk->GetSocket());
04034
04035 fSendGroupView = kTRUE;
04036
04037 if (IsMaster()) {
04038 if (reason && !strcmp(reason, kPROOF_TerminateWorker)) {
04039
04040
04041 fSlaves->Remove(wrk);
04042 fBadSlaves->Remove(wrk);
04043 fActiveSlaves->Remove(wrk);
04044 fInactiveSlaves->Remove(wrk);
04045 fUniqueSlaves->Remove(wrk);
04046 fAllUniqueSlaves->Remove(wrk);
04047 fNonUniqueMasters->Remove(wrk);
04048 delete wrk;
04049 } else {
04050 fBadSlaves->Add(wrk);
04051 fActiveSlaves->Remove(wrk);
04052 fUniqueSlaves->Remove(wrk);
04053 fAllUniqueSlaves->Remove(wrk);
04054 fNonUniqueMasters->Remove(wrk);
04055 if (fCurrentMonitor) fCurrentMonitor->DeActivate(wrk->GetSocket());
04056 wrk->Close();
04057
04058 if (fMergersSet) {
04059 Int_t mergersCount = -1;
04060 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
04061 if (mc) mergersCount = mc->GetVal();
04062
04063 if (mergersCount == 0) {
04064 Int_t activeWorkers = fCurrentMonitor ? fCurrentMonitor->GetActive() : GetNumberOfActiveSlaves();
04065 if (activeWorkers > 1) {
04066 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
04067 if (activeWorkers / fMergersCount < 2)
04068 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
04069 }
04070 }
04071 }
04072 }
04073
04074
04075 SaveWorkerInfo();
04076 } else {
04077
04078
04079 fSlaves->Remove(wrk);
04080 if (fManager)
04081 fManager->DiscardSession(this);
04082 }
04083 }
04084
04085
04086 void TProof::MarkBad(TSocket *s, const char *reason)
04087 {
04088
04089
04090
04091 R__LOCKGUARD2(fCloseMutex);
04092
04093
04094 if (!IsValid()) return;
04095
04096 TSlave *wrk = FindSlave(s);
04097 MarkBad(wrk, reason);
04098 }
04099
04100
04101 void TProof::TerminateWorker(TSlave *wrk)
04102 {
04103
04104
04105 if (!wrk) {
04106 Warning("TerminateWorker", "worker instance undefined: protocol error? ");
04107 return;
04108 }
04109
04110
04111 if (wrk->GetSocket() && wrk->GetSocket()->IsValid()) {
04112 TMessage mess(kPROOF_STOP);
04113 wrk->GetSocket()->Send(mess);
04114 } else {
04115 if (gDebug > 0)
04116 Info("TerminateWorker", "connection to worker is already down: cannot"
04117 " send termination message");
04118 }
04119
04120
04121 MarkBad(wrk, kPROOF_TerminateWorker);
04122 }
04123
04124
04125 void TProof::TerminateWorker(const char *ord)
04126 {
04127
04128
04129 if (ord && strlen(ord) > 0) {
04130 Bool_t all = (ord[0] == '*') ? kTRUE : kFALSE;
04131 if (IsMaster()) {
04132 TIter nxw(fSlaves);
04133 TSlave *wrk = 0;
04134 while ((wrk = (TSlave *)nxw())) {
04135 if (all || !strcmp(wrk->GetOrdinal(), ord)) {
04136 TerminateWorker(wrk);
04137 if (!all) break;
04138 }
04139 }
04140 } else {
04141 TMessage mess(kPROOF_STOP);
04142 mess << TString(ord);
04143 Broadcast(mess);
04144 }
04145 }
04146 }
04147
04148
04149 Int_t TProof::Ping()
04150 {
04151
04152
04153 return Ping(kActive);
04154 }
04155
04156
04157 Int_t TProof::Ping(ESlaves list)
04158 {
04159
04160
04161 TList *slaves = 0;
04162 if (list == kAll) slaves = fSlaves;
04163 if (list == kActive) slaves = fActiveSlaves;
04164 if (list == kUnique) slaves = fUniqueSlaves;
04165 if (list == kAllUnique) slaves = fAllUniqueSlaves;
04166
04167 if (slaves->GetSize() == 0) return 0;
04168
04169 int nsent = 0;
04170 TIter next(slaves);
04171
04172 TSlave *sl;
04173 while ((sl = (TSlave *)next())) {
04174 if (sl->IsValid()) {
04175 if (sl->Ping() == -1) {
04176 MarkBad(sl, "ping unsuccessful");
04177 } else {
04178 nsent++;
04179 }
04180 }
04181 }
04182
04183 return nsent;
04184 }
04185
04186
04187 void TProof::Touch()
04188 {
04189
04190
04191 TList *slaves = fSlaves;
04192
04193 if (slaves->GetSize() == 0) return;
04194
04195 TIter next(slaves);
04196
04197 TSlave *sl;
04198 while ((sl = (TSlave *)next())) {
04199 if (sl->IsValid()) {
04200 sl->Touch();
04201 }
04202 }
04203
04204 return;
04205 }
04206
04207
04208 void TProof::Print(Option_t *option) const
04209 {
04210
04211
04212 TString secCont;
04213
04214 if (TestBit(TProof::kIsClient)) {
04215 Printf("Connected to: %s (%s)", GetMaster(),
04216 IsValid() ? "valid" : "invalid");
04217 Printf("Port number: %d", GetPort());
04218 Printf("User: %s", GetUser());
04219 if (gROOT->GetSvnRevision() > 0)
04220 Printf("ROOT version|rev: %s|r%d", gROOT->GetVersion(), gROOT->GetSvnRevision());
04221 else
04222 Printf("ROOT version: %s", gROOT->GetVersion());
04223 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
04224 gSystem->GetBuildCompilerVersion());
04225 TSlave *sl = (TSlave *)fActiveSlaves->First();
04226 if (sl) {
04227 TString sc;
04228 if (sl->GetSocket()->GetSecContext())
04229 Printf("Security context: %s",
04230 sl->GetSocket()->GetSecContext()->AsString(sc));
04231 Printf("Proofd protocol version: %d", sl->GetSocket()->GetRemoteProtocol());
04232 } else {
04233 Printf("Security context: Error - No connection");
04234 Printf("Proofd protocol version: Error - No connection");
04235 }
04236 Printf("Client protocol version: %d", GetClientProtocol());
04237 Printf("Remote protocol version: %d", GetRemoteProtocol());
04238 Printf("Log level: %d", GetLogLevel());
04239 Printf("Session unique tag: %s", IsValid() ? GetSessionTag() : "");
04240 Printf("Default data pool: %s", IsValid() ? GetDataPoolUrl() : "");
04241 if (IsValid())
04242 const_cast<TProof*>(this)->SendPrint(option);
04243 } else {
04244 const_cast<TProof*>(this)->AskStatistics();
04245 if (IsParallel())
04246 Printf("*** Master server %s (parallel mode, %d workers):",
04247 gProofServ->GetOrdinal(), GetParallel());
04248 else
04249 Printf("*** Master server %s (sequential mode):",
04250 gProofServ->GetOrdinal());
04251
04252 Printf("Master host name: %s", gSystem->HostName());
04253 Printf("Port number: %d", GetPort());
04254 if (strlen(gProofServ->GetGroup()) > 0) {
04255 Printf("User/Group: %s/%s", GetUser(), gProofServ->GetGroup());
04256 } else {
04257 Printf("User: %s", GetUser());
04258 }
04259 TString ver(gROOT->GetVersion());
04260 if (gROOT->GetSvnRevision() > 0)
04261 ver += Form("|r%d", gROOT->GetSvnRevision());
04262 if (gSystem->Getenv("ROOTVERSIONTAG"))
04263 ver += Form("|%s", gSystem->Getenv("ROOTVERSIONTAG"));
04264 Printf("ROOT version|rev|tag: %s", ver.Data());
04265 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
04266 gSystem->GetBuildCompilerVersion());
04267 Printf("Protocol version: %d", GetClientProtocol());
04268 Printf("Image name: %s", GetImage());
04269 Printf("Working directory: %s", gSystem->WorkingDirectory());
04270 Printf("Config directory: %s", GetConfDir());
04271 Printf("Config file: %s", GetConfFile());
04272 Printf("Log level: %d", GetLogLevel());
04273 Printf("Number of workers: %d", GetNumberOfSlaves());
04274 Printf("Number of active workers: %d", GetNumberOfActiveSlaves());
04275 Printf("Number of unique workers: %d", GetNumberOfUniqueSlaves());
04276 Printf("Number of inactive workers: %d", GetNumberOfInactiveSlaves());
04277 Printf("Number of bad workers: %d", GetNumberOfBadSlaves());
04278 Printf("Total MB's processed: %.2f", float(GetBytesRead())/(1024*1024));
04279 Printf("Total real time used (s): %.3f", GetRealTime());
04280 Printf("Total CPU time used (s): %.3f", GetCpuTime());
04281 if (TString(option).Contains("a", TString::kIgnoreCase) && GetNumberOfSlaves()) {
04282 Printf("List of workers:");
04283 TList masters;
04284 TIter nextslave(fSlaves);
04285 while (TSlave* sl = dynamic_cast<TSlave*>(nextslave())) {
04286 if (!sl->IsValid()) continue;
04287
04288 if (sl->GetSlaveType() == TSlave::kSlave) {
04289 sl->Print(option);
04290 } else if (sl->GetSlaveType() == TSlave::kMaster) {
04291 TMessage mess(kPROOF_PRINT);
04292 mess.WriteString(option);
04293 if (sl->GetSocket()->Send(mess) == -1)
04294 const_cast<TProof*>(this)->MarkBad(sl, "could not send kPROOF_PRINT request");
04295 else
04296 masters.Add(sl);
04297 } else {
04298 Error("Print", "TSlave is neither Master nor Worker");
04299 R__ASSERT(0);
04300 }
04301 }
04302 const_cast<TProof*>(this)->Collect(&masters, fCollectTimeout);
04303 }
04304 }
04305 }
04306
04307
04308 Long64_t TProof::Process(TDSet *dset, const char *selector, Option_t *option,
04309 Long64_t nentries, Long64_t first)
04310 {
04311
04312
04313
04314
04315
04316
04317 if (!IsValid() || !fPlayer) return -1;
04318
04319
04320 SetRunStatus(TProof::kRunning);
04321
04322
04323 fSync = (GetQueryMode(option) == kSync);
04324
04325 TString opt(option);
04326 if (fSync && (!IsIdle() || IsWaiting())) {
04327
04328 Info("Process", "session is in waiting or processing status: switch to asynchronous mode");
04329 fSync = kFALSE;
04330 opt.ReplaceAll("SYNC","");
04331 opt += "ASYN";
04332 }
04333
04334
04335 if ((IsIdle() && !IsWaiting()) && fRunningDSets && fRunningDSets->GetSize() > 0) {
04336 fRunningDSets->SetOwner(kTRUE);
04337 fRunningDSets->Delete();
04338 }
04339
04340
04341
04342 TSignalHandler *sh = 0;
04343 if (fSync) {
04344 if (gApplication)
04345 sh = gSystem->RemoveSignalHandler(gApplication->GetSignalHandler());
04346 }
04347
04348 Long64_t rv = fPlayer->Process(dset, selector, opt.Data(), nentries, first);
04349
04350 if (fSync) {
04351
04352 if (sh)
04353 gSystem->AddSignalHandler(sh);
04354 }
04355
04356 return rv;
04357 }
04358
04359
04360 Long64_t TProof::Process(TFileCollection *fc, const char *selector,
04361 Option_t *option, Long64_t nentries, Long64_t first)
04362 {
04363
04364
04365
04366
04367
04368
04369 if (!IsValid() || !fPlayer) return -1;
04370
04371 if (fProtocol < 17) {
04372 Info("Process", "server version < 5.18/00:"
04373 " processing of TFileCollection not supported");
04374 return -1;
04375 }
04376
04377
04378
04379 TDSet *dset = new TDSet(Form("TFileCollection:%s", fc->GetName()), 0, 0, "");
04380 fPlayer->AddInput(fc);
04381 Long64_t retval = Process(dset, selector, option, nentries, first);
04382 fPlayer->GetInputList()->Remove(fc);
04383
04384
04385 if (IsLite() && !fSync) {
04386 if (!fRunningDSets) fRunningDSets = new TList;
04387 fRunningDSets->Add(dset);
04388 } else {
04389 delete dset;
04390 }
04391
04392 return retval;
04393 }
04394
04395
04396 Long64_t TProof::Process(const char *dsetname, const char *selector,
04397 Option_t *option, Long64_t nentries,
04398 Long64_t first, TObject *elist)
04399 {
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438
04439
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451 if (fProtocol < 13) {
04452 Info("Process", "processing 'by name' not supported by the server");
04453 return -1;
04454 }
04455
04456 TString dsname, fname(dsetname);
04457
04458
04459
04460
04461
04462 const char *separator = (fname.EndsWith(",")) ? "," : "|";
04463 if (!strcmp(separator, ",") || fname.EndsWith("|")) fname.Remove(fname.Length()-1, 1);
04464 if (!(gSystem->AccessPathName(fname, kReadPermission))) {
04465 TUrl uf(fname, kTRUE);
04466 uf.SetOptions(TString::Format("%sfiletype=raw", uf.GetOptions()));
04467 TFile *f = TFile::Open(uf.GetUrl());
04468 if (f && !(f->IsZombie())) {
04469 const Int_t blen = 8192;
04470 char buf[blen];
04471 Long64_t rest = f->GetSize();
04472 while (rest > 0) {
04473 Long64_t len = (rest > blen - 1) ? blen - 1 : rest;
04474 if (f->ReadBuffer(buf, len)) {
04475 Error("Process", "problems reading from file '%s'", fname.Data());
04476 dsname = "";
04477 break;
04478 }
04479 buf[len] = '\0';
04480 dsname += buf;
04481 rest -= len;
04482 }
04483 f->Close();
04484 SafeDelete(f);
04485
04486 if (rest > 0) return -1;
04487 } else {
04488 Error("Process", "could not open file '%s'", fname.Data());
04489 return -1;
04490 }
04491 }
04492 if (dsname.IsNull()) {
04493 dsname = dsetname;
04494 } else {
04495
04496 if (dsname.EndsWith("\n")) dsname.Remove(dsname.Length()-1, 1);
04497
04498 dsname.ReplaceAll("\n", separator);
04499 if (gDebug > 0) {
04500 Info("Process", "processing multi-dataset read from file '%s':", fname.Data());
04501 Info("Process", " '%s'", dsname.Data());
04502 }
04503 }
04504
04505 TString names(dsname), name, enl, newname;
04506
04507 if (fProtocol < 28 && names.Index(TRegexp("[, |]")) != kNPOS) {
04508 Info("Process", "multi-dataset processing not supported by the server");
04509 return -1;
04510 }
04511
04512 TEntryList *el = 0;
04513 TString dsobj, dsdir;
04514 Int_t from = 0;
04515 while (names.Tokenize(name, from, "[, |]")) {
04516
04517 newname = name;
04518
04519 enl = "";
04520 Int_t ienl = name.Index("?enl=");
04521 if (ienl == kNPOS) {
04522 ienl = name.Index("<<");
04523 if (ienl != kNPOS) {
04524 newname.Remove(ienl);
04525 ienl += strlen("<<");
04526 }
04527 } else {
04528 newname.Remove(ienl);
04529 ienl += strlen("?enl=");
04530 }
04531
04532
04533 TString obj, dir("/");
04534 Int_t idxc = newname.Index("#");
04535 if (idxc != kNPOS) {
04536 Int_t idxs = newname.Index("/", 1, idxc, TString::kExact);
04537 if (idxs != kNPOS) {
04538 obj = newname(idxs+1, newname.Length());
04539 dir = newname(idxc+1, newname.Length());
04540 dir.Remove(dir.Index("/") + 1);
04541 newname.Remove(idxc);
04542 } else {
04543 obj = newname(idxc+1, newname.Length());
04544 newname.Remove(idxc);
04545 }
04546 } else if (newname.Index(":") != kNPOS && newname.Index("://") == kNPOS) {
04547
04548 Error("Process", "bad name syntax (%s): please use"
04549 " a '#' after the dataset name", name.Data());
04550 dsname.ReplaceAll(name, "");
04551 continue;
04552 }
04553 if (dsobj.IsNull() && dsdir.IsNull()) {
04554
04555 dsobj = obj;
04556 dsdir = dir;
04557 } else if (obj != dsobj || dir != dsdir) {
04558
04559 Warning("Process", "'obj' or 'dir' specification not consistent w/ the first given: ignore");
04560 }
04561
04562 if (ienl != kNPOS) {
04563
04564 enl = name(ienl, name.Length());
04565
04566 el = (GetInputList()) ? dynamic_cast<TEntryList *>(GetInputList()->FindObject(enl)) : 0;
04567
04568 if (!el && gDirectory) {
04569 if ((el = dynamic_cast<TEntryList *>(gDirectory->FindObject(enl)))) {
04570
04571
04572 if (fProtocol >= 28) {
04573 if (!(GetInputList()->FindObject(el->GetName()))) AddInput(el);
04574 }
04575 }
04576 }
04577
04578 if (!el) {
04579 if (!gSystem->AccessPathName(enl)) {
04580 TFile *f = TFile::Open(enl);
04581 if (f && !(f->IsZombie()) && f->GetListOfKeys()) {
04582 TIter nxk(f->GetListOfKeys());
04583 TKey *k = 0;
04584 while ((k = (TKey *) nxk())) {
04585 if (!strcmp(k->GetClassName(), "TEntryList")) {
04586 if (!el) {
04587 if ((el = dynamic_cast<TEntryList *>(f->Get(k->GetName())))) {
04588
04589
04590 if (fProtocol >= 28) {
04591 if (!(GetInputList()->FindObject(el->GetName()))) {
04592 el = (TEntryList *) el->Clone();
04593 AddInput(el);
04594 }
04595 } else {
04596 el = (TEntryList *) el->Clone();
04597 }
04598 }
04599 } else if (strcmp(el->GetName(), k->GetName())) {
04600 Warning("Process", "multiple entry lists found in file '%s': the first one is taken;\n"
04601 "if this is not what you want, load first the content in memory"
04602 "and select it by name ", enl.Data());
04603 }
04604 }
04605 }
04606 } else {
04607 Warning("Process","file '%s' cannot be open or is empty - ignoring", enl.Data());
04608 }
04609 }
04610 }
04611
04612 if (fProtocol >= 28) {
04613 newname += "?enl=";
04614 if (el) {
04615
04616 newname += el->GetName();
04617 } else {
04618
04619
04620 newname += enl;
04621 }
04622 }
04623 }
04624
04625 dsname.ReplaceAll(name, newname);
04626 }
04627
04628
04629 TDSet *dset = new TDSet(dsname, dsobj, dsdir);
04630
04631 if (el && fProtocol < 28) {
04632 dset->SetEntryList(el);
04633 } else {
04634 dset->SetEntryList(elist);
04635 }
04636
04637 Long64_t retval = Process(dset, selector, option, nentries, first);
04638
04639 if (IsLite() && !fSync) {
04640 if (!fRunningDSets) fRunningDSets = new TList;
04641 fRunningDSets->Add(dset);
04642 } else {
04643 delete dset;
04644 }
04645 return retval;
04646 }
04647
04648
04649 Long64_t TProof::Process(const char *selector, Long64_t n, Option_t *option)
04650 {
04651
04652
04653
04654
04655
04656 if (!IsValid()) return -1;
04657
04658 if (fProtocol < 16) {
04659 Info("Process", "server version < 5.17/04: generic processing not supported");
04660 return -1;
04661 }
04662
04663
04664 TDSet *dset = new TDSet;
04665 dset->SetBit(TDSet::kEmpty);
04666
04667 Long64_t retval = Process(dset, selector, option, n);
04668
04669
04670 if (IsLite() && !fSync) {
04671 if (!fRunningDSets) fRunningDSets = new TList;
04672 fRunningDSets->Add(dset);
04673 } else {
04674 delete dset;
04675 }
04676 return retval;
04677 }
04678
04679
04680 Int_t TProof::GetQueryReference(Int_t qry, TString &ref)
04681 {
04682
04683
04684
04685 ref = "";
04686 if (qry > 0) {
04687 if (!fQueries)
04688 GetListOfQueries();
04689 if (fQueries) {
04690 TIter nxq(fQueries);
04691 TQueryResult *qr = 0;
04692 while ((qr = (TQueryResult *) nxq()))
04693 if (qr->GetSeqNum() == qry) {
04694 ref = Form("%s:%s", qr->GetTitle(), qr->GetName());
04695 return 0;
04696 }
04697 }
04698 }
04699 return -1;
04700 }
04701
04702
04703 Long64_t TProof::Finalize(Int_t qry, Bool_t force)
04704 {
04705
04706
04707
04708
04709
04710
04711 if (fPlayer) {
04712 if (qry > 0) {
04713 TString ref;
04714 if (GetQueryReference(qry, ref) == 0) {
04715 return Finalize(ref, force);
04716 } else {
04717 Info("Finalize", "query #%d not found", qry);
04718 }
04719 } else {
04720
04721 return Finalize("", force);
04722 }
04723 }
04724 return -1;
04725 }
04726
04727
04728 Long64_t TProof::Finalize(const char *ref, Bool_t force)
04729 {
04730
04731
04732
04733
04734
04735
04736 if (fPlayer) {
04737
04738 TQueryResult *qr = (ref && strlen(ref) > 0) ? fPlayer->GetQueryResult(ref)
04739 : GetQueryResult();
04740 Bool_t retrieve = kFALSE;
04741 TString xref(ref);
04742 if (!qr) {
04743 if (!xref.IsNull()) {
04744 retrieve = kTRUE;
04745 }
04746 } else {
04747 if (qr->IsFinalized()) {
04748 if (force) {
04749 retrieve = kTRUE;
04750 } else {
04751 Info("Finalize","query already finalized:"
04752 " use Finalize(<qry>,kTRUE) to force new retrieval");
04753 qr = 0;
04754 }
04755 } else {
04756 retrieve = kTRUE;
04757 xref.Form("%s:%s", qr->GetTitle(), qr->GetName());
04758 }
04759 }
04760 if (retrieve) {
04761 Retrieve(xref.Data());
04762 qr = fPlayer->GetQueryResult(xref.Data());
04763 }
04764 if (qr)
04765 return fPlayer->Finalize(qr);
04766 }
04767 return -1;
04768 }
04769
04770
04771 Int_t TProof::Retrieve(Int_t qry, const char *path)
04772 {
04773
04774
04775
04776 if (qry > 0) {
04777 TString ref;
04778 if (GetQueryReference(qry, ref) == 0)
04779 return Retrieve(ref, path);
04780 else
04781 Info("Retrieve", "query #%d not found", qry);
04782 } else {
04783 Info("Retrieve","positive argument required - do nothing");
04784 }
04785 return -1;
04786 }
04787
04788
04789 Int_t TProof::Retrieve(const char *ref, const char *path)
04790 {
04791
04792
04793
04794
04795 if (ref) {
04796 TMessage m(kPROOF_RETRIEVE);
04797 m << TString(ref);
04798 Broadcast(m, kActive);
04799 Collect(kActive, fCollectTimeout);
04800
04801
04802 if (path) {
04803
04804
04805 TQueryResult *qr = fPlayer ? fPlayer->GetQueryResult(ref) : 0;
04806
04807 if (qr) {
04808
04809 TFile *farc = TFile::Open(path,"UPDATE");
04810 if (!(farc->IsOpen())) {
04811 Info("Retrieve", "archive file cannot be open (%s)", path);
04812 return 0;
04813 }
04814 farc->cd();
04815
04816
04817 qr->SetArchived(path);
04818
04819
04820 qr->Write();
04821
04822 farc->Close();
04823 SafeDelete(farc);
04824
04825 } else {
04826 Info("Retrieve", "query not found after retrieve");
04827 return -1;
04828 }
04829 }
04830
04831 return 0;
04832 }
04833 return -1;
04834 }
04835
04836
04837 Int_t TProof::Remove(Int_t qry, Bool_t all)
04838 {
04839
04840
04841 if (qry > 0) {
04842 TString ref;
04843 if (GetQueryReference(qry, ref) == 0)
04844 return Remove(ref, all);
04845 else
04846 Info("Remove", "query #%d not found", qry);
04847 } else {
04848 Info("Remove","positive argument required - do nothing");
04849 }
04850 return -1;
04851 }
04852
04853
04854 Int_t TProof::Remove(const char *ref, Bool_t all)
04855 {
04856
04857
04858
04859
04860
04861
04862 if (all) {
04863
04864 if (fPlayer)
04865 fPlayer->RemoveQueryResult(ref);
04866 }
04867
04868 if (IsLite()) return 0;
04869
04870 if (ref) {
04871 TMessage m(kPROOF_REMOVE);
04872 m << TString(ref);
04873 Broadcast(m, kActive);
04874 Collect(kActive, fCollectTimeout);
04875 return 0;
04876 }
04877 return -1;
04878 }
04879
04880
04881 Int_t TProof::Archive(Int_t qry, const char *path)
04882 {
04883
04884
04885 if (qry > 0) {
04886 TString ref;
04887 if (GetQueryReference(qry, ref) == 0)
04888 return Archive(ref, path);
04889 else
04890 Info("Archive", "query #%d not found", qry);
04891 } else {
04892 Info("Archive","positive argument required - do nothing");
04893 }
04894 return -1;
04895 }
04896
04897
04898 Int_t TProof::Archive(const char *ref, const char *path)
04899 {
04900
04901
04902
04903
04904
04905 if (ref) {
04906 TMessage m(kPROOF_ARCHIVE);
04907 m << TString(ref) << TString(path);
04908 Broadcast(m, kActive);
04909 Collect(kActive, fCollectTimeout);
04910 return 0;
04911 }
04912 return -1;
04913 }
04914
04915
04916 Int_t TProof::CleanupSession(const char *sessiontag)
04917 {
04918
04919
04920 if (sessiontag) {
04921 TMessage m(kPROOF_CLEANUPSESSION);
04922 m << TString(sessiontag);
04923 Broadcast(m, kActive);
04924 Collect(kActive, fCollectTimeout);
04925 return 0;
04926 }
04927 return -1;
04928 }
04929
04930
04931 void TProof::SetQueryMode(EQueryMode mode)
04932 {
04933
04934
04935 fQueryMode = mode;
04936
04937 if (gDebug > 0)
04938 Info("SetQueryMode","query mode is set to: %s", fQueryMode == kSync ?
04939 "Sync" : "Async");
04940 }
04941
04942
04943 TProof::EQueryMode TProof::GetQueryMode(Option_t *mode) const
04944 {
04945
04946
04947 EQueryMode qmode = fQueryMode;
04948
04949 if (mode && (strlen(mode) > 0)) {
04950 TString m(mode);
04951 m.ToUpper();
04952 if (m.Contains("ASYN")) {
04953 qmode = kAsync;
04954 } else if (m.Contains("SYNC")) {
04955 qmode = kSync;
04956 }
04957 }
04958
04959 if (gDebug > 0)
04960 Info("GetQueryMode","query mode is set to: %s", qmode == kSync ?
04961 "Sync" : "Async");
04962
04963 return qmode;
04964 }
04965
04966
04967 Long64_t TProof::DrawSelect(TDSet *dset, const char *varexp,
04968 const char *selection, Option_t *option,
04969 Long64_t nentries, Long64_t first)
04970 {
04971
04972
04973
04974
04975
04976 if (!IsValid() || !fPlayer) return -1;
04977
04978
04979 if (!IsIdle()) {
04980 Info("DrawSelect","not idle, asynchronous Draw not supported");
04981 return -1;
04982 }
04983 TString opt(option);
04984 Int_t idx = opt.Index("ASYN", 0, TString::kIgnoreCase);
04985 if (idx != kNPOS)
04986 opt.Replace(idx,4,"");
04987
04988 return fPlayer->DrawSelect(dset, varexp, selection, opt, nentries, first);
04989 }
04990
04991
04992 Long64_t TProof::DrawSelect(const char *dsetname, const char *varexp,
04993 const char *selection, Option_t *option,
04994 Long64_t nentries, Long64_t first, TObject *enl)
04995 {
04996
04997
04998
04999
05000
05001
05002
05003
05004
05005
05006
05007
05008
05009
05010
05011
05012 if (fProtocol < 13) {
05013 Info("Process", "processing 'by name' not supported by the server");
05014 return -1;
05015 }
05016
05017 TString name(dsetname);
05018 TString obj;
05019 TString dir = "/";
05020 Int_t idxc = name.Index("#");
05021 if (idxc != kNPOS) {
05022 Int_t idxs = name.Index("/", 1, idxc, TString::kExact);
05023 if (idxs != kNPOS) {
05024 obj = name(idxs+1, name.Length());
05025 dir = name(idxc+1, name.Length());
05026 dir.Remove(dir.Index("/") + 1);
05027 name.Remove(idxc);
05028 } else {
05029 obj = name(idxc+1, name.Length());
05030 name.Remove(idxc);
05031 }
05032 } else if (name.Index(":") != kNPOS && name.Index("://") == kNPOS) {
05033
05034 Error("DrawSelect", "bad name syntax (%s): please use"
05035 " a '#' after the dataset name", dsetname);
05036 return -1;
05037 }
05038
05039 TDSet *dset = new TDSet(name, obj, dir);
05040
05041 dset->SetEntryList(enl);
05042 Long64_t retval = DrawSelect(dset, varexp, selection, option, nentries, first);
05043 delete dset;
05044 return retval;
05045 }
05046
05047
05048 void TProof::StopProcess(Bool_t abort, Int_t timeout)
05049 {
05050
05051
05052 PDB(kGlobal,2)
05053 Info("StopProcess","enter %d", abort);
05054
05055 if (!IsValid())
05056 return;
05057
05058
05059 ERunStatus rst = abort ? TProof::kAborted : TProof::kStopped;
05060 SetRunStatus(rst);
05061
05062 if (fPlayer)
05063 fPlayer->StopProcess(abort, timeout);
05064
05065
05066
05067 if (TestBit(TProof::kIsClient) || abort)
05068 InterruptCurrentMonitor();
05069
05070 if (fSlaves->GetSize() == 0)
05071 return;
05072
05073
05074 TSlave *sl;
05075 TIter next(fSlaves);
05076 while ((sl = (TSlave *)next()))
05077 if (sl->IsValid())
05078
05079 sl->StopProcess(abort, timeout);
05080 }
05081
05082
05083 void TProof::DisableGoAsyn()
05084 {
05085
05086
05087 Emit("DisableGoAsyn()");
05088 }
05089
05090
05091 void TProof::GoAsynchronous()
05092 {
05093
05094
05095 if (!IsValid()) return;
05096
05097 if (GetRemoteProtocol() < 22) {
05098 Info("GoAsynchronous", "functionality not supported by the server - ignoring");
05099 return;
05100 }
05101
05102 if (fSync && !IsIdle()) {
05103 TMessage m(kPROOF_GOASYNC);
05104 Broadcast(m);
05105 } else {
05106 Info("GoAsynchronous", "either idle or already in asynchronous mode - ignoring");
05107 }
05108 }
05109
05110
05111 void TProof::RecvLogFile(TSocket *s, Int_t size)
05112 {
05113
05114
05115 const Int_t kMAXBUF = 16384;
05116 char buf[kMAXBUF];
05117
05118
05119 Int_t fdout = -1;
05120 if (!fLogToWindowOnly) {
05121 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
05122 if (fdout < 0) {
05123 Warning("RecvLogFile", "file descriptor for outputs undefined (%d):"
05124 " will not log msgs", fdout);
05125 return;
05126 }
05127 lseek(fdout, (off_t) 0, SEEK_END);
05128 }
05129
05130 Int_t left, rec, r;
05131 Long_t filesize = 0;
05132
05133 while (filesize < size) {
05134 left = Int_t(size - filesize);
05135 if (left >= kMAXBUF)
05136 left = kMAXBUF-1;
05137 rec = s->RecvRaw(&buf, left);
05138 filesize = (rec > 0) ? (filesize + rec) : filesize;
05139 if (!fLogToWindowOnly) {
05140 if (rec > 0) {
05141
05142 char *p = buf;
05143 r = rec;
05144 while (r) {
05145 Int_t w;
05146
05147 w = write(fdout, p, r);
05148
05149 if (w < 0) {
05150 SysError("RecvLogFile", "error writing to unit: %d", fdout);
05151 break;
05152 }
05153 r -= w;
05154 p += w;
05155 }
05156 } else if (rec < 0) {
05157 Error("RecvLogFile", "error during receiving log file");
05158 break;
05159 }
05160 }
05161 if (rec > 0) {
05162 buf[rec] = 0;
05163 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
05164 }
05165 }
05166
05167
05168 if (fRedirLog && IsIdle() && !TestBit(TProof::kIsMaster))
05169 fRedirLog = kFALSE;
05170 }
05171
05172
05173 void TProof::NotifyLogMsg(const char *msg, const char *sfx)
05174 {
05175
05176
05177
05178
05179 Int_t len = 0;
05180 if (!msg || (len = strlen(msg)) <= 0)
05181 return;
05182
05183
05184 Int_t lsfx = (sfx) ? strlen(sfx) : 0;
05185
05186
05187 Int_t fdout = -1;
05188 if (!fLogToWindowOnly) {
05189 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
05190 if (fdout < 0) {
05191 Warning("NotifyLogMsg", "file descriptor for outputs undefined (%d):"
05192 " will not notify msgs", fdout);
05193 return;
05194 }
05195 lseek(fdout, (off_t) 0, SEEK_END);
05196 }
05197
05198 if (!fLogToWindowOnly) {
05199
05200 if (len > 0) {
05201 char *p = (char *)msg;
05202 Int_t r = len;
05203 while (r) {
05204 Int_t w = write(fdout, p, r);
05205 if (w < 0) {
05206 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
05207 break;
05208 }
05209 r -= w;
05210 p += w;
05211 }
05212
05213 if (lsfx > 0)
05214 if (write(fdout, sfx, lsfx) != lsfx)
05215 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
05216 }
05217 }
05218 if (len > 0) {
05219
05220
05221 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, kFALSE);
05222 }
05223
05224
05225 if (fRedirLog && IsIdle())
05226 fRedirLog = kFALSE;
05227 }
05228
05229
05230 void TProof::LogMessage(const char *msg, Bool_t all)
05231 {
05232
05233
05234 PDB(kGlobal,1)
05235 Info("LogMessage","Enter ... %s, 'all: %s", msg ? msg : "",
05236 all ? "true" : "false");
05237
05238 if (gROOT->IsBatch()) {
05239 PDB(kGlobal,1) Info("LogMessage","GUI not started - use TProof::ShowLog()");
05240 return;
05241 }
05242
05243 if (msg)
05244 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, all);
05245
05246
05247
05248
05249 if (all)
05250 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
05251
05252 const Int_t kMAXBUF = 32768;
05253 char buf[kMAXBUF];
05254 Int_t len;
05255 do {
05256 while ((len = read(fileno(fLogFileR), buf, kMAXBUF-1)) < 0 &&
05257 TSystem::GetErrno() == EINTR)
05258 TSystem::ResetErrno();
05259
05260 if (len < 0) {
05261 Error("LogMessage", "error reading log file");
05262 break;
05263 }
05264
05265 if (len > 0) {
05266 buf[len] = 0;
05267 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
05268 }
05269
05270 } while (len > 0);
05271 }
05272
05273
05274 Int_t TProof::SendGroupView()
05275 {
05276
05277
05278
05279
05280 if (!IsValid()) return -1;
05281 if (TestBit(TProof::kIsClient)) return 0;
05282 if (!fSendGroupView) return 0;
05283 fSendGroupView = kFALSE;
05284
05285 TIter next(fActiveSlaves);
05286 TSlave *sl;
05287
05288 int bad = 0, cnt = 0, size = GetNumberOfActiveSlaves();
05289 char str[32];
05290
05291 while ((sl = (TSlave *)next())) {
05292 snprintf(str, 32, "%d %d", cnt, size);
05293 if (sl->GetSocket()->Send(str, kPROOF_GROUPVIEW) == -1) {
05294 MarkBad(sl, "could not send kPROOF_GROUPVIEW message");
05295 bad++;
05296 } else
05297 cnt++;
05298 }
05299
05300
05301
05302
05303 if (bad) SendGroupView();
05304
05305 return GetNumberOfActiveSlaves();
05306 }
05307
05308
05309 Bool_t TProof::GetFileInCmd(const char *cmd, TString &fn)
05310 {
05311
05312
05313
05314
05315 TString s = cmd;
05316 s = s.Strip(TString::kBoth);
05317
05318 if (s.Length() > 0 &&
05319 (s.BeginsWith(".L") || s.BeginsWith(".x") || s.BeginsWith(".X"))) {
05320 TString file = s(2, s.Length());
05321 TString acm, arg, io;
05322 fn = gSystem->SplitAclicMode(file, acm, arg, io);
05323 if (!fn.IsNull())
05324 return kTRUE;
05325 }
05326
05327
05328 return kFALSE;
05329 }
05330
05331
05332 Int_t TProof::Exec(const char *cmd, Bool_t plusMaster)
05333 {
05334
05335
05336
05337
05338
05339
05340
05341 return Exec(cmd, kActive, plusMaster);
05342 }
05343
05344
05345 Int_t TProof::Exec(const char *cmd, ESlaves list, Bool_t plusMaster)
05346 {
05347
05348
05349
05350
05351
05352
05353 if (!IsValid()) return -1;
05354
05355 TString s = cmd;
05356 s = s.Strip(TString::kBoth);
05357
05358 if (!s.Length()) return 0;
05359
05360
05361 TString filename;
05362 if (TProof::GetFileInCmd(s.Data(), filename)) {
05363 char *fn = gSystem->Which(TROOT::GetMacroPath(), filename, kReadPermission);
05364 if (fn) {
05365 if (GetNumberOfUniqueSlaves() > 0) {
05366 if (SendFile(fn, kAscii | kForward | kCpBin) < 0) {
05367 Error("Exec", "file %s could not be transfered", fn);
05368 delete [] fn;
05369 return -1;
05370 }
05371 } else {
05372 TString scmd = s(0,3) + fn;
05373 Int_t n = SendCommand(scmd, list);
05374 delete [] fn;
05375 return n;
05376 }
05377 } else {
05378 Error("Exec", "macro %s not found", filename.Data());
05379 return -1;
05380 }
05381 delete [] fn;
05382 }
05383
05384 if (plusMaster) {
05385 if (IsLite()) {
05386 gROOT->ProcessLine(cmd);
05387 } else {
05388 Int_t n = GetParallel();
05389 SetParallelSilent(0);
05390 Int_t res = SendCommand(cmd, list);
05391 SetParallelSilent(n);
05392 if (res < 0)
05393 return res;
05394 }
05395 }
05396 return SendCommand(cmd, list);
05397 }
05398
05399
05400 Int_t TProof::SendCommand(const char *cmd, ESlaves list)
05401 {
05402
05403
05404
05405
05406
05407
05408
05409
05410 if (!IsValid()) return -1;
05411
05412 Broadcast(cmd, kMESS_CINT, list);
05413 Collect(list);
05414
05415 return fStatus;
05416 }
05417
05418
05419 Int_t TProof::SendCurrentState(ESlaves list)
05420 {
05421
05422
05423
05424
05425 if (!IsValid()) return -1;
05426
05427
05428
05429 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
05430
05431 return GetParallel();
05432 }
05433
05434
05435 Int_t TProof::SendInitialState()
05436 {
05437
05438
05439
05440
05441 if (!IsValid()) return -1;
05442
05443 SetLogLevel(fLogLevel, gProofDebugMask);
05444
05445 return GetNumberOfActiveSlaves();
05446 }
05447
05448
05449 Bool_t TProof::CheckFile(const char *file, TSlave *slave, Long_t modtime, Int_t cpopt)
05450 {
05451
05452
05453
05454
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465
05466 Bool_t sendto = kFALSE;
05467
05468
05469 TString sn = slave->GetName();
05470 sn += ":";
05471 sn += slave->GetOrdinal();
05472 sn += ":";
05473 sn += gSystem->BaseName(file);
05474
05475
05476 FileMap_t::const_iterator it;
05477 if ((it = fFileMap.find(sn)) != fFileMap.end()) {
05478
05479 MD5Mod_t md = (*it).second;
05480 if (md.fModtime != modtime) {
05481 TMD5 *md5 = TMD5::FileChecksum(file);
05482 if (md5) {
05483 if ((*md5) != md.fMD5) {
05484 sendto = kTRUE;
05485 md.fMD5 = *md5;
05486 md.fModtime = modtime;
05487 fFileMap[sn] = md;
05488
05489
05490
05491
05492
05493 if (TestBit(TProof::kIsMaster)) {
05494 sendto = kFALSE;
05495 TMessage mess(kPROOF_CHECKFILE);
05496 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
05497 slave->GetSocket()->Send(mess);
05498
05499 fCheckFileStatus = 0;
05500 Collect(slave, fCollectTimeout, kPROOF_CHECKFILE);
05501 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
05502 }
05503 }
05504 delete md5;
05505 } else {
05506 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
05507 return kFALSE;
05508 }
05509 }
05510 } else {
05511
05512 TMD5 *md5 = TMD5::FileChecksum(file);
05513 MD5Mod_t md;
05514 if (md5) {
05515 md.fMD5 = *md5;
05516 md.fModtime = modtime;
05517 fFileMap[sn] = md;
05518 delete md5;
05519 } else {
05520 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
05521 return kFALSE;
05522 }
05523 TMessage mess(kPROOF_CHECKFILE);
05524 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
05525 slave->GetSocket()->Send(mess);
05526
05527 fCheckFileStatus = 0;
05528 Collect(slave, fCollectTimeout, kPROOF_CHECKFILE);
05529 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
05530 }
05531
05532 return sendto;
05533 }
05534
05535
05536 Int_t TProof::SendFile(const char *file, Int_t opt, const char *rfile, TSlave *wrk)
05537 {
05538
05539
05540
05541
05542
05543
05544
05545
05546
05547
05548
05549
05550
05551
05552
05553
05554
05555
05556
05557
05558
05559
05560
05561 if (!IsValid()) return -1;
05562
05563
05564 TList *slaves = (rfile && !strcmp(rfile, "cache")) ? fUniqueSlaves : fActiveSlaves;
05565
05566 if (wrk) {
05567 slaves = new TList();
05568 slaves->Add(wrk);
05569 }
05570
05571 if (slaves->GetSize() == 0) return 0;
05572
05573 #ifndef R__WIN32
05574 Int_t fd = open(file, O_RDONLY);
05575 #else
05576 Int_t fd = open(file, O_RDONLY | O_BINARY);
05577 #endif
05578 if (fd < 0) {
05579 SysError("SendFile", "cannot open file %s", file);
05580 return -1;
05581 }
05582
05583
05584 Long64_t size;
05585 Long_t id, flags, modtime;
05586 if (gSystem->GetPathInfo(file, &id, &size, &flags, &modtime) == 1) {
05587 Error("SendFile", "cannot stat file %s", file);
05588 return -1;
05589 }
05590 if (size == 0) {
05591 Error("SendFile", "empty file %s", file);
05592 return -1;
05593 }
05594
05595
05596 Bool_t bin = (opt & kBinary) ? kTRUE : kFALSE;
05597 Bool_t force = (opt & kForce) ? kTRUE : kFALSE;
05598 Bool_t fw = (opt & kForward) ? kTRUE : kFALSE;
05599
05600
05601 Int_t cpopt = 0;
05602 if ((opt & kCp)) cpopt |= kCp;
05603 if ((opt & kCpBin)) cpopt |= (kCp | kCpBin);
05604
05605 const Int_t kMAXBUF = 32768;
05606 char buf[kMAXBUF];
05607 Int_t nsl = 0;
05608
05609 TIter next(slaves);
05610 TSlave *sl;
05611 TString fnam(rfile);
05612 if (fnam == "cache") {
05613 fnam += Form(":%s", gSystem->BaseName(file));
05614 } else if (fnam.IsNull()) {
05615 fnam = gSystem->BaseName(file);
05616 }
05617
05618 while ((sl = (TSlave *)next())) {
05619 if (!sl->IsValid())
05620 continue;
05621
05622 Bool_t sendto = force ? kTRUE : CheckFile(file, sl, modtime, cpopt);
05623
05624
05625
05626 PDB(kPackage,2) {
05627 const char *snd = (sl->fSlaveType == TSlave::kSlave && sendto) ? "" : "not";
05628 Info("SendFile", "%s sending file %s to: %s:%s (%d)", snd,
05629 file, sl->GetName(), sl->GetOrdinal(), sendto);
05630 }
05631 if (sl->fSlaveType == TSlave::kSlave && !sendto)
05632 continue;
05633
05634
05635 Long64_t siz = sendto ? size : 0;
05636 snprintf(buf, kMAXBUF, "%s %d %lld %d", fnam.Data(), bin, siz, fw);
05637 if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
05638 MarkBad(sl, "could not send kPROOF_SENDFILE request");
05639 continue;
05640 }
05641
05642 if (sendto) {
05643
05644 lseek(fd, 0, SEEK_SET);
05645
05646 Int_t len;
05647 do {
05648 while ((len = read(fd, buf, kMAXBUF)) < 0 && TSystem::GetErrno() == EINTR)
05649 TSystem::ResetErrno();
05650
05651 if (len < 0) {
05652 SysError("SendFile", "error reading from file %s", file);
05653 Interrupt(kSoftInterrupt, kActive);
05654 close(fd);
05655 return -1;
05656 }
05657
05658 if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
05659 SysError("SendFile", "error writing to slave %s:%s (now offline)",
05660 sl->GetName(), sl->GetOrdinal());
05661 MarkBad(sl, "sendraw failure");
05662 sl = 0;
05663 break;
05664 }
05665
05666 } while (len > 0);
05667
05668 nsl++;
05669 }
05670
05671 if (sl)
05672 Collect(sl, fCollectTimeout, kPROOF_SENDFILE);
05673 }
05674
05675 close(fd);
05676
05677
05678 if (slaves != fActiveSlaves && slaves != fUniqueSlaves)
05679 SafeDelete(slaves);
05680
05681 return nsl;
05682 }
05683
05684
05685 Int_t TProof::SendObject(const TObject *obj, ESlaves list)
05686 {
05687
05688
05689
05690 if (!IsValid() || !obj) return -1;
05691
05692 TMessage mess(kMESS_OBJECT);
05693
05694 mess.WriteObject(obj);
05695 return Broadcast(mess, list);
05696 }
05697
05698
05699 Int_t TProof::SendPrint(Option_t *option)
05700 {
05701
05702
05703
05704 if (!IsValid()) return -1;
05705
05706 Broadcast(option, kPROOF_PRINT, kActive);
05707 return Collect(kActive, fCollectTimeout);
05708 }
05709
05710
05711 void TProof::SetLogLevel(Int_t level, UInt_t mask)
05712 {
05713
05714
05715 char str[32];
05716 fLogLevel = level;
05717 gProofDebugLevel = level;
05718 gProofDebugMask = (TProofDebug::EProofDebugMask) mask;
05719 snprintf(str, 32, "%d %u", level, mask);
05720 Broadcast(str, kPROOF_LOGLEVEL, kAll);
05721 }
05722
05723
05724 void TProof::SetRealTimeLog(Bool_t on)
05725 {
05726
05727
05728
05729
05730
05731
05732 if (IsValid()) {
05733 TMessage mess(kPROOF_REALTIMELOG);
05734 mess << on;
05735 Broadcast(mess);
05736 } else {
05737 Warning("SetRealTimeLog","session is invalid - do nothing");
05738 }
05739 }
05740
05741
05742 Int_t TProof::SetParallelSilent(Int_t nodes, Bool_t random)
05743 {
05744
05745
05746
05747
05748 if (!IsValid()) return -1;
05749
05750 if (TestBit(TProof::kIsMaster)) {
05751 GoParallel(nodes, kFALSE, random);
05752 return SendCurrentState();
05753 } else {
05754 PDB(kGlobal,1) Info("SetParallelSilent", "request %d node%s", nodes,
05755 nodes == 1 ? "" : "s");
05756 TMessage mess(kPROOF_PARALLEL);
05757 mess << nodes << random;
05758 Broadcast(mess);
05759 Collect(kActive, fCollectTimeout);
05760 Int_t n = GetParallel();
05761 PDB(kGlobal,1) Info("SetParallelSilent", "got %d node%s", n, n == 1 ? "" : "s");
05762 return n;
05763 }
05764 }
05765
05766
05767 Int_t TProof::SetParallel(Int_t nodes, Bool_t random)
05768 {
05769
05770
05771
05772 Int_t n = SetParallelSilent(nodes, random);
05773 if (TestBit(TProof::kIsClient)) {
05774 if (n < 1) {
05775 Printf("PROOF set to sequential mode");
05776 } else {
05777 TString subfix = (n == 1) ? "" : "s";
05778 if (random)
05779 subfix += ", randomly selected";
05780 Printf("PROOF set to parallel mode (%d worker%s)", n, subfix.Data());
05781 }
05782 }
05783 return n;
05784 }
05785
05786
05787 Int_t TProof::GoParallel(Int_t nodes, Bool_t attach, Bool_t random)
05788 {
05789
05790
05791
05792
05793
05794
05795
05796 if (!IsValid()) return -1;
05797
05798 if (nodes < 0) nodes = 0;
05799
05800 fActiveSlaves->Clear();
05801 fActiveMonitor->RemoveAll();
05802
05803
05804
05805 TSlave *sl = 0;
05806 TList *wlst = new TList;
05807 TIter nxt(fSlaves);
05808 fInactiveSlaves->Clear();
05809 while ((sl = (TSlave *)nxt())) {
05810 if (sl->IsValid() && !fBadSlaves->FindObject(sl)) {
05811 if (strcmp("IGNORE", sl->GetImage()) == 0) continue;
05812 if ((sl->GetSlaveType() != TSlave::kSlave) &&
05813 (sl->GetSlaveType() != TSlave::kMaster)) {
05814 Error("GoParallel", "TSlave is neither Master nor Slave");
05815 R__ASSERT(0);
05816 }
05817
05818 wlst->Add(sl);
05819
05820 fInactiveSlaves->Add(sl);
05821 sl->SetStatus(TSlave::kInactive);
05822 }
05823 }
05824 Int_t nwrks = (nodes > wlst->GetSize()) ? wlst->GetSize() : nodes;
05825 int cnt = 0;
05826 fEndMaster = TestBit(TProof::kIsMaster) ? kTRUE : kFALSE;
05827 while (cnt < nwrks) {
05828
05829 if (random) {
05830 Int_t iwrk = (Int_t) (gRandom->Rndm() * wlst->GetSize());
05831 sl = (TSlave *) wlst->At(iwrk);
05832 } else {
05833
05834 sl = (TSlave *) wlst->First();
05835 }
05836 if (!sl) {
05837 Error("GoParallel", "attaching to candidate!");
05838 break;
05839 }
05840
05841 wlst->Remove(sl);
05842
05843 Int_t slavenodes = 0;
05844 if (sl->GetSlaveType() == TSlave::kSlave) {
05845 sl->SetStatus(TSlave::kActive);
05846 fActiveSlaves->Add(sl);
05847 fInactiveSlaves->Remove(sl);
05848 fActiveMonitor->Add(sl->GetSocket());
05849 slavenodes = 1;
05850 } else if (sl->GetSlaveType() == TSlave::kMaster) {
05851 fEndMaster = kFALSE;
05852 TMessage mess(kPROOF_PARALLEL);
05853 if (!attach) {
05854 mess << nodes-cnt;
05855 } else {
05856
05857 mess.SetWhat(kPROOF_LOGFILE);
05858 mess << -1 << -1;
05859 }
05860 if (sl->GetSocket()->Send(mess) == -1) {
05861 MarkBad(sl, "could not send kPROOF_PARALLEL or kPROOF_LOGFILE request");
05862 slavenodes = 0;
05863 } else {
05864 Collect(sl, fCollectTimeout);
05865 if (sl->IsValid()) {
05866 sl->SetStatus(TSlave::kActive);
05867 fActiveSlaves->Add(sl);
05868 fInactiveSlaves->Remove(sl);
05869 fActiveMonitor->Add(sl->GetSocket());
05870 if (sl->GetParallel() > 0) {
05871 slavenodes = sl->GetParallel();
05872 } else {
05873
05874 slavenodes = 1;
05875 }
05876 } else {
05877 MarkBad(sl, "collect failed after kPROOF_PARALLEL or kPROOF_LOGFILE request");
05878 slavenodes = 0;
05879 }
05880 }
05881 }
05882
05883 cnt += slavenodes;
05884 }
05885
05886
05887 wlst->SetOwner(0);
05888 SafeDelete(wlst);
05889
05890
05891 AskStatistics();
05892
05893
05894 FindUniqueSlaves();
05895
05896
05897 if (!attach)
05898 SendGroupView();
05899
05900 Int_t n = GetParallel();
05901
05902 if (TestBit(TProof::kIsClient)) {
05903 if (n < 1)
05904 printf("PROOF set to sequential mode\n");
05905 else
05906 printf("PROOF set to parallel mode (%d worker%s)\n",
05907 n, n == 1 ? "" : "s");
05908 }
05909
05910 PDB(kGlobal,1) Info("GoParallel", "got %d node%s", n, n == 1 ? "" : "s");
05911 return n;
05912 }
05913
05914
05915 void TProof::ShowData()
05916 {
05917
05918
05919
05920 if (!IsValid() || !fManager) return;
05921
05922
05923 fManager->Find("~/data", "-type f", "all");
05924 }
05925
05926
05927 void TProof::ClearData(UInt_t what, const char *dsname)
05928 {
05929
05930
05931
05932
05933
05934
05935
05936 if (!IsValid() || !fManager) return;
05937
05938
05939 TString prompt, a("Y");
05940 Bool_t force = (what & kForceClear) ? kTRUE : kFALSE;
05941 Bool_t doask = (!force && isatty(0) != 0 && isatty(1) != 0) ? kTRUE : kFALSE;
05942
05943
05944 if ((what & TProof::kPurge)) {
05945
05946 if (doask && !Prompt("Do you really want to remove all data files")) return;
05947 if (fManager->Rm("~/data/*", "-rf", "all") < 0)
05948 Warning("ClearData", "problems purging data directory");
05949 return;
05950 } else if ((what & TProof::kDataset)) {
05951
05952 if (!dsname || strlen(dsname) <= 0) {
05953 Error("ClearData", "dataset name mandatory when removing a full dataset");
05954 return;
05955 }
05956
05957 if (!ExistsDataSet(dsname)) {
05958 Error("ClearData", "dataset '%s' does not exists", dsname);
05959 return;
05960 }
05961
05962 TFileCollection *fc = GetDataSet(dsname);
05963 if (!fc) {
05964 Error("ClearData", "could not retrieve info about dataset '%s'", dsname);
05965 return;
05966 }
05967
05968 if (doask && !Prompt(TString::Format("Do you really want to remove all data files"
05969 " of dataset '%s'", dsname))) return;
05970
05971 Bool_t rmds = kTRUE;
05972 TIter nxf(fc->GetList());
05973 TFileInfo *fi = 0;
05974 Int_t rfiles = 0, nfiles = fc->GetList()->GetSize();
05975 while ((fi = (TFileInfo *) nxf())) {
05976
05977 TString host, file;
05978
05979 TUrl uf(*(fi->GetFirstUrl()));
05980 file = uf.GetFile();
05981 host = uf.GetHost();
05982
05983 Int_t nurl = fi->GetNUrls();
05984 fi->ResetUrl();
05985 TUrl *up = 0;
05986 while (nurl-- && fi->NextUrl()) {
05987 up = fi->GetCurrentUrl();
05988 if (!strcmp(up->GetProtocol(), "file")) {
05989 TString opt(up->GetOptions());
05990 if (opt.BeginsWith("node=")) {
05991 host=opt;
05992 host.ReplaceAll("node=","");
05993 file = up->GetFile();
05994 break;
05995 }
05996 }
05997 }
05998
05999 if (fManager->Rm(file.Data(), "-f", host.Data()) != 0) {
06000 Error("ClearData", "problems removing '%s'", file.Data());
06001
06002 rmds = kFALSE;
06003 }
06004 rfiles++;
06005 ClearDataProgress(rfiles, nfiles);
06006 }
06007 fprintf(stderr, "\n");
06008 if (rmds) {
06009
06010 RemoveDataSet(dsname);
06011 }
06012 } else if (what & TProof::kUnregistered) {
06013
06014
06015 TString outtmp("ProofClearData_");
06016 FILE *ftmp = gSystem->TempFileName(outtmp);
06017 if (!ftmp) {
06018 Error("ClearData", "cannot create temp file for logs");
06019 return;
06020 }
06021 fclose(ftmp);
06022 RedirectHandle_t h;
06023 gSystem->RedirectOutput(outtmp.Data(), "w", &h);
06024 ShowData();
06025 gSystem->RedirectOutput(0, 0, &h);
06026
06027 ifstream in;
06028 in.open(outtmp.Data());
06029 if (!in.is_open()) {
06030 Error("ClearData", "could not open temp file for logs: %s", outtmp.Data());
06031 gSystem->Unlink(outtmp);
06032 return;
06033 }
06034
06035 Int_t nfiles = 0;
06036 TMap *afmap = new TMap;
06037 TString line, host, file;
06038 Int_t from = 0;
06039 while (in.good()) {
06040 line.ReadLine(in);
06041 if (line.IsNull()) continue;
06042 while (line.EndsWith("\n")) { line.Strip(TString::kTrailing, '\n'); }
06043 from = 0;
06044 if (line.Tokenize(host, from, "| ")) line.Tokenize(file, from, "| ");
06045 if (!host.IsNull() && !file.IsNull()) {
06046 TList *fl = (TList *) afmap->GetValue(host.Data());
06047 if (!fl) {
06048 fl = new TList();
06049 fl->SetName(host);
06050 afmap->Add(new TObjString(host), fl);
06051 }
06052 fl->Add(new TObjString(file));
06053 nfiles++;
06054 PDB(kDataset,2)
06055 Info("ClearData", "added info for: h:%s, f:%s", host.Data(), file.Data());
06056 } else {
06057 Warning("ClearData", "found incomplete line: '%s'", line.Data());
06058 }
06059 }
06060
06061 in.close();
06062 gSystem->Unlink(outtmp);
06063
06064
06065 TString sel = TString::Format("/%s/%s/", GetGroup(), GetUser());
06066 TMap *fcmap = GetDataSets(sel);
06067 if (!fcmap || (fcmap && fcmap->GetSize() <= 0)) {
06068 PDB(kDataset,1)
06069 Warning("ClearData", "no dataset beloning to '%s'", sel.Data());
06070 SafeDelete(fcmap);
06071 }
06072
06073
06074 TString opt;
06075 TObjString *os = 0;
06076 if (fcmap) {
06077 TIter nxfc(fcmap);
06078 while ((os = (TObjString *) nxfc())) {
06079 TFileCollection *fc = 0;
06080 if ((fc = (TFileCollection *) fcmap->GetValue(os))) {
06081 TFileInfo *fi = 0;
06082 TIter nxfi(fc->GetList());
06083 while ((fi = (TFileInfo *) nxfi())) {
06084
06085 fi->ResetUrl();
06086 Int_t nurl = fi->GetNUrls();
06087 TUrl *up = 0;
06088 while (nurl-- && fi->NextUrl()) {
06089 up = fi->GetCurrentUrl();
06090 if (!strcmp(up->GetProtocol(), "file")) {
06091 opt = up->GetOptions();
06092 if (opt.BeginsWith("node=")) {
06093 host=opt;
06094 host.ReplaceAll("node=","");
06095 file = up->GetFile();
06096 PDB(kDataset,2)
06097 Info("ClearData", "found: host: %s, file: %s", host.Data(), file.Data());
06098
06099 TList *fl = (TList *) afmap->GetValue(host.Data());
06100 if (fl) {
06101 TObjString *fn = (TObjString *) fl->FindObject(file.Data());
06102 if (fn) {
06103 fl->Remove(fn);
06104 SafeDelete(fn);
06105 nfiles--;
06106 } else {
06107 Warning("ClearData",
06108 "registered file '%s' not found in the full list!", file.Data());
06109 }
06110 }
06111 break;
06112 }
06113 }
06114 }
06115 }
06116 }
06117 }
06118
06119 if (fcmap) fcmap->SetOwner(kTRUE);
06120 SafeDelete(fcmap);
06121 }
06122
06123 Info("ClearData", "%d unregistered files to be removed:", nfiles);
06124 afmap->Print();
06125
06126 if (doask && !Prompt(TString::Format("Do you really want to remove all %d"
06127 " unregistered data files", nfiles))) return;
06128
06129 Int_t rfiles = 0;
06130 TIter nxls(afmap);
06131 while ((os = (TObjString *) nxls())) {
06132 TList *fl = 0;
06133 if ((fl = (TList *) afmap->GetValue(os))) {
06134 TIter nxf(fl);
06135 TObjString *fn = 0;
06136 while ((fn = (TObjString *) nxf())) {
06137
06138 if (fManager->Rm(fn->GetName(), "-f", os->GetName()) != 0) {
06139 Error("ClearData", "problems removing '%s' on host '%s'", fn->GetName(), os->GetName());
06140 }
06141 rfiles++;
06142 ClearDataProgress(rfiles, nfiles);
06143 }
06144 }
06145 }
06146 fprintf(stderr, "\n");
06147
06148 afmap->SetOwner(kTRUE);
06149 SafeDelete(afmap);
06150 }
06151 }
06152
06153
06154 Bool_t TProof::Prompt(const char *p)
06155 {
06156
06157
06158
06159 TString pp(p);
06160 if (!pp.Contains("?")) pp += "?";
06161 if (!pp.Contains("[y/N]")) pp += " [y/N]";
06162 TString a = Getline(pp.Data());
06163 if (a != "\n" && a[0] != 'y' && a[0] != 'Y' && a[0] != 'n' && a[0] != 'N') {
06164 Printf("Please answer y, Y, n or N");
06165
06166 return kFALSE;
06167 } else if (a == "\n" || a[0] == 'n' || a[0] == 'N') {
06168
06169 return kFALSE;
06170 }
06171
06172 return kTRUE;
06173 }
06174
06175
06176 void TProof::ClearDataProgress(Int_t r, Int_t t)
06177 {
06178
06179
06180 fprintf(stderr, "[TProof::ClearData] Total %5d files\t|", t);
06181 for (Int_t l = 0; l < 20; l++) {
06182 if (r > 0 && t > 0) {
06183 if (l < 20*r/t)
06184 fprintf(stderr, "=");
06185 else if (l == 20*r/t)
06186 fprintf(stderr, ">");
06187 else if (l > 20*r/t)
06188 fprintf(stderr, ".");
06189 } else
06190 fprintf(stderr, "=");
06191 }
06192 fprintf(stderr, "| %.02f %% \r", 100.0*(t ? (r/t) : 1));
06193 }
06194
06195
06196 void TProof::ShowCache(Bool_t all)
06197 {
06198
06199
06200
06201 if (!IsValid()) return;
06202
06203 TMessage mess(kPROOF_CACHE);
06204 mess << Int_t(kShowCache) << all;
06205 Broadcast(mess, kUnique);
06206
06207 if (all) {
06208 TMessage mess2(kPROOF_CACHE);
06209 mess2 << Int_t(kShowSubCache) << all;
06210 Broadcast(mess2, fNonUniqueMasters);
06211
06212 Collect(kAllUnique, fCollectTimeout);
06213 } else {
06214 Collect(kUnique, fCollectTimeout);
06215 }
06216 }
06217
06218
06219 void TProof::ClearCache(const char *file)
06220 {
06221
06222
06223
06224 if (!IsValid()) return;
06225
06226 TMessage mess(kPROOF_CACHE);
06227 mess << Int_t(kClearCache) << TString(file);
06228 Broadcast(mess, kUnique);
06229
06230 TMessage mess2(kPROOF_CACHE);
06231 mess2 << Int_t(kClearSubCache) << TString(file);
06232 Broadcast(mess2, fNonUniqueMasters);
06233
06234 Collect(kAllUnique);
06235
06236
06237 fFileMap.clear();
06238 }
06239
06240
06241 void TProof::SystemCmd(const char *cmd, Int_t fdout)
06242 {
06243
06244
06245 if (fdout < 0) {
06246
06247 gSystem->Exec(cmd);
06248 } else {
06249
06250 FILE *fin = gSystem->OpenPipe(cmd, "r");
06251 if (fin) {
06252
06253 char line[2048];
06254 while (fgets(line, 2048, fin)) {
06255 Int_t r = strlen(line);
06256 if (r > 0) {
06257 if (write(fdout, line, r) < 0) {
06258 ::Warning("TProof::SystemCmd",
06259 "errno %d writing to file descriptor %d",
06260 TSystem::GetErrno(), fdout);
06261 }
06262 } else {
06263
06264 break;
06265 }
06266 }
06267 gSystem->ClosePipe(fin);
06268 }
06269 }
06270 }
06271
06272
06273 void TProof::ShowPackages(Bool_t all, Bool_t redirlog)
06274 {
06275
06276
06277
06278
06279
06280 if (!IsValid()) return;
06281
06282 Bool_t oldredir = fRedirLog;
06283 if (redirlog) fRedirLog = kTRUE;
06284
06285
06286 FILE *fout = (fRedirLog) ? fLogFileW : stdout;
06287 if (!fout) {
06288 Warning("ShowPackages", "file descriptor for outputs undefined (%p):"
06289 " will not log msgs", fout);
06290 return;
06291 }
06292 lseek(fileno(fout), (off_t) 0, SEEK_END);
06293
06294 if (TestBit(TProof::kIsClient)) {
06295 if (fGlobalPackageDirList && fGlobalPackageDirList->GetSize() > 0) {
06296
06297 TIter nxd(fGlobalPackageDirList);
06298 TNamed *nm = 0;
06299 while ((nm = (TNamed *)nxd())) {
06300 fprintf(fout, "*** Global Package cache %s client:%s ***\n",
06301 nm->GetName(), nm->GetTitle());
06302 fflush(fout);
06303 SystemCmd(Form("%s %s", kLS, nm->GetTitle()), fileno(fout));
06304 fprintf(fout, "\n");
06305 fflush(fout);
06306 }
06307 }
06308 fprintf(fout, "*** Package cache client:%s ***\n", fPackageDir.Data());
06309 fflush(fout);
06310 SystemCmd(Form("%s %s", kLS, fPackageDir.Data()), fileno(fout));
06311 fprintf(fout, "\n");
06312 }
06313
06314
06315 if (IsLite()) {
06316 fRedirLog = oldredir;
06317 return;
06318 }
06319
06320 TMessage mess(kPROOF_CACHE);
06321 mess << Int_t(kShowPackages) << all;
06322 Broadcast(mess, kUnique);
06323
06324 if (all) {
06325 TMessage mess2(kPROOF_CACHE);
06326 mess2 << Int_t(kShowSubPackages) << all;
06327 Broadcast(mess2, fNonUniqueMasters);
06328
06329 Collect(kAllUnique, fCollectTimeout);
06330 } else {
06331 Collect(kUnique, fCollectTimeout);
06332 }
06333
06334 fRedirLog = oldredir;
06335 }
06336
06337
06338 void TProof::ShowEnabledPackages(Bool_t all)
06339 {
06340
06341
06342
06343
06344 if (!IsValid()) return;
06345
06346 if (TestBit(TProof::kIsClient)) {
06347 printf("*** Enabled packages on client on %s\n", gSystem->HostName());
06348 TIter next(fEnabledPackagesOnClient);
06349 while (TObjString *str = (TObjString*) next())
06350 printf("%s\n", str->GetName());
06351 }
06352
06353
06354 if (IsLite()) return;
06355
06356 TMessage mess(kPROOF_CACHE);
06357 mess << Int_t(kShowEnabledPackages) << all;
06358 Broadcast(mess);
06359 Collect(kActive, fCollectTimeout);
06360 }
06361
06362
06363 Int_t TProof::ClearPackages()
06364 {
06365
06366
06367
06368 if (!IsValid()) return -1;
06369
06370 if (UnloadPackages() == -1)
06371 return -1;
06372
06373 if (DisablePackages() == -1)
06374 return -1;
06375
06376 return fStatus;
06377 }
06378
06379
06380 Int_t TProof::ClearPackage(const char *package)
06381 {
06382
06383
06384
06385 if (!IsValid()) return -1;
06386
06387 if (!package || !strlen(package)) {
06388 Error("ClearPackage", "need to specify a package name");
06389 return -1;
06390 }
06391
06392
06393 TString pac = package;
06394 if (pac.EndsWith(".par"))
06395 pac.Remove(pac.Length()-4);
06396 pac = gSystem->BaseName(pac);
06397
06398 if (UnloadPackage(pac) == -1)
06399 return -1;
06400
06401 if (DisablePackage(pac) == -1)
06402 return -1;
06403
06404 return fStatus;
06405 }
06406
06407
06408 Int_t TProof::DisablePackage(const char *package)
06409 {
06410
06411
06412
06413 if (!IsValid()) return -1;
06414
06415 if (!package || !strlen(package)) {
06416 Error("DisablePackage", "need to specify a package name");
06417 return -1;
06418 }
06419
06420
06421 TString pac = package;
06422 if (pac.EndsWith(".par"))
06423 pac.Remove(pac.Length()-4);
06424 pac = gSystem->BaseName(pac);
06425
06426 if (DisablePackageOnClient(pac) == -1)
06427 return -1;
06428
06429
06430 if (IsLite()) return 0;
06431
06432 Int_t st = -1;
06433 Bool_t done = kFALSE;
06434 if (fManager) {
06435
06436 TString path;
06437 path.Form("~/packages/%s", package);
06438 if (fManager->Rm(path, "-rf", "all") != -1) {
06439 path.Append(".par");
06440 if (fManager->Rm(path, "-f", "all") != -1) {
06441 done = kTRUE;
06442 st = 0;
06443 }
06444 }
06445 }
06446 if (!done) {
06447
06448 TMessage mess(kPROOF_CACHE);
06449 mess << Int_t(kDisablePackage) << pac;
06450 Broadcast(mess, kUnique);
06451
06452 TMessage mess2(kPROOF_CACHE);
06453 mess2 << Int_t(kDisableSubPackage) << pac;
06454 Broadcast(mess2, fNonUniqueMasters);
06455
06456 Collect(kAllUnique);
06457 st = fStatus;
06458 }
06459
06460
06461 return st;
06462 }
06463
06464
06465 Int_t TProof::DisablePackageOnClient(const char *package)
06466 {
06467
06468
06469
06470 if (TestBit(TProof::kIsClient)) {
06471
06472 fPackageLock->Lock();
06473 gSystem->Exec(Form("%s %s/%s", kRM, fPackageDir.Data(), package));
06474 gSystem->Exec(Form("%s %s/%s.par", kRM, fPackageDir.Data(), package));
06475 gSystem->Exec(Form("%s %s/%s/%s.par", kRM, fPackageDir.Data(), kPROOF_PackDownloadDir, package));
06476 fPackageLock->Unlock();
06477 if (!gSystem->AccessPathName(Form("%s/%s/%s.par", fPackageDir.Data(), kPROOF_PackDownloadDir, package)))
06478 Warning("DisablePackageOnClient", "unable to remove cached package PAR file for %s", package);
06479 if (!gSystem->AccessPathName(Form("%s/%s.par", fPackageDir.Data(), package)))
06480 Warning("DisablePackageOnClient", "unable to remove package PAR file for %s", package);
06481 if (!gSystem->AccessPathName(Form("%s/%s", fPackageDir.Data(), package)))
06482 Warning("DisablePackageOnClient", "unable to remove package directory for %s", package);
06483 }
06484
06485 return 0;
06486 }
06487
06488
06489 Int_t TProof::DisablePackages()
06490 {
06491
06492
06493
06494 if (!IsValid()) return -1;
06495
06496
06497 if (TestBit(TProof::kIsClient)) {
06498 fPackageLock->Lock();
06499 gSystem->Exec(Form("%s %s/*", kRM, fPackageDir.Data()));
06500 fPackageLock->Unlock();
06501 }
06502
06503
06504 if (IsLite()) return 0;
06505
06506 TMessage mess(kPROOF_CACHE);
06507 mess << Int_t(kDisablePackages);
06508 Broadcast(mess, kUnique);
06509
06510 TMessage mess2(kPROOF_CACHE);
06511 mess2 << Int_t(kDisableSubPackages);
06512 Broadcast(mess2, fNonUniqueMasters);
06513
06514 Collect(kAllUnique);
06515
06516 return fStatus;
06517 }
06518
06519
06520 Int_t TProof::BuildPackage(const char *package, EBuildPackageOpt opt)
06521 {
06522
06523
06524
06525
06526
06527
06528
06529
06530
06531 if (!IsValid()) return -1;
06532
06533 if (!package || !strlen(package)) {
06534 Error("BuildPackage", "need to specify a package name");
06535 return -1;
06536 }
06537
06538
06539 TString pac = package;
06540 if (pac.EndsWith(".par"))
06541 pac.Remove(pac.Length()-4);
06542 pac = gSystem->BaseName(pac);
06543
06544 Bool_t buildOnClient = kTRUE;
06545 if (opt == kDontBuildOnClient) {
06546 buildOnClient = kFALSE;
06547 opt = kBuildAll;
06548 }
06549
06550 TString pdir;
06551 Int_t st = 0;
06552 if (buildOnClient) {
06553 if (TestBit(TProof::kIsClient) && fPackageLock) fPackageLock->Lock();
06554 if ((st = BuildPackageOnClient(pac, 1, &pdir) != 0)) {
06555 if (TestBit(TProof::kIsClient) && fPackageLock) fPackageLock->Unlock();
06556 return -1;
06557 }
06558 }
06559
06560 if (opt <= kBuildAll && (!IsLite() || !buildOnClient)) {
06561 TMessage mess(kPROOF_CACHE);
06562 mess << Int_t(kBuildPackage) << pac;
06563 Broadcast(mess, kUnique);
06564
06565 TMessage mess2(kPROOF_CACHE);
06566 mess2 << Int_t(kBuildSubPackage) << pac;
06567 Broadcast(mess2, fNonUniqueMasters);
06568 }
06569
06570 if (opt >= kBuildAll) {
06571
06572
06573 if (buildOnClient) {
06574 st = BuildPackageOnClient(pac, 2, &pdir);
06575 if (TestBit(TProof::kIsClient) && fPackageLock) fPackageLock->Unlock();
06576 }
06577
06578 fStatus = 0;
06579 if (!IsLite() || !buildOnClient)
06580 Collect(kAllUnique);
06581
06582 if (fStatus < 0 || st < 0)
06583 return -1;
06584 }
06585
06586 return 0;
06587 }
06588
06589
06590 Int_t TProof::BuildPackageOnClient(const char *pack, Int_t opt, TString *path)
06591 {
06592
06593
06594
06595
06596
06597
06598
06599
06600
06601
06602
06603 TString downloaddir;
06604 downloaddir.Form("%s/%s", fPackageDir.Data(), kPROOF_PackDownloadDir);
06605
06606 if (opt != 0 && !path) {
06607 Error("BuildPackageOnClient", "for opt=%d != 0 'patyh' must be defined", opt);
06608 return -1;
06609 }
06610
06611 if (TestBit(TProof::kIsClient)) {
06612 Int_t status = 0;
06613 TString pdir, ocwd;
06614
06615 if (opt == 0 || opt == 1) {
06616
06617 pdir.Form("%s/%s", fPackageDir.Data(), pack);
06618 if (gSystem->AccessPathName(pdir, kReadPermission) ||
06619 gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission)) {
06620 pdir = "";
06621
06622 if (fGlobalPackageDirList && fGlobalPackageDirList->GetSize() > 0) {
06623
06624 TIter nxd(fGlobalPackageDirList);
06625 TNamed *nm = 0;
06626 while ((nm = (TNamed *)nxd())) {
06627 pdir = Form("%s/%s", nm->GetTitle(), pack);
06628 if (!gSystem->AccessPathName(pdir, kReadPermission) &&
06629 !gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission)) {
06630
06631 break;
06632 }
06633 pdir = "";
06634 }
06635 }
06636 } else {
06637
06638
06639
06640 TString tpar(pdir);
06641 if (!tpar.EndsWith(".par")) tpar += ".par";
06642 Bool_t badPAR = kTRUE;
06643 FileStat_t stpar;
06644 if (gSystem->GetPathInfo(tpar, stpar) == 0) {
06645 #ifndef WIN32
06646 char ctmp[1024];
06647 if (!R_ISLNK(stpar.fMode) || readlink(tpar.Data(), ctmp, 1024) > 0) {
06648
06649 badPAR = kFALSE;
06650 }
06651 #else
06652
06653 badPAR = kFALSE;
06654 #endif
06655 }
06656
06657 if (badPAR) {
06658
06659 gSystem->Exec(Form("%s %s", kRM, pdir.Data()));
06660
06661 gSystem->Exec(Form("%s %s", kRM, tpar.Data()));
06662
06663 pdir = "";
06664 }
06665 }
06666
06667 Bool_t wasDownloaded = kFALSE;
06668 TString dlpar;
06669 dlpar.Form("%s/%s", downloaddir.Data(), gSystem->BaseName(pack));
06670 if (!dlpar.EndsWith(".par")) dlpar += ".par";
06671 if (!pdir.IsNull()) {
06672 if (!gSystem->AccessPathName(dlpar, kFileExists))
06673 wasDownloaded = kTRUE;
06674 }
06675 if (pdir.IsNull() || wasDownloaded) {
06676
06677 if (DownloadPackage(pack, downloaddir) != 0) {
06678 Error("BuildPackageOnClient",
06679 "PAR file '%s.par' not found and could not be downloaded", pack);
06680 return -1;
06681 } else {
06682 TMD5 *md5 = TMD5::FileChecksum(dlpar);
06683 if (UploadPackageOnClient(dlpar, kUntar, md5) == -1) {
06684 Error("BuildPackageOnClient",
06685 "PAR file '%s.par' not found and could not be unpacked locally", pack);
06686 delete md5;
06687 return -1;
06688 }
06689 delete md5;
06690
06691 pdir.Form("%s/%s", fPackageDir.Data(), pack);
06692 }
06693 } else if (pdir.IsNull()) {
06694 Error("BuildPackageOnClient", "PAR file '%s.par' not found", pack);
06695 return -1;
06696 }
06697 PDB(kPackage, 1)
06698 Info("BuildPackageOnClient", "package %s exists and has PROOF-INF directory", pack);
06699
06700 if (opt == 1) {
06701 *path = pdir;
06702 return 0;
06703 }
06704 }
06705
06706 if (opt == 0 || opt == 2) {
06707 if (opt == 2) pdir = path->Data();
06708
06709 ocwd = gSystem->WorkingDirectory();
06710 gSystem->ChangeDirectory(pdir);
06711
06712
06713 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
06714
06715
06716
06717 Bool_t savever = kFALSE;
06718 Int_t rev = -1;
06719 TString v;
06720 FILE *f = fopen("PROOF-INF/proofvers.txt", "r");
06721 if (f) {
06722 TString r;
06723 v.Gets(f);
06724 r.Gets(f);
06725 rev = (!r.IsNull() && r.IsDigit()) ? r.Atoi() : -1;
06726 fclose(f);
06727 }
06728 if (!f || v != gROOT->GetVersion() ||
06729 (gROOT->GetSvnRevision() > 0 && rev != gROOT->GetSvnRevision())) {
06730 savever = kTRUE;
06731 Info("BuildPackageOnClient",
06732 "%s: version change (current: %s:%d, build: %s:%d): cleaning ... ",
06733 pack, gROOT->GetVersion(), gROOT->GetSvnRevision(), v.Data(), rev);
06734
06735 gSystem->ChangeDirectory(fPackageDir);
06736
06737 gSystem->Exec(Form("%s %s", kRM, pdir.Data()));
06738
06739 char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP, kExecutePermission);
06740 if (gunzip) {
06741 TString par = Form("%s.par", pdir.Data());
06742
06743 TString cmd(Form(kUNTAR3, gunzip, par.Data()));
06744 status = gSystem->Exec(cmd);
06745 if ((status = gSystem->Exec(cmd))) {
06746 Error("BuildPackageOnClient", "failure executing: %s", cmd.Data());
06747 } else {
06748
06749 gSystem->ChangeDirectory(pdir);
06750 }
06751 delete [] gunzip;
06752 } else {
06753 Error("BuildPackageOnClient", "%s not found", kGUNZIP);
06754 status = -1;
06755 }
06756 }
06757
06758 if (gSystem->Exec("export ROOTPROOFCLIENT=\"1\" ; PROOF-INF/BUILD.sh")) {
06759 Error("BuildPackageOnClient", "building package %s on the client failed", pack);
06760 status = -1;
06761 }
06762
06763 if (savever && !status) {
06764 f = fopen("PROOF-INF/proofvers.txt", "w");
06765 if (f) {
06766 fputs(gROOT->GetVersion(), f);
06767 fputs(Form("\n%d",gROOT->GetSvnRevision()), f);
06768 fclose(f);
06769 }
06770 }
06771 } else {
06772 PDB(kPackage, 1)
06773 Info("BuildPackageOnClient",
06774 "package %s exists but has no PROOF-INF/BUILD.sh script", pack);
06775 }
06776
06777 gSystem->ChangeDirectory(ocwd);
06778
06779 return status;
06780 }
06781 }
06782 return 0;
06783 }
06784
06785
06786 Int_t TProof::LoadPackage(const char *package, Bool_t notOnClient, TList *loadopts)
06787 {
06788
06789
06790
06791
06792
06793
06794
06795
06796 if (!IsValid()) return -1;
06797
06798 if (!package || !strlen(package)) {
06799 Error("LoadPackage", "need to specify a package name");
06800 return -1;
06801 }
06802
06803
06804 TString pac = package;
06805 if (pac.EndsWith(".par"))
06806 pac.Remove(pac.Length()-4);
06807 pac = gSystem->BaseName(pac);
06808
06809 if (!notOnClient)
06810 if (LoadPackageOnClient(pac, loadopts) == -1)
06811 return -1;
06812
06813 TMessage mess(kPROOF_CACHE);
06814 mess << Int_t(kLoadPackage) << pac;
06815 if (loadopts) mess << loadopts;
06816 Broadcast(mess);
06817
06818 Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
06819 Collect(kActive, -1, -1, deactivateOnFailure);
06820
06821 return fStatus;
06822 }
06823
06824
06825 Int_t TProof::LoadPackageOnClient(const char *pack, TList *loadopts)
06826 {
06827
06828
06829
06830
06831
06832
06833
06834
06835
06836 if (TestBit(TProof::kIsClient)) {
06837 Int_t status = 0;
06838 TString pdir, ocwd;
06839
06840 if (fEnabledPackagesOnClient->FindObject(pack)) {
06841 Info("LoadPackageOnClient", "package %s already loaded", pack);
06842 return 0;
06843 }
06844
06845
06846 pdir.Form("%s/%s", fPackageDir.Data(), pack);
06847
06848 if (gSystem->AccessPathName(pdir, kReadPermission)) {
06849
06850 if (fGlobalPackageDirList && fGlobalPackageDirList->GetSize() > 0) {
06851
06852 TIter nxd(fGlobalPackageDirList);
06853 TNamed *nm = 0;
06854 while ((nm = (TNamed *)nxd())) {
06855 pdir = Form("%s/%s", nm->GetTitle(), pack);
06856 if (!gSystem->AccessPathName(pdir, kReadPermission)) {
06857
06858 break;
06859 }
06860 pdir = "";
06861 }
06862 if (pdir.Length() <= 0) {
06863
06864 Error("LoadPackageOnClient", "failure locating %s ...", pack);
06865 return -1;
06866 }
06867 }
06868 }
06869
06870 ocwd = gSystem->WorkingDirectory();
06871 gSystem->ChangeDirectory(pdir);
06872
06873
06874 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
06875
06876
06877 TString setup, setupfn;
06878 setup.Form("SETUP_%x", TString(pack).Hash());
06879 setupfn.Form("%s/%s.C", gSystem->TempDirectory(), setup.Data());
06880 TMacro setupmc("PROOF-INF/SETUP.C");
06881 TObjString *setupline = setupmc.GetLineWith("SETUP(");
06882 if (setupline) {
06883 TString setupstring(setupline->GetString());
06884 setupstring.ReplaceAll("SETUP(", TString::Format("%s(", setup.Data()));
06885 setupline->SetString(setupstring);
06886 } else {
06887
06888 Warning("LoadPackageOnClient", "macro '%s/PROOF-INF/SETUP.C' does not contain a SETUP()"
06889 " function", pack);
06890 }
06891 setupmc.SaveSource(setupfn.Data());
06892
06893 if (gROOT->LoadMacro(setupfn.Data()) != 0) {
06894
06895 Error("LoadPackageOnClient", "macro '%s/PROOF-INF/SETUP.C' could not be loaded:"
06896 " cannot continue", pack);
06897 status = -1;
06898 } else {
06899
06900 TFunction *fun = (TFunction *) gROOT->GetListOfGlobalFunctions()->FindObject(setup);
06901 if (!fun) {
06902
06903 Error("LoadPackageOnClient", "function SETUP() not found in macro '%s/PROOF-INF/SETUP.C':"
06904 " cannot continue", pack);
06905 status = -1;
06906 } else {
06907 TMethodCall callEnv;
06908
06909 if (fun->GetNargs() == 0) {
06910
06911 callEnv.InitWithPrototype(setup,"");
06912
06913 if (loadopts)
06914 Warning("LoadPackageOnClient", "loaded SETUP() does not take any argument:"
06915 " the specified TList object will be ignored");
06916 } else if (fun->GetNargs() == 1) {
06917 TMethodArg *arg = (TMethodArg *) fun->GetListOfMethodArgs()->First();
06918 if (arg) {
06919
06920 TString argsig(arg->GetTitle());
06921 if (argsig.BeginsWith("TList")) {
06922 callEnv.InitWithPrototype(setup,"TList *");
06923 callEnv.ResetParam();
06924 callEnv.SetParam((Long_t) loadopts);
06925 } else if (argsig.BeginsWith("const char")) {
06926 callEnv.InitWithPrototype(setup,"const char *");
06927 callEnv.ResetParam();
06928 TObjString *os = loadopts ? dynamic_cast<TObjString *>(loadopts->First()) : 0;
06929 if (os) {
06930 callEnv.SetParam((Long_t) os->GetName());
06931 } else {
06932 if (loadopts && loadopts->First()) {
06933 Warning("LoadPackageOnClient", "found object argument of type %s:"
06934 " SETUP expects 'const char *': ignoring",
06935 loadopts->First()->ClassName());
06936 }
06937 callEnv.SetParam((Long_t) 0);
06938 }
06939 } else {
06940
06941 Error("LoadPackageOnClient", "unsupported SETUP signature: SETUP(%s)"
06942 " cannot continue", arg->GetTitle());
06943 status = -1;
06944 }
06945 } else {
06946
06947 Error("LoadPackageOnClient", "cannot get information about the SETUP() argument:"
06948 " cannot continue");
06949 status = -1;
06950 }
06951 } else if (fun->GetNargs() > 1) {
06952
06953 Error("LoadPackageOnClient", "function SETUP() can have at most a 'TList *' argument:"
06954 " cannot continue");
06955 status = -1;
06956 }
06957
06958 Long_t setuprc = (status == 0) ? 0 : -1;
06959 if (status == 0) {
06960 callEnv.Execute(setuprc);
06961 if (setuprc < 0) status = -1;
06962 }
06963 }
06964 }
06965
06966 if (!gSystem->AccessPathName(setupfn.Data())) gSystem->Unlink(setupfn.Data());
06967 } else {
06968 PDB(kPackage, 1)
06969 Info("LoadPackageOnClient",
06970 "package %s exists but has no PROOF-INF/SETUP.C script", pack);
06971 }
06972
06973 gSystem->ChangeDirectory(ocwd);
06974
06975 if (status == 0) {
06976
06977
06978 fPackageLock->Lock();
06979
06980 FileStat_t stat;
06981 Int_t st = gSystem->GetPathInfo(pack, stat);
06982
06983
06984
06985 if (stat.fIsLink)
06986 gSystem->Unlink(pack);
06987 else if (st == 0) {
06988 Error("LoadPackageOnClient", "cannot create symlink %s in %s on client, "
06989 "another item with same name already exists", pack, ocwd.Data());
06990 fPackageLock->Unlock();
06991 return -1;
06992 }
06993 gSystem->Symlink(pdir, pack);
06994
06995 fPackageLock->Unlock();
06996
06997
06998 gSystem->AddIncludePath(TString("-I") + pack);
06999
07000
07001 gROOT->ProcessLine(TString(".include ") + pack);
07002
07003 fEnabledPackagesOnClient->Add(new TObjString(pack));
07004 PDB(kPackage, 1)
07005 Info("LoadPackageOnClient", "package %s successfully loaded", pack);
07006 } else
07007 Error("LoadPackageOnClient", "loading package %s on client failed", pack);
07008
07009 return status;
07010 }
07011 return 0;
07012 }
07013
07014
07015 Int_t TProof::UnloadPackage(const char *package)
07016 {
07017
07018
07019
07020 if (!IsValid()) return -1;
07021
07022 if (!package || !strlen(package)) {
07023 Error("UnloadPackage", "need to specify a package name");
07024 return -1;
07025 }
07026
07027
07028 TString pac = package;
07029 if (pac.EndsWith(".par"))
07030 pac.Remove(pac.Length()-4);
07031 pac = gSystem->BaseName(pac);
07032
07033 if (UnloadPackageOnClient(pac) == -1)
07034 return -1;
07035
07036
07037 if (IsLite()) return 0;
07038
07039 TMessage mess(kPROOF_CACHE);
07040 mess << Int_t(kUnloadPackage) << pac;
07041 Broadcast(mess);
07042 Collect();
07043
07044 return fStatus;
07045 }
07046
07047
07048 Int_t TProof::UnloadPackageOnClient(const char *package)
07049 {
07050
07051
07052
07053
07054
07055 if (TestBit(TProof::kIsClient)) {
07056 TObjString *pack = (TObjString *) fEnabledPackagesOnClient->FindObject(package);
07057 if (pack) {
07058
07059 TString aclicincpath = gSystem->GetIncludePath();
07060 TString cintincpath = gInterpreter->GetIncludePath();
07061
07062 aclicincpath.Remove(aclicincpath.Length() - cintincpath.Length() - 1);
07063
07064 aclicincpath.ReplaceAll(TString(" -I") + package, "");
07065 gSystem->SetIncludePath(aclicincpath);
07066
07067
07068
07069
07070 fEnabledPackagesOnClient->Remove(pack);
07071 }
07072
07073
07074 if (!gSystem->AccessPathName(package))
07075 if (gSystem->Unlink(package) != 0)
07076 Warning("UnloadPackageOnClient", "unable to remove symlink to %s", package);
07077
07078
07079 delete pack;
07080 }
07081 return 0;
07082 }
07083
07084
07085 Int_t TProof::UnloadPackages()
07086 {
07087
07088
07089
07090 if (!IsValid()) return -1;
07091
07092 if (TestBit(TProof::kIsClient)) {
07093
07094 TIter nextpackage(fEnabledPackagesOnClient);
07095 while (TObjString *objstr = dynamic_cast<TObjString*>(nextpackage()))
07096 if (UnloadPackageOnClient(objstr->String()) == -1 )
07097 return -1;
07098 }
07099
07100
07101 if (IsLite()) return 0;
07102
07103 TMessage mess(kPROOF_CACHE);
07104 mess << Int_t(kUnloadPackages);
07105 Broadcast(mess);
07106 Collect();
07107
07108 return fStatus;
07109 }
07110
07111
07112 Int_t TProof::EnablePackage(const char *package, Bool_t notOnClient)
07113 {
07114
07115
07116
07117
07118
07119
07120
07121 return EnablePackage(package, (TList *)0, notOnClient);
07122 }
07123
07124
07125 Int_t TProof::EnablePackage(const char *package, const char *loadopts,
07126 Bool_t notOnClient)
07127 {
07128
07129
07130
07131
07132
07133
07134
07135
07136 TList *optls = 0;
07137 if (loadopts && strlen(loadopts)) {
07138 if (fProtocol > 28) {
07139 optls = new TList;
07140 optls->Add(new TObjString(loadopts));
07141 optls->SetOwner(kTRUE);
07142 } else {
07143
07144 Warning("EnablePackage", "remote server does not support options: ignoring the option string");
07145 }
07146 }
07147
07148 Int_t rc = EnablePackage(package, optls, notOnClient);
07149
07150 SafeDelete(optls);
07151
07152 return rc;
07153 }
07154
07155
07156 Int_t TProof::EnablePackage(const char *package, TList *loadopts,
07157 Bool_t notOnClient)
07158 {
07159
07160
07161
07162
07163
07164
07165
07166
07167 if (!IsValid()) return -1;
07168
07169 if (!package || !strlen(package)) {
07170 Error("EnablePackage", "need to specify a package name");
07171 return -1;
07172 }
07173
07174
07175 TString pac = package;
07176 if (pac.EndsWith(".par"))
07177 pac.Remove(pac.Length()-4);
07178 pac = gSystem->BaseName(pac);
07179
07180 EBuildPackageOpt opt = kBuildAll;
07181 if (notOnClient)
07182 opt = kDontBuildOnClient;
07183
07184 if (BuildPackage(pac, opt) == -1)
07185 return -1;
07186
07187 TList *optls = loadopts;
07188 if (optls && fProtocol <= 28) {
07189 Warning("EnablePackage", "remote server does not support options: ignoring the option list");
07190 optls = 0;
07191 }
07192
07193 if (LoadPackage(pac, notOnClient, optls) == -1)
07194 return -1;
07195
07196 return 0;
07197 }
07198
07199
07200 Int_t TProof::DownloadPackage(const char *pack, const char *dstdir)
07201 {
07202
07203
07204
07205
07206
07207
07208
07209 if (!fManager || !(fManager->IsValid())) {
07210 Error("DownloadPackage", "the manager is undefined!");
07211 return -1;
07212 }
07213
07214
07215 TString parname(gSystem->BaseName(pack)), src, dst;
07216 if (!parname.EndsWith(".par")) parname += ".par";
07217 src.Form("packages/%s", parname.Data());
07218 if (!dstdir || strlen(dstdir) <= 0) {
07219 dst.Form("./%s", parname.Data());
07220 } else {
07221
07222 FileStat_t st;
07223 if (gSystem->GetPathInfo(dstdir, st) != 0) {
07224
07225 if (gSystem->mkdir(dstdir, kTRUE) != 0) {
07226 Error("DownloadPackage",
07227 "could not create the destination directory '%s' (errno: %d)",
07228 dstdir, TSystem::GetErrno());
07229 return -1;
07230 }
07231 } else if (!R_ISDIR(st.fMode) && !R_ISLNK(st.fMode)) {
07232 Error("DownloadPackage",
07233 "destination path '%s' exist but is not a directory!", dstdir);
07234 return -1;
07235 }
07236 dst.Form("%s/%s", dstdir, parname.Data());
07237 }
07238
07239
07240 FileStat_t stsrc;
07241 RedirectHandle_t rh;
07242 if (gSystem->RedirectOutput(fLogFileName, "a", &rh) != 0)
07243 Warning("DownloadPackage", "problems redirecting output to '%s'", fLogFileName.Data());
07244 Int_t rc = fManager->Stat(src, stsrc);
07245 if (gSystem->RedirectOutput(0, 0, &rh) != 0)
07246 Warning("DownloadPackage", "problems restoring output");
07247 if (rc != 0) {
07248
07249 ShowPackages(kFALSE, kTRUE);
07250 TMacro *mp = GetLastLog();
07251 if (mp) {
07252
07253 Bool_t isGlobal = kFALSE;
07254 TIter nxl(mp->GetListOfLines());
07255 TObjString *os = 0;
07256 TString globaldir;
07257 while ((os = (TObjString *) nxl())) {
07258 TString s(os->GetName());
07259 if (s.Contains("*** Global Package cache")) {
07260
07261 s.Remove(0, s.Last(':') + 1);
07262 s.Remove(s.Last(' '));
07263 globaldir = s;
07264 isGlobal = kTRUE;
07265 } else if (s.Contains("*** Package cache")) {
07266 isGlobal = kFALSE;
07267 globaldir = "";
07268 }
07269
07270 if (isGlobal && s.Contains(parname)) {
07271 src.Form("%s/%s", globaldir.Data(), parname.Data());
07272 break;
07273 }
07274 }
07275
07276 delete mp;
07277 }
07278 }
07279
07280
07281 if (fManager->GetFile(src, dst, "silent") != 0) {
07282 Error("DownloadPackage", "problems downloading '%s' (src:%s, dst:%s)",
07283 pack, src.Data(), dst.Data());
07284 return -1;
07285 } else {
07286 Info("DownloadPackage", "'%s' cross-checked against master repository (local path: %s)",
07287 pack, dst.Data());
07288 }
07289
07290 return 0;
07291 }
07292
07293
07294 Int_t TProof::UploadPackage(const char *pack, EUploadPackageOpt opt)
07295 {
07296
07297
07298
07299
07300
07301
07302
07303
07304
07305
07306
07307
07308
07309
07310
07311
07312
07313
07314
07315
07316 if (!IsValid()) return -1;
07317
07318 TString par = pack;
07319 if (!par.EndsWith(".par"))
07320
07321 par += ".par";
07322
07323
07324 gSystem->ExpandPathName(par);
07325 if (gSystem->AccessPathName(par, kReadPermission)) {
07326 TString tried = par;
07327
07328 par = Form("%s/%s", fPackageDir.Data(), gSystem->BaseName(par));
07329 if (gSystem->AccessPathName(par, kReadPermission)) {
07330
07331 if (fGlobalPackageDirList && fGlobalPackageDirList->GetSize() > 0) {
07332
07333 TIter nxd(fGlobalPackageDirList);
07334 TNamed *nm = 0;
07335 TString pdir;
07336 while ((nm = (TNamed *)nxd())) {
07337 pdir = Form("%s/%s", nm->GetTitle(), pack);
07338 if (!gSystem->AccessPathName(pdir, kReadPermission)) {
07339
07340 break;
07341 }
07342 pdir = "";
07343 }
07344 if (pdir.Length() > 0) {
07345
07346 if (gDebug > 0)
07347 Info("UploadPackage", "global package found (%s): no upload needed",
07348 pdir.Data());
07349 return 0;
07350 }
07351 }
07352 Error("UploadPackage", "PAR file '%s' not found; paths tried: %s, %s",
07353 gSystem->BaseName(par), tried.Data(), par.Data());
07354 return -1;
07355 }
07356 }
07357
07358
07359
07360
07361
07362
07363
07364
07365
07366
07367
07368
07369 TMD5 *md5 = TMD5::FileChecksum(par);
07370
07371 if (!md5 || (md5 && UploadPackageOnClient(par, opt, md5) == -1)) {
07372 if (md5) delete md5;
07373 return -1;
07374 }
07375
07376
07377 if (IsLite()) {
07378 delete md5;
07379 return 0;
07380 }
07381
07382 TString smsg;
07383 smsg.Form("+%s", gSystem->BaseName(par));
07384
07385 TMessage mess(kPROOF_CHECKFILE);
07386 mess << smsg << (*md5);
07387 TMessage mess2(kPROOF_CHECKFILE);
07388 smsg.Replace(0, 1, "-");
07389 mess2 << smsg << (*md5);
07390 TMessage mess3(kPROOF_CHECKFILE);
07391 smsg.Replace(0, 1, "=");
07392 mess3 << smsg << (*md5);
07393
07394 delete md5;
07395
07396 if (fProtocol > 8) {
07397
07398 mess << (UInt_t) opt;
07399 mess2 << (UInt_t) opt;
07400 mess3 << (UInt_t) opt;
07401 }
07402
07403
07404 TIter next(fUniqueSlaves);
07405 TSlave *sl = 0;
07406 while ((sl = (TSlave *) next())) {
07407 if (!sl->IsValid())
07408 continue;
07409
07410 sl->GetSocket()->Send(mess);
07411
07412 fCheckFileStatus = 0;
07413 Collect(sl, fCollectTimeout, kPROOF_CHECKFILE);
07414 if (fCheckFileStatus == 0) {
07415
07416 if (fProtocol > 5) {
07417
07418 smsg.Form("%s/%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir,
07419 gSystem->BaseName(par));
07420 if (SendFile(par, (kBinary | kForce | kCpBin | kForward), smsg.Data(), sl) < 0) {
07421 Error("UploadPackage", "%s: problems uploading file %s",
07422 sl->GetOrdinal(), par.Data());
07423 return -1;
07424 }
07425 } else {
07426
07427 TFTP ftp(TString("root://")+sl->GetName(), 1);
07428 if (!ftp.IsZombie()) {
07429 smsg.Form("%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir);
07430 ftp.cd(smsg.Data());
07431 ftp.put(par, gSystem->BaseName(par));
07432 }
07433 }
07434
07435
07436 sl->GetSocket()->Send(mess2);
07437 fCheckFileStatus = 0;
07438 Collect(sl, fCollectTimeout, kPROOF_CHECKFILE);
07439 if (fCheckFileStatus == 0) {
07440 Error("UploadPackage", "%s: unpacking of package %s failed",
07441 sl->GetOrdinal(), gSystem->BaseName(par));
07442 return -1;
07443 }
07444 }
07445 }
07446
07447
07448 TIter nextmaster(fNonUniqueMasters);
07449 TSlave *ma;
07450 while ((ma = (TSlave *) nextmaster())) {
07451 if (!ma->IsValid())
07452 continue;
07453
07454 ma->GetSocket()->Send(mess3);
07455
07456 fCheckFileStatus = 0;
07457 Collect(ma, fCollectTimeout, kPROOF_CHECKFILE);
07458 if (fCheckFileStatus == 0) {
07459
07460 Error("UploadPackage", "package %s did not exist on submaster %s",
07461 par.Data(), ma->GetOrdinal());
07462 return -1;
07463 }
07464 }
07465
07466 return 0;
07467 }
07468
07469
07470 Int_t TProof::UploadPackageOnClient(const char *parpack, EUploadPackageOpt opt, TMD5 *md5)
07471 {
07472
07473
07474
07475
07476
07477
07478
07479
07480
07481
07482
07483
07484 Int_t status = 0;
07485
07486 if (TestBit(TProof::kIsClient)) {
07487
07488 TString par(parpack);
07489 #ifndef WIN32
07490 char ctmp[4096];
07491 ssize_t sz = readlink(par.Data(), ctmp, 4096);
07492 if (sz >= 4096) sz = 4095;
07493 if (sz > 0) {
07494 ctmp[sz] = '\0';
07495 par = ctmp;
07496 } else if (TSystem::GetErrno() != EINVAL) {
07497 Warning("UploadPackageOnClient",
07498 "could not resolve the symbolik link '%s'", par.Data());
07499 }
07500 #endif
07501
07502
07503
07504 fPackageLock->Lock();
07505
07506
07507
07508
07509
07510 TString downloadpath;
07511 downloadpath.Form("%s/%s/%s", fPackageDir.Data(), kPROOF_PackDownloadDir, gSystem->BaseName(par));
07512 if (!gSystem->AccessPathName(downloadpath, kFileExists) && downloadpath != par) {
07513 if (gSystem->Unlink(downloadpath) != 0) {
07514 Warning("UploadPackageOnClient",
07515 "problems removing downloaded version of '%s' (%s):\n"
07516 "may imply inconsistencies in subsequent updates",
07517 gSystem->BaseName(par), downloadpath.Data());
07518 }
07519 }
07520 TString lpar;
07521 lpar.Form("%s/%s", fPackageDir.Data(), gSystem->BaseName(par));
07522 FileStat_t stat;
07523 Int_t st = gSystem->GetPathInfo(lpar, stat);
07524
07525
07526
07527 if (stat.fIsLink)
07528 gSystem->Unlink(lpar);
07529 else if (st == 0) {
07530 Error("UploadPackageOnClient", "cannot create symlink %s on client, "
07531 "another item with same name already exists",
07532 lpar.Data());
07533 fPackageLock->Unlock();
07534 return -1;
07535 }
07536 if (!gSystem->IsAbsoluteFileName(par)) {
07537 TString fpar = par;
07538 gSystem->Symlink(gSystem->PrependPathName(gSystem->WorkingDirectory(), fpar), lpar);
07539 } else
07540 gSystem->Symlink(par, lpar);
07541
07542
07543
07544 TString packnam = par(0, par.Length() - 4);
07545 packnam = gSystem->BaseName(packnam);
07546 TString md5f = fPackageDir + "/" + packnam + "/PROOF-INF/md5.txt";
07547 TMD5 *md5local = TMD5::ReadChecksum(md5f);
07548 if (!md5local || (*md5) != (*md5local)) {
07549
07550 if ((opt & TProof::kRemoveOld)) {
07551
07552 if (gSystem->Exec(Form("%s %s/%s", kRM, fPackageDir.Data(),
07553 packnam.Data())))
07554 Error("UploadPackageOnClient", "failure executing: %s %s/%s",
07555 kRM, fPackageDir.Data(), packnam.Data());
07556 }
07557
07558 char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP,
07559 kExecutePermission);
07560 if (gunzip) {
07561
07562 if (gSystem->Exec(Form(kUNTAR2, gunzip, par.Data(), fPackageDir.Data())))
07563 Error("Uploadpackage", "failure executing: %s",
07564 Form(kUNTAR2, gunzip, par.Data(), fPackageDir.Data()));
07565 delete [] gunzip;
07566 } else
07567 Error("UploadPackageOnClient", "%s not found", kGUNZIP);
07568
07569
07570 if (gSystem->AccessPathName(fPackageDir + "/" + packnam, kWritePermission)) {
07571
07572 Error("UploadPackageOnClient",
07573 "package %s did not unpack into %s/%s", par.Data(), fPackageDir.Data(),
07574 packnam.Data());
07575 status = -1;
07576 } else {
07577
07578 TMD5::WriteChecksum(md5f, md5);
07579 }
07580 }
07581 fPackageLock->Unlock();
07582 delete md5local;
07583 }
07584 return status;
07585 }
07586
07587
07588 Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
07589 TList *wrks)
07590 {
07591
07592
07593
07594
07595
07596
07597
07598
07599
07600
07601
07602
07603
07604
07605
07606 if (!IsValid()) return -1;
07607
07608 if (!macro || !strlen(macro)) {
07609 Error("Load", "need to specify a macro name");
07610 return -1;
07611 }
07612
07613 if (TestBit(TProof::kIsClient)) {
07614 if (wrks) {
07615 Error("Load", "the 'wrks' arg can be used only on the master");
07616 return -1;
07617 }
07618
07619
07620 TString addsname, implname = macro;
07621 Ssiz_t icom = implname.Index(",");
07622 if (icom != kNPOS) {
07623 addsname = implname(icom + 1, implname.Length());
07624 implname.Remove(icom);
07625 }
07626 TString basemacro = gSystem->BaseName(implname), mainmacro(implname);
07627 TString acmode, args, io;
07628 implname = gSystem->SplitAclicMode(implname, acmode, args, io);
07629
07630
07631 Int_t dot = implname.Last('.');
07632 if (dot == kNPOS) {
07633 Info("Load", "macro '%s' does not contain a '.': do nothing", macro);
07634 return -1;
07635 }
07636
07637
07638 Bool_t hasHeader = kTRUE;
07639 TString headname = implname;
07640 headname.Remove(dot);
07641 headname += ".h";
07642 if (gSystem->AccessPathName(headname, kReadPermission)) {
07643 TString h = headname;
07644 headname.Remove(dot);
07645 headname += ".hh";
07646 if (gSystem->AccessPathName(headname, kReadPermission)) {
07647 hasHeader = kFALSE;
07648 if (gDebug > 0)
07649 Info("Load", "no associated header file found: tried: %s %s",
07650 h.Data(), headname.Data());
07651 }
07652 }
07653
07654
07655 TString addincs;
07656 TList addfiles;
07657 if (!addsname.IsNull()) {
07658 TString fn;
07659 Int_t from = 0;
07660 while (addsname.Tokenize(fn, from, ",")) {
07661 if (gSystem->AccessPathName(fn, kReadPermission)) {
07662 Error("Load", "additional file '%s' not found", fn.Data());
07663 return -1;
07664 }
07665
07666 if (!notOnClient) {
07667 TString dirn(gSystem->DirName(fn));
07668 if (addincs.IsNull()) {
07669 addincs.Form("-I%s", dirn.Data());
07670 } else if (!addincs.Contains(dirn)) {
07671 addincs += TString::Format(" -I%s", dirn.Data());
07672 }
07673 }
07674
07675 addfiles.Add(new TObjString(fn));
07676 }
07677 }
07678
07679
07680
07681 if (SendFile(implname, kAscii | kForward , "cache") == -1) {
07682 Error("Load", "problems sending implementation file %s", implname.Data());
07683 return -1;
07684 }
07685 if (hasHeader)
07686 if (SendFile(headname, kAscii | kForward , "cache") == -1) {
07687 Error("Load", "problems sending header file %s", headname.Data());
07688 return -1;
07689 }
07690
07691 if (addfiles.GetSize() > 0) {
07692 TIter nxfn(&addfiles);
07693 TObjString *os = 0;
07694 while ((os = (TObjString *) nxfn())) {
07695 if (SendFile(os->GetName(), kAscii | kForward , "cache") == -1) {
07696 Error("Load", "problems sending additional file %s", os->GetName());
07697 return -1;
07698 }
07699 }
07700 addfiles.SetOwner(kTRUE);
07701 }
07702
07703
07704 TMessage mess(kPROOF_CACHE);
07705 mess << Int_t(kLoadMacro) << basemacro;
07706 Broadcast(mess, kActive);
07707
07708
07709 if (!notOnClient) {
07710
07711 TString oldincs = gSystem->GetIncludePath();
07712 if (!addincs.IsNull()) gSystem->AddIncludePath(addincs);
07713
07714
07715
07716 gROOT->ProcessLine(Form(".L %s", mainmacro.Data()));
07717
07718
07719 if (!addincs.IsNull()) gSystem->SetIncludePath(oldincs);
07720
07721
07722 TString mp(TROOT::GetMacroPath());
07723 TString np(gSystem->DirName(macro));
07724 if (!np.IsNull()) {
07725 np += ":";
07726 if (!mp.BeginsWith(np) && !mp.Contains(":"+np)) {
07727 Int_t ip = (mp.BeginsWith(".:")) ? 2 : 0;
07728 mp.Insert(ip, np);
07729 TROOT::SetMacroPath(mp);
07730 if (gDebug > 0)
07731 Info("Load", "macro path set to '%s'", TROOT::GetMacroPath());
07732 }
07733 }
07734 }
07735
07736
07737 Collect(kActive);
07738
07739 } else {
07740
07741
07742
07743
07744 TString basemacro = gSystem->BaseName(macro);
07745 TMessage mess(kPROOF_CACHE);
07746
07747 if (uniqueWorkers) {
07748 mess << Int_t(kLoadMacro) << basemacro;
07749 if (wrks)
07750 Broadcast(mess, wrks);
07751 else
07752 Broadcast(mess, kUnique);
07753 } else {
07754
07755 Collect(kUnique);
07756
07757
07758 TList others;
07759 TSlave *wrk = 0;
07760 TIter nxw(fActiveSlaves);
07761 while ((wrk = (TSlave *)nxw())) {
07762 if (!fUniqueSlaves->FindObject(wrk)) {
07763 others.Add(wrk);
07764 }
07765 }
07766
07767
07768 Int_t ld = basemacro.Last('.');
07769 if (ld != kNPOS) {
07770 Int_t lpp = basemacro.Index("++", ld);
07771 if (lpp != kNPOS) basemacro.Replace(lpp, 2, "+");
07772 }
07773 mess << Int_t(kLoadMacro) << basemacro;
07774 Broadcast(mess, &others);
07775 Collect(&others);
07776 }
07777
07778 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
07779 if (!fLoadedMacros) {
07780 fLoadedMacros = new TList();
07781 fLoadedMacros->SetOwner();
07782 }
07783
07784 if (!wrks)
07785 fLoadedMacros->Add(new TObjString(macro));
07786 }
07787
07788
07789 return 0;
07790 }
07791
07792
07793 Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks)
07794 {
07795
07796
07797
07798
07799
07800 if ((!libpath || !strlen(libpath))) {
07801 if (gDebug > 0)
07802 Info("AddDynamicPath", "list is empty - nothing to do");
07803 return 0;
07804 }
07805
07806
07807 if (onClient)
07808 HandleLibIncPath("lib", kTRUE, libpath);
07809
07810 TMessage m(kPROOF_LIB_INC_PATH);
07811 m << TString("lib") << (Bool_t)kTRUE;
07812
07813
07814 if (libpath && strlen(libpath))
07815 m << TString(libpath);
07816 else
07817 m << TString("-");
07818
07819
07820 if (wrks)
07821 Broadcast(m, wrks);
07822 else
07823 Broadcast(m);
07824 Collect(kActive, fCollectTimeout);
07825
07826 return 0;
07827 }
07828
07829
07830 Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks)
07831 {
07832
07833
07834
07835
07836
07837 if ((!incpath || !strlen(incpath))) {
07838 if (gDebug > 0)
07839 Info("AddIncludePath", "list is empty - nothing to do");
07840 return 0;
07841 }
07842
07843
07844 if (onClient)
07845 HandleLibIncPath("inc", kTRUE, incpath);
07846
07847 TMessage m(kPROOF_LIB_INC_PATH);
07848 m << TString("inc") << (Bool_t)kTRUE;
07849
07850
07851 if (incpath && strlen(incpath))
07852 m << TString(incpath);
07853 else
07854 m << TString("-");
07855
07856
07857 if (wrks)
07858 Broadcast(m, wrks);
07859 else
07860 Broadcast(m);
07861 Collect(kActive, fCollectTimeout);
07862
07863 return 0;
07864 }
07865
07866
07867 Int_t TProof::RemoveDynamicPath(const char *libpath, Bool_t onClient)
07868 {
07869
07870
07871
07872
07873
07874 if ((!libpath || !strlen(libpath))) {
07875 if (gDebug > 0)
07876 Info("RemoveDynamicPath", "list is empty - nothing to do");
07877 return 0;
07878 }
07879
07880
07881 if (onClient)
07882 HandleLibIncPath("lib", kFALSE, libpath);
07883
07884 TMessage m(kPROOF_LIB_INC_PATH);
07885 m << TString("lib") <<(Bool_t)kFALSE;
07886
07887
07888 if (libpath && strlen(libpath))
07889 m << TString(libpath);
07890 else
07891 m << TString("-");
07892
07893
07894 Broadcast(m);
07895 Collect(kActive, fCollectTimeout);
07896
07897 return 0;
07898 }
07899
07900
07901 Int_t TProof::RemoveIncludePath(const char *incpath, Bool_t onClient)
07902 {
07903
07904
07905
07906
07907
07908 if ((!incpath || !strlen(incpath))) {
07909 if (gDebug > 0)
07910 Info("RemoveIncludePath", "list is empty - nothing to do");
07911 return 0;
07912 }
07913
07914
07915 if (onClient)
07916 HandleLibIncPath("in", kFALSE, incpath);
07917
07918 TMessage m(kPROOF_LIB_INC_PATH);
07919 m << TString("inc") << (Bool_t)kFALSE;
07920
07921
07922 if (incpath && strlen(incpath))
07923 m << TString(incpath);
07924 else
07925 m << TString("-");
07926
07927
07928 Broadcast(m);
07929 Collect(kActive, fCollectTimeout);
07930
07931 return 0;
07932 }
07933
07934
07935 void TProof::HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
07936 {
07937
07938
07939 TString type(what);
07940 TString path(dirs);
07941
07942
07943 if ((type != "lib") && (type != "inc")) {
07944 Error("HandleLibIncPath","unknown action type: %s - protocol error?", type.Data());
07945 return;
07946 }
07947
07948
07949 path.ReplaceAll(","," ");
07950
07951
07952 TObjArray *op = 0;
07953 if (path.Length() > 0 && path != "-") {
07954 if (!(op = path.Tokenize(" "))) {
07955 Warning("HandleLibIncPath","decomposing path %s", path.Data());
07956 return;
07957 }
07958 }
07959
07960 if (add) {
07961
07962 if (type == "lib") {
07963
07964
07965 TIter nxl(op, kIterBackward);
07966 TObjString *lib = 0;
07967 while ((lib = (TObjString *) nxl())) {
07968
07969 TString xlib = lib->GetName();
07970 gSystem->ExpandPathName(xlib);
07971
07972 if (!gSystem->AccessPathName(xlib, kReadPermission)) {
07973 TString newlibpath = gSystem->GetDynamicPath();
07974
07975 Int_t pos = 0;
07976 if (newlibpath.BeginsWith(".:"))
07977 pos = 2;
07978 if (newlibpath.Index(xlib) == kNPOS) {
07979 newlibpath.Insert(pos,Form("%s:", xlib.Data()));
07980 gSystem->SetDynamicPath(newlibpath);
07981 }
07982 } else {
07983 if (gDebug > 0)
07984 Info("HandleLibIncPath",
07985 "libpath %s does not exist or cannot be read - not added", xlib.Data());
07986 }
07987 }
07988
07989 } else {
07990
07991
07992 TIter nxi(op);
07993 TObjString *inc = 0;
07994 while ((inc = (TObjString *) nxi())) {
07995
07996 TString xinc = inc->GetName();
07997 gSystem->ExpandPathName(xinc);
07998
07999 if (!gSystem->AccessPathName(xinc, kReadPermission)) {
08000 TString curincpath = gSystem->GetIncludePath();
08001 if (curincpath.Index(xinc) == kNPOS)
08002 gSystem->AddIncludePath(Form("-I%s", xinc.Data()));
08003 } else
08004 if (gDebug > 0)
08005 Info("HandleLibIncPath",
08006 "incpath %s does not exist or cannot be read - not added", xinc.Data());
08007 }
08008 }
08009
08010
08011 } else {
08012
08013 if (type == "lib") {
08014
08015
08016 TIter nxl(op);
08017 TObjString *lib = 0;
08018 while ((lib = (TObjString *) nxl())) {
08019
08020 TString xlib = lib->GetName();
08021 gSystem->ExpandPathName(xlib);
08022
08023 TString newlibpath = gSystem->GetDynamicPath();
08024 newlibpath.ReplaceAll(Form("%s:", xlib.Data()),"");
08025 gSystem->SetDynamicPath(newlibpath);
08026 }
08027
08028 } else {
08029
08030
08031 TIter nxi(op);
08032 TObjString *inc = 0;
08033 while ((inc = (TObjString *) nxi())) {
08034 TString newincpath = gSystem->GetIncludePath();
08035 newincpath.ReplaceAll(Form("-I%s", inc->GetName()),"");
08036
08037 newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
08038 gSystem->SetIncludePath(newincpath);
08039 }
08040 }
08041 }
08042 }
08043
08044
08045 TList *TProof::GetListOfPackages()
08046 {
08047
08048
08049 if (!IsValid())
08050 return (TList *)0;
08051
08052 TMessage mess(kPROOF_CACHE);
08053 mess << Int_t(kListPackages);
08054 Broadcast(mess);
08055 Collect(kActive, fCollectTimeout);
08056
08057 return fAvailablePackages;
08058 }
08059
08060
08061 TList *TProof::GetListOfEnabledPackages()
08062 {
08063
08064
08065 if (!IsValid())
08066 return (TList *)0;
08067
08068 TMessage mess(kPROOF_CACHE);
08069 mess << Int_t(kListEnabledPackages);
08070 Broadcast(mess);
08071 Collect(kActive, fCollectTimeout);
08072
08073 return fEnabledPackages;
08074 }
08075
08076
08077 void TProof::PrintProgress(Long64_t total, Long64_t processed,
08078 Float_t procTime, Long64_t bytesread)
08079 {
08080
08081
08082 if (fPrintProgress) {
08083 Bool_t redirlog = fRedirLog;
08084 fRedirLog = kFALSE;
08085
08086 (*fPrintProgress)(total, processed, procTime, bytesread);
08087 fRedirLog = redirlog;
08088 return;
08089 }
08090
08091 fprintf(stderr, "[TProof::Progress] Total %lld events\t|", total);
08092
08093 for (int l = 0; l < 20; l++) {
08094 if (total > 0) {
08095 if (l < 20*processed/total)
08096 fprintf(stderr, "=");
08097 else if (l == 20*processed/total)
08098 fprintf(stderr, ">");
08099 else if (l > 20*processed/total)
08100 fprintf(stderr, ".");
08101 } else
08102 fprintf(stderr, "=");
08103 }
08104 Float_t evtrti = (procTime > 0. && processed > 0) ? processed / procTime : -1.;
08105 Float_t mbsrti = (procTime > 0. && bytesread > 0) ? bytesread / procTime : -1.;
08106 if (evtrti > 0.) {
08107 if (mbsrti > 0.) {
08108 TString sunit("B/s");
08109 const Float_t toK = 1024., toM = 1048576., toG = 1073741824.;
08110 if (mbsrti >= toG) {
08111 mbsrti /= toG;
08112 sunit = "GB/s";
08113 } else if (mbsrti >= toM) {
08114 mbsrti /= toM;
08115 sunit = "MB/s";
08116 } else if (mbsrti >= toK) {
08117 mbsrti /= toK;
08118 sunit = "kB/s";
08119 }
08120 fprintf(stderr, "| %.02f %% [%.1f evts/s, %.1f %s]\r",
08121 (total ? ((100.0*processed)/total) : 100.0), evtrti, mbsrti, sunit.Data());
08122 } else {
08123 fprintf(stderr, "| %.02f %% [%.1f evts/s]\r",
08124 (total ? ((100.0*processed)/total) : 100.0), evtrti);
08125 }
08126 } else {
08127 fprintf(stderr, "| %.02f %%\r",
08128 (total ? ((100.0*processed)/total) : 100.0));
08129 }
08130 if (processed >= total)
08131 fprintf(stderr, "\n");
08132 }
08133
08134
08135 void TProof::Progress(Long64_t total, Long64_t processed)
08136 {
08137
08138
08139
08140 if (fPrintProgress) {
08141
08142 return (*fPrintProgress)(total, processed, -1., -1);
08143 }
08144
08145 PDB(kGlobal,1)
08146 Info("Progress","%2f (%lld/%lld)", 100.*processed/total, processed, total);
08147
08148 if (gROOT->IsBatch()) {
08149
08150 if (total > 0)
08151 PrintProgress(total, processed);
08152 } else {
08153 EmitVA("Progress(Long64_t,Long64_t)", 2, total, processed);
08154 }
08155 }
08156
08157
08158 void TProof::Progress(Long64_t total, Long64_t processed, Long64_t bytesread,
08159 Float_t initTime, Float_t procTime,
08160 Float_t evtrti, Float_t mbrti)
08161 {
08162
08163
08164
08165 PDB(kGlobal,1)
08166 Info("Progress","%lld %lld %lld %f %f %f %f", total, processed, bytesread,
08167 initTime, procTime, evtrti, mbrti);
08168
08169 if (gROOT->IsBatch()) {
08170
08171 if (total > 0)
08172 PrintProgress(total, processed, procTime, bytesread);
08173 } else {
08174 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
08175 7, total, processed, bytesread, initTime, procTime, evtrti, mbrti);
08176 }
08177 }
08178
08179
08180 void TProof::Progress(Long64_t total, Long64_t processed, Long64_t bytesread,
08181 Float_t initTime, Float_t procTime,
08182 Float_t evtrti, Float_t mbrti, Int_t actw, Int_t tses, Float_t eses)
08183 {
08184
08185
08186
08187 PDB(kGlobal,1)
08188 Info("Progress","%lld %lld %lld %f %f %f %f %d %f", total, processed, bytesread,
08189 initTime, procTime, evtrti, mbrti, actw, eses);
08190
08191 if (gROOT->IsBatch()) {
08192
08193 if (total > 0)
08194 PrintProgress(total, processed, procTime, bytesread);
08195 } else {
08196 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
08197 10, total, processed, bytesread, initTime, procTime, evtrti, mbrti, actw, tses, eses);
08198 }
08199 }
08200
08201
08202 void TProof::Feedback(TList *objs)
08203 {
08204
08205
08206
08207 PDB(kGlobal,1)
08208 Info("Feedback","%d objects", objs->GetSize());
08209 PDB(kFeedback,1) {
08210 Info("Feedback","%d objects", objs->GetSize());
08211 objs->ls();
08212 }
08213
08214 Emit("Feedback(TList *objs)", (Long_t) objs);
08215 }
08216
08217
08218 void TProof::CloseProgressDialog()
08219 {
08220
08221
08222 PDB(kGlobal,1)
08223 Info("CloseProgressDialog",
08224 "called: have progress dialog: %d", fProgressDialogStarted);
08225
08226
08227 if (!fProgressDialogStarted)
08228 return;
08229
08230 Emit("CloseProgressDialog()");
08231 }
08232
08233
08234 void TProof::ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst,
08235 Long64_t ent)
08236 {
08237
08238
08239 PDB(kGlobal,1)
08240 Info("ResetProgressDialog","(%s,%d,%lld,%lld)", sel, sz, fst, ent);
08241
08242 EmitVA("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
08243 4, sel, sz, fst, ent);
08244 }
08245
08246
08247 void TProof::StartupMessage(const char *msg, Bool_t st, Int_t done, Int_t total)
08248 {
08249
08250
08251 PDB(kGlobal,1)
08252 Info("StartupMessage","(%s,%d,%d,%d)", msg, st, done, total);
08253
08254 EmitVA("StartupMessage(const char*,Bool_t,Int_t,Int_t)",
08255 4, msg, st, done, total);
08256 }
08257
08258
08259 void TProof::DataSetStatus(const char *msg, Bool_t st, Int_t done, Int_t total)
08260 {
08261
08262
08263 PDB(kGlobal,1)
08264 Info("DataSetStatus","(%s,%d,%d,%d)", msg, st, done, total);
08265
08266 EmitVA("DataSetStatus(const char*,Bool_t,Int_t,Int_t)",
08267 4, msg, st, done, total);
08268 }
08269
08270
08271 void TProof::SendDataSetStatus(const char *action, UInt_t done,
08272 UInt_t tot, Bool_t st)
08273 {
08274
08275
08276 if (IsLite()) {
08277 if (tot) {
08278 TString type = "files";
08279 Int_t frac = (Int_t) (done*100.)/tot;
08280 char msg[512] = {0};
08281 if (frac >= 100) {
08282 snprintf(msg, 512, "%s: OK (%d %s) \n",
08283 action,tot, type.Data());
08284 } else {
08285 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
08286 action, done, tot, frac);
08287 }
08288 if (fSync)
08289 fprintf(stderr,"%s", msg);
08290 else
08291 NotifyLogMsg(msg, 0);
08292 }
08293 return;
08294 }
08295
08296 if (TestBit(TProof::kIsMaster)) {
08297 TMessage mess(kPROOF_DATASET_STATUS);
08298 mess << TString(action) << tot << done << st;
08299 gProofServ->GetSocket()->Send(mess);
08300 }
08301 }
08302
08303
08304 void TProof::QueryResultReady(const char *ref)
08305 {
08306
08307
08308 PDB(kGlobal,1)
08309 Info("QueryResultReady","ref: %s", ref);
08310
08311 Emit("QueryResultReady(const char*)",ref);
08312 }
08313
08314
08315 void TProof::ValidateDSet(TDSet *dset)
08316 {
08317
08318
08319 if (dset->ElementsValid()) return;
08320
08321 TList nodes;
08322 nodes.SetOwner();
08323
08324 TList slholder;
08325 slholder.SetOwner();
08326 TList elemholder;
08327 elemholder.SetOwner();
08328
08329
08330 TIter nextSlave(GetListOfActiveSlaves());
08331 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
08332 TList *sllist = 0;
08333 TPair *p = dynamic_cast<TPair*>(nodes.FindObject(sl->GetName()));
08334 if (!p) {
08335 sllist = new TList;
08336 sllist->SetName(sl->GetName());
08337 slholder.Add(sllist);
08338 TList *elemlist = new TList;
08339 elemlist->SetName(TString(sl->GetName())+"_elem");
08340 elemholder.Add(elemlist);
08341 nodes.Add(new TPair(sllist, elemlist));
08342 } else {
08343 sllist = dynamic_cast<TList*>(p->Key());
08344 }
08345 if (sllist) sllist->Add(sl);
08346 }
08347
08348
08349 TList nonLocal;
08350
08351 for (Int_t i = 0; i < 2; i++) {
08352 Bool_t local = i>0?kFALSE:kTRUE;
08353 TIter nextElem(local ? dset->GetListOfElements() : &nonLocal);
08354 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
08355 if (elem->GetValid()) continue;
08356 TPair *p = dynamic_cast<TPair*>(local?nodes.FindObject(TUrl(elem->GetFileName()).GetHost()):nodes.At(0));
08357 if (p) {
08358 TList *eli = dynamic_cast<TList*>(p->Value());
08359 TList *sli = dynamic_cast<TList*>(p->Key());
08360 if (eli && sli) {
08361 eli->Add(elem);
08362
08363
08364 TPair *p2 = p;
08365 Bool_t stop = kFALSE;
08366 while (!stop) {
08367 TPair *p3 = dynamic_cast<TPair*>(nodes.After(p2->Key()));
08368 if (p3) {
08369 TList *p3v = dynamic_cast<TList*>(p3->Value());
08370 TList *p3k = dynamic_cast<TList*>(p3->Key());
08371 if (p3v && p3k) {
08372 Int_t nelem = p3v->GetSize();
08373 Int_t nsl = p3k->GetSize();
08374 if (nelem*sli->GetSize() < eli->GetSize()*nsl) p2 = p3;
08375 else stop = kTRUE;
08376 }
08377 } else {
08378 stop = kTRUE;
08379 }
08380 }
08381
08382 if (p2!=p) {
08383 nodes.Remove(p->Key());
08384 nodes.AddAfter(p2->Key(), p);
08385 }
08386 } else {
08387 Warning("ValidateDSet", "invalid values from TPair! Protocol error?");
08388 continue;
08389 }
08390
08391 } else {
08392 if (local) {
08393 nonLocal.Add(elem);
08394 } else {
08395 Warning("ValidateDSet", "no node to allocate TDSetElement to - ignoring");
08396 }
08397 }
08398 }
08399 }
08400
08401
08402 TList usedslaves;
08403 TIter nextNode(&nodes);
08404 SetDSet(dset);
08405 while (TPair *node = dynamic_cast<TPair*>(nextNode())) {
08406 TList *slaves = dynamic_cast<TList*>(node->Key());
08407 TList *setelements = dynamic_cast<TList*>(node->Value());
08408 if (!slaves || !setelements) continue;
08409
08410 Int_t nslaves = slaves->GetSize();
08411 Int_t nelements = setelements->GetSize();
08412 for (Int_t i=0; i<nslaves; i++) {
08413
08414 TDSet copyset(dset->GetType(), dset->GetObjName(),
08415 dset->GetDirectory());
08416 for (Int_t j = (i*nelements)/nslaves;
08417 j < ((i+1)*nelements)/nslaves;
08418 j++) {
08419 TDSetElement *elem =
08420 dynamic_cast<TDSetElement*>(setelements->At(j));
08421 if (elem) {
08422 copyset.Add(elem->GetFileName(), elem->GetObjName(),
08423 elem->GetDirectory(), elem->GetFirst(),
08424 elem->GetNum(), elem->GetMsd());
08425 }
08426 }
08427
08428 if (copyset.GetListOfElements()->GetSize()>0) {
08429 TMessage mesg(kPROOF_VALIDATE_DSET);
08430 mesg << ©set;
08431
08432 TSlave *sl = dynamic_cast<TSlave*>(slaves->At(i));
08433 if (sl) {
08434 PDB(kGlobal,1) Info("ValidateDSet",
08435 "Sending TDSet with %d elements to slave %s"
08436 " to be validated",
08437 copyset.GetListOfElements()->GetSize(),
08438 sl->GetOrdinal());
08439 sl->GetSocket()->Send(mesg);
08440 usedslaves.Add(sl);
08441 }
08442 }
08443 }
08444 }
08445
08446 PDB(kGlobal,1)
08447 Info("ValidateDSet","Calling Collect");
08448 Collect(&usedslaves);
08449 SetDSet(0);
08450 }
08451
08452
08453 void TProof::AddInputData(TObject *obj, Bool_t push)
08454 {
08455
08456
08457
08458
08459
08460
08461 if (obj) {
08462 if (!fInputData) fInputData = new TList;
08463 if (!fInputData->FindObject(obj)) {
08464 fInputData->Add(obj);
08465 SetBit(TProof::kNewInputData);
08466 }
08467 }
08468 if (push) SetBit(TProof::kNewInputData);
08469 }
08470
08471
08472 void TProof::ClearInputData(TObject *obj)
08473 {
08474
08475
08476
08477 if (!obj) {
08478 if (fInputData) {
08479 fInputData->SetOwner(kTRUE);
08480 SafeDelete(fInputData);
08481 }
08482 ResetBit(TProof::kNewInputData);
08483
08484
08485 TObject *o = 0;
08486 TList *in = GetInputList();
08487 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
08488 in->Remove(o);
08489 while ((o = GetInputList()->FindObject("PROOF_InputData")))
08490 in->Remove(o);
08491
08492
08493 fInputDataFile = "";
08494 gSystem->Unlink(kPROOF_InputDataFile);
08495
08496 } else if (fInputData) {
08497 Int_t sz = fInputData->GetSize();
08498 while (fInputData->FindObject(obj))
08499 fInputData->Remove(obj);
08500
08501 if (sz != fInputData->GetSize())
08502 SetBit(TProof::kNewInputData);
08503 }
08504 }
08505
08506
08507 void TProof::ClearInputData(const char *name)
08508 {
08509
08510
08511 TObject *obj = (fInputData && name) ? fInputData->FindObject(name) : 0;
08512 if (obj) ClearInputData(obj);
08513 }
08514
08515
08516 void TProof::SetInputDataFile(const char *datafile)
08517 {
08518
08519
08520
08521
08522
08523
08524 if (datafile && strlen(datafile) > 0) {
08525 if (fInputDataFile != datafile && strcmp(datafile, kPROOF_InputDataFile))
08526 SetBit(TProof::kNewInputData);
08527 fInputDataFile = datafile;
08528 } else {
08529 if (!fInputDataFile.IsNull())
08530 SetBit(TProof::kNewInputData);
08531 fInputDataFile = "";
08532 }
08533
08534 if (fInputDataFile != kPROOF_InputDataFile && !fInputDataFile.IsNull() &&
08535 gSystem->AccessPathName(fInputDataFile, kReadPermission)) {
08536 fInputDataFile = "";
08537 }
08538 }
08539
08540
08541 void TProof::SendInputDataFile()
08542 {
08543
08544
08545
08546
08547
08548
08549
08550
08551
08552 TString dataFile;
08553 PrepareInputDataFile(dataFile);
08554
08555
08556 if (dataFile.Length() > 0) {
08557
08558 Info("SendInputDataFile", "broadcasting %s", dataFile.Data());
08559 BroadcastFile(dataFile.Data(), kBinary, "cache", kActive);
08560
08561
08562 AddInput(new TNamed("PROOF_InputDataFile", Form("cache:%s", gSystem->BaseName(dataFile))));
08563 }
08564 }
08565
08566
08567 void TProof::PrepareInputDataFile(TString &dataFile)
08568 {
08569
08570
08571
08572
08573
08574
08575
08576
08577
08578 Bool_t newdata = TestBit(TProof::kNewInputData) ? kTRUE : kFALSE;
08579
08580 ResetBit(TProof::kNewInputData);
08581
08582
08583 Bool_t list_ok = (fInputData && fInputData->GetSize() > 0) ? kTRUE : kFALSE;
08584
08585 Bool_t file_ok = kFALSE;
08586 if (fInputDataFile != kPROOF_InputDataFile && !fInputDataFile.IsNull() &&
08587 !gSystem->AccessPathName(fInputDataFile, kReadPermission)) {
08588
08589 TFile *f = TFile::Open(fInputDataFile);
08590 if (f && f->GetListOfKeys() && f->GetListOfKeys()->GetSize() > 0)
08591 file_ok = kTRUE;
08592 }
08593
08594
08595 TObject *o = 0;
08596 TList *in = GetInputList();
08597 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
08598 in->Remove(o);
08599 while ((o = GetInputList()->FindObject("PROOF_InputData")))
08600 in->Remove(o);
08601
08602
08603 dataFile = "";
08604 if (!list_ok && !file_ok) return;
08605
08606
08607 if (file_ok && !list_ok) {
08608
08609 dataFile = fInputDataFile;
08610 } else if (!file_ok && list_ok) {
08611 fInputDataFile = kPROOF_InputDataFile;
08612
08613 if (!newdata && !gSystem->AccessPathName(fInputDataFile)) return;
08614
08615 TFile *f = TFile::Open(fInputDataFile, "RECREATE");
08616 if (f) {
08617 f->cd();
08618 TIter next(fInputData);
08619 TObject *obj;
08620 while ((obj = next())) {
08621 obj->Write(0, TObject::kSingleKey, 0);
08622 }
08623 f->Close();
08624 SafeDelete(f);
08625 } else {
08626 Error("PrepareInputDataFile", "could not (re-)create %s", fInputDataFile.Data());
08627 return;
08628 }
08629 dataFile = fInputDataFile;
08630 } else if (file_ok && list_ok) {
08631 dataFile = kPROOF_InputDataFile;
08632
08633 if (newdata || gSystem->AccessPathName(dataFile)) {
08634
08635 if (!gSystem->AccessPathName(dataFile))
08636 gSystem->Unlink(dataFile);
08637 if (dataFile != fInputDataFile) {
08638
08639 if (gSystem->CopyFile(fInputDataFile, dataFile, kTRUE) != 0) {
08640 Error("PrepareInputDataFile", "could not make local copy of %s", fInputDataFile.Data());
08641 return;
08642 }
08643 }
08644
08645 TFile *f = TFile::Open(dataFile, "UPDATE");
08646 if (f) {
08647 f->cd();
08648 TIter next(fInputData);
08649 TObject *obj = 0;
08650 while ((obj = next())) {
08651 obj->Write(0, TObject::kSingleKey, 0);
08652 }
08653 f->Close();
08654 SafeDelete(f);
08655 } else {
08656 Error("PrepareInputDataFile", "could not open %s for updating", dataFile.Data());
08657 return;
08658 }
08659 }
08660 }
08661
08662
08663 return;
08664 }
08665
08666
08667 void TProof::AddInput(TObject *obj)
08668 {
08669
08670
08671
08672 if (fPlayer) fPlayer->AddInput(obj);
08673 }
08674
08675
08676 void TProof::ClearInput()
08677 {
08678
08679
08680 if (fPlayer) fPlayer->ClearInput();
08681
08682
08683 AddInput(fFeedback);
08684 }
08685
08686
08687 TList *TProof::GetInputList()
08688 {
08689
08690
08691 return (fPlayer ? fPlayer->GetInputList() : (TList *)0);
08692 }
08693
08694
08695 TObject *TProof::GetOutput(const char *name)
08696 {
08697
08698
08699
08700
08701 return (fPlayer) ? fPlayer->GetOutput(name) : (TObject *)0;
08702 }
08703
08704
08705 TList *TProof::GetOutputList()
08706 {
08707
08708
08709 return (fPlayer ? fPlayer->GetOutputList() : (TList *)0);
08710 }
08711
08712
08713 void TProof::SetParameter(const char *par, const char *value)
08714 {
08715
08716
08717
08718 if (!fPlayer) {
08719 Warning("SetParameter", "player undefined! Ignoring");
08720 return;
08721 }
08722
08723 TList *il = fPlayer->GetInputList();
08724 TObject *item = il->FindObject(par);
08725 if (item) {
08726 il->Remove(item);
08727 delete item;
08728 }
08729 il->Add(new TNamed(par, value));
08730 }
08731
08732
08733 void TProof::SetParameter(const char *par, Int_t value)
08734 {
08735
08736
08737 if (!fPlayer) {
08738 Warning("SetParameter", "player undefined! Ignoring");
08739 return;
08740 }
08741
08742 TList *il = fPlayer->GetInputList();
08743 TObject *item = il->FindObject(par);
08744 if (item) {
08745 il->Remove(item);
08746 delete item;
08747 }
08748 il->Add(new TParameter<Int_t>(par, value));
08749 }
08750
08751
08752 void TProof::SetParameter(const char *par, Long_t value)
08753 {
08754
08755
08756 if (!fPlayer) {
08757 Warning("SetParameter", "player undefined! Ignoring");
08758 return;
08759 }
08760
08761 TList *il = fPlayer->GetInputList();
08762 TObject *item = il->FindObject(par);
08763 if (item) {
08764 il->Remove(item);
08765 delete item;
08766 }
08767 il->Add(new TParameter<Long_t>(par, value));
08768 }
08769
08770
08771 void TProof::SetParameter(const char *par, Long64_t value)
08772 {
08773
08774
08775 if (!fPlayer) {
08776 Warning("SetParameter", "player undefined! Ignoring");
08777 return;
08778 }
08779
08780 TList *il = fPlayer->GetInputList();
08781 TObject *item = il->FindObject(par);
08782 if (item) {
08783 il->Remove(item);
08784 delete item;
08785 }
08786 il->Add(new TParameter<Long64_t>(par, value));
08787 }
08788
08789
08790 void TProof::SetParameter(const char *par, Double_t value)
08791 {
08792
08793
08794 if (!fPlayer) {
08795 Warning("SetParameter", "player undefined! Ignoring");
08796 return;
08797 }
08798
08799 TList *il = fPlayer->GetInputList();
08800 TObject *item = il->FindObject(par);
08801 if (item) {
08802 il->Remove(item);
08803 delete item;
08804 }
08805 il->Add(new TParameter<Double_t>(par, value));
08806 }
08807
08808
08809 TObject *TProof::GetParameter(const char *par) const
08810 {
08811
08812
08813
08814 if (!fPlayer) {
08815 Warning("GetParameter", "player undefined! Ignoring");
08816 return (TObject *)0;
08817 }
08818
08819 TList *il = fPlayer->GetInputList();
08820 return il->FindObject(par);
08821 }
08822
08823
08824 void TProof::DeleteParameters(const char *wildcard)
08825 {
08826
08827
08828
08829 if (!fPlayer) return;
08830
08831 if (!wildcard) wildcard = "";
08832 TRegexp re(wildcard, kTRUE);
08833 Int_t nch = strlen(wildcard);
08834
08835 TList *il = fPlayer->GetInputList();
08836 if (il) {
08837 TObject *p = 0;
08838 TIter next(il);
08839 while ((p = next())) {
08840 TString s = p->GetName();
08841 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
08842 il->Remove(p);
08843 delete p;
08844 }
08845 }
08846 }
08847
08848
08849 void TProof::ShowParameters(const char *wildcard) const
08850 {
08851
08852
08853
08854 if (!fPlayer) return;
08855
08856 if (!wildcard) wildcard = "";
08857 TRegexp re(wildcard, kTRUE);
08858 Int_t nch = strlen(wildcard);
08859
08860 TList *il = fPlayer->GetInputList();
08861 TObject *p;
08862 TIter next(il);
08863 while ((p = next())) {
08864 TString s = p->GetName();
08865 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
08866 if (p->IsA() == TNamed::Class()) {
08867 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
08868 } else if (p->IsA() == TParameter<Long_t>::Class()) {
08869 Printf("%s\t\t\t%ld", s.Data(), dynamic_cast<TParameter<Long_t>*>(p)->GetVal());
08870 } else if (p->IsA() == TParameter<Long64_t>::Class()) {
08871 Printf("%s\t\t\t%lld", s.Data(), dynamic_cast<TParameter<Long64_t>*>(p)->GetVal());
08872 } else if (p->IsA() == TParameter<Double_t>::Class()) {
08873 Printf("%s\t\t\t%f", s.Data(), dynamic_cast<TParameter<Double_t>*>(p)->GetVal());
08874 } else {
08875 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
08876 }
08877 }
08878 }
08879
08880
08881 void TProof::AddFeedback(const char *name)
08882 {
08883
08884
08885 PDB(kFeedback, 3)
08886 Info("AddFeedback", "Adding object \"%s\" to feedback", name);
08887 if (fFeedback->FindObject(name) == 0)
08888 fFeedback->Add(new TObjString(name));
08889 }
08890
08891
08892 void TProof::RemoveFeedback(const char *name)
08893 {
08894
08895
08896 TObject *obj = fFeedback->FindObject(name);
08897 if (obj != 0) {
08898 fFeedback->Remove(obj);
08899 delete obj;
08900 }
08901 }
08902
08903
08904 void TProof::ClearFeedback()
08905 {
08906
08907
08908 fFeedback->Delete();
08909 }
08910
08911
08912 void TProof::ShowFeedback() const
08913 {
08914
08915
08916 if (fFeedback->GetSize() == 0) {
08917 Info("","no feedback requested");
08918 return;
08919 }
08920
08921 fFeedback->Print();
08922 }
08923
08924
08925 TList *TProof::GetFeedbackList() const
08926 {
08927
08928
08929 return fFeedback;
08930 }
08931
08932
08933 TTree *TProof::GetTreeHeader(TDSet *dset)
08934 {
08935
08936
08937
08938 TList *l = GetListOfActiveSlaves();
08939 TSlave *sl = (TSlave*) l->First();
08940 if (sl == 0) {
08941 Error("GetTreeHeader", "No connection");
08942 return 0;
08943 }
08944
08945 TSocket *soc = sl->GetSocket();
08946 TMessage msg(kPROOF_GETTREEHEADER);
08947
08948 msg << dset;
08949
08950 soc->Send(msg);
08951
08952 TMessage *reply;
08953 Int_t d = -1;
08954 if (fProtocol >= 20) {
08955 Collect(sl, fCollectTimeout, kPROOF_GETTREEHEADER);
08956 reply = (TMessage *) fRecvMessages->First();
08957 } else {
08958 d = soc->Recv(reply);
08959 }
08960 if (!reply) {
08961 Error("GetTreeHeader", "Error getting a replay from the master.Result %d", (int) d);
08962 return 0;
08963 }
08964
08965 TString s1;
08966 TTree *t = 0;
08967 (*reply) >> s1;
08968 if (s1 == "Success")
08969 (*reply) >> t;
08970
08971 PDB(kGlobal, 1) {
08972 if (t) {
08973 Info("GetTreeHeader", "%s, message size: %d, entries: %d",
08974 s1.Data(), reply->BufferSize(), (int) t->GetMaxEntryLoop());
08975 } else {
08976 Info("GetTreeHeader", "tree header retrieval failed");
08977 }
08978 }
08979 delete reply;
08980
08981 return t;
08982 }
08983
08984
08985 TDrawFeedback *TProof::CreateDrawFeedback()
08986 {
08987
08988
08989
08990 return (fPlayer ? fPlayer->CreateDrawFeedback(this) : (TDrawFeedback *)0);
08991 }
08992
08993
08994 void TProof::SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)
08995 {
08996
08997
08998 if (fPlayer) fPlayer->SetDrawFeedbackOption(f, opt);
08999 }
09000
09001
09002 void TProof::DeleteDrawFeedback(TDrawFeedback *f)
09003 {
09004
09005
09006 if (fPlayer) fPlayer->DeleteDrawFeedback(f);
09007 }
09008
09009
09010 TList *TProof::GetOutputNames()
09011 {
09012
09013
09014 return 0;
09015
09016
09017
09018
09019
09020
09021
09022
09023
09024
09025
09026
09027
09028
09029
09030
09031
09032
09033
09034
09035
09036
09037
09038
09039
09040
09041
09042
09043
09044
09045
09046
09047
09048
09049
09050
09051
09052
09053
09054
09055
09056
09057
09058
09059
09060
09061
09062
09063
09064
09065
09066
09067
09068 }
09069
09070
09071 void TProof::Browse(TBrowser *b)
09072 {
09073
09074
09075 b->Add(fActiveSlaves, fActiveSlaves->Class(), "fActiveSlaves");
09076 b->Add(&fMaster, fMaster.Class(), "fMaster");
09077 b->Add(fFeedback, fFeedback->Class(), "fFeedback");
09078 b->Add(fChains, fChains->Class(), "fChains");
09079
09080 if (fPlayer) {
09081 b->Add(fPlayer->GetInputList(), fPlayer->GetInputList()->Class(), "InputList");
09082 if (fPlayer->GetOutputList())
09083 b->Add(fPlayer->GetOutputList(), fPlayer->GetOutputList()->Class(), "OutputList");
09084 if (fPlayer->GetListOfResults())
09085 b->Add(fPlayer->GetListOfResults(),
09086 fPlayer->GetListOfResults()->Class(), "ListOfResults");
09087 }
09088 }
09089
09090
09091 void TProof::SetPlayer(TVirtualProofPlayer *player)
09092 {
09093
09094
09095 if (fPlayer)
09096 delete fPlayer;
09097 fPlayer = player;
09098 };
09099
09100
09101 TVirtualProofPlayer *TProof::MakePlayer(const char *player, TSocket *s)
09102 {
09103
09104
09105
09106
09107 if (!player)
09108 player = "remote";
09109
09110 SetPlayer(TVirtualProofPlayer::Create(player, this, s));
09111 return GetPlayer();
09112 }
09113
09114
09115 void TProof::AddChain(TChain *chain)
09116 {
09117
09118
09119 fChains->Add(chain);
09120 }
09121
09122
09123 void TProof::RemoveChain(TChain *chain)
09124 {
09125
09126
09127 fChains->Remove(chain);
09128 }
09129
09130
09131 void TProof::GetLog(Int_t start, Int_t end)
09132 {
09133
09134
09135
09136 if (!IsValid() || TestBit(TProof::kIsMaster)) return;
09137
09138 TMessage msg(kPROOF_LOGFILE);
09139
09140 msg << start << end;
09141
09142 Broadcast(msg, kActive);
09143 Collect(kActive, fCollectTimeout);
09144 }
09145
09146
09147 TMacro *TProof::GetLastLog()
09148 {
09149
09150
09151
09152
09153 TMacro *maclog = 0;
09154
09155
09156 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
09157 if (nowlog < 0) {
09158 SysError("GetLastLog",
09159 "problem lseeking log file to current position (errno: %d)", TSystem::GetErrno());
09160 return maclog;
09161 }
09162
09163
09164 off_t startlog = nowlog;
09165 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
09166 if (endlog < 0) {
09167 SysError("GetLastLog",
09168 "problem lseeking log file to end position (errno: %d)", TSystem::GetErrno());
09169 return maclog;
09170 }
09171
09172
09173 UInt_t tolog = (UInt_t)(endlog - startlog);
09174 if (tolog <= 0) return maclog;
09175
09176
09177 if (lseek(fileno(fLogFileR), startlog, SEEK_SET) < 0) {
09178 SysError("GetLastLog",
09179 "problem lseeking log file to start position (errno: %d)", TSystem::GetErrno());
09180 return maclog;
09181 }
09182
09183
09184 maclog = new TMacro;
09185
09186
09187 char line[2048];
09188 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
09189 while (fgets(line, wanted, fLogFileR)) {
09190 Int_t r = strlen(line);
09191 if (r > 0) {
09192 if (line[r-1] == '\n') line[r-1] = '\0';
09193 maclog->AddLine(line);
09194 } else {
09195
09196 break;
09197 }
09198 tolog -= r;
09199 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
09200 }
09201
09202
09203 if (lseek(fileno(fLogFileR), nowlog, SEEK_SET) < 0) {
09204 Warning("GetLastLog",
09205 "problem lseeking log file to original position (errno: %d)", TSystem::GetErrno());
09206 }
09207
09208
09209 return maclog;
09210 }
09211
09212
09213 void TProof::PutLog(TQueryResult *pq)
09214 {
09215
09216
09217 if (!pq) return;
09218
09219 TList *lines = pq->GetLogFile()->GetListOfLines();
09220 if (lines) {
09221 TIter nxl(lines);
09222 TObjString *l = 0;
09223 while ((l = (TObjString *)nxl()))
09224 EmitVA("LogMessage(const char*,Bool_t)", 2, l->GetName(), kFALSE);
09225 }
09226 }
09227
09228
09229 void TProof::ShowLog(const char *queryref)
09230 {
09231
09232
09233
09234
09235
09236 Retrieve(queryref);
09237
09238 if (fPlayer) {
09239 if (queryref) {
09240 if (fPlayer->GetListOfResults()) {
09241 TIter nxq(fPlayer->GetListOfResults());
09242 TQueryResult *qr = 0;
09243 while ((qr = (TQueryResult *) nxq()))
09244 if (strstr(queryref, qr->GetTitle()) &&
09245 strstr(queryref, qr->GetName()))
09246 break;
09247 if (qr) {
09248 PutLog(qr);
09249 return;
09250 }
09251
09252 }
09253 }
09254 }
09255 }
09256
09257
09258 void TProof::ShowLog(Int_t qry)
09259 {
09260
09261
09262
09263
09264
09265
09266
09267
09268 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
09269 if (nowlog < 0) {
09270 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
09271 return;
09272 }
09273
09274
09275 off_t startlog = nowlog;
09276 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
09277 if (endlog < 0) {
09278 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
09279 return;
09280 }
09281
09282 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
09283 if (qry == 0) {
09284 startlog = 0;
09285 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
09286 } else if (qry != -1) {
09287
09288 TQueryResult *pq = 0;
09289 if (qry == -2) {
09290
09291 pq = (GetQueryResults()) ? ((TQueryResult *)(GetQueryResults()->Last())) : 0;
09292 if (!pq) {
09293 GetListOfQueries();
09294 if (fQueries)
09295 pq = (TQueryResult *)(fQueries->Last());
09296 }
09297 } else if (qry > 0) {
09298 TList *queries = GetQueryResults();
09299 if (queries) {
09300 TIter nxq(queries);
09301 while ((pq = (TQueryResult *)nxq()))
09302 if (qry == pq->GetSeqNum())
09303 break;
09304 }
09305 if (!pq) {
09306 queries = GetListOfQueries();
09307 TIter nxq(queries);
09308 while ((pq = (TQueryResult *)nxq()))
09309 if (qry == pq->GetSeqNum())
09310 break;
09311 }
09312 }
09313 if (pq) {
09314 PutLog(pq);
09315 return;
09316 } else {
09317 if (gDebug > 0)
09318 Info("ShowLog","query %d not found in list", qry);
09319 qry = -1;
09320 }
09321 }
09322
09323
09324 UInt_t tolog = (UInt_t)(endlog - startlog);
09325
09326
09327 if (tolog <= 0)
09328
09329
09330 lseek(fileno(fLogFileR), startlog, SEEK_SET);
09331
09332
09333 Int_t np = 0;
09334 char line[2048];
09335 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
09336 while (fgets(line, wanted, fLogFileR)) {
09337
09338 Int_t r = strlen(line);
09339 if (!SendingLogToWindow()) {
09340 if (line[r-1] != '\n') line[r-1] = '\n';
09341 if (r > 0) {
09342 char *p = line;
09343 while (r) {
09344 Int_t w = write(fileno(stdout), p, r);
09345 if (w < 0) {
09346 SysError("ShowLog", "error writing to stdout");
09347 break;
09348 }
09349 r -= w;
09350 p += w;
09351 }
09352 }
09353 tolog -= strlen(line);
09354 np++;
09355
09356
09357 if (!(np%10)) {
09358 char *opt = Getline("More (y/n)? [y]");
09359 if (opt[0] == 'n')
09360 break;
09361 }
09362
09363
09364 if (tolog <= 0)
09365 break;
09366
09367
09368 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
09369 } else {
09370
09371 if (line[r-1] == '\n') line[r-1] = 0;
09372 LogMessage(line, kFALSE);
09373 }
09374 }
09375 if (!SendingLogToWindow()) {
09376
09377 if (write(fileno(stdout), "\n", 1) != 1)
09378 SysError("ShowLog", "error writing to stdout");
09379 }
09380
09381
09382 if (qry > -1)
09383 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
09384 }
09385
09386
09387 void TProof::cd(Int_t id)
09388 {
09389
09390
09391
09392 if (GetManager()) {
09393 TProofDesc *d = GetManager()->GetProofDesc(id);
09394 if (d) {
09395 if (d->GetProof()) {
09396 gProof = d->GetProof();
09397 return;
09398 }
09399 }
09400
09401
09402 gProof = this;
09403 }
09404
09405 return;
09406 }
09407
09408
09409 void TProof::Detach(Option_t *opt)
09410 {
09411
09412
09413
09414
09415 if (!IsValid()) return;
09416
09417
09418 TSlave *sl = (TSlave *) fActiveSlaves->First();
09419 TSocket *s = 0;
09420 if (!sl || !(sl->IsValid()) || !(s = sl->GetSocket())) {
09421 Error("Detach","corrupted worker instance: wrk:%p, sock:%p", sl, s);
09422 return;
09423 }
09424
09425 Bool_t shutdown = (strchr(opt,'s') || strchr(opt,'S')) ? kTRUE : kFALSE;
09426
09427
09428 if (shutdown && !IsIdle()) {
09429
09430 Remove("cleanupqueue");
09431
09432 Long_t timeout = gEnv->GetValue("Proof.ShutdownTimeout", 60);
09433 timeout = (timeout > 20) ? timeout : 20;
09434
09435 StopProcess(kFALSE, (Long_t) (timeout / 2));
09436
09437 Collect(kActive, timeout);
09438 }
09439
09440
09441 DeActivateAsyncInput();
09442
09443
09444 sl->FlushSocket();
09445
09446
09447 Close(opt);
09448
09449
09450 if (fProgressDialogStarted)
09451 CloseProgressDialog();
09452
09453
09454 if (GetManager() && GetManager()->QuerySessions("L")) {
09455 TIter nxd(GetManager()->QuerySessions("L"));
09456 TProofDesc *d = 0;
09457 while ((d = (TProofDesc *)nxd())) {
09458 if (d->GetProof() == this) {
09459 d->SetProof(0);
09460 GetManager()->QuerySessions("L")->Remove(d);
09461 break;
09462 }
09463 }
09464 }
09465
09466
09467 fValid = kFALSE;
09468
09469 return;
09470 }
09471
09472
09473 void TProof::SetAlias(const char *alias)
09474 {
09475
09476
09477
09478
09479
09480 TNamed::SetTitle(alias);
09481 if (TestBit(TProof::kIsMaster))
09482
09483 TNamed::SetName(alias);
09484
09485
09486 if (!IsValid()) return;
09487
09488 if (!IsProofd() && TestBit(TProof::kIsClient)) {
09489 TSlave *sl = (TSlave *) fActiveSlaves->First();
09490 if (sl)
09491 sl->SetAlias(alias);
09492 }
09493
09494 return;
09495 }
09496
09497
09498 Int_t TProof::UploadDataSet(const char *dataSetName,
09499 TList *files,
09500 const char *desiredDest,
09501 Int_t opt,
09502 TList *skippedFiles)
09503 {
09504
09505
09506
09507
09508
09509
09510
09511
09512
09513
09514
09515
09516
09517
09518
09519
09520
09521
09522
09523
09524
09525
09526
09527
09528
09529
09530
09531 if (!IsValid()) {
09532 Error("UploadDataSet", "not connected");
09533 return -1;
09534 }
09535
09536 if (fProtocol < 15) {
09537 Info("UploadDataSet", "functionality not available: the server has an"
09538 " incompatible version of TFileInfo");
09539 return -1;
09540 }
09541
09542 if (IsLite()) {
09543 Info("UploadDataSet", "Lite-session: functionality not needed - do nothing");
09544 return -1;
09545 }
09546
09547
09548 if (strchr(dataSetName, '/')) {
09549 if (strstr(dataSetName, "public") != dataSetName) {
09550 Error("UploadDataSet",
09551 "Name of public dataset should start with public/");
09552 return kError;
09553 }
09554 }
09555 if ((opt & kOverwriteAllFiles && opt & kOverwriteNoFiles) ||
09556 (opt & kNoOverwriteDataSet && opt & kAppend) ||
09557 (opt & kOverwriteDataSet && opt & kAppend) ||
09558 (opt & kNoOverwriteDataSet && opt & kOverwriteDataSet)) {
09559 Error("UploadDataSet", "you specified contradicting options.");
09560 return kError;
09561 }
09562
09563
09564 Int_t overwriteAll = (opt & kOverwriteAllFiles) ? kTRUE : kFALSE;
09565 Int_t overwriteNone = (opt & kOverwriteNoFiles) ? kTRUE : kFALSE;
09566 Int_t goodName = (opt & (kOverwriteDataSet | kAppend)) ? 1 : -1;
09567 Int_t appendToDataSet = (opt & kAppend) ? kTRUE : kFALSE;
09568 Int_t overwriteNoDataSet = (opt & kNoOverwriteDataSet) ? kTRUE : kFALSE;
09569
09570
09571
09572 if (!skippedFiles && overwriteNone) {
09573 Error("UploadDataSet",
09574 "Provide pointer to TList object as skippedFiles argument when using kOverwriteNoFiles option.");
09575 return kError;
09576 }
09577
09578 if (skippedFiles) {
09579 if (skippedFiles->Class() != TList::Class()) {
09580 Error("UploadDataSet",
09581 "Provided skippedFiles argument does not point to a TList object.");
09582 return kError;
09583 }
09584 }
09585
09586 Int_t fileCount = 0;
09587 if (goodName == -1) {
09588
09589
09590 TMessage nameMess(kPROOF_DATASETS);
09591 nameMess << Int_t(kCheckDataSetName);
09592 nameMess << TString(dataSetName);
09593 Broadcast(nameMess);
09594 Collect(kActive, fCollectTimeout);
09595 if (fStatus == -1) {
09596
09597 while (goodName == -1 && !overwriteNoDataSet) {
09598 Info("UploadDataSet", "dataset %s already exist. ",
09599 dataSetName);
09600 Info("UploadDataSet", "do you want to overwrite it[Yes/No/Append]?");
09601 TString answer;
09602 answer.ReadToken(cin);
09603 if (!strncasecmp(answer.Data(), "y", 1)) {
09604 goodName = 1;
09605 } else if (!strncasecmp(answer.Data(), "n", 1)) {
09606 goodName = 0;
09607 } else if (!strncasecmp(answer.Data(), "a", 1)) {
09608 goodName = 1;
09609 appendToDataSet = kTRUE;
09610 }
09611 }
09612 } else {
09613 goodName = 1;
09614 }
09615 }
09616 if (goodName == 1) {
09617
09618 char *relativeDestDir = Form("%s/%s/",
09619 gSystem->GetUserInfo()->fUser.Data(),
09620 desiredDest?desiredDest:"");
09621
09622
09623 relativeDestDir = CollapseSlashesInPath(relativeDestDir);
09624 TString dest = Form("%s/%s", GetDataPoolUrl(), relativeDestDir);
09625
09626 delete[] relativeDestDir;
09627
09628
09629 TFileCollection *fileList = new TFileCollection();
09630 TIter next(files);
09631 while (TFileInfo *fileInfo = ((TFileInfo*)next())) {
09632 TUrl *fileUrl = fileInfo->GetFirstUrl();
09633 if (gSystem->AccessPathName(fileUrl->GetUrl()) == kFALSE) {
09634
09635
09636 const char *ent = gSystem->BaseName(fileUrl->GetFile());
09637
09638 Int_t goodFileName = 1;
09639 if (!overwriteAll &&
09640 gSystem->AccessPathName(Form("%s/%s", dest.Data(), ent), kFileExists)
09641 == kFALSE) {
09642 goodFileName = -1;
09643 while (goodFileName == -1 && !overwriteAll && !overwriteNone) {
09644 Info("UploadDataSet", "file %s already exists. ", Form("%s/%s", dest.Data(), ent));
09645 Info("UploadDataSet", "do you want to overwrite it [Yes/No/all/none]?");
09646 TString answer;
09647 answer.ReadToken(cin);
09648 if (!strncasecmp(answer.Data(), "y", 1))
09649 goodFileName = 1;
09650 else if (!strncasecmp(answer.Data(), "all", 3))
09651 overwriteAll = kTRUE;
09652 else if (!strncasecmp(answer.Data(), "none", 4))
09653 overwriteNone = kTRUE;
09654 else if (!strncasecmp(answer.Data(), "n", 1))
09655 goodFileName = 0;
09656 }
09657 }
09658
09659
09660 if (goodFileName == 1 || overwriteAll) {
09661
09662 Info("UploadDataSet", "Uploading %s to %s/%s",
09663 fileUrl->GetUrl(), dest.Data(), ent);
09664 if (TFile::Cp(fileUrl->GetUrl(), Form("%s/%s", dest.Data(), ent))) {
09665 fileList->GetList()->Add(new TFileInfo(Form("%s/%s", dest.Data(), ent)));
09666 } else
09667 Error("UploadDataSet", "file %s was not copied", fileUrl->GetUrl());
09668 } else {
09669 fileList->GetList()->Add(new TFileInfo(Form("%s/%s", dest.Data(), ent)));
09670 if (skippedFiles) {
09671
09672
09673 skippedFiles->Add(new TFileInfo(fileUrl->GetUrl()));
09674 }
09675 }
09676 }
09677 }
09678
09679 if ((fileCount = fileList->GetList()->GetSize()) == 0) {
09680 Info("UploadDataSet", "no files were copied. The dataset will not be saved");
09681 } else {
09682 TString o = (appendToDataSet) ? "" : "O";
09683 if (!RegisterDataSet(dataSetName, fileList, o)) {
09684 Error("UploadDataSet", "Error while saving dataset: %s", dataSetName);
09685 fileCount = kError;
09686 }
09687 }
09688 delete fileList;
09689 } else if (overwriteNoDataSet) {
09690 Info("UploadDataSet", "dataset %s already exists", dataSetName);
09691 return kDataSetExists;
09692 }
09693
09694 return fileCount;
09695 }
09696
09697
09698 Int_t TProof::UploadDataSet(const char *dataSetName,
09699 const char *files,
09700 const char *desiredDest,
09701 Int_t opt,
09702 TList *skippedFiles)
09703 {
09704
09705
09706
09707
09708
09709
09710
09711
09712
09713
09714
09715
09716
09717
09718
09719
09720
09721
09722
09723 if (fProtocol < 15) {
09724 Info("UploadDataSet", "functionality not available: the server has an"
09725 " incompatible version of TFileInfo");
09726 return -1;
09727 }
09728
09729 TList fileList;
09730 fileList.SetOwner();
09731 void *dataSetDir = gSystem->OpenDirectory(gSystem->DirName(files));
09732 const char* ent;
09733 TString filesExp(gSystem->BaseName(files));
09734 filesExp.ReplaceAll("*",".*");
09735 TRegexp rg(filesExp);
09736 while ((ent = gSystem->GetDirEntry(dataSetDir))) {
09737 TString entryString(ent);
09738 if (entryString.Index(rg) != kNPOS) {
09739
09740 TString u(Form("file://%s/%s", gSystem->DirName(files), ent));
09741 if (gSystem->AccessPathName(u, kReadPermission) == kFALSE)
09742 fileList.Add(new TFileInfo(u));
09743 }
09744 }
09745 Int_t fileCount;
09746 if ((fileCount = fileList.GetSize()) == 0)
09747 Printf("No files match your selection. The dataset will not be saved");
09748 else
09749 fileCount = UploadDataSet(dataSetName, &fileList, desiredDest,
09750 opt, skippedFiles);
09751 return fileCount;
09752 }
09753
09754
09755 Int_t TProof::UploadDataSetFromFile(const char *dataset, const char *file,
09756 const char *dest, Int_t opt,
09757 TList *skippedFiles)
09758 {
09759
09760
09761
09762
09763
09764
09765 if (fProtocol < 15) {
09766 Info("UploadDataSetFromFile", "functionality not available: the server has an"
09767 " incompatible version of TFileInfo");
09768 return -1;
09769 }
09770
09771 Int_t fileCount = -1;
09772
09773 TList fileList;
09774 fileList.SetOwner();
09775 ifstream f;
09776 f.open(gSystem->ExpandPathName(file), ifstream::out);
09777 if (f.is_open()) {
09778 while (f.good()) {
09779 TString line;
09780 line.ReadToDelim(f);
09781 line.Strip(TString::kTrailing, '\n');
09782 if (gSystem->AccessPathName(line, kReadPermission) == kFALSE)
09783 fileList.Add(new TFileInfo(line));
09784 }
09785 f.close();
09786 if ((fileCount = fileList.GetSize()) == 0)
09787 Info("UploadDataSetFromFile",
09788 "no files match your selection. The dataset will not be saved");
09789 else
09790 fileCount = UploadDataSet(dataset, &fileList, dest,
09791 opt, skippedFiles);
09792 } else {
09793 Error("UploadDataSetFromFile", "unable to open the specified file");
09794 }
09795
09796 return fileCount;
09797 }
09798
09799
09800 Bool_t TProof::RegisterDataSet(const char *dataSetName,
09801 TFileCollection *dataSet, const char* optStr)
09802 {
09803
09804
09805
09806
09807
09808
09809
09810
09811
09812
09813
09814
09815
09816 if (fProtocol < 17) {
09817 Info("RegisterDataSet",
09818 "functionality not available: the server does not have dataset support");
09819 return kFALSE;
09820 }
09821
09822 if (!dataSetName || strlen(dataSetName) <= 0) {
09823 Info("RegisterDataSet", "specifying a dataset name is mandatory");
09824 return kFALSE;
09825 }
09826
09827 TMessage mess(kPROOF_DATASETS);
09828 mess << Int_t(kRegisterDataSet);
09829 mess << TString(dataSetName);
09830 mess << TString(optStr);
09831 mess.WriteObject(dataSet);
09832 Broadcast(mess);
09833
09834 Bool_t result = kTRUE;
09835 Collect();
09836 if (fStatus != 0) {
09837 Error("RegisterDataSet", "dataset was not saved");
09838 result = kFALSE;
09839 }
09840 return result;
09841 }
09842
09843
09844 Int_t TProof::SetDataSetTreeName(const char *dataset, const char *treename)
09845 {
09846
09847
09848
09849
09850
09851 if (fProtocol < 23) {
09852 Info("SetDataSetTreeName", "functionality not supported by the server");
09853 return -1;
09854 }
09855
09856 if (!dataset || strlen(dataset) <= 0) {
09857 Info("SetDataSetTreeName", "specifying a dataset name is mandatory");
09858 return -1;
09859 }
09860
09861 if (!treename || strlen(treename) <= 0) {
09862 Info("SetDataSetTreeName", "specifying a tree name is mandatory");
09863 return -1;
09864 }
09865
09866 TUri uri(dataset);
09867 TString fragment(treename);
09868 if (!fragment.BeginsWith("/")) fragment.Insert(0, "/");
09869 uri.SetFragment(fragment);
09870
09871 TMessage mess(kPROOF_DATASETS);
09872 mess << Int_t(kSetDefaultTreeName);
09873 mess << uri.GetUri();
09874 Broadcast(mess);
09875
09876 Collect();
09877 if (fStatus != 0) {
09878 Error("SetDataSetTreeName", "some error occured: default tree name not changed");
09879 return -1;
09880 }
09881 return 0;
09882 }
09883
09884
09885 TMap *TProof::GetDataSets(const char *uri, const char *optStr)
09886 {
09887
09888
09889
09890
09891
09892
09893 if (fProtocol < 15) {
09894 Info("GetDataSets",
09895 "functionality not available: the server does not have dataset support");
09896 return 0;
09897 }
09898 if (fProtocol < 31 && strstr(optStr, ":lite:"))
09899 Warning("GetDataSets", "'lite' option not supported by the server");
09900
09901 TMessage mess(kPROOF_DATASETS);
09902 mess << Int_t(kGetDataSets);
09903 mess << TString(uri ? uri : "");
09904 mess << TString(optStr ? optStr : "");
09905 Broadcast(mess);
09906 Collect(kActive, fCollectTimeout);
09907
09908 TMap *dataSetMap = 0;
09909 if (fStatus != 0) {
09910 Error("GetDataSets", "error receiving datasets information");
09911 } else {
09912
09913 TMessage *retMess = (TMessage *) fRecvMessages->First();
09914 if (retMess && retMess->What() == kMESS_OK) {
09915 if (!(dataSetMap = (TMap *)(retMess->ReadObject(TMap::Class()))))
09916 Error("GetDataSets", "error receiving datasets");
09917 } else
09918 Error("GetDataSets", "message not found or wrong type (%p)", retMess);
09919 }
09920
09921 return dataSetMap;
09922 }
09923
09924
09925 void TProof::ShowDataSets(const char *uri, const char* optStr)
09926 {
09927
09928
09929
09930 if (fProtocol < 15) {
09931 Info("ShowDataSets",
09932 "functionality not available: the server does not have dataset support");
09933 return;
09934 }
09935
09936 TMessage mess(kPROOF_DATASETS);
09937 mess << Int_t(kShowDataSets);
09938 mess << TString(uri ? uri : "");
09939 mess << TString(optStr ? optStr : "");
09940 Broadcast(mess);
09941
09942 Collect(kActive, fCollectTimeout);
09943 if (fStatus != 0)
09944 Error("ShowDataSets", "error receiving datasets information");
09945 }
09946
09947
09948 Bool_t TProof::ExistsDataSet(const char *dataset)
09949 {
09950
09951
09952 if (fProtocol < 15) {
09953 Info("ExistsDataSet", "functionality not available: the server has an"
09954 " incompatible version of TFileInfo");
09955 return kFALSE;
09956 }
09957
09958 if (!dataset || strlen(dataset) <= 0) {
09959 Error("ExistsDataSet", "dataset name missing");
09960 return kFALSE;
09961 }
09962
09963 TMessage msg(kPROOF_DATASETS);
09964 msg << Int_t(kCheckDataSetName) << TString(dataset);
09965 Broadcast(msg);
09966 Collect(kActive, fCollectTimeout);
09967 if (fStatus == -1) {
09968
09969 return kTRUE;
09970 }
09971
09972 return kFALSE;
09973 }
09974
09975
09976 void TProof::ClearDataSetCache(const char *dataset)
09977 {
09978
09979
09980 if (fProtocol < 28) {
09981 Info("ClearDataSetCache", "functionality not available on server");
09982 return;
09983 }
09984
09985 TMessage msg(kPROOF_DATASETS);
09986 msg << Int_t(kCache) << TString(dataset) << TString("clear");
09987 Broadcast(msg);
09988 Collect(kActive, fCollectTimeout);
09989
09990 return;
09991 }
09992
09993
09994 void TProof::ShowDataSetCache(const char *dataset)
09995 {
09996
09997
09998 if (fProtocol < 28) {
09999 Info("ShowDataSetCache", "functionality not available on server");
10000 return;
10001 }
10002
10003 TMessage msg(kPROOF_DATASETS);
10004 msg << Int_t(kCache) << TString(dataset) << TString("show");
10005 Broadcast(msg);
10006 Collect(kActive, fCollectTimeout);
10007
10008 return;
10009 }
10010
10011
10012 TFileCollection *TProof::GetDataSet(const char *uri, const char *optStr)
10013 {
10014
10015
10016
10017
10018
10019
10020
10021 if (fProtocol < 15) {
10022 Info("GetDataSet", "functionality not available: the server has an"
10023 " incompatible version of TFileInfo");
10024 return 0;
10025 }
10026
10027 if (!uri || strlen(uri) <= 0) {
10028 Info("GetDataSet", "specifying a dataset name is mandatory");
10029 return 0;
10030 }
10031
10032 TMessage nameMess(kPROOF_DATASETS);
10033 nameMess << Int_t(kGetDataSet);
10034 nameMess << TString(uri);
10035 nameMess << TString(optStr ? optStr: "");
10036 if (Broadcast(nameMess) < 0)
10037 Error("GetDataSet", "sending request failed");
10038
10039 Collect(kActive, fCollectTimeout);
10040 TFileCollection *fileList = 0;
10041 if (fStatus != 0) {
10042 Error("GetDataSet", "error receiving datasets information");
10043 } else {
10044
10045 TMessage *retMess = (TMessage *) fRecvMessages->First();
10046 if (retMess && retMess->What() == kMESS_OK) {
10047 if (!(fileList = (TFileCollection*)(retMess->ReadObject(TFileCollection::Class()))))
10048 Error("GetDataSet", "error reading list of files");
10049 } else
10050 Error("GetDataSet", "message not found or wrong type (%p)", retMess);
10051 }
10052
10053 return fileList;
10054 }
10055
10056
10057 void TProof::ShowDataSet(const char *uri, const char* opt)
10058 {
10059
10060
10061 TFileCollection *fileList = 0;
10062 if ((fileList = GetDataSet(uri))) {
10063 fileList->Print(opt);
10064 delete fileList;
10065 } else
10066 Warning("ShowDataSet","no such dataset: %s", uri);
10067 }
10068
10069
10070 Int_t TProof::RemoveDataSet(const char *uri, const char* optStr)
10071 {
10072
10073
10074
10075 TMessage nameMess(kPROOF_DATASETS);
10076 nameMess << Int_t(kRemoveDataSet);
10077 nameMess << TString(uri?uri:"");
10078 nameMess << TString(optStr?optStr:"");
10079 if (Broadcast(nameMess) < 0)
10080 Error("RemoveDataSet", "sending request failed");
10081 Collect(kActive, fCollectTimeout);
10082
10083 if (fStatus != 0)
10084 return -1;
10085 else
10086 return 0;
10087 }
10088
10089
10090 TList* TProof::FindDataSets(const char* , const char* )
10091 {
10092
10093
10094 Error ("FindDataSets", "not yet implemented");
10095 return (TList *) 0;
10096 }
10097
10098
10099 Int_t TProof::VerifyDataSet(const char *uri, const char* optStr)
10100 {
10101
10102
10103
10104 if (fProtocol < 15) {
10105 Info("VerifyDataSet", "functionality not available: the server has an"
10106 " incompatible version of TFileInfo");
10107 return kError;
10108 }
10109
10110 Int_t nMissingFiles = 0;
10111 TMessage nameMess(kPROOF_DATASETS);
10112 nameMess << Int_t(kVerifyDataSet);
10113 nameMess << TString(uri ? uri : "");
10114 nameMess << TString(optStr ? optStr : "");
10115 Broadcast(nameMess);
10116
10117 Collect(kActive, fCollectTimeout);
10118
10119 if (fStatus < 0) {
10120 Info("VerifyDataSet", "no such dataset %s", uri);
10121 return -1;
10122 } else
10123 nMissingFiles = fStatus;
10124 return nMissingFiles;
10125 }
10126
10127
10128 TMap *TProof::GetDataSetQuota(const char* optStr)
10129 {
10130
10131
10132 if (IsLite()) {
10133 Info("UploadDataSet", "Lite-session: functionality not implemented");
10134 return (TMap *)0;
10135 }
10136
10137 TMessage mess(kPROOF_DATASETS);
10138 mess << Int_t(kGetQuota);
10139 mess << TString(optStr?optStr:"");
10140 Broadcast(mess);
10141
10142 Collect(kActive, fCollectTimeout);
10143 TMap *groupQuotaMap = 0;
10144 if (fStatus < 0) {
10145 Info("GetDataSetQuota", "could not receive quota");
10146 } else {
10147
10148 TMessage *retMess = (TMessage *) fRecvMessages->First();
10149 if (retMess && retMess->What() == kMESS_OK) {
10150 if (!(groupQuotaMap = (TMap*)(retMess->ReadObject(TMap::Class()))))
10151 Error("GetDataSetQuota", "error getting quotas");
10152 } else
10153 Error("GetDataSetQuota", "message not found or wrong type (%p)", retMess);
10154 }
10155
10156 return groupQuotaMap;
10157 }
10158
10159
10160 void TProof::ShowDataSetQuota(Option_t* opt)
10161 {
10162
10163
10164
10165 if (fProtocol < 15) {
10166 Info("ShowDataSetQuota",
10167 "functionality not available: the server does not have dataset support");
10168 return;
10169 }
10170
10171 if (IsLite()) {
10172 Info("UploadDataSet", "Lite-session: functionality not implemented");
10173 return;
10174 }
10175
10176 TMessage mess(kPROOF_DATASETS);
10177 mess << Int_t(kShowQuota);
10178 mess << TString(opt?opt:"");
10179 Broadcast(mess);
10180
10181 Collect();
10182 if (fStatus != 0)
10183 Error("ShowDataSetQuota", "error receiving quota information");
10184 }
10185
10186
10187 void TProof::InterruptCurrentMonitor()
10188 {
10189
10190 if (fCurrentMonitor)
10191 fCurrentMonitor->Interrupt();
10192 }
10193
10194
10195 void TProof::ActivateWorker(const char *ord)
10196 {
10197
10198
10199
10200
10201
10202
10203
10204 ModifyWorkerLists(ord, kTRUE);
10205 }
10206
10207
10208 void TProof::DeactivateWorker(const char *ord)
10209 {
10210
10211
10212
10213
10214
10215
10216
10217 ModifyWorkerLists(ord, kFALSE);
10218 }
10219
10220
10221 void TProof::ModifyWorkerLists(const char *ord, Bool_t add)
10222 {
10223
10224
10225
10226
10227
10228
10229
10230
10231 if (!ord || strlen(ord) <= 0) {
10232 Info("ModifyWorkerLists",
10233 "An ordinal number - e.g. \"0.4\" or \"*\" for all - is required as input");
10234 return;
10235 }
10236
10237 Bool_t fw = kTRUE;
10238 Bool_t rs = kFALSE;
10239
10240
10241 TList *in = (add) ? fInactiveSlaves : fActiveSlaves;
10242 TList *out = (add) ? fActiveSlaves : fInactiveSlaves;
10243
10244 if (TestBit(TProof::kIsMaster)) {
10245 fw = IsEndMaster() ? kFALSE : kTRUE;
10246
10247 if (in->GetSize() > 0) {
10248 TIter nxw(in);
10249 TSlave *wrk = 0;
10250 while ((wrk = (TSlave *) nxw())) {
10251 if (ord[0] == '*' || !strncmp(wrk->GetOrdinal(), ord, strlen(ord))) {
10252
10253 if (!out->FindObject(wrk)) {
10254 out->Add(wrk);
10255 if (add)
10256 fActiveMonitor->Add(wrk->GetSocket());
10257 }
10258
10259 in->Remove(wrk);
10260 if (!add) {
10261 fActiveMonitor->Remove(wrk->GetSocket());
10262 wrk->SetStatus(TSlave::kInactive);
10263 } else
10264 wrk->SetStatus(TSlave::kActive);
10265
10266
10267 fw = kFALSE;
10268
10269 rs = kTRUE;
10270
10271 if (ord[0] != '*')
10272 break;
10273 }
10274 }
10275 }
10276 }
10277
10278
10279 if (rs)
10280 FindUniqueSlaves();
10281
10282
10283 Int_t action = (add) ? (Int_t) kActivateWorker : (Int_t) kDeactivateWorker;
10284 if (fw) {
10285 TMessage mess(kPROOF_WORKERLISTS);
10286 mess << action << TString(ord);
10287 Broadcast(mess);
10288 Collect(kActive, fCollectTimeout);
10289 }
10290 }
10291
10292
10293 TProof *TProof::Open(const char *cluster, const char *conffile,
10294 const char *confdir, Int_t loglevel)
10295 {
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307 const char *pn = "TProof::Open";
10308
10309
10310
10311 if (!cluster) {
10312
10313 TPluginManager *pm = gROOT->GetPluginManager();
10314 if (!pm) {
10315 ::Error(pn, "plugin manager not found");
10316 return 0;
10317 }
10318
10319 if (gROOT->IsBatch()) {
10320 ::Error(pn, "we are in batch mode, cannot show PROOF Session Viewer");
10321 return 0;
10322 }
10323
10324 TPluginHandler *sv = pm->FindHandler("TSessionViewer", "");
10325 if (!sv) {
10326 ::Error(pn, "no plugin found for TSessionViewer");
10327 return 0;
10328 }
10329 if (sv->LoadPlugin() == -1) {
10330 ::Error(pn, "plugin for TSessionViewer could not be loaded");
10331 return 0;
10332 }
10333 sv->ExecPlugin(0);
10334 return 0;
10335
10336 } else {
10337
10338 TString clst(cluster);
10339 if (clst.BeginsWith("workers=") || clst.BeginsWith("tunnel="))
10340 clst.Insert(0, "/?");
10341
10342
10343 TUrl u(clst);
10344
10345
10346 TString opts(u.GetOptions());
10347 if (!opts.IsNull()) {
10348 Int_t it = opts.Index("tunnel=");
10349 if (it != kNPOS) {
10350 TString sport = opts(it + strlen("tunnel="), opts.Length());
10351 TString host("127.0.0.1");
10352 Int_t port = -1;
10353 Int_t ic = sport.Index(":");
10354 if (ic != kNPOS) {
10355
10356 host = sport(0, ic);
10357 sport.Remove(0, ic + 1);
10358 }
10359 if (!sport.IsDigit()) {
10360
10361 TRegexp re("[^0-9]");
10362 Int_t ind = sport.Index(re);
10363 if (ind != kNPOS)
10364 sport.Remove(ind);
10365 }
10366
10367 if (sport.IsDigit())
10368 port = sport.Atoi();
10369 if (port > 0) {
10370
10371 ::Info("TProof::Open","using tunnel at %s:%d", host.Data(), port);
10372 gEnv->SetValue("XNet.SOCKS4Host", host);
10373 gEnv->SetValue("XNet.SOCKS4Port", port);
10374 } else {
10375
10376 ::Warning("TProof::Open",
10377 "problems parsing tunnelling info from options: %s", opts.Data());
10378 }
10379 }
10380 }
10381
10382
10383 Int_t locid = -1;
10384 Bool_t create = kFALSE;
10385 if (opts.Length() > 0) {
10386 if (opts.BeginsWith("N",TString::kIgnoreCase)) {
10387 create = kTRUE;
10388 opts.Remove(0,1);
10389 u.SetOptions(opts);
10390 } else if (opts.IsDigit()) {
10391 locid = opts.Atoi();
10392 }
10393 }
10394
10395
10396 TProofMgr *mgr = TProofMgr::Create(u.GetUrl());
10397
10398 TProof *proof = 0;
10399 if (mgr && mgr->IsValid()) {
10400
10401
10402
10403 Bool_t attach = (create || mgr->IsProofd() || mgr->IsLite()) ? kFALSE : kTRUE;
10404 if (attach) {
10405 TProofDesc *d = 0;
10406 if (locid < 0)
10407
10408 d = (TProofDesc *) mgr->QuerySessions("")->First();
10409 else
10410 d = (TProofDesc *) mgr->GetProofDesc(locid);
10411 if (d) {
10412 proof = (TProof*) mgr->AttachSession(d);
10413 if (!proof || !proof->IsValid()) {
10414 if (locid)
10415 ::Error(pn, "new session could not be attached");
10416 SafeDelete(proof);
10417 }
10418 }
10419 }
10420
10421
10422 if (!proof) {
10423 proof = (TProof*) mgr->CreateSession(conffile, confdir, loglevel);
10424 if (!proof || !proof->IsValid()) {
10425 ::Error(pn, "new session could not be created");
10426 SafeDelete(proof);
10427 }
10428 }
10429 }
10430 return proof;
10431 }
10432 }
10433
10434
10435 TProofMgr *TProof::Mgr(const char *url)
10436 {
10437
10438
10439
10440 if (!url)
10441 return (TProofMgr *)0;
10442
10443
10444 return TProofMgr::Create(url);
10445 }
10446
10447
10448 void TProof::Reset(const char *url, Bool_t hard)
10449 {
10450
10451
10452 if (url) {
10453 TProofMgr *mgr = TProof::Mgr(url);
10454 if (mgr && mgr->IsValid())
10455 mgr->Reset(hard);
10456 else
10457 ::Error("TProof::Reset",
10458 "unable to initialize a valid manager instance");
10459 }
10460 }
10461
10462
10463 const TList *TProof::GetEnvVars()
10464 {
10465
10466
10467 return fgProofEnvList;
10468 }
10469
10470
10471 void TProof::AddEnvVar(const char *name, const char *value)
10472 {
10473
10474
10475
10476 if (gDebug > 0) ::Info("TProof::AddEnvVar","%s=%s", name, value);
10477
10478 if (fgProofEnvList == 0) {
10479
10480 fgProofEnvList = new TList;
10481 fgProofEnvList->SetOwner();
10482 } else {
10483
10484 TObject *o = fgProofEnvList->FindObject(name);
10485 if (o != 0) {
10486 fgProofEnvList->Remove(o);
10487 }
10488 }
10489 fgProofEnvList->Add(new TNamed(name, value));
10490 }
10491
10492
10493 void TProof::DelEnvVar(const char *name)
10494 {
10495
10496
10497
10498 if (fgProofEnvList == 0) return;
10499
10500 TObject *o = fgProofEnvList->FindObject(name);
10501 if (o != 0) {
10502 fgProofEnvList->Remove(o);
10503 }
10504 }
10505
10506
10507 void TProof::ResetEnvVars()
10508 {
10509
10510
10511
10512 if (fgProofEnvList == 0) return;
10513
10514 SafeDelete(fgProofEnvList);
10515 }
10516
10517
10518 void TProof::SaveWorkerInfo()
10519 {
10520
10521
10522
10523
10524
10525 if (TestBit(TProof::kIsClient))
10526 return;
10527
10528
10529 if (!gProofServ) {
10530 Error("SaveWorkerInfo","gProofServ undefined");
10531 return;
10532 }
10533
10534
10535 if (!fSlaves && !fBadSlaves) {
10536 Warning("SaveWorkerInfo","all relevant worker lists is undefined");
10537 return;
10538 }
10539
10540
10541 TString fnwrk = Form("%s/.workers",
10542 gSystem->DirName(gProofServ->GetSessionDir()));
10543 FILE *fwrk = fopen(fnwrk.Data(),"w");
10544 if (!fwrk) {
10545 Error("SaveWorkerInfo",
10546 "cannot open %s for writing (errno: %d)", fnwrk.Data(), errno);
10547 return;
10548 }
10549
10550
10551 TString addlogext;
10552 if (gSystem->Getenv("PROOF_ADDITIONALLOG")) {
10553 addlogext = gSystem->Getenv("PROOF_ADDITIONALLOG");
10554 if (gDebug > 0)
10555 Info("SaveWorkerInfo", "request for additional line with ext: '%s'", addlogext.Data());
10556 }
10557
10558
10559 TIter nxa(fSlaves);
10560 TSlave *wrk = 0;
10561 while ((wrk = (TSlave *) nxa())) {
10562 Int_t status = (fBadSlaves && fBadSlaves->FindObject(wrk)) ? 0 : 1;
10563
10564 fprintf(fwrk,"%s@%s:%d %d %s %s.log\n",
10565 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
10566 wrk->GetOrdinal(), wrk->GetWorkDir());
10567
10568 if (addlogext.Length() > 0) {
10569 fprintf(fwrk,"%s@%s:%d %d %s %s.%s\n",
10570 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
10571 wrk->GetOrdinal(), wrk->GetWorkDir(), addlogext.Data());
10572 }
10573 }
10574
10575
10576 fclose(fwrk);
10577
10578
10579 return;
10580 }
10581
10582
10583 Int_t TProof::GetParameter(TCollection *c, const char *par, TString &value)
10584 {
10585
10586
10587
10588
10589 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
10590 if (obj) {
10591 TNamed *p = dynamic_cast<TNamed*>(obj);
10592 if (p) {
10593 value = p->GetTitle();
10594 return 0;
10595 }
10596 }
10597 return -1;
10598
10599 }
10600
10601
10602 Int_t TProof::GetParameter(TCollection *c, const char *par, Int_t &value)
10603 {
10604
10605
10606
10607
10608 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
10609 if (obj) {
10610 TParameter<Int_t> *p = dynamic_cast<TParameter<Int_t>*>(obj);
10611 if (p) {
10612 value = p->GetVal();
10613 return 0;
10614 }
10615 }
10616 return -1;
10617 }
10618
10619
10620 Int_t TProof::GetParameter(TCollection *c, const char *par, Long_t &value)
10621 {
10622
10623
10624
10625
10626 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
10627 if (obj) {
10628 TParameter<Long_t> *p = dynamic_cast<TParameter<Long_t>*>(obj);
10629 if (p) {
10630 value = p->GetVal();
10631 return 0;
10632 }
10633 }
10634 return -1;
10635 }
10636
10637
10638 Int_t TProof::GetParameter(TCollection *c, const char *par, Long64_t &value)
10639 {
10640
10641
10642
10643
10644 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
10645 if (obj) {
10646 TParameter<Long64_t> *p = dynamic_cast<TParameter<Long64_t>*>(obj);
10647 if (p) {
10648 value = p->GetVal();
10649 return 0;
10650 }
10651 }
10652 return -1;
10653 }
10654
10655
10656 Int_t TProof::GetParameter(TCollection *c, const char *par, Double_t &value)
10657 {
10658
10659
10660
10661
10662 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
10663 if (obj) {
10664 TParameter<Double_t> *p = dynamic_cast<TParameter<Double_t>*>(obj);
10665 if (p) {
10666 value = p->GetVal();
10667 return 0;
10668 }
10669 }
10670 return -1;
10671 }
10672
10673
10674 Int_t TProof::AssertDataSet(TDSet *dset, TList *input,
10675 TDataSetManager *mgr, TString &emsg)
10676 {
10677
10678
10679
10680
10681
10682 emsg = "";
10683
10684
10685 if (!dset || !input || !mgr) {
10686 emsg.Form("invalid inputs (%p, %p, %p)", dset, input, mgr);
10687 return -1;
10688 }
10689
10690 TList *datasets = new TList;
10691 TFileCollection *dataset = 0;
10692 TString lookupopt;
10693 TString dsname(dset->GetName());
10694
10695 if (dsname.BeginsWith("TFileCollection:")) {
10696
10697 dsname.ReplaceAll("TFileCollection:", "");
10698
10699 dataset = (TFileCollection *) input->FindObject(dsname);
10700 if (!dataset) {
10701 emsg.Form("TFileCollection %s not found in input list", dset->GetName());
10702 return -1;
10703 }
10704
10705 input->RecursiveRemove(dataset);
10706
10707 datasets->Add(new TPair(dataset, new TObjString("")));
10708
10709
10710 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
10711 lookupopt = gEnv->GetValue("Proof.LookupOpt", "all");
10712 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
10713 }
10714 }
10715
10716
10717
10718
10719 TString dsnparse;
10720
10721
10722
10723 if (!dataset) {
10724 TString dsns(dsname.Data()), dsn1;
10725 Int_t from1 = 0;
10726 while (dsns.Tokenize(dsn1, from1, "[, ]")) {
10727 TString dsn2, enl;
10728 Int_t from2 = 0;
10729 TFileCollection *fc = 0;
10730 while (dsn1.Tokenize(dsn2, from2, "|")) {
10731 enl = "";
10732 Int_t ienl = dsn2.Index("?enl=");
10733 if (ienl != kNPOS) {
10734 enl = dsn2(ienl + 5, dsn2.Length());
10735 dsn2.Remove(ienl);
10736 }
10737 if ((fc = mgr->GetDataSet(dsn2.Data()))) {
10738 dsnparse = dsn2;
10739 if (!dataset) {
10740
10741 dataset = fc;
10742 } else {
10743
10744 dataset->Add(fc);
10745 SafeDelete(fc);
10746 }
10747 }
10748 }
10749
10750 if (dataset) {
10751 if (dataset->GetList()->First())
10752 ((TFileInfo *)(dataset->GetList()->First()))->SetTitle(dsn1.Data());
10753
10754 if (enl.IsNull()) {
10755 datasets->Add(new TPair(dataset, new TObjString("")));
10756 } else {
10757 datasets->Add(new TPair(dataset, new TObjString(enl.Data())));
10758 }
10759 }
10760
10761 dataset = 0;
10762 }
10763 if (!datasets || datasets->GetSize() <= 0) {
10764 emsg.Form("no dataset(s) found on the master corresponding to: %s", dsname.Data());
10765 return -1;
10766 } else {
10767
10768 if (!(dataset = (TFileCollection *) ((TPair *)(datasets->First()))->Key())) {
10769 emsg.Form("dataset pointer is null: corruption? - aborting");
10770 return -1;
10771 }
10772 }
10773
10774
10775 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
10776 lookupopt = gEnv->GetValue("Proof.LookupOpt", "stagedOnly");
10777 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
10778 }
10779 } else {
10780
10781 dsnparse = dsname;
10782 }
10783
10784
10785
10786
10787
10788 TString dsTree;
10789
10790 mgr->ParseUri(dsnparse.Data(), 0, 0, 0, &dsTree);
10791 if (dsTree.IsNull()) {
10792
10793
10794 dsTree += dset->GetDirectory();
10795 dsTree += dset->GetObjName();
10796 }
10797 if (!dsTree.IsNull() && dsTree != "/") {
10798 TString tree(dsTree);
10799 Int_t idx = tree.Index("/");
10800 if (idx != kNPOS) {
10801 TString dir = tree(0, idx+1);
10802 tree.Remove(0, idx);
10803 dset->SetDirectory(dir);
10804 }
10805 dset->SetObjName(tree);
10806 } else {
10807
10808 dsTree = dataset->GetDefaultTreeName();
10809 }
10810
10811
10812 TList *srvmapsref = TDataSetManager::GetDataSetSrvMaps();
10813 TList *srvmapslist = srvmapsref;
10814 TString srvmaps;
10815 if (TProof::GetParameter(input, "PROOF_DataSetSrvMaps", srvmaps) == 0) {
10816 srvmapslist = TDataSetManager::ParseDataSetSrvMaps(srvmaps);
10817 if (gProofServ) {
10818 TString msg;
10819 if (srvmapsref && !srvmapslist) {
10820 msg.Form("+++ Info: dataset server mapping(s) DISABLED by user");
10821 } else if (srvmapsref && srvmapslist && srvmapslist != srvmapsref) {
10822 msg.Form("+++ Info: dataset server mapping(s) modified by user");
10823 } else if (!srvmapsref && srvmapslist) {
10824 msg.Form("+++ Info: dataset server mapping(s) added by user");
10825 }
10826 gProofServ->SendAsynMessage(msg.Data());
10827 }
10828 }
10829
10830
10831 if (datasets->GetSize() > 1) dset->SetBit(TDSet::kMultiDSet);
10832
10833 TList *listOfMissingFiles = new TList;
10834 TEntryList *entrylist = 0;
10835 TPair *pair = 0;
10836 TIter nxds(datasets);
10837 while ((pair = (TPair *) nxds())) {
10838
10839 dataset = (TFileCollection *) pair->Key();
10840
10841 TEntryList *enl = 0;
10842 TObjString *os = (TObjString *) pair->Value();
10843 if (strlen(os->GetName())) {
10844 if (!(enl = dynamic_cast<TEntryList *>(input->FindObject(os->GetName())))) {
10845 if (gProofServ)
10846 gProofServ->SendAsynMessage(TString::Format("+++ Warning:"
10847 " entry list %s not found", os->GetName()));
10848 }
10849 if (enl && (!(enl->GetLists()) || enl->GetLists()->GetSize() <= 0)) {
10850 if (gProofServ)
10851 gProofServ->SendAsynMessage(TString::Format("+++ Warning:"
10852 " no sub-lists in entry-list!"));
10853 }
10854 }
10855 TList *missingFiles = new TList;
10856 TSeqCollection* files = dataset->GetList();
10857 if (gDebug > 0) files->Print();
10858 Bool_t availableOnly = (lookupopt != "all") ? kTRUE : kFALSE;
10859 if (dset->TestBit(TDSet::kMultiDSet)) {
10860 TDSet *ds = new TDSet(dataset->GetName(), dset->GetObjName(), dset->GetDirectory());
10861 ds->SetSrvMaps(srvmapslist);
10862 if (!ds->Add(files, dsTree, availableOnly, missingFiles)) {
10863 emsg.Form("error integrating dataset %s", dataset->GetName());
10864 continue;
10865 }
10866
10867 dset->Add(ds);
10868
10869 if (enl) ds->SetEntryList(enl);
10870 } else {
10871 dset->SetSrvMaps(srvmapslist);
10872 if (!dset->Add(files, dsTree, availableOnly, missingFiles)) {
10873 emsg.Form("error integrating dataset %s", dataset->GetName());
10874 continue;
10875 }
10876 if (enl) entrylist = enl;
10877 }
10878 if (missingFiles) {
10879
10880
10881 TIter next(missingFiles);
10882 TObject *file;
10883 while ((file = next())) {
10884 dataset->GetList()->Remove(file);
10885 listOfMissingFiles->Add(file);
10886 }
10887 missingFiles->SetOwner(kFALSE);
10888 missingFiles->Clear();
10889 }
10890 SafeDelete(missingFiles);
10891 }
10892
10893 nxds.Reset();
10894 while ((pair = (TPair *) nxds())) {
10895 if (pair->Key()) delete pair->Key();
10896 if (pair->Value()) delete pair->Value();
10897 }
10898 datasets->SetOwner(kTRUE);
10899 SafeDelete(datasets);
10900
10901
10902 if (srvmapslist && srvmapslist != srvmapsref) {
10903 srvmapslist->SetOwner(kTRUE);
10904 SafeDelete(srvmapslist);
10905 }
10906
10907
10908 if (entrylist) dset->SetEntryList(entrylist);
10909
10910
10911
10912
10913 if (listOfMissingFiles && listOfMissingFiles->GetSize() > 0) {
10914 listOfMissingFiles->SetName("MissingFiles");
10915 input->Add(listOfMissingFiles);
10916 }
10917
10918
10919 return 0;
10920 }
10921
10922
10923 Int_t TProof::SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
10924 {
10925
10926
10927
10928 TList *input = 0;
10929
10930
10931 if (!qr || !(input = qr->GetInputList()) ||
10932 !cachedir || strlen(cachedir) <= 0) return 0;
10933
10934
10935 TNamed *data = (TNamed *) input->FindObject("PROOF_InputDataFile");
10936 TList *inputdata = (TList *) input->FindObject("PROOF_InputData");
10937 if (!data && !inputdata) return 0;
10938
10939 if (!data)
10940 input->Add((data = new TNamed("PROOF_InputDataFile", kPROOF_InputDataFile)));
10941
10942 TString dstname(data->GetTitle()), srcname;
10943 Bool_t fromcache = kFALSE;
10944 if (dstname.BeginsWith("cache:")) {
10945 fromcache = kTRUE;
10946 dstname.ReplaceAll("cache:", "");
10947 srcname.Form("%s/%s", cachedir, dstname.Data());
10948 if (gSystem->AccessPathName(srcname)) {
10949 emsg.Form("input data file not found in cache (%s)", srcname.Data());
10950 return -1;
10951 }
10952 }
10953
10954
10955 if (fromcache) {
10956 if (gSystem->CopyFile(srcname, dstname, kTRUE) != 0) {
10957 emsg.Form("problems copying %s to %s", srcname.Data(), dstname.Data());
10958 return -1;
10959 }
10960 } else {
10961
10962 if (inputdata && inputdata->GetSize() > 0) {
10963 TFile *f = TFile::Open(dstname.Data(), "RECREATE");
10964 if (f) {
10965 f->cd();
10966 inputdata->Write();
10967 f->Close();
10968 delete f;
10969 } else {
10970 emsg.Form("could not create %s", dstname.Data());
10971 return -1;
10972 }
10973 } else {
10974 emsg.Form("no input data!");
10975 return -1;
10976 }
10977 }
10978 ::Info("TProof::SaveInputData", "input data saved to %s", dstname.Data());
10979
10980
10981 data->SetTitle(dstname);
10982 if (inputdata) {
10983 input->Remove(inputdata);
10984 inputdata->SetOwner();
10985 delete inputdata;
10986 }
10987
10988
10989 return 0;
10990 }
10991
10992
10993 Int_t TProof::SendInputData(TQueryResult *qr, TProof *p, TString &emsg)
10994 {
10995
10996
10997 TList *input = 0;
10998
10999
11000 if (!qr || !(input = qr->GetInputList())) return 0;
11001
11002
11003 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
11004 if (!inputdata) return 0;
11005
11006 TString fname(inputdata->GetTitle());
11007 if (gSystem->AccessPathName(fname)) {
11008 emsg.Form("input data file not found in sandbox (%s)", fname.Data());
11009 return -1;
11010 }
11011
11012
11013 if (!p || !p->IsValid()) {
11014 emsg.Form("TProof object undefined or invalid: protocol error!");
11015 return -1;
11016 }
11017
11018
11019 p->BroadcastFile(fname, TProof::kBinary, "cache");
11020
11021
11022 return 0;
11023 }
11024
11025
11026 Int_t TProof::GetInputData(TList *input, const char *cachedir, TString &emsg)
11027 {
11028
11029
11030
11031 if (!input || !cachedir || strlen(cachedir) <= 0) return 0;
11032
11033
11034 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
11035 if (!inputdata) return 0;
11036
11037 TString fname;
11038 fname.Form("%s/%s", cachedir, inputdata->GetTitle());
11039 if (gSystem->AccessPathName(fname)) {
11040 emsg.Form("input data file not found in cache (%s)", fname.Data());
11041 return -1;
11042 }
11043
11044
11045 TFile *f = TFile::Open(fname.Data());
11046 if (f) {
11047 TList *keys = (TList *) f->GetListOfKeys();
11048 if (!keys) {
11049 emsg.Form("could not get list of object keys from file");
11050 return -1;
11051 }
11052 TIter nxk(keys);
11053 TKey *k = 0;
11054 while ((k = (TKey *)nxk())) {
11055 TObject *o = f->Get(k->GetName());
11056 if (o) input->Add(o);
11057 }
11058 f->Close();
11059 delete f;
11060 } else {
11061 emsg.Form("could not open %s", fname.Data());
11062 return -1;
11063 }
11064
11065
11066 return 0;
11067 }
11068
11069
11070 void TProof::LogViewer(const char *url, Int_t idx)
11071 {
11072
11073
11074 if (!gROOT->IsBatch()) {
11075
11076 if (!fgLogViewer) {
11077 if ((fgLogViewer =
11078 gROOT->GetPluginManager()->FindHandler("TProofProgressLog"))) {
11079 if (fgLogViewer->LoadPlugin() == -1) {
11080 fgLogViewer = 0;
11081 ::Error("TProof::LogViewer", "cannot load the relevant plug-in");
11082 return;
11083 }
11084 }
11085 }
11086 if (fgLogViewer) {
11087
11088 TString u = (url && strlen(url) <= 0) ? "lite" : url;
11089 fgLogViewer->ExecPlugin(2, u.Data(), idx);
11090 }
11091 } else {
11092 if (url && strlen(url) > 0) {
11093 ::Info("TProof::LogViewer",
11094 "batch mode: use TProofLog *pl = TProof::Mgr(\"%s\")->GetSessionLogs(%d)", url, idx);
11095 } else if (url && strlen(url) <= 0) {
11096 ::Info("TProof::LogViewer",
11097 "batch mode: use TProofLog *pl = TProof::Mgr(\"lite\")->GetSessionLogs(%d)", idx);
11098 } else {
11099 ::Info("TProof::LogViewer",
11100 "batch mode: use TProofLog *pl = TProof::Mgr(\"<master>\")->GetSessionLogs(%d)", idx);
11101 }
11102 }
11103
11104 return;
11105 }
11106
11107
11108 void TProof::SetProgressDialog(Bool_t on)
11109 {
11110
11111
11112
11113 if (on)
11114 SetBit(kUseProgressDialog);
11115 else
11116 ResetBit(kUseProgressDialog);
11117 }
11118
11119
11120 void TProof::ShowMissingFiles(TQueryResult *qr)
11121 {
11122
11123
11124
11125
11126 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
11127 if (!xqr) {
11128 Warning("ShowMissingFiles", "no (last) query found: do nothing");
11129 return;
11130 }
11131
11132
11133 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
11134 if (!missing) {
11135 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
11136 return;
11137 }
11138
11139 Int_t nmf = 0;
11140 Long64_t msz = 0, mszzip = 0, mev = 0;
11141
11142 TFileInfo *fi = 0;
11143 TIter nxf(missing);
11144 while ((fi = (TFileInfo *) nxf())) {
11145 fi->Print();
11146 nmf++;
11147 TFileInfoMeta *im = fi->GetMetaData();
11148 if (im) {
11149 if (im->GetTotBytes() > 0) msz += im->GetTotBytes();
11150 if (im->GetZipBytes() > 0) mszzip += im->GetZipBytes();
11151 mev += im->GetEntries();
11152 }
11153 }
11154
11155
11156 if (msz <= 0) msz = -1;
11157 if (mszzip <= 0) mszzip = -1;
11158 Double_t xf = (Double_t)mev / (mev + xqr->GetEntries()) ;
11159 Printf(" +++ %d files missing, i.e. %lld events (%lld bytes, %lld zipped) --> about %.2f%% of the total events",
11160 nmf, mev, msz, mszzip, xf * 100.);
11161 }
11162
11163
11164 TFileCollection *TProof::GetMissingFiles(TQueryResult *qr)
11165 {
11166
11167
11168
11169
11170
11171 TFileCollection *fc = 0;
11172
11173 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
11174 if (!xqr) {
11175 Warning("GetMissingFiles", "no (last) query found: do nothing");
11176 return fc;
11177 }
11178
11179
11180 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
11181 if (!missing) {
11182 if (gDebug > 0)
11183 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
11184 return fc;
11185 }
11186
11187
11188 TString fcname("unknown");
11189 TDSet *ds = (TDSet *) xqr->GetInputObject("TDSet");
11190 if (ds) {
11191 fcname.Form("%s.m0", ds->GetName());
11192 Int_t j = 1;
11193 while (gDirectory->FindObject(fcname) && j < 1000)
11194 fcname.Form("%s.m%d", ds->GetName(), j++);
11195 }
11196 fc = new TFileCollection(fcname, "Missing Files");
11197 if (ds) fc->SetDefaultTreeName(ds->GetObjName());
11198
11199 TFileInfo *fi = 0;
11200 TIter nxf(missing);
11201 while ((fi = (TFileInfo *) nxf())) {
11202 fc->Add((TFileInfo *) fi->Clone());
11203 }
11204 fc->Update();
11205
11206 return fc;
11207 }