TXNetFile.cxx

Go to the documentation of this file.
00001 // @(#)root/netx:$Id: TXNetFile.cxx 37046 2010-11-28 20:12:19Z ganis $
00002 // Author: Alvise Dorigo, Fabrizio Furano
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, 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 // TXNetFile                                                            //
00015 //                                                                      //
00016 // Authors: Alvise Dorigo, Fabrizio Furano                              //
00017 //          INFN Padova, 2003                                           //
00018 // Interfaced to the standalone client (XrdClient): G. Ganis, CERN      //
00019 //                                                                      //
00020 // TXNetFile is an extension of TNetFile able to deal with new xrootd   //
00021 // server. Its new features are:                                        //
00022 //  - Automatic server kind recognition (xrootd load balancer, xrootd   //
00023 //    data server, old rootd)                                           //
00024 //  - Backward compatibility with old rootd server (acts as an old      //
00025 //    TNetFile)                                                         //
00026 //  - Fault tolerance for read/write operations (read/write timeouts    //
00027 //    and retry)                                                        //
00028 //  - Internal connection timeout (tunable indipendently from the OS    //
00029 //    one) handled by threads                                           //
00030 //  - handling of redirections from server                              //
00031 //  - Single TCP physical channel for multiple TXNetFile's instances    //
00032 //    inside the same application                                       //
00033 //    So, each TXNetFile object client must send messages containing    //
00034 //    its ID (streamid). The server, of course, will respond with       //
00035 //    messages containing the client's ID, in order to make the client  //
00036 //    able to recognize its message by matching its streamid with that  //
00037 //    one contained in the server's response.                           //
00038 //  - Tunable log verbosity level (0 = nothing, 3 = dump read/write     //
00039 //    buffers too!)                                                     //
00040 //  - Many parameters configurable via TEnv facility (see SetParm()     //
00041 //    methods)                                                          //
00042 //                                                                      //
00043 //////////////////////////////////////////////////////////////////////////
00044 
00045 #include "Bytes.h"
00046 
00047 #include "TError.h"
00048 #include "TEnv.h"
00049 #include "TSocket.h"
00050 #include "TXNetFile.h"
00051 #include "TROOT.h"
00052 #include "TVirtualMonitoring.h"
00053 #include "TFileStager.h"
00054 #include "TFileCacheRead.h"
00055 #include "TTimeStamp.h"
00056 #include "TVirtualPerfStats.h"
00057 
00058 #include <XrdClient/XrdClient.hh>
00059 #include <XrdClient/XrdClientConst.hh>
00060 #include <XrdClient/XrdClientEnv.hh>
00061 #include <XProtocol/XProtocol.hh>
00062 #ifdef OLDXRDOUC
00063 #  include "XrdOuc/XrdOucPthread.hh"
00064 #else
00065 #  include "XrdSys/XrdSysPthread.hh"
00066 #endif
00067 
00068 ClassImp(TXNetFile);
00069 
00070 Bool_t TXNetFile::fgInitDone = kFALSE;
00071 Bool_t TXNetFile::fgRootdBC = kTRUE;
00072 TFileStager *TXNetFile::fgFileStager = 0;
00073 
00074 //_____________________________________________________________________________
00075 TXNetFile::TXNetFile(const char *url, Option_t *option, const char* ftitle,
00076                      Int_t compress, Int_t netopt, Bool_t parallelopen,
00077                      const char *logicalurl) :
00078             TNetFile((logicalurl ? logicalurl : url), ftitle, compress, kFALSE)
00079 {
00080    // Create a TXNetFile object. A TXNetFile object is the same as a TNetFile
00081    // (from which the former derives) except that the protocol is extended to
00082    // support dealing with new xrootd data server or xrootd load balancer
00083    // server.
00084    //
00085    // The "url" argument must be of the form
00086    //
00087    //   root://server1:port1[,server2:port2,...,serverN:portN]/pathfile,
00088    //
00089    // Note that this means that multiple servers (>= 1) can be specified in
00090    // the url. The connection will try to connect to the first server:port
00091    // and if that does not succeed, it will try the second one, and so on
00092    // until it finds a server that will respond.
00093    //
00094    // See the TNetFile documentation for the description of the other arguments.
00095    //
00096    // The creation consists of internal variable settings (most important is
00097    // the client's domain), creation of a TXUrl array containing all specified
00098    // urls (a single url is serverX:portX/pathfile), trying to connect to the
00099    // servers calling Connect() method, getting a valid access to the remote
00100    // server the client is connected to using GetAccessToSrv() method,
00101    // recognizing the remote server (if an old rootd the TNetFile's Create
00102    // method will be called).
00103    //
00104    // The options field of the URL can be used for the following purposes:
00105    //   a. open a non-ROOT generic file
00106    //      "root://server1:port1[,server2:port2,...]/pathfile?filetype=raw"
00107    //   b. re-check the environment variables
00108    //      "root://server1:port1[,server2:port2,...]/pathfile?checkenv"
00109    //   c. set the cache size (in bytes)
00110    //      "root://server1:port1[,server2:port2,...]/pathfile?cachesz=20000000"
00111    //   d. set the read-ahead size (in bytes)
00112    //      "root://server1:port1[,server2:port2,...]/pathfile?readaheadsz=100000"
00113    //   e. set the cache remove policy
00114    //      "root://server1:port1[,server2:port2,...]/pathfile?rmpolicy=1"
00115    //   f. set the max number of redirections
00116    //      "root://server1:port1[,server2:port2,...]/pathfile?mxredir=2"
00117    // (multiple options can be set concurrently)
00118    TUrl urlnoanchor(url);
00119    // Set debug level
00120    EnvPutInt(NAME_DEBUG, gEnv->GetValue("XNet.Debug", -1));
00121 
00122    // Set environment, if needed
00123    if (!fgInitDone || strstr(urlnoanchor.GetOptions(),"checkenv")) {
00124       SetEnv();
00125       fgInitDone = kTRUE;
00126 
00127       // Print the tag, if required (only once)
00128       if (gEnv->GetValue("XNet.PrintTAG",0) == 1)
00129          Info("TXNetFile","(eXtended TNetFile) %s",
00130               gROOT->GetVersion());
00131    }
00132 
00133    // Remove anchors from the URL!
00134    urlnoanchor.SetAnchor("");
00135 
00136    // Init mutex used in the asynchronous open machinery
00137    fInitMtx = new XrdSysRecMutex();
00138 
00139    if (gMonitoringWriter) {
00140       // Init the monitoring system
00141       if (!fOpenPhases) {
00142          fOpenPhases = new TList;
00143          fOpenPhases->SetOwner();
00144       }
00145       // Should not be null instead of "xrdopen" to init the thing ?
00146       gMonitoringWriter->SendFileOpenProgress(this, fOpenPhases, "xrdopen", kFALSE);
00147    }
00148 
00149    // Create an instance
00150    CreateXClient(urlnoanchor.GetUrl(), option, netopt, parallelopen);
00151 }
00152 
00153 //_____________________________________________________________________________
00154 TXNetFile::~TXNetFile()
00155 {
00156    // Destructor.
00157 
00158    if (IsOpen())
00159       Close(0);
00160 
00161    SafeDelete(fClient);
00162    SafeDelete(fInitMtx);
00163 }
00164 
00165 //_____________________________________________________________________________
00166 void TXNetFile::FormUrl(TUrl uu, TString &uus)
00167 {
00168    // Form url for rootd socket.
00169 
00170    // Protocol
00171    uus = "root://";
00172 
00173    // User, if any
00174    if (strlen(uu.GetUser()) > 0) {
00175       uus += uu.GetUser();
00176       uus += "@";
00177    }
00178 
00179    // Host, if any
00180    if (strlen(uu.GetHost()) > 0) {
00181       uus += uu.GetHost();
00182    }
00183 
00184    // Port, if any
00185    if (uu.GetPort() > 0) {
00186       uus += ":";
00187       uus += uu.GetPort();
00188    }
00189 
00190    // End of string
00191    uus += "/";
00192 }
00193 
00194 //_____________________________________________________________________________
00195 Int_t TXNetFile::ParseOptions(const char *opts,
00196                               Int_t &cachesz, Int_t &readaheadsz,
00197                               Int_t &rmpolicy, Int_t &mxredir, Int_t &rastrategy, Int_t &readtrimblksz)
00198 {
00199    // Parse input options for cache parameters
00200    static const char *keys[6] = { "cachesz=", "readaheadsz=", "rmpolicy=",
00201                                   "mxredir=", "readaheadstrategy=", "readtrimblksz=" };
00202    Int_t fo = 0;
00203    TString s(opts);
00204 
00205    UInt_t i = 0;
00206    for (i = 0; i < (sizeof(keys)/sizeof(keys[0])); i++) {
00207       Int_t j = s.Index(keys[i]);
00208       if (j != kNPOS) {
00209          TString val(s(j+strlen(keys[i]), s.Length()));
00210          // Cut of non digits
00211          Int_t k = 0;
00212          while (k < val.Length())
00213             if (!TString(val(k++)).IsDigit())
00214                break;
00215          if (k < val.Length())
00216             val.Remove(--k);
00217          if (val.IsDigit()) {
00218             fo++;
00219             if (i == 0)
00220                cachesz = val.Atoi();
00221             else if (i == 1)
00222                readaheadsz = val.Atoi();
00223             else if (i == 2)
00224                rmpolicy = val.Atoi();
00225             else if (i == 3)
00226                mxredir = val.Atoi();
00227             else if (i == 4)
00228                rastrategy = val.Atoi();
00229             else if (i == 5)
00230                readtrimblksz = val.Atoi();
00231          }
00232       }
00233    }
00234 
00235    // Notify
00236    if (gDebug > 0)
00237       Info("ParseCacheOptions","found: cachesz = %d, readaheadsz = %d, "
00238            "rmpolicy = %d, mxredir = %d, rastrategy = %d, readtrimblksz = %d",
00239            cachesz, readaheadsz, rmpolicy, mxredir, rastrategy, readtrimblksz);
00240 
00241    // Done
00242    return fo;
00243 }
00244 
00245 //_____________________________________________________________________________
00246 void TXNetFile::CreateXClient(const char *url, Option_t *option, Int_t netopt,
00247                               Bool_t parallelopen)
00248 {
00249    // The real creation work is done here.
00250 
00251    Int_t cachesz = -1, readaheadsz = -1, rmpolicy = -1, mxredir = -1, np = 0;
00252    Int_t readaheadstrategy = -1, readtrimblksz = -1;
00253 
00254    fClient = 0;
00255    fNetopt = netopt;
00256 
00257    // Set the timeout (default 999999999 secs, i.e. far, far in the future)
00258    gSystem->Setenv("XRDCLIENTMAXWAIT", Form("%d",TFile::GetOpenTimeout()));
00259 
00260    if (GetOnlyStaged()) {
00261       // Check if the file is staged before opening it
00262       if (!fgFileStager || !(fgFileStager->Matches(url))) {
00263          SafeDelete(fgFileStager);
00264          fgFileStager = TFileStager::Open(url);
00265       }
00266       if (fgFileStager) {
00267          if (!(fgFileStager->IsStaged(url))) {
00268             ::Warning("TXNetFile","<%s> is not staged - StageOnly flag is set!",url);
00269             goto zombie;
00270          }
00271       }
00272    }
00273 
00274    // Init members
00275    fIsRootd = kFALSE;
00276 
00277    // The parallel open can be forced to true in the config
00278    if (gEnv->GetValue("XNet.ForceParallelOpen", 0))
00279       parallelopen = kTRUE;
00280    fAsyncOpenStatus = (parallelopen) ? kAOSInProgress : fAsyncOpenStatus ;
00281 
00282    Bool_t isRootd;
00283    isRootd = kFALSE;
00284    //
00285    // Setup a client instance
00286    fClient = new XrdClient(url);
00287    if (!fClient) {
00288       fAsyncOpenStatus = (parallelopen) ? kAOSFailure : fAsyncOpenStatus ;
00289       Error("CreateXClient","fatal error: new object creation failed -"
00290             " out of system resources.");
00291       gSystem->Abort();
00292       goto zombie;
00293    }
00294 
00295    // Get client (cache, redir) parameters, if any
00296    np = ParseOptions(TUrl(url).GetOptions(),
00297                      cachesz, readaheadsz, rmpolicy, mxredir,
00298                      readaheadstrategy, readtrimblksz);
00299 
00300    // Set max redir, if asked
00301    if (mxredir > 0) {
00302       if (fClient->GetClientConn()) {
00303          if (gDebug > 0)
00304             Info("CreateXClient", "setting maxredir = %d", mxredir);
00305          fClient->GetClientConn()->SetMaxRedirCnt(mxredir);
00306       }
00307       np--;
00308    }
00309    // Set the cache parameters, if any
00310    if (np > 0) {
00311       if (gDebug > 0)
00312          Info("CreateXClient", "setting cachesz = %d, readaheadsz = %d, "
00313                                "rmpolicy = %d",
00314                                cachesz, readaheadsz, rmpolicy);
00315       fClient->SetCacheParameters(cachesz, readaheadsz, rmpolicy);
00316 
00317       if (readaheadstrategy >= 0) {
00318          if (gDebug > 0)
00319             Info("CreateXClient", "setting readaheadstrategy = %d", readaheadstrategy);
00320          fClient->SetReadAheadStrategy(readaheadstrategy);
00321       }
00322 
00323       if (readtrimblksz >= 0) {
00324          if (gDebug > 0)
00325             Info("CreateXClient", "setting readtrimblksz = %d", readtrimblksz);
00326          fClient->SetBlockReadTrimming(readtrimblksz);
00327       }
00328 
00329    }
00330 
00331    //
00332    // Now try opening the file
00333    if (!Open(option, parallelopen)) {
00334       if (!fClient->IsOpen_wait()) {
00335          if (gDebug > 1)
00336             Info("CreateXClient", "remote file could not be open");
00337 
00338          // If the server is a rootd we need to create a TNetFile
00339          isRootd = (fClient->GetClientConn()->GetServerType() == kSTRootd);
00340 
00341          if (isRootd) {
00342             if (fgRootdBC) {
00343 
00344                Int_t sd = fClient->GetClientConn()->GetOpenSockFD();
00345                if (sd > -1) {
00346                   //
00347                   // Create a TSocket on the open connection
00348                   TSocket *s = new TSocket(sd);
00349 
00350                   s->SetOption(kNoBlock, 0);
00351 
00352                   // Find out the remote protocol (send the client protocol first)
00353                   Int_t rproto = GetRootdProtocol(s);
00354                   if (rproto < 0) {
00355                      Error("CreateXClient", "getting rootd server protocol");
00356                      goto zombie;
00357                   }
00358 
00359                   // Finalize TSocket initialization
00360                   s->SetRemoteProtocol(rproto);
00361                   TUrl uut((fClient->GetClientConn()
00362                                    ->GetCurrentUrl()).GetUrl().c_str());
00363                   TString uu;
00364                   FormUrl(uut,uu);
00365 
00366                   if (gDebug > 2)
00367                      Info("CreateXClient"," url: %s",uu.Data());
00368                   s->SetUrl(uu.Data());
00369                   s->SetService("rootd");
00370                   s->SetServType(TSocket::kROOTD);
00371                   //
00372                   // Set rootd flag
00373                   fIsRootd = kTRUE;
00374                   //
00375                   // Now we can check if we can create a TNetFile on the
00376                   // open connection
00377                   if (rproto > 13) {
00378                      //
00379                      // Remote support for reuse of open connection
00380                      TNetFile::Create(s, option, netopt);
00381                   } else {
00382                      //
00383                      // Open connection has been closed because could
00384                      // not be reused; TNetFile will open a new connection
00385                      TNetFile::Create(uu.Data(), option, netopt);
00386                   }
00387 
00388                   return;
00389                } else {
00390                   Error("CreateXClient", "rootd: underlying socket undefined");
00391                   goto zombie;
00392                }
00393             } else {
00394                if (gDebug > 0)
00395                   Info("CreateXClient", "rootd: fall back not enabled - closing");
00396                goto zombie;
00397             }
00398          } else {
00399             Error("CreateXClient", "open attempt failed on %s", fUrl.GetUrl());
00400             goto zombie;
00401          }
00402       }
00403    }
00404 
00405    return;
00406 
00407 zombie:
00408    // error in file opening occured, make this object a zombie
00409    SafeDelete(fClient);
00410    MakeZombie();
00411    gDirectory = gROOT;
00412 }
00413 
00414 //_____________________________________________________________________________
00415 Int_t TXNetFile::GetRootdProtocol(TSocket *s)
00416 {
00417    // Find out the remote rootd protocol version.
00418    // Returns -1 in case of error.
00419 
00420    Int_t rproto = -1;
00421 
00422    UInt_t cproto = 0;
00423    Int_t len = sizeof(cproto);
00424    memcpy((char *)&cproto,
00425       Form(" %d", TSocket::GetClientProtocol()),len);
00426    Int_t ns = s->SendRaw(&cproto, len);
00427    if (ns != len) {
00428       ::Error("TXNetFile::GetRootdProtocol",
00429               "sending %d bytes to rootd server [%s:%d]",
00430               len, (s->GetInetAddress()).GetHostName(), s->GetPort());
00431       return -1;
00432    }
00433 
00434    // Get the remote protocol
00435    Int_t ibuf[2] = {0};
00436    len = sizeof(ibuf);
00437    Int_t nr = s->RecvRaw(ibuf, len);
00438    if (nr != len) {
00439       ::Error("TXNetFile::GetRootdProtocol",
00440               "reading %d bytes from rootd server [%s:%d]",
00441               len, (s->GetInetAddress()).GetHostName(), s->GetPort());
00442       return -1;
00443    }
00444    Int_t kind = net2host(ibuf[0]);
00445    if (kind == kROOTD_PROTOCOL) {
00446       rproto = net2host(ibuf[1]);
00447    } else {
00448       kind = net2host(ibuf[1]);
00449       if (kind == kROOTD_PROTOCOL) {
00450          len = sizeof(rproto);
00451          nr = s->RecvRaw(&rproto, len);
00452          if (nr != len) {
00453             ::Error("TXNetFile::GetRootdProtocol",
00454                     "reading %d bytes from rootd server [%s:%d]",
00455                     len, (s->GetInetAddress()).GetHostName(), s->GetPort());
00456             return -1;
00457          }
00458          rproto = net2host(rproto);
00459       }
00460    }
00461    if (gDebug > 2)
00462       ::Info("TXNetFile::GetRootdProtocol",
00463              "remote rootd: buf1: %d, buf2: %d rproto: %d",
00464              net2host(ibuf[0]),net2host(ibuf[1]),rproto);
00465 
00466    // We are done
00467    return rproto;
00468 }
00469 
00470 //_____________________________________________________________________________
00471 Bool_t TXNetFile::Open(Option_t *option, Bool_t doitparallel)
00472 {
00473    // The real creation work is done here.
00474 
00475    //
00476    // Parse options
00477    kXR_unt16 openOpt = 0;
00478    memset(&openOpt, 0, sizeof(openOpt));
00479    TString opt = option;
00480    opt.ToUpper();
00481    //
00482    // Check force, accepting 'f'/'F' for backward compatibility,
00483    // and special read syntax
00484    if (opt.BeginsWith("-") || opt.BeginsWith("F") || (opt == "+READ")) {
00485       opt.Remove(0,1);
00486       openOpt |= kXR_force;
00487    }
00488    //
00489    // Read flag
00490    Bool_t read = (opt == "READ");
00491    //
00492    // Create flag ("NEW" == "CREATE")
00493    Bool_t create = (opt == "CREATE" || opt == "NEW");
00494    //
00495    // Recreate flag
00496    Bool_t recreate = (opt == "RECREATE");
00497    //
00498    // Update flag
00499    Bool_t update = (opt == "UPDATE");
00500    //
00501    // Default is Read
00502    if (!create && !recreate && !update && !read) {
00503       read = kTRUE;
00504       opt = "READ";
00505    }
00506    //
00507    // Save effective options
00508    fOption = opt;
00509    if (create || update || recreate)
00510       fWritable = 1;
00511    //
00512    // Update requires the file existing: check that and switch to create,
00513    // if the file is not found.
00514    if (update) {
00515       if (gSystem->AccessPathName(fUrl.GetUrl(), kFileExists)) {
00516          update = kFALSE;
00517          create = kTRUE;
00518       }
00519       if (update) {
00520          if (gSystem->AccessPathName(fUrl.GetUrl(), kWritePermission)) {
00521             Error("Open", "no write permission, could not open file %s",
00522                           fUrl.GetUrl());
00523             fAsyncOpenStatus = (doitparallel) ? kAOSFailure : fAsyncOpenStatus ;
00524             return kFALSE;
00525          }
00526          openOpt |= kXR_open_updt;
00527       }
00528    }
00529 
00530    //
00531    // Create and Recreate are correlated
00532    if (create)
00533       openOpt |= kXR_new;
00534    if (recreate) {
00535       openOpt |= kXR_delete;
00536       create = kTRUE;
00537    }
00538 
00539    Bool_t mkpath = (gEnv->GetValue("XNet.Mkpath", 0) == 1) ? kTRUE : kFALSE;
00540    char *p = (char*)strstr(fUrl.GetOptions(), "mkpath=");
00541    if (p)
00542      mkpath = (*(p + strlen("mkpath=")) == '1') ? kTRUE : kFALSE;
00543    if (mkpath)
00544      openOpt |= kXR_mkpath;
00545 
00546    if (read)
00547       openOpt |= kXR_open_read;
00548 
00549    //
00550    // Set open mode to rw-r-r
00551    kXR_unt16 openMode = kXR_or | kXR_gr | kXR_ur | kXR_uw;
00552 
00553    //
00554    // Open file (FileOpenerThread disabled for the time being)
00555    if (!fClient->Open(openMode, openOpt, doitparallel)) {
00556       if (gDebug > 1)
00557          Info("Open", "remote file could not be open");
00558       fAsyncOpenStatus = (doitparallel) ? kAOSFailure : fAsyncOpenStatus ;
00559       return kFALSE;
00560    } else {
00561       // Initialize the file
00562       // If we are using the parallel open, the init phase is
00563       // performed later. In checking for the IsOpen or
00564       // asynchronously in a callback func
00565       if (!doitparallel) {
00566          // Mutex serialization is done inside
00567          Init(create);
00568          // If initialization failed close everything
00569          if (TFile::IsZombie()) {
00570             fClient->Close();
00571             // To avoid problems in final deletion of object not completely
00572             // initialized
00573             fWritable = 0;
00574             // Notify failure
00575             return kFALSE;
00576          }
00577       }
00578    }
00579 
00580    // We are done
00581    return kTRUE;
00582 }
00583 
00584 //_____________________________________________________________________________
00585 Bool_t TXNetFile::ReadBuffer(char *buffer, Int_t bufferLength)
00586 {
00587    // Override TNetFile::ReadBuffer to deal with the xrootd server.
00588    // Returns kTRUE in case of errors.
00589 
00590    if (IsZombie()) {
00591       Error("ReadBuffer", "ReadBuffer is not possible because object"
00592             " is in 'zombie' state");
00593       return kTRUE;
00594    }
00595 
00596    if (fIsRootd) {
00597       if (gDebug > 1)
00598          Info("ReadBuffer","Calling TNetFile::ReadBuffer");
00599       return TNetFile::ReadBuffer(buffer, bufferLength);
00600    }
00601 
00602    if (!IsOpen()) {
00603       Error("ReadBuffer","The remote file is not open");
00604       return kTRUE;
00605    }
00606 
00607    Bool_t result = kFALSE;
00608 
00609    if (bufferLength==0)
00610       return 0;
00611 
00612    // This returns:
00613    //  2 if errors
00614    //  1 it looks like the block has already been prefetched
00615    //  0 it looks like the block has not been prefetched
00616    // But we don't want it to return the buffer, to avoid recursion
00617    Int_t st = 0;
00618    if (GetCacheRead() && GetCacheRead()->IsAsyncReading()) {
00619       st = ReadBufferViaCache(0, bufferLength);
00620       if (st == 1)
00621          fOffset -= bufferLength;
00622    } else {
00623       if (GetCacheRead()) {
00624          st = ReadBufferViaCache(buffer, bufferLength);
00625          if (st == 1)
00626             return kFALSE;
00627       }
00628    }
00629 
00630    Double_t start = 0;
00631    if (gPerfStats) start = TTimeStamp();
00632 
00633    // Read from the remote xrootd
00634    Int_t nr = fClient->Read(buffer, fOffset, bufferLength);
00635 
00636    if (!nr)
00637       return kTRUE;
00638 
00639    if (gDebug > 1)
00640       Info("ReadBuffer", "%d bytes of data read from offset"
00641                          " %lld (%d requested)", nr, fOffset, bufferLength);
00642 
00643    fOffset += bufferLength;
00644 
00645    if (!st) {
00646      // Update the counters only if the block has not been prefetched
00647      fBytesRead += nr;
00648      fReadCalls++;
00649 #ifdef WIN32
00650      SetFileBytesRead(GetFileBytesRead() + nr);
00651      SetFileReadCalls(GetFileReadCalls() + 1);
00652 #else
00653      fgBytesRead += nr;
00654      fgReadCalls++;
00655 #endif
00656 
00657      if (gPerfStats)
00658         gPerfStats->FileReadEvent(this, bufferLength, start);
00659 
00660    }
00661 
00662    if (gMonitoringWriter)
00663       gMonitoringWriter->SendFileReadProgress(this);
00664 
00665    return result;
00666 }
00667 
00668 //_____________________________________________________________________________
00669 Bool_t TXNetFile::ReadBuffer(char *buffer, Long64_t pos, Int_t bufferLength)
00670 {
00671    // Pass through to TNetFile implementation which will call back eventually
00672    // to our ReadBuffer with 2 arguments to deal with xrootd errors.
00673 
00674    return TNetFile::ReadBuffer(buffer, pos, bufferLength);
00675 }
00676 
00677 //______________________________________________________________________________
00678 Bool_t TXNetFile::ReadBufferAsync(Long64_t offs, Int_t bufferLength)
00679 {
00680    // Implementation dealing with the xrootd server.
00681    // Returns kTRUE in case of errors.
00682    // This is the same as TXNetFile::ReadBuffer but using the async
00683    // call from xrootd
00684 
00685    if (IsZombie()) {
00686       Error("ReadBuffer", "ReadBuffer is not possible because object"
00687             " is in 'zombie' state");
00688       return kTRUE;
00689    }
00690 
00691    if (fIsRootd) {
00692       if (gDebug > 1)
00693          Error("ReadBufferAsync","Not supported for rootd");
00694       return kTRUE;
00695    }
00696 
00697    if (!IsOpen()) {
00698       Error("ReadBuffer","The remote file is not open");
00699       return kTRUE;
00700    }
00701 
00702    Double_t start = 0;
00703    if (gPerfStats) start = TTimeStamp();
00704 
00705    Bool_t result = kFALSE;
00706 
00707    if (bufferLength==0)
00708       return 0;
00709 
00710    SynchronizeCacheSize();
00711 
00712    // Read for the remote xrootd
00713    // This doesnt return the number of bytes read...
00714    // and even if it did we dont want to update fBytesRead
00715    // because that would be updated in the real read
00716    XReqErrorType nr = fClient->Read_Async(offs+fArchiveOffset, bufferLength);
00717 
00718    if (nr != kOK)
00719       return kTRUE;
00720 
00721    fBytesRead += bufferLength;
00722    fReadCalls++;
00723 #ifdef WIN32
00724    SetFileBytesRead(GetFileBytesRead() + bufferLength);
00725    SetFileReadCalls(GetFileReadCalls() + 1);
00726 #else
00727    fgBytesRead += bufferLength;
00728    fgReadCalls++;
00729 #endif
00730 
00731    if (gPerfStats)
00732       gPerfStats->FileReadEvent(this, bufferLength, start);
00733 
00734    if (gDebug > 1)
00735       Info("ReadBufferAsync", "%d bytes of data read request from offset"
00736                               " %lld", bufferLength, offs);
00737    return result;
00738 }
00739 
00740 //______________________________________________________________________________
00741 Bool_t TXNetFile::ReadBuffers(char *buf,  Long64_t *pos, Int_t *len, Int_t nbuf)
00742 {
00743    // Read the nbuf blocks described in arrays pos and len,
00744    // where pos[i] is the seek position of block i of length len[i].
00745    // Note that for nbuf=1, this call is equivalent to TFile::ReafBuffer
00746    // This function is overloaded by TNetFile, TWebFile, etc.
00747    // Returns kTRUE in case of failure.
00748    // Note: This is the overloading made in TXNetFile, If ReadBuffers
00749    // is supported by xrootd it will try to gt the whole list from one single
00750    // call avoiding the latency of multiple calls
00751 
00752    if (IsZombie()) {
00753       Error("ReadBuffers", "ReadBuffers is not possible because object"
00754             " is in 'zombie' state");
00755       return kTRUE;
00756    }
00757 
00758    if (fIsRootd) {
00759       if (gDebug > 1)
00760          Info("ReadBuffers","Calling TNetFile::ReadBuffers");
00761       return TNetFile::ReadBuffers(buf, pos, len, nbuf);
00762    }
00763 
00764    if (!IsOpen()) {
00765       Error("ReadBuffers","The remote file is not open");
00766       return kTRUE;
00767    }
00768 
00769    Double_t start = 0;
00770    if (gPerfStats) start = TTimeStamp();
00771 
00772    if (fArchiveOffset)
00773       for (Int_t i = 0; i < nbuf; i++)
00774          pos[i] += fArchiveOffset;
00775 
00776    // A null buffer means that we want to use the async stuff
00777    //  hence we have to sync the cache size in XrdClient with the supposed
00778    //  size in TFile.
00779    if (!buf) {
00780       // Null buffer + 0 blocks means 'reset cache'
00781       if (!nbuf) ResetCache();
00782       SynchronizeCacheSize();
00783    }
00784 
00785    // Read for the remote xrootd
00786    Long64_t nr = fClient->ReadV(buf, pos, len, nbuf);
00787 
00788    if (gDebug > 1)
00789       Info("ReadBuffers", "response from ReadV(%d) nr: %lld", nbuf, nr);
00790 
00791    if (nr > 0) {
00792 
00793       if (gDebug > 1)
00794          Info("ReadBuffers", "%lld bytes of data read from a list of %d buffers",
00795               nr, nbuf);
00796 
00797       if (GetCacheRead() && GetCacheRead()->GetBufferSize() < nr)
00798          Info("ReadBuffers", "%lld bytes of data read with a smaller (%d) TFileCacheRead buffer size?",
00799               nr, GetCacheRead()->GetBufferSize());
00800 
00801       // Where should we leave the offset ?
00802       // fOffset += bufferLength;
00803       fBytesRead += nr;
00804       fReadCalls++;
00805 #ifdef WIN32
00806       SetFileBytesRead(GetFileBytesRead() + nr);
00807       SetFileReadCalls(GetFileReadCalls() + 1);
00808 #else
00809       fgBytesRead += nr;
00810       fgReadCalls++;
00811 #endif
00812 
00813       if (gPerfStats) {
00814          fOffset = pos[0];
00815          gPerfStats->FileReadEvent(this, pos[nbuf-1]+len[nbuf-1]-pos[0], start);
00816       }
00817 
00818       if (gMonitoringWriter)
00819          gMonitoringWriter->SendFileReadProgress(this);
00820 
00821       return kFALSE;
00822    }
00823 
00824    if (gDebug > 1)
00825       Info("ReadBuffers", "XrdClient->ReadV failed, executing TFile::ReadBuffers");
00826 
00827    // If it wasnt able to use the specialized call
00828    // then use the generic one that is a plain loop
00829    // of individual requests
00830    if (buf && nbuf)
00831       return TFile::ReadBuffers(buf, pos, len, nbuf);
00832    // If the async call was needed (buf == 0) and it got an error,
00833    // just return error
00834    else return kTRUE;
00835 }
00836 
00837 //_____________________________________________________________________________
00838 Bool_t TXNetFile::WriteBuffer(const char *buffer, Int_t bufferLength)
00839 {
00840    // Override TNetFile::WriteBuffer to deal with the xrootd server.
00841    // Returns kTRUE in case of errors.
00842 
00843    if (IsZombie()) {
00844       Error("WriteBuffer", "WriteBuffer is not possible because object"
00845             " is in 'zombie' state");
00846       return kTRUE;
00847    }
00848 
00849    if (!fWritable) {
00850       if (gDebug > 1)
00851          Info("WriteBuffer","file not writable");
00852       return kTRUE;
00853    }
00854 
00855    if (fIsRootd) {
00856       if (gDebug > 1)
00857          Info("WriteBuffer","Calling TNetFile::WriteBuffer");
00858       return TNetFile::WriteBuffer(buffer, bufferLength );
00859    }
00860 
00861    if (!IsOpen()) {
00862       Error("WriteBuffer","The remote file is not open");
00863       return kTRUE;
00864    }
00865 
00866    Int_t st;
00867    if ((st = WriteBufferViaCache(buffer, bufferLength))) {
00868       if (st == 2)
00869          return kTRUE;
00870       return kFALSE;
00871    }
00872 
00873    // Read for the remote xrootd
00874    if (!fClient->Write(buffer, fOffset, bufferLength)) {
00875       if (gDebug > 0)
00876          Info("WriteBuffer",
00877               "error writing %d bytes of data wrote to offset %lld",
00878               bufferLength , fOffset);
00879       return kTRUE;
00880    }
00881 
00882    if (gDebug > 1)
00883       Info("WriteBuffer", " %d bytes of data wrote to offset"
00884                          " %lld", bufferLength , fOffset);
00885 
00886    fOffset += bufferLength;
00887    fBytesWrite += bufferLength;
00888 #ifdef WIN32
00889    SetFileBytesWritten(GetFileBytesWritten() + bufferLength);
00890 #else
00891    fgBytesWrite += bufferLength;
00892 #endif
00893 
00894    return kFALSE;
00895 }
00896 
00897 //_____________________________________________________________________________
00898 void TXNetFile::Init(Bool_t create)
00899 {
00900    // Initialize the file. Makes sure that the file is really open before
00901    // calling TFile::Init. It may block.
00902 
00903    if (fInitDone) {
00904       // TFile::Init already called once
00905       if (gDebug > 1)
00906          Info("Init","TFile::Init already called once");
00907       return;
00908    }
00909 
00910    if (fIsRootd) {
00911       if (gDebug > 1)
00912          Info("Init","rootd: calling directly TFile::Init");
00913       return TNetFile::Init(create);
00914    }
00915 
00916    if (fClient) {
00917       // A mutex serializes this very delicate section
00918       XrdSysMutexHelper m(fInitMtx);
00919 
00920       // To safely perform the Init() we must make sure that
00921       // the file is successfully open; this call may block
00922       if (fClient->IsOpen_wait()) {
00923 
00924          // Notify the monitoring system
00925          if (gMonitoringWriter)
00926             gMonitoringWriter->SendFileOpenProgress(this, fOpenPhases, "rootinit", kFALSE);
00927 
00928          // Avoid big transfers at this level
00929          bool usecachesave = fClient->UseCache(0);
00930          // Note that Init will trigger recursive calls
00931          TFile::Init(create);
00932          // so TFile::IsOpen() returns true when in TFile::~TFile
00933          fD = -2;
00934          // Restore requested behaviour
00935          fClient->UseCache(usecachesave);
00936 
00937             // Notify the monitoring system
00938          if (gMonitoringWriter)
00939             gMonitoringWriter->SendFileOpenProgress(this, fOpenPhases, "endopen", kTRUE);
00940 
00941          // Set the Endpoint Url we are now connected to. Unless there was some opaque info
00942          // which cannot be re-used
00943          if (fClient->GetClientConn() && fClient->GetClientConn()->fRedirOpaque.length() <= 0) {
00944             fEndpointUrl = fClient->GetClientConn()->GetCurrentUrl().GetUrl().c_str();
00945             // Check equivalence of initial and end-point Url to see whether we have
00946             // been redirected
00947             if (fEndpointUrl.GetPort() != fUrl.GetPort() ||
00948                strcmp(fEndpointUrl.GetHostFQDN(), fUrl.GetHostFQDN()))
00949                SetBit(TFile::kRedirected);
00950          }
00951       } else {
00952          if (gDebug > 0)
00953             Info("Init","open request failed!");
00954          SafeDelete(fClient);
00955          MakeZombie();
00956          gDirectory = gROOT;
00957       }
00958    }
00959 }
00960 
00961 //_____________________________________________________________________________
00962 Bool_t TXNetFile::IsOpen() const
00963 {
00964    // Return kTRUE if the file is open, kFALSE otherwise.
00965 
00966    if (fIsRootd) {
00967       if (gDebug > 1)
00968          Info("IsOpen","Calling TNetFile::IsOpen");
00969       return TNetFile::IsOpen();
00970    }
00971 
00972    if (!fClient)
00973       return kFALSE;
00974 
00975    // We are done
00976    return ((fClient && fInitDone) ? fClient->IsOpen() : kFALSE);
00977 }
00978 
00979 //_____________________________________________________________________________
00980 TFile::EAsyncOpenStatus TXNetFile::GetAsyncOpenStatus()
00981 {
00982    // Return status of asynchronous request
00983 
00984    if (fAsyncOpenStatus != TFile::kAOSNotAsync) {
00985       if (fClient->IsOpen_inprogress()) {
00986          return TFile::kAOSInProgress;
00987       } else {
00988          if (fClient->IsOpen())
00989             return TFile::kAOSSuccess;
00990          else
00991             return TFile::kAOSFailure;
00992       }
00993    }
00994 
00995    // Not asynchronous
00996    return TFile::kAOSNotAsync;
00997 }
00998 
00999 //_____________________________________________________________________________
01000 Int_t TXNetFile::ReOpen(const Option_t *Mode)
01001 {
01002    // Re-open the file (see TNetFile::ReOpen() or TFile::ReOpen()
01003    // for more details).
01004 
01005    if (fIsRootd) {
01006       if (gDebug > 1)
01007          Info("ReOpen","Calling TNetFile::ReOpen");
01008       return TNetFile::ReOpen(Mode);
01009    }
01010 
01011    return TFile::ReOpen(Mode);
01012 }
01013 
01014 //_____________________________________________________________________________
01015 void TXNetFile::Close(const Option_t *opt)
01016 {
01017    // Close the file (see TNetFile::Close() or TFile::Close()
01018    // for more details).
01019 
01020    if (fIsRootd) {
01021       if (gDebug > 1)
01022          Info("Close","Calling TNetFile::Close");
01023       TNetFile::Close(opt);
01024       return;
01025    }
01026 
01027    if (!fClient) return;
01028 
01029    TFile::Close(opt);
01030 
01031    fIsRootd = kFALSE;
01032 
01033    if (IsOpen())
01034       fClient->Close();
01035 
01036    fD = -1;  // so TFile::IsOpen() returns false when in TFile::~TFile
01037 }
01038 
01039 //_____________________________________________________________________________
01040 void TXNetFile::Flush()
01041 {
01042    // Flushes un-written data.
01043    if (IsZombie()) {
01044       Error("Flush", "Flush is not possible because object is"
01045             " in 'zombie' state");
01046       return;
01047    }
01048 
01049    if (!fWritable) {
01050       if (gDebug > 1)
01051          Info("Flush", "file not writable - do nothing");
01052       return;
01053    }
01054 
01055    if (fIsRootd) {
01056       if (gDebug > 1)
01057          Info("Flush","Calling TNetFile::Flush");
01058       TNetFile::Flush();
01059       return;
01060    }
01061 
01062    if (!IsOpen()) {
01063       Error("Flush","The remote file is not open");
01064       return;
01065    }
01066 
01067    FlushWriteCache();
01068 
01069    //
01070    // Flush via the remote xrootd
01071    fClient->Sync();
01072    if (gDebug > 1)
01073       Info("Flush", "XrdClient::Sync called.");
01074 }
01075 
01076 //_____________________________________________________________________________
01077 Int_t TXNetFile::SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags,
01078                           Long_t *modtime)
01079 {
01080    // Override TNetFile::SysStat (see parent's method for more details).
01081 
01082    if (IsZombie()) {
01083       Error("SysStat", "SysStat is not possible because object is"
01084             " in 'zombie' state");
01085       *size = 0;
01086       return 1;
01087    }
01088 
01089    if (fIsRootd) {
01090       if (gDebug > 1)
01091          Info("SysStat", "calling TNetFile::SysStat");
01092       return TNetFile::SysStat(fd, id, size, flags, modtime);
01093    }
01094 
01095    // Return file stat information. The interface and return value is
01096    // identical to TSystem::GetPathInfo().
01097    struct XrdClientStatInfo stinfo;
01098    if (fClient && fClient->Stat(&stinfo)) {
01099       *id = (Long_t)(stinfo.id);
01100       *size = (Long64_t)(stinfo.size);
01101       *flags = (Long_t)(stinfo.flags);
01102       *modtime = (Long_t)(stinfo.modtime);
01103       if (gDebug > 1)
01104          Info("SysStat", "got stats = %ld %lld %ld %ld",
01105                          *id, *size, *flags, *modtime);
01106    } else {
01107 
01108       if (gDebug > 1) {
01109          if (!IsOpen()) Info("SysStat", "could not stat remote file. Not opened.");
01110          else
01111             Info("SysStat", "could not stat remote file");
01112       }
01113 
01114 
01115       *id = -1;
01116       return 1;
01117    }
01118 
01119    // We are done
01120    return 0;
01121 }
01122 
01123 //_____________________________________________________________________________
01124 Int_t TXNetFile::SysClose(Int_t fd)
01125 {
01126    // Override TNetFile::SysClose (see parent's method for more details).
01127 
01128    if (IsZombie()) {
01129       Error("SysClose", "SysClose is not possible because object is"
01130             " in 'zombie' state");
01131       return 0;
01132    }
01133 
01134    if (fIsRootd) {
01135       if (gDebug > 1)
01136          Info("SysClose","Calling TNetFile::SysClose");
01137       return TNetFile::SysClose(fd);
01138    }
01139 
01140    // Send close to remote xrootd
01141    if (IsOpen())
01142       fClient->Close();
01143 
01144    return 0;
01145 }
01146 
01147 //_____________________________________________________________________________
01148 Int_t TXNetFile::SysOpen(const char* pathname, Int_t flags, UInt_t mode)
01149 {
01150    // Override TNetFile::SysOpen (see parent's method for more details).
01151 
01152    if (fIsRootd) {
01153       if (gDebug > 1)
01154          Info("SysOpen", "Calling TNetFile::SysOpen");
01155       return TNetFile::SysOpen(pathname, flags, mode);
01156    }
01157 
01158    if (!fClient) {
01159 
01160       // Create an instance of XrdClient
01161       CreateXClient(fUrl.GetUrl(), fOption, fNetopt, kFALSE);
01162 
01163    } else {
01164 
01165       // url is not needed because already stored
01166       // fOption is set in TFile::ReOpen
01167       Open(fOption.Data(), kFALSE);
01168    }
01169 
01170    // If not successful, flag it
01171    if (!IsOpen())
01172       return -1;
01173 
01174    // This means ok for net files
01175    return -2;  // set as fD in ReOpen
01176 }
01177 
01178 //_____________________________________________________________________________
01179 void TXNetFile::SetEnv()
01180 {
01181    // Set the relevant environment variables
01182 
01183    // List of domains where redirection is allowed
01184    TString allowRE = gEnv->GetValue("XNet.RedirDomainAllowRE", "");
01185    if (allowRE.Length() > 0)
01186       EnvPutString(NAME_REDIRDOMAINALLOW_RE, allowRE.Data());
01187 
01188    // List of domains where redirection is denied
01189    TString denyRE  = gEnv->GetValue("XNet.RedirDomainDenyRE", "");
01190    if (denyRE.Length() > 0)
01191       EnvPutString(NAME_REDIRDOMAINDENY_RE, denyRE.Data());
01192 
01193    // List of domains where connection is allowed
01194    TString allowCO = gEnv->GetValue("XNet.ConnectDomainAllowRE", "");
01195    if (allowCO.Length() > 0)
01196       EnvPutString(NAME_CONNECTDOMAINALLOW_RE, allowCO.Data());
01197 
01198    // List of domains where connection is denied
01199    TString denyCO  = gEnv->GetValue("XNet.ConnectDomainDenyRE", "");
01200    if (denyCO.Length() > 0)
01201       EnvPutString(NAME_CONNECTDOMAINDENY_RE, denyCO.Data());
01202 
01203    // Connect Timeout
01204    Int_t connTO = gEnv->GetValue("XNet.ConnectTimeout",
01205                                   DFLT_CONNECTTIMEOUT);
01206    EnvPutInt(NAME_CONNECTTIMEOUT, connTO);
01207 
01208    // Reconnect Timeout
01209    Int_t recoTO = gEnv->GetValue("XNet.ReconnectWait",
01210                                   DFLT_RECONNECTWAIT);
01211    if (recoTO == DFLT_RECONNECTWAIT) {
01212       // Check also the old variable name
01213       recoTO = gEnv->GetValue("XNet.ReconnectTimeout",
01214                                   DFLT_RECONNECTWAIT);
01215    }
01216    EnvPutInt(NAME_RECONNECTWAIT, recoTO);
01217 
01218    // Request Timeout
01219    Int_t requTO = gEnv->GetValue("XNet.RequestTimeout",
01220                                   DFLT_REQUESTTIMEOUT);
01221    EnvPutInt(NAME_REQUESTTIMEOUT, requTO);
01222 
01223    // Max number of redirections
01224    Int_t maxRedir = gEnv->GetValue("XNet.MaxRedirectCount",
01225                                     DFLT_MAXREDIRECTCOUNT);
01226    EnvPutInt(NAME_MAXREDIRECTCOUNT, maxRedir);
01227 
01228 
01229    // Read ahead size
01230    Int_t rAheadsiz = gEnv->GetValue("XNet.ReadAheadSize",
01231                                      DFLT_READAHEADSIZE);
01232    EnvPutInt(NAME_READAHEADSIZE, rAheadsiz);
01233 
01234 
01235    // Cache size (<= 0 disables cache)
01236    Int_t rCachesiz = gEnv->GetValue("XNet.ReadCacheSize",
01237                                      DFLT_READCACHESIZE);
01238 
01239    EnvPutInt(NAME_READCACHESIZE, rCachesiz);
01240 
01241    // Max number of retries on first connect
01242    Int_t maxRetries = gEnv->GetValue("XNet.FirstConnectMaxCnt",
01243                                      DFLT_FIRSTCONNECTMAXCNT);
01244    EnvPutInt(NAME_FIRSTCONNECTMAXCNT, maxRetries);
01245 
01246    // Parallel stream count
01247    Int_t parStreamsCnt = gEnv->GetValue("XNet.ParStreamsPerPhyConn",
01248                                         DFLT_MULTISTREAMCNT);
01249    EnvPutInt(NAME_MULTISTREAMCNT, parStreamsCnt);
01250 
01251    // Change the TCP window size (0 means 'scaling' on some platforms)
01252    Int_t tcpWindowSize = gEnv->GetValue("XNet.DfltTcpWindowSize",
01253                                         DFLT_DFLTTCPWINDOWSIZE);
01254    EnvPutInt(NAME_DFLTTCPWINDOWSIZE, tcpWindowSize);
01255 
01256    // Change the transaction timeout
01257    Int_t transactionTimeout = gEnv->GetValue("XNet.TransactionTimeout",
01258                                              DFLT_TRANSACTIONTIMEOUT);
01259    EnvPutInt(NAME_TRANSACTIONTIMEOUT, transactionTimeout);
01260 
01261    // Whether to activate automatic rootd backward-compatibility
01262    // (We override XrdClient default)
01263    fgRootdBC = gEnv->GetValue("XNet.RootdFallback", 1);
01264    EnvPutInt(NAME_KEEPSOCKOPENIFNOTXRD, fgRootdBC);
01265 
01266    // Dynamic forwarding (SOCKS4)
01267    TString socks4Host = gEnv->GetValue("XNet.SOCKS4Host","");
01268    Int_t socks4Port = gEnv->GetValue("XNet.SOCKS4Port",-1);
01269    if (socks4Port > 0) {
01270       if (socks4Host.IsNull())
01271          // Default
01272          socks4Host = "127.0.0.1";
01273       EnvPutString(NAME_SOCKS4HOST, socks4Host.Data());
01274       EnvPutInt(NAME_SOCKS4PORT, socks4Port);
01275    }
01276 
01277    const char *cenv = 0;
01278 
01279    // For password-based authentication
01280    TString autolog = gEnv->GetValue("XSec.Pwd.AutoLogin","1");
01281    if (autolog.Length() > 0 &&
01282       (!(cenv = gSystem->Getenv("XrdSecPWDAUTOLOG")) || strlen(cenv) <= 0))
01283       gSystem->Setenv("XrdSecPWDAUTOLOG",autolog.Data());
01284 
01285    // Old style netrc file
01286    TString netrc;
01287    netrc.Form("%s/.rootnetrc",gSystem->HomeDirectory());
01288    gSystem->Setenv("XrdSecNETRC", netrc.Data());
01289 
01290    TString alogfile = gEnv->GetValue("XSec.Pwd.ALogFile","");
01291    if (alogfile.Length() > 0)
01292       gSystem->Setenv("XrdSecPWDALOGFILE",alogfile.Data());
01293 
01294    TString verisrv = gEnv->GetValue("XSec.Pwd.VerifySrv","1");
01295    if (verisrv.Length() > 0 &&
01296       (!(cenv = gSystem->Getenv("XrdSecPWDVERIFYSRV")) || strlen(cenv) <= 0))
01297       gSystem->Setenv("XrdSecPWDVERIFYSRV",verisrv.Data());
01298 
01299    TString srvpuk = gEnv->GetValue("XSec.Pwd.ServerPuk","");
01300    if (srvpuk.Length() > 0)
01301       gSystem->Setenv("XrdSecPWDSRVPUK",srvpuk.Data());
01302 
01303    // For GSI authentication
01304    TString cadir = gEnv->GetValue("XSec.GSI.CAdir","");
01305    if (cadir.Length() > 0)
01306       gSystem->Setenv("XrdSecGSICADIR",cadir.Data());
01307 
01308    TString crldir = gEnv->GetValue("XSec.GSI.CRLdir","");
01309    if (crldir.Length() > 0)
01310       gSystem->Setenv("XrdSecGSICRLDIR",crldir.Data());
01311 
01312    TString crlext = gEnv->GetValue("XSec.GSI.CRLextension","");
01313    if (crlext.Length() > 0)
01314       gSystem->Setenv("XrdSecGSICRLEXT",crlext.Data());
01315 
01316    TString ucert = gEnv->GetValue("XSec.GSI.UserCert","");
01317    if (ucert.Length() > 0)
01318       gSystem->Setenv("XrdSecGSIUSERCERT",ucert.Data());
01319 
01320    TString ukey = gEnv->GetValue("XSec.GSI.UserKey","");
01321    if (ukey.Length() > 0)
01322       gSystem->Setenv("XrdSecGSIUSERKEY",ukey.Data());
01323 
01324    TString upxy = gEnv->GetValue("XSec.GSI.UserProxy","");
01325    if (upxy.Length() > 0)
01326       gSystem->Setenv("XrdSecGSIUSERPROXY",upxy.Data());
01327 
01328    TString valid = gEnv->GetValue("XSec.GSI.ProxyValid","");
01329    if (valid.Length() > 0)
01330       gSystem->Setenv("XrdSecGSIPROXYVALID",valid.Data());
01331 
01332    TString deplen = gEnv->GetValue("XSec.GSI.ProxyForward","0");
01333    if (deplen.Length() > 0 &&
01334       (!(cenv = gSystem->Getenv("XrdSecGSIPROXYDEPLEN")) || strlen(cenv) <= 0))
01335       gSystem->Setenv("XrdSecGSIPROXYDEPLEN",deplen.Data());
01336 
01337    TString pxybits = gEnv->GetValue("XSec.GSI.ProxyKeyBits","");
01338    if (pxybits.Length() > 0)
01339       gSystem->Setenv("XrdSecGSIPROXYKEYBITS",pxybits.Data());
01340 
01341    TString crlcheck = gEnv->GetValue("XSec.GSI.CheckCRL","1");
01342    if (crlcheck.Length() > 0 &&
01343       (!(cenv = gSystem->Getenv("XrdSecGSICRLCHECK")) || strlen(cenv) <= 0))
01344       gSystem->Setenv("XrdSecGSICRLCHECK",crlcheck.Data());
01345 
01346    TString delegpxy = gEnv->GetValue("XSec.GSI.DelegProxy","0");
01347    if (delegpxy.Length() > 0 &&
01348       (!(cenv = gSystem->Getenv("XrdSecGSIDELEGPROXY")) || strlen(cenv) <= 0))
01349       gSystem->Setenv("XrdSecGSIDELEGPROXY",delegpxy.Data());
01350 
01351    TString signpxy = gEnv->GetValue("XSec.GSI.SignProxy","1");
01352    if (signpxy.Length() > 0 &&
01353       (!(cenv = gSystem->Getenv("XrdSecGSISIGNPROXY")) || strlen(cenv) <= 0))
01354       gSystem->Setenv("XrdSecGSISIGNPROXY",signpxy.Data());
01355 
01356    // Using ROOT mechanism to IGNORE SIGPIPE signal
01357    gSystem->IgnoreSignal(kSigPipe);
01358 }
01359 
01360 //_____________________________________________________________________________
01361 void TXNetFile::SynchronizeCacheSize()
01362 {
01363    // Synchronize the cache size
01364    // Alternative purging policy
01365 
01366    if (fClient == 0) return;
01367 
01368    fClient->UseCache(TRUE);
01369    Int_t size;
01370    Long64_t bytessubmitted, byteshit, misscount, readreqcnt;
01371    Float_t  missrate, bytesusefulness;
01372    int newbsz = -1;
01373    if (fClient->GetCacheInfo(size, bytessubmitted,
01374                              byteshit, misscount,
01375                              missrate, readreqcnt,
01376                              bytesusefulness) ) {
01377 
01378       // To allow for some space for outstanding data
01379       TFileCacheRead *cacheRead = GetCacheRead();
01380       if (cacheRead) {
01381          newbsz = GetBufferSize() / 2 * 3;
01382          newbsz = TMath::Max(newbsz, size);
01383       } else {
01384          newbsz = size;
01385       }
01386 
01387    }
01388 
01389    if (newbsz > 0)
01390       fClient->SetCacheParameters(newbsz, 0, XrdClientReadCache::kRmBlk_FIFO);
01391 }
01392 
01393 //_____________________________________________________________________________
01394 void TXNetFile::ResetCache()
01395 {
01396    // Reset the cache
01397 
01398    if (fClient)
01399       fClient->RemoveAllDataFromCache();
01400 }
01401 
01402 //______________________________________________________________________________
01403 Int_t TXNetFile::GetBytesToPrefetch() const
01404 {
01405    // Max number of bytes to prefetch.
01406 
01407    Int_t size;
01408    Long64_t bytessubmitted, byteshit, misscount, readreqcnt;
01409    Float_t  missrate, bytesusefulness;
01410    Int_t bytes = 0;
01411    if (fClient && fClient->GetCacheInfo(size, bytessubmitted,
01412                                         byteshit, misscount,
01413                                         missrate, readreqcnt,
01414                                         bytesusefulness) )
01415    bytes = size;
01416    return ((bytes < 0) ? 0 : bytes);
01417 }
01418 
01419 //______________________________________________________________________________
01420 void TXNetFile::Print(Option_t *option) const
01421 {
01422    // Print the local statistics.
01423 
01424    Printf("TXNetFile caching information:");
01425 
01426    Int_t size;
01427    Long64_t bytessubmitted, byteshit, misscount, readreqcnt;
01428    Float_t  missrate, bytesusefulness;
01429 
01430    if (fClient && fClient->GetCacheInfo(size, bytessubmitted,
01431                                         byteshit, misscount,
01432                                         missrate, readreqcnt,
01433                                         bytesusefulness)) {
01434       Printf(" Max size:                  %d",   size);
01435       Printf(" Bytes submitted:           %lld", bytessubmitted);
01436       Printf(" Bytes hit (estimation):    %lld", byteshit);
01437       Printf(" Miss count:                %lld", misscount);
01438       Printf(" Miss rate:                 %f",   missrate);
01439       Printf(" Read requests count:       %lld", readreqcnt);
01440       Printf(" Bytes usefulness:          %f\n", bytesusefulness);
01441    } else
01442       Printf(" -- No Xrd client instance allocated --\n");
01443 
01444    TFile::Print(option);
01445 }

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