pmain.cxx

Go to the documentation of this file.
00001 // @(#)root/main:$Id: pmain.cxx 28886 2009-06-10 16:11:20Z brun $
00002 // Author: Fons Rademakers   15/02/97
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // PMain                                                                //
00015 //                                                                      //
00016 // Main program used to create PROOF server application.                //
00017 //                                                                      //
00018 //////////////////////////////////////////////////////////////////////////
00019 #include <stdio.h>
00020 #include <errno.h>
00021 
00022 #ifdef WIN32
00023 #include <io.h>
00024 #else
00025 #include <sys/time.h>
00026 #include <sys/resource.h>
00027 #endif
00028 #include <stdio.h>
00029 #include <errno.h>
00030 #include <stdlib.h>
00031 #include <sys/types.h>
00032 
00033 #include "RConfig.h"
00034 #include "RConfigure.h"
00035 #ifdef R__AFS
00036 #include "TAFS.h"
00037 #endif
00038 #include "TApplication.h"
00039 #include "TInterpreter.h"
00040 #include "TROOT.h"
00041 #include "TSystem.h"
00042 
00043 
00044 static Int_t gLogLevel = 0;
00045 
00046 // Special type for the hook to the TXProofServ constructor, needed to avoid
00047 // using the plugin manager
00048 typedef TApplication *(*TProofServ_t)(Int_t *argc, char **argv, FILE *flog);
00049 
00050 #ifdef R__AFS
00051 // Special type for the hook to the TAFS constructor, needed to avoid
00052 // using the plugin manager
00053 typedef TAFS *(*TAFS_t)(const char *, const char *, Int_t);
00054 // Instance of the AFS token class
00055 static TAFS *gAFS = 0;
00056 #endif
00057 
00058 //______________________________________________________________________________
00059 static void ReadPutEnvs(const char *envfile)
00060 {
00061    // Read envs from file 'envfile' and add them to the env space
00062 
00063    // Check inputs
00064    if (!envfile || strlen(envfile) <= 0) return;
00065 
00066    // Open the file
00067    FILE *fenv = fopen(envfile, "r");
00068    if (!fenv) return;
00069 
00070    // Read lines
00071    char ln[4096];
00072    while (fgets(ln, sizeof(ln), fenv)) {
00073       int l = strlen(ln);
00074       // Strip '\n'
00075       if (l > 0 && ln[l-1] == '\n') { ln[l-1] = '\0'; l--; }
00076       // Skip comments or empty line
00077       if (l <= 0 || ln[0] == '#') continue;
00078       // Skip lines not in the form '<name>=<value>'
00079       if (!strchr(ln, '=')) continue;
00080       // Good line
00081       char *ev = new char[l+1];
00082       strcpy(ev, ln);
00083       putenv(ev);
00084    }
00085 
00086    // Close the file
00087    fclose(fenv);
00088 }
00089 
00090 //______________________________________________________________________________
00091 static FILE *RedirectOutput(const char *logfile, const char *loc)
00092 {
00093    // Redirect stdout to 'logfile'. This log file will be flushed to the
00094    // client or master after each command.
00095    // On success return a pointer to the open log file. Return 0 on failure.
00096 
00097    if (loc)
00098       fprintf(stderr,"%s: RedirectOutput: enter: %s\n", loc, logfile);
00099 
00100    if (!logfile || strlen(logfile) <= 0) {
00101       fprintf(stderr,"%s: RedirectOutput: logfile path undefined\n", loc);
00102       return 0;
00103    }
00104 
00105    if (loc)
00106       fprintf(stderr,"%s: RedirectOutput: reopen %s\n", loc, logfile);
00107    FILE *flog = freopen(logfile, "a", stdout);
00108    if (!flog) {
00109       fprintf(stderr,"%s: RedirectOutput: could not freopen stdout\n", loc);
00110       return 0;
00111    }
00112 
00113    if (loc)
00114       fprintf(stderr,"%s: RedirectOutput: dup2 ...\n", loc);
00115    if ((dup2(fileno(stdout), fileno(stderr))) < 0) {
00116       fprintf(stderr,"%s: RedirectOutput: could not redirect stderr\n", loc);
00117       return 0;
00118    }
00119 
00120    if (loc)
00121       fprintf(stderr,"%s: RedirectOutput: read open ...\n", loc);
00122    FILE *fLog = fopen(logfile, "r");
00123    if (!fLog) {
00124       fprintf(stderr,"%s: RedirectOutput: could not open logfile %s\n", loc, logfile);
00125       return 0;
00126    }
00127 
00128    if (loc)
00129       fprintf(stderr,"%s: RedirectOutput: done!\n", loc);
00130    // We are done
00131    return fLog;
00132 }
00133 
00134 //______________________________________________________________________________
00135 static void SetMaxMemLimits(const char *prog)
00136 {
00137    // Set limits on the address space (virtual memory) if required.
00138 
00139 #ifndef WIN32
00140    const char *assoft = gSystem->Getenv("ROOTPROOFASSOFT");
00141    const char *ashard = gSystem->Getenv("ROOTPROOFASHARD");
00142 
00143    if (assoft || ashard) {
00144       struct rlimit aslim, aslimref;
00145       if (getrlimit(RLIMIT_AS, &aslimref) != 0) {
00146          fprintf(stderr,"%s: problems getting RLIMIT_AS values (errno: %d)\n", prog, errno);
00147          exit(1);
00148       }
00149       if (gLogLevel > 0)
00150          fprintf(stderr, "%s: memory limits currently set to %lld (soft) and %lld (hard) bytes\n",
00151                          prog, (Long64_t)aslimref.rlim_cur, (Long64_t)aslimref.rlim_max);
00152       aslim.rlim_cur = aslimref.rlim_cur;
00153       aslim.rlim_max = aslimref.rlim_max;
00154       if (assoft) {
00155          Long_t rlim_cur = strtol(assoft, 0, 10);
00156          if (rlim_cur < kMaxLong && rlim_cur > 0)
00157             aslim.rlim_cur = (rlim_t) rlim_cur * (1024 * 1024);
00158       }
00159       if (ashard) {
00160          Long_t rlim_max = strtol(ashard, 0, 10);
00161          if (rlim_max < kMaxLong && rlim_max > 0)
00162             aslim.rlim_max = (rlim_t) rlim_max * (1024 * 1024);
00163       }
00164       // Change the limits, if required
00165       if ((aslim.rlim_cur != aslimref.rlim_cur) || (aslim.rlim_max != aslimref.rlim_max)) {
00166          fprintf(stderr, "%s: setting memory limits to %lld (soft) and %lld (hard) bytes\n",
00167                          prog, (Long64_t)aslim.rlim_cur, (Long64_t)aslim.rlim_max);
00168          if (setrlimit(RLIMIT_AS, &aslim) != 0) {
00169             fprintf(stderr,"%s: problems setting RLIMIT_AS values (errno: %d)\n", prog, errno);
00170             exit(1);
00171          }
00172       }
00173    }
00174 #endif
00175 }
00176 
00177 #ifdef R__AFS
00178 //______________________________________________________________________________
00179 static Int_t InitAFS(const char *fileafs, const char *loc)
00180 {
00181    // Init AFS token using credentials at fileafs
00182 
00183    TString getter("GetTAFS");
00184    char *p = 0;
00185    TString afslib = "libAFSAuth";
00186    if ((p = gSystem->DynamicPathName(afslib, kTRUE))) {
00187       delete[] p;
00188       if (gSystem->Load(afslib) == -1) {
00189          if (loc)
00190             fprintf(stderr,"%s: can't load %s\n", loc, afslib.Data());
00191          return -1;
00192       }
00193    } else {
00194       if (loc)
00195          fprintf(stderr,"%s: can't locate %s\n", loc, afslib.Data());
00196       return -1;
00197    }
00198 
00199    // Locate constructor
00200    Func_t f = gSystem->DynFindSymbol(afslib, getter);
00201    if (f) {
00202       gAFS = (*((TAFS_t)f))(fileafs, 0, -1);
00203       if (!gAFS) {
00204          if (loc)
00205             fprintf(stderr,"%s: could not initialize a valid TAFS\n", loc);
00206          return -1;
00207       }
00208    } else {
00209       if (loc)
00210          fprintf(stderr,"%s: can't find %s\n", loc, getter.Data());
00211       return -1;
00212    }
00213 
00214    // Done
00215    return 0;
00216 }
00217 #endif
00218 
00219 //______________________________________________________________________________
00220 int main(int argc, char **argv)
00221 {
00222    // PROOF server main program.
00223 
00224 #ifdef R__DEBUG
00225    int debug = 1;
00226    while (debug)
00227       ;
00228 #endif
00229    if (argc >= 6) {
00230       // Read and put system envs
00231       ReadPutEnvs(argv[5]);
00232    }
00233 
00234    gLogLevel = (argc >= 5) ? strtol(argv[4], 0, 10) : -1;
00235    if (gLogLevel < 0 && gSystem->Getenv("ROOTPROOFLOGLEVEL"))
00236       gLogLevel = atoi(gSystem->Getenv("ROOTPROOFLOGLEVEL"));
00237    if (gLogLevel > 0)
00238       fprintf(stderr,"%s: starting %s\n", argv[1], argv[0]);
00239 
00240    // Redirect the output
00241    FILE *fLog = 0;
00242    const char *loc = 0;
00243    const char *logfile = gSystem->Getenv("ROOTPROOFLOGFILE");
00244    if (logfile && !gSystem->Getenv("ROOTPROOFDONOTREDIR")) {
00245       loc = (gLogLevel > 0) ? argv[1] : 0;
00246       if (gLogLevel > 0)
00247          fprintf(stderr,"%s: redirecting output to %s\n", argv[1], logfile);
00248       if (!(fLog = RedirectOutput(logfile, loc))) {
00249          fprintf(stderr,"%s: problems redirecting output to file %s\n", argv[1], logfile);
00250          exit(1);
00251       }
00252    }
00253    if (gLogLevel > 0)
00254       fprintf(stderr,"%s: output redirected to: %s\n",
00255              argv[1], (logfile ? logfile : "+++not redirected+++"));
00256 
00257    SetMaxMemLimits(argv[1]);
00258 
00259 #ifdef R__AFS
00260    // Init AFS, if required
00261    if (gSystem->Getenv("ROOTPROOFAFSCREDS")) {
00262       if (InitAFS(gSystem->Getenv("ROOTPROOFAFSCREDS"), loc) != 0) {
00263           fprintf(stderr,"%s: unable to initialize the AFS token\n", argv[1]);
00264       } else {
00265          if (gLogLevel > 0)
00266             fprintf(stderr,"%s: AFS token initialized\n", argv[1]);
00267       }
00268    }
00269 #endif
00270 
00271    gROOT->SetBatch();
00272    TApplication *theApp = 0;
00273 
00274    // Enable autoloading
00275    gInterpreter->EnableAutoLoading();
00276 
00277    TString getter("GetTProofServ");
00278    TString prooflib = "libProof";
00279    if (argc > 2) {
00280       if (!strcmp(argv[2], "lite")) {
00281          // Lite version for local processing
00282          getter = "GetTProofServLite";
00283       } else if (!strcmp(argv[2], "xpd")) {
00284          // XPD: additionally load the appropriate library
00285          prooflib = "libProofx";
00286          getter = "GetTXProofServ";
00287       }
00288    }
00289    char *p = 0;
00290    if ((p = gSystem->DynamicPathName(prooflib, kTRUE))) {
00291       delete[] p;
00292       if (gSystem->Load(prooflib) == -1) {
00293          fprintf(stderr,"%s: can't load %s\n", argv[1], prooflib.Data());
00294          exit(1);
00295       }
00296    } else {
00297       fprintf(stderr,"%s: can't locate %s\n", argv[1], prooflib.Data());
00298       exit(1);
00299    }
00300 
00301    // Locate constructor
00302    Func_t f = gSystem->DynFindSymbol(prooflib, getter);
00303    if (f) {
00304       theApp = (TApplication *) (*((TProofServ_t)f))(&argc, argv, fLog);
00305    } else {
00306       fprintf(stderr,"%s: can't find %s\n", argv[1], getter.Data());
00307       exit(1);
00308    }
00309 
00310    // Ready to run
00311    if (gLogLevel > 0)
00312       fprintf(stderr,"%s: running the TProofServ application\n", argv[1]);
00313 
00314    theApp->Run();
00315 
00316 #ifdef R__AFS
00317    // Cleanup
00318    if (gAFS)
00319       delete gAFS;
00320 #endif
00321 
00322    // We can exit now
00323    gSystem->Exit(0);
00324 }

Generated on Tue Jul 5 14:30:42 2011 for ROOT_528-00b_version by  doxygen 1.5.1