32 #include "RConfigure.h"
41 #include <netinet/in.h>
43 #include <sys/types.h>
65 #include "compiledata.h"
70 static volatile Int_t gProofServDebug = 1;
75 class TProofServLiteInterruptHandler :
public TSignalHandler {
76 TProofServLite *fServ;
78 TProofServLiteInterruptHandler(TProofServLite *s)
79 : TSignalHandler(kSigUrgent, kFALSE) { fServ = s; }
86 Bool_t TProofServLiteInterruptHandler::Notify()
88 fServ->HandleUrgentData();
89 if (TROOT::Initialized()) {
98 class TProofServLiteSigPipeHandler :
public TSignalHandler {
99 TProofServLite *fServ;
101 TProofServLiteSigPipeHandler(TProofServLite *s) : TSignalHandler(kSigPipe, kFALSE)
109 Bool_t TProofServLiteSigPipeHandler::Notify()
111 fServ->HandleSigPipe();
118 class TProofServLiteTerminationHandler :
public TSignalHandler {
119 TProofServLite *fServ;
121 TProofServLiteTerminationHandler(TProofServLite *s)
122 : TSignalHandler(kSigTermination, kFALSE) { fServ = s; }
129 Bool_t TProofServLiteTerminationHandler::Notify()
131 Printf(
"TProofServLiteTerminationHandler::Notify: wake up!");
133 fServ->HandleTermination();
140 class TProofServLiteSegViolationHandler :
public TSignalHandler {
141 TProofServLite *fServ;
143 TProofServLiteSegViolationHandler(TProofServLite *s)
144 : TSignalHandler(kSigSegmentationViolation, kFALSE) { fServ = s; }
151 Bool_t TProofServLiteSegViolationHandler::Notify()
154 Printf(
"**** Segmentation violation: terminating ****");
156 fServ->HandleTermination();
163 class TProofServLiteInputHandler :
public TFileHandler {
164 TProofServLite *fServ;
166 TProofServLiteInputHandler(TProofServLite *s, Int_t fd) : TFileHandler(fd, 1)
169 Bool_t ReadNotify() {
return Notify(); }
175 Bool_t TProofServLiteInputHandler::Notify()
177 fServ->HandleSocketInput();
182 ClassImp(TProofServLite);
187 TApplication *GetTProofServLite(Int_t *argc,
char **argv, FILE *flog)
188 {
return new TProofServLite(argc, argv, flog); }
194 TProofServLite::TProofServLite(Int_t *argc,
char **argv, FILE *flog)
195 : TProofServ(argc, argv, flog)
197 fInterruptHandler = 0;
198 fTerminated = kFALSE;
206 Int_t TProofServLite::CreateServer()
208 if (gProofDebugLevel > 0)
209 Info(
"CreateServer",
"starting server creation");
214 if ((fLogFileDes = fileno(fLogFile)) < 0) {
215 Error(
"CreateServer",
"resolving the log file description number");
221 fSockPath = gEnv->GetValue(
"ProofServ.OpenSock",
"");
222 if (fSockPath.Length() <= 0) {
223 Error(
"CreateServer",
"Socket setup by xpd undefined");
226 TString entity = gEnv->GetValue(
"ProofServ.Entity",
"");
227 if (entity.Length() > 0)
228 fSockPath.Insert(0,TString::Format(
"%s/", entity.Data()));
231 fSocket =
new TSocket(fSockPath);
232 if (!fSocket || !(fSocket->IsValid())) {
233 Error(
"CreateServer",
"Failed to open connection to the client");
243 Int_t sock = fSocket->GetDescriptor();
246 fInterruptHandler =
new TProofServLiteInterruptHandler(
this);
247 gSystem->AddSignalHandler(fInterruptHandler);
248 gSystem->AddFileHandler(
new TProofServLiteInputHandler(
this, sock));
251 if (gEnv->GetValue(
"Proof.GdbHook",0) == 2) {
252 while (gProofServDebug)
256 if (gProofDebugLevel > 0)
257 Info(
"CreateServer",
"Service: %s, ConfDir: %s, IsMaster: %d",
258 fService.Data(), fConfDir.Data(), (Int_t)fMasterServ);
271 if (!fLogFile || (fLogFileDes = fileno(fLogFile)) < 0) {
279 ProcessLine(
"#include <iostream>", kTRUE);
280 ProcessLine(
"#include <string>",kTRUE);
284 logon = gEnv->GetValue(
"Proof.Load", (
char *)0);
286 char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
288 ProcessLine(TString::Format(
".L %s", logon), kTRUE);
293 logon = gEnv->GetValue(
"Proof.Logon", (
char *)0);
294 if (logon && !NoLogOpt()) {
295 char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
302 gInterpreter->SaveContext();
303 gInterpreter->SaveGlobalsContext();
316 TProofServLite::~TProofServLite()
324 void TProofServLite::HandleSigPipe()
332 void TProofServLite::HandleTermination()
341 Int_t TProofServLite::Setup()
346 snprintf(str, 512,
"**** Welcome to the PROOF server @ %s ****", gSystem->HostName());
348 snprintf(str, 512,
"**** PROOF worker server @ %s started ****", gSystem->HostName());
351 if (fSocket->Send(str) != 1+
static_cast<Int_t
>(strlen(str))) {
352 Error(
"Setup",
"failed to send proof server startup message");
357 if ((fProtocol = gEnv->GetValue(
"ProofServ.ClientVersion", -1)) < 0) {
358 Error(
"Setup",
"remote proof protocol missing");
363 UserGroup_t *pw = gSystem->GetUserInfo();
370 fWorkDir = gEnv->GetValue(
"ProofServ.Sandbox", TString::Format(
"~/%s", kPROOF_WorkDir));
371 Info(
"Setup",
"fWorkDir: %s", fWorkDir.Data());
374 fTopSessionTag = gEnv->GetValue(
"ProofServ.SessionTag",
"-1");
375 fSessionTag.Form(
"%s-%s-%ld-%d", fOrdinal.Data(), gSystem->HostName(),
376 (Long_t)TTimeStamp().GetSec(), gSystem->GetPid());
377 if (gProofDebugLevel > 0)
378 Info(
"Setup",
"session tag is %s", fSessionTag.Data());
379 if (fTopSessionTag.IsNull()) fTopSessionTag = fSessionTag;
382 TMessage m(kPROOF_SESSIONTAG);
387 if ((fSessionDir = gEnv->GetValue(
"ProofServ.SessionDir",
"-1")) ==
"-1") {
388 Error(
"Setup",
"Session dir missing");
393 if (gSystem->Getenv(
"ROOTPROOFLOGFILE")) {
394 TString logfile = gSystem->Getenv(
"ROOTPROOFLOGFILE");
395 Int_t iord = logfile.Index(TString::Format(
"-%s", fOrdinal.Data()));
396 if (iord != kNPOS) logfile.Remove(iord);
397 logfile += TString::Format(
"-%s.log", fSessionTag.Data());
398 gSystem->Symlink(gSystem->Getenv(
"ROOTPROOFLOGFILE"), logfile);
402 char *workdir = gSystem->ExpandPathName(fWorkDir.Data());
405 if (gProofDebugLevel > 0)
406 Info(
"Setup",
"working directory set to %s", fWorkDir.Data());
409 if (SetupCommon() != 0) {
410 Error(
"Setup",
"common setup failed");
415 fSocket->SetOption(kKeepAlive, 1);
418 gSystem->AddSignalHandler(
new TProofServLiteSigPipeHandler(
this));
421 gSystem->AddSignalHandler(
new TProofServLiteTerminationHandler(
this));
424 gSystem->AddSignalHandler(
new TProofServLiteSegViolationHandler(
this));
433 void TProofServLite::Terminate(Int_t status)
441 Info(
"Terminate",
"starting session termination operations ...");
446 gSystem->ChangeDirectory(
"/");
448 gSystem->MakeDirectory(fSessionDir+
"/.delete");
449 gSystem->Exec(TString::Format(
"%s %s", kRM, fSessionDir.Data()));
453 if (!fDataDir.IsNull() && !gSystem->AccessPathName(fDataDir, kWritePermission)) {
454 if (UnlinkDataDir(fDataDir))
455 Info(
"Terminate",
"data directory '%s' has been removed", fDataDir.Data());
460 gSystem->RemoveSignalHandler(fInterruptHandler);
466 Printf(
"Terminate: termination operations ended: quitting!");
472 void TProofServLite::HandleFork(TMessage *mess)
475 Error(
"HandleFork",
"empty message!");
483 Info("HandleFork", "cloning to %s", clones.Data());
487 while (clones.Tokenize(clone, from, " ")) {
491 if ((rc = Fork()) < 0) {
492 Error(
"HandleFork",
"failed to fork %s", clone.Data());
498 SetupOnFork(clone.Data());
511 Int_t TProofServLite::SetupOnFork(
const char *ord)
513 if (gProofDebugLevel > 0)
514 Info(
"SetupOnFork",
"finalizing setup of %s", ord);
519 sord.Form(
"-%s", fOrdinal.Data());
527 TString sdir = gSystem->DirName(fSessionDir.Data());
528 RedirectOutput(sdir.Data(),
"a");
531 if (!fLogFile || (fLogFileDes = fileno(fLogFile)) < 0) {
538 void *dirp = gSystem->OpenDirectory(sdir);
542 while ((e = gSystem->GetDirEntry(dirp))) {
543 ent.Form(
"%s/%s", sdir.Data(), e);
545 if (gSystem->GetPathInfo(ent.Data(), st) == 0) {
546 if (st.fIsLink && ent.Contains(sord)) {
548 Info("SetupOnFork","unlinking: %s", ent.Data());
549 gSystem->Unlink(ent);
553 gSystem->FreeDirectory(dirp);
557 fSessionTag.Form("%s-%d-%d", gSystem->HostName(), (
int)time(0), gSystem->GetPid());
560 TString logfile = gSystem->Getenv("ROOTPROOFLOGFILE");
561 logfile.ReplaceAll("-0.0", sord.Data());
562 gSystem->Setenv("ROOTPROOFLOGFILE", logfile);
563 Int_t iord = logfile.Index(sord.Data());
564 if (iord != kNPOS) logfile.Remove(iord + sord.Length());
565 logfile += TString::Format("-%s.log", fSessionTag.Data());
566 gSystem->Symlink(gSystem->Getenv("ROOTPROOFLOGFILE"), logfile);
569 fSockPath = gEnv->GetValue("ProofServ.OpenSock", "");
570 if (fSockPath.Length() <= 0) {
571 Error(
"CreateServer",
"Socket setup by xpd undefined");
574 TString entity = gEnv->GetValue(
"ProofServ.Entity",
"");
575 if (entity.Length() > 0)
576 fSockPath.Insert(0, TString::Format(
"%s/", entity.Data()));
579 fSocket =
new TSocket(fSockPath);
580 if (!fSocket || !(fSocket->IsValid())) {
581 Error(
"CreateServer",
"Failed to open connection to the client");
591 Int_t sock = fSocket->GetDescriptor();
594 fInterruptHandler =
new TProofServLiteInterruptHandler(
this);
595 gSystem->AddSignalHandler(fInterruptHandler);
596 gSystem->AddFileHandler(
new TProofServLiteInputHandler(
this, sock));
599 if (gEnv->GetValue(
"Proof.GdbHook",0) == 2) {
600 while (gProofServDebug)
604 if (gProofDebugLevel > 0)
605 Info(
"SetupOnFork",
"Service: %s, ConfDir: %s, IsMaster: %d",
606 fService.Data(), fConfDir.Data(), (Int_t)fMasterServ);
616 ProcessLine(
"#define ROOT_Rtypes 0", kTRUE);
617 ProcessLine(
"#define ROOT_TError 0", kTRUE);
618 ProcessLine(
"#define ROOT_TGenericClassInfo 0", kTRUE);
621 gInterpreter->SaveContext();
622 gInterpreter->SaveGlobalsContext();