ROOT  6.06/09
Reference Guide
TXNetFile.cxx
Go to the documentation of this file.
1 // @(#)root/netx:$Id$
2 // Author: Alvise Dorigo, Fabrizio Furano
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TXNetFile //
15 // //
16 // Authors: Alvise Dorigo, Fabrizio Furano //
17 // INFN Padova, 2003 //
18 // Interfaced to the standalone client (XrdClient): G. Ganis, CERN //
19 // //
20 // TXNetFile is an extension of TNetFile able to deal with new xrootd //
21 // server. Its new features are: //
22 // - Automatic server kind recognition (xrootd load balancer, xrootd //
23 // data server, old rootd) //
24 // - Backward compatibility with old rootd server (acts as an old //
25 // TNetFile) //
26 // - Fault tolerance for read/write operations (read/write timeouts //
27 // and retry) //
28 // - Internal connection timeout (tunable indipendently from the OS //
29 // one) handled by threads //
30 // - handling of redirections from server //
31 // - Single TCP physical channel for multiple TXNetFile's instances //
32 // inside the same application //
33 // So, each TXNetFile object client must send messages containing //
34 // its ID (streamid). The server, of course, will respond with //
35 // messages containing the client's ID, in order to make the client //
36 // able to recognize its message by matching its streamid with that //
37 // one contained in the server's response. //
38 // - Tunable log verbosity level (0 = nothing, 3 = dump read/write //
39 // buffers too!) //
40 // - Many parameters configurable via TEnv facility (see SetParm() //
41 // methods) //
42 // //
43 //////////////////////////////////////////////////////////////////////////
44 
45 #include "Bytes.h"
46 
47 #include "TError.h"
48 #include "TEnv.h"
49 #include "TSocket.h"
50 #include "TXNetFile.h"
51 #include "TROOT.h"
52 #include "TVirtualMonitoring.h"
53 #include "TFileStager.h"
54 #include "TFileCacheRead.h"
55 #include "TTimeStamp.h"
56 #include "TVirtualPerfStats.h"
57 
58 #include <XrdClient/XrdClient.hh>
60 #include <XrdClient/XrdClientConst.hh>
61 #include <XrdClient/XrdClientEnv.hh>
62 #include <XProtocol/XProtocol.hh>
63 
64 #include "XpdSysPthread.h"
65 #include "XrdSysToOuc.h"
66 
68 
71 TFileStager *TXNetFile::fgFileStager = 0;
72 
73 ////////////////////////////////////////////////////////////////////////////////
74 /// Create a TXNetFile object. A TXNetFile object is the same as a TNetFile
75 /// (from which the former derives) except that the protocol is extended to
76 /// support dealing with new xrootd data server or xrootd load balancer
77 /// server.
78 ///
79 /// The "url" argument must be of the form
80 ///
81 /// root://server1:port1[,server2:port2,...,serverN:portN]/pathfile,
82 ///
83 /// Note that this means that multiple servers (>= 1) can be specified in
84 /// the url. The connection will try to connect to the first server:port
85 /// and if that does not succeed, it will try the second one, and so on
86 /// until it finds a server that will respond.
87 ///
88 /// See the TNetFile documentation for the description of the other arguments.
89 ///
90 /// The creation consists of internal variable settings (most important is
91 /// the client's domain), creation of a TXUrl array containing all specified
92 /// urls (a single url is serverX:portX/pathfile), trying to connect to the
93 /// servers calling Connect() method, getting a valid access to the remote
94 /// server the client is connected to using GetAccessToSrv() method,
95 /// recognizing the remote server (if an old rootd the TNetFile's Create
96 /// method will be called).
97 ///
98 /// The options field of the URL can be used for the following purposes:
99 /// a. open a non-ROOT generic file
100 /// "root://server1:port1[,server2:port2,...]/pathfile?filetype=raw"
101 /// b. re-check the environment variables
102 /// "root://server1:port1[,server2:port2,...]/pathfile?checkenv"
103 /// c. set the cache size (in bytes)
104 /// "root://server1:port1[,server2:port2,...]/pathfile?cachesz=20000000"
105 /// d. set the read-ahead size (in bytes)
106 /// "root://server1:port1[,server2:port2,...]/pathfile?readaheadsz=100000"
107 /// e. set the cache remove policy
108 /// "root://server1:port1[,server2:port2,...]/pathfile?rmpolicy=1"
109 /// f. set the max number of redirections
110 /// "root://server1:port1[,server2:port2,...]/pathfile?mxredir=2"
111 /// (multiple options can be set concurrently)
112 
113 TXNetFile::TXNetFile(const char *url, Option_t *option, const char* ftitle,
114  Int_t compress, Int_t netopt, Bool_t parallelopen,
115  const char *logicalurl) :
116  TNetFile((logicalurl ? logicalurl : url), ftitle, compress, kFALSE)
117 {
118  TUrl urlnoanchor(url);
119  // Set debug level
120  EnvPutInt(NAME_DEBUG, gEnv->GetValue("XNet.Debug", 0));
121 
122  // Set environment, if needed
123  if (!fgInitDone || strstr(urlnoanchor.GetOptions(),"checkenv")) {
124  SetEnv();
125  fgInitDone = kTRUE;
126 
127  // Print the tag, if required (only once)
128  if (gEnv->GetValue("XNet.PrintTAG",0) == 1)
129  Info("TXNetFile","(eXtended TNetFile) %s",
130  gROOT->GetVersion());
131  }
132 
133  // Remove anchors from the URL!
134  urlnoanchor.SetAnchor("");
135 
136  // Init mutex used in the asynchronous open machinery
137  fInitMtx = (void *) new XrdSysRecMutex();
138 
139  if (gMonitoringWriter) {
140  // Init the monitoring system
141  if (!fOpenPhases) {
142  fOpenPhases = new TList;
144  }
145  // Should not be null instead of "xrdopen" to init the thing ?
147  }
148 
149  // Create an instance
150  CreateXClient(urlnoanchor.GetUrl(), option, netopt, parallelopen);
151 }
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 /// Destructor.
155 
157 {
158  if (IsOpen())
159  Close(0);
160 
163  if (mtx) delete mtx;
164  fInitMtx = 0;
165 }
166 
167 ////////////////////////////////////////////////////////////////////////////////
168 /// Form url for rootd socket.
169 
171 {
172  // Protocol
173  uus = "root://";
174 
175  // User, if any
176  if (strlen(uu.GetUser()) > 0) {
177  uus += uu.GetUser();
178  uus += "@";
179  }
180 
181  // Host, if any
182  if (strlen(uu.GetHost()) > 0) {
183  uus += uu.GetHost();
184  }
185 
186  // Port, if any
187  if (uu.GetPort() > 0) {
188  uus += ":";
189  uus += uu.GetPort();
190  }
191 
192  // End of string
193  uus += "/";
194 }
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 /// Parse input options for cache parameters
198 
200  Int_t &cachesz, Int_t &readaheadsz,
201  Int_t &rmpolicy, Int_t &mxredir, Int_t &rastrategy, Int_t &readtrimblksz)
202 {
203  static const char *keys[6] = { "cachesz=", "readaheadsz=", "rmpolicy=",
204  "mxredir=", "readaheadstrategy=", "readtrimblksz=" };
205  Int_t fo = 0;
206  TString s(opts);
207 
208  UInt_t i = 0;
209  for (i = 0; i < (sizeof(keys)/sizeof(keys[0])); i++) {
210  Int_t j = s.Index(keys[i]);
211  if (j != kNPOS) {
212  TString val(s(j+strlen(keys[i]), s.Length()));
213  // Cut of non digits
214  Int_t k = 0;
215  while (k < val.Length())
216  if (!TString(val(k++)).IsDigit())
217  break;
218  if (k < val.Length())
219  val.Remove(--k);
220  if (val.IsDigit()) {
221  fo++;
222  if (i == 0)
223  cachesz = val.Atoi();
224  else if (i == 1)
225  readaheadsz = val.Atoi();
226  else if (i == 2)
227  rmpolicy = val.Atoi();
228  else if (i == 3)
229  mxredir = val.Atoi();
230  else if (i == 4)
231  rastrategy = val.Atoi();
232  else if (i == 5)
233  readtrimblksz = val.Atoi();
234  }
235  }
236  }
237 
238  // Notify
239  if (gDebug > 0)
240  Info("ParseCacheOptions","found: cachesz = %d, readaheadsz = %d, "
241  "rmpolicy = %d, mxredir = %d, rastrategy = %d, readtrimblksz = %d",
242  cachesz, readaheadsz, rmpolicy, mxredir, rastrategy, readtrimblksz);
243 
244  // Done
245  return fo;
246 }
247 
248 ////////////////////////////////////////////////////////////////////////////////
249 /// The real creation work is done here.
250 
251 void TXNetFile::CreateXClient(const char *url, Option_t *option, Int_t netopt,
252  Bool_t parallelopen)
253 {
254  Int_t cachesz = -1, readaheadsz = -1, rmpolicy = -1, mxredir = -1, np = 0;
255  Int_t readaheadstrategy = -1, readtrimblksz = -1;
256 
257  fClient = 0;
258  fNetopt = netopt;
259 
260  // Set the timeout (default 999999999 secs, i.e. far, far in the future)
261  gSystem->Setenv("XRDCLIENTMAXWAIT", Form("%d",TFile::GetOpenTimeout()));
262 
263  if (GetOnlyStaged()) {
264  // Check if the file is staged before opening it
265  if (!fgFileStager || !(fgFileStager->Matches(url))) {
268  }
269  if (fgFileStager) {
270  if (!(fgFileStager->IsStaged(url))) {
271  ::Warning("TXNetFile","<%s> is not staged - StageOnly flag is set!",url);
272  goto zombie;
273  }
274  }
275  }
276 
277  // Init members
278  fIsRootd = kFALSE;
279 
280  // The parallel open can be forced to true in the config
281  if (gEnv->GetValue("XNet.ForceParallelOpen", 0))
282  parallelopen = kTRUE;
283  fAsyncOpenStatus = (parallelopen) ? kAOSInProgress : fAsyncOpenStatus ;
284 
285  Bool_t isRootd;
286  isRootd = kFALSE;
287  //
288  // Setup a client instance
289  fClient = new XrdClient(url);
290  if (!fClient) {
291  fAsyncOpenStatus = (parallelopen) ? kAOSFailure : fAsyncOpenStatus ;
292  Error("CreateXClient","fatal error: new object creation failed -"
293  " out of system resources.");
294  gSystem->Abort();
295  goto zombie;
296  }
297 
298  // Get client (cache, redir) parameters, if any
299  np = ParseOptions(TUrl(url).GetOptions(),
300  cachesz, readaheadsz, rmpolicy, mxredir,
301  readaheadstrategy, readtrimblksz);
302 
303  // Set max redir, if asked
304  if (mxredir > 0) {
305  if (fClient->GetClientConn()) {
306  if (gDebug > 0)
307  Info("CreateXClient", "setting maxredir = %d", mxredir);
308  fClient->GetClientConn()->SetMaxRedirCnt(mxredir);
309  }
310  np--;
311  }
312  // Set the cache parameters, if any
313  if (np > 0) {
314  if (gDebug > 0)
315  Info("CreateXClient", "setting cachesz = %d, readaheadsz = %d, "
316  "rmpolicy = %d",
317  cachesz, readaheadsz, rmpolicy);
318  fClient->SetCacheParameters(cachesz, readaheadsz, rmpolicy);
319 
320  if (readaheadstrategy >= 0) {
321  if (gDebug > 0)
322  Info("CreateXClient", "setting readaheadstrategy = %d", readaheadstrategy);
323  fClient->SetReadAheadStrategy(readaheadstrategy);
324  }
325 
326  if (readtrimblksz >= 0) {
327  if (gDebug > 0)
328  Info("CreateXClient", "setting readtrimblksz = %d", readtrimblksz);
329  fClient->SetBlockReadTrimming(readtrimblksz);
330  }
331 
332  }
333 
334  //
335  // Now try opening the file
336  if (!Open(option, parallelopen)) {
337  if (!fClient->IsOpen_wait()) {
338  if (gDebug > 1)
339  Info("CreateXClient", "remote file could not be open");
340 
341  // If the server is a rootd we need to create a TNetFile
342  isRootd = (fClient->GetClientConn()->GetServerType() == kSTRootd);
343 
344  if (isRootd) {
345  if (fgRootdBC) {
346 
347  Int_t sd = fClient->GetClientConn()->GetOpenSockFD();
348  if (sd > -1) {
349  //
350  // Create a TSocket on the open connection
351  TSocket *s = new TSocket(sd);
352 
353  s->SetOption(kNoBlock, 0);
354 
355  // Find out the remote protocol (send the client protocol first)
356  Int_t rproto = GetRootdProtocol(s);
357  if (rproto < 0) {
358  Error("CreateXClient", "getting rootd server protocol");
359  goto zombie;
360  }
361 
362  // Finalize TSocket initialization
363  s->SetRemoteProtocol(rproto);
364  TUrl uut((fClient->GetClientConn()
365  ->GetCurrentUrl()).GetUrl().c_str());
366  TString uu;
367  FormUrl(uut,uu);
368 
369  if (gDebug > 2)
370  Info("CreateXClient"," url: %s",uu.Data());
371  s->SetUrl(uu.Data());
372  s->SetService("rootd");
374  //
375  // Set rootd flag
376  fIsRootd = kTRUE;
377  //
378  // Now we can check if we can create a TNetFile on the
379  // open connection
380  if (rproto > 13) {
381  //
382  // Remote support for reuse of open connection
383  TNetFile::Create(s, option, netopt);
384  } else {
385  //
386  // Open connection has been closed because could
387  // not be reused; TNetFile will open a new connection
388  TNetFile::Create(uu.Data(), option, netopt);
389  }
390 
391  return;
392  } else {
393  Error("CreateXClient", "rootd: underlying socket undefined");
394  goto zombie;
395  }
396  } else {
397  if (gDebug > 0)
398  Info("CreateXClient", "rootd: fall back not enabled - closing");
399  goto zombie;
400  }
401  } else {
402  Error("CreateXClient", "open attempt failed on %s", fUrl.GetUrl());
403  goto zombie;
404  }
405  }
406  }
407 
408  return;
409 
410 zombie:
411  // error in file opening occured, make this object a zombie
413  MakeZombie();
414  gDirectory = gROOT;
415 }
416 
417 ////////////////////////////////////////////////////////////////////////////////
418 /// Find out the remote rootd protocol version.
419 /// Returns -1 in case of error.
420 
422 {
423  Int_t rproto = -1;
424 
425  UInt_t cproto = 0;
426  Int_t len = sizeof(cproto);
427  memcpy((char *)&cproto,
428  Form(" %d", TSocket::GetClientProtocol()),len);
429  Int_t ns = s->SendRaw(&cproto, len);
430  if (ns != len) {
431  ::Error("TXNetFile::GetRootdProtocol",
432  "sending %d bytes to rootd server [%s:%d]",
433  len, (s->GetInetAddress()).GetHostName(), s->GetPort());
434  return -1;
435  }
436 
437  // Get the remote protocol
438  Int_t ibuf[2] = {0};
439  len = sizeof(ibuf);
440  Int_t nr = s->RecvRaw(ibuf, len);
441  if (nr != len) {
442  ::Error("TXNetFile::GetRootdProtocol",
443  "reading %d bytes from rootd server [%s:%d]",
444  len, (s->GetInetAddress()).GetHostName(), s->GetPort());
445  return -1;
446  }
447  Int_t kind = net2host(ibuf[0]);
448  if (kind == kROOTD_PROTOCOL) {
449  rproto = net2host(ibuf[1]);
450  } else {
451  kind = net2host(ibuf[1]);
452  if (kind == kROOTD_PROTOCOL) {
453  len = sizeof(rproto);
454  nr = s->RecvRaw(&rproto, len);
455  if (nr != len) {
456  ::Error("TXNetFile::GetRootdProtocol",
457  "reading %d bytes from rootd server [%s:%d]",
458  len, (s->GetInetAddress()).GetHostName(), s->GetPort());
459  return -1;
460  }
461  rproto = net2host(rproto);
462  }
463  }
464  if (gDebug > 2)
465  ::Info("TXNetFile::GetRootdProtocol",
466  "remote rootd: buf1: %d, buf2: %d rproto: %d",
467  net2host(ibuf[0]),net2host(ibuf[1]),rproto);
468 
469  // We are done
470  return rproto;
471 }
472 
473 ////////////////////////////////////////////////////////////////////////////////
474 /// The real creation work is done here.
475 
476 Bool_t TXNetFile::Open(Option_t *option, Bool_t doitparallel)
477 {
478  //
479  // Parse options
480  kXR_unt16 openOpt = 0;
481  memset(&openOpt, 0, sizeof(openOpt));
482  TString opt = option;
483  opt.ToUpper();
484  //
485  // Check force, accepting 'f'/'F' for backward compatibility,
486  // and special read syntax
487  if (opt.BeginsWith("-") || opt.BeginsWith("F") || (opt == "+READ")) {
488  opt.Remove(0,1);
489  openOpt |= kXR_force;
490  }
491  //
492  // Read flag
493  Bool_t read = (opt == "READ");
494  //
495  // Create flag ("NEW" == "CREATE")
496  Bool_t create = (opt == "CREATE" || opt == "NEW");
497  //
498  // Recreate flag
499  Bool_t recreate = (opt == "RECREATE");
500  //
501  // Update flag
502  Bool_t update = (opt == "UPDATE");
503  //
504  // Default is Read
505  if (!create && !recreate && !update && !read) {
506  read = kTRUE;
507  opt = "READ";
508  }
509  //
510  // Save effective options
511  fOption = opt;
512  if (create || update || recreate)
513  fWritable = 1;
514  //
515  // Update requires the file existing: check that and switch to create,
516  // if the file is not found.
517  if (update) {
519  update = kFALSE;
520  create = kTRUE;
521  }
522  if (update) {
524  Error("Open", "no write permission, could not open file %s",
525  fUrl.GetUrl());
526  fAsyncOpenStatus = (doitparallel) ? kAOSFailure : fAsyncOpenStatus ;
527  return kFALSE;
528  }
529  openOpt |= kXR_open_updt;
530  }
531  }
532 
533  //
534  // Create and Recreate are correlated
535  if (create)
536  openOpt |= kXR_new;
537  if (recreate) {
538  openOpt |= kXR_delete;
539  create = kTRUE;
540  }
541 
542  Bool_t mkpath = (gEnv->GetValue("XNet.Mkpath", 0) == 1) ? kTRUE : kFALSE;
543  char *p = (char*)strstr(fUrl.GetOptions(), "mkpath=");
544  if (p)
545  mkpath = (*(p + strlen("mkpath=")) == '1') ? kTRUE : kFALSE;
546  if (mkpath)
547  openOpt |= kXR_mkpath;
548 
549  if (read)
550  openOpt |= kXR_open_read;
551 
552  //
553  // Set open mode to rw-r-r
554  kXR_unt16 openMode = kXR_or | kXR_gr | kXR_ur | kXR_uw;
555 
556  //
557  // Open file (FileOpenerThread disabled for the time being)
558  if (!fClient->Open(openMode, openOpt, doitparallel)) {
559  if (gDebug > 1)
560  Info("Open", "remote file could not be open");
561  fAsyncOpenStatus = (doitparallel) ? kAOSFailure : fAsyncOpenStatus ;
562  return kFALSE;
563  } else {
564  // Initialize the file
565  // If we are using the parallel open, the init phase is
566  // performed later. In checking for the IsOpen or
567  // asynchronously in a callback func
568  if (!doitparallel) {
569  // Mutex serialization is done inside
570  Init(create);
571  // If initialization failed close everything
572  if (TFile::IsZombie()) {
573  fClient->Close();
574  // To avoid problems in final deletion of object not completely
575  // initialized
576  fWritable = 0;
577  // Notify failure
578  return kFALSE;
579  }
580  }
581  }
582 
583  // We are done
584  return kTRUE;
585 }
586 
587 ////////////////////////////////////////////////////////////////////////////////
588 /// Override TNetFile::ReadBuffer to deal with the xrootd server.
589 /// Returns kTRUE in case of errors.
590 
591 Bool_t TXNetFile::ReadBuffer(char *buffer, Int_t bufferLength)
592 {
593  if (IsZombie()) {
594  Error("ReadBuffer", "ReadBuffer is not possible because object"
595  " is in 'zombie' state");
596  return kTRUE;
597  }
598 
599  if (fIsRootd) {
600  if (gDebug > 1)
601  Info("ReadBuffer","Calling TNetFile::ReadBuffer");
602  return TNetFile::ReadBuffer(buffer, bufferLength);
603  }
604 
605  if (!IsOpen()) {
606  Error("ReadBuffer","The remote file is not open");
607  return kTRUE;
608  }
609 
610  Bool_t result = kFALSE;
611 
612  if (bufferLength==0)
613  return 0;
614 
615  // This returns:
616  // 2 if errors
617  // 1 it looks like the block has already been prefetched
618  // 0 it looks like the block has not been prefetched
619  // But we don't want it to return the buffer, to avoid recursion
620  Int_t st = 0;
621 
622  //using the new method to read
623  if (GetCacheRead() && GetCacheRead()->IsEnablePrefetching()) {
624  st = ReadBufferViaCache(buffer, bufferLength); //modify to "buffer" so that it work with the ne version!!!
625  if (st == 1){
626  fOffset -= bufferLength;
627  return kFALSE;
628  }
629  }
630  else{ //using the old method to read
631  if (GetCacheRead() && GetCacheRead()->IsAsyncReading()) {
632  st = ReadBufferViaCache(0, bufferLength);
633  if (st == 1)
634  fOffset -= bufferLength;
635  } else {
636  if (GetCacheRead()) {
637  st = ReadBufferViaCache(buffer, bufferLength);
638  if (st == 1)
639  return kFALSE;
640  }
641  }
642  }
643 
644  Double_t start = 0;
645  if (gPerfStats) start = TTimeStamp();
646 
647  // Read from the remote xrootd
648  Int_t nr = fClient->Read(buffer, fOffset, bufferLength);
649 
650  if (!nr)
651  return kTRUE;
652 
653  if (gDebug > 1)
654  Info("ReadBuffer", "%d bytes of data read from offset"
655  " %lld (%d requested)", nr, fOffset, bufferLength);
656 
657  fOffset += bufferLength;
658 
659  fBytesRead += nr;
660  fReadCalls++;
661 #ifdef WIN32
664 #else
665  fgBytesRead += nr;
666  fgReadCalls++;
667 #endif
668 
669  if (gPerfStats)
670  gPerfStats->FileReadEvent(this, bufferLength, start);
671 
672  if (gMonitoringWriter)
674 
675  return result;
676 }
677 
678 ////////////////////////////////////////////////////////////////////////////////
679 /// Pass through to TNetFile implementation which will call back eventually
680 /// to our ReadBuffer with 2 arguments to deal with xrootd errors.
681 
682 Bool_t TXNetFile::ReadBuffer(char *buffer, Long64_t pos, Int_t bufferLength)
683 {
684  return TNetFile::ReadBuffer(buffer, pos, bufferLength);
685 }
686 
687 ////////////////////////////////////////////////////////////////////////////////
688 /// Implementation dealing with the xrootd server.
689 /// Returns kTRUE in case of errors.
690 /// This is the same as TXNetFile::ReadBuffer but using the async
691 /// call from xrootd
692 
694 {
695  if (IsZombie()) {
696  Error("ReadBuffer", "ReadBuffer is not possible because object"
697  " is in 'zombie' state");
698  return kTRUE;
699  }
700 
701  if (fIsRootd) {
702  if (gDebug > 1)
703  Error("ReadBufferAsync","Not supported for rootd");
704  return kTRUE;
705  }
706 
707  if (!IsOpen()) {
708  Error("ReadBuffer","The remote file is not open");
709  return kTRUE;
710  }
711 
712  Double_t start = 0;
713  if (gPerfStats) start = TTimeStamp();
714 
715  Bool_t result = kFALSE;
716 
717  if (bufferLength==0)
718  return 0;
719 
721 
722  // Read for the remote xrootd
723  // This doesnt return the number of bytes read...
724  // and even if it did we dont want to update fBytesRead
725  // because that would be updated in the real read
726  XReqErrorType nr = fClient->Read_Async(offs+fArchiveOffset, bufferLength);
727 
728  if (nr != kOK)
729  return kTRUE;
730 
731  fBytesRead += bufferLength;
732  fReadCalls++;
733 #ifdef WIN32
734  SetFileBytesRead(GetFileBytesRead() + bufferLength);
736 #else
737  fgBytesRead += bufferLength;
738  fgReadCalls++;
739 #endif
740 
741  if (gPerfStats)
742  gPerfStats->FileReadEvent(this, bufferLength, start);
743 
744  if (gDebug > 1)
745  Info("ReadBufferAsync", "%d bytes of data read request from offset"
746  " %lld", bufferLength, offs);
747  return result;
748 }
749 
750 ////////////////////////////////////////////////////////////////////////////////
751 /// Read the nbuf blocks described in arrays pos and len,
752 /// where pos[i] is the seek position of block i of length len[i].
753 /// Note that for nbuf=1, this call is equivalent to TFile::ReadBuffer
754 /// This function is overloaded by TNetFile, TWebFile, etc.
755 /// Returns kTRUE in case of failure.
756 /// Note: This is the overloading made in TXNetFile. If ReadBuffers
757 /// is supported by xrootd it will try to get the whole list from one single
758 /// call avoiding the latency of multiple calls
759 
760 Bool_t TXNetFile::ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
761 {
762  if (IsZombie()) {
763  Error("ReadBuffers", "ReadBuffers is not possible because object"
764  " is in 'zombie' state");
765  return kTRUE;
766  }
767 
768  if (fIsRootd) {
769  if (gDebug > 1)
770  Info("ReadBuffers","Calling TNetFile::ReadBuffers");
771  return TNetFile::ReadBuffers(buf, pos, len, nbuf);
772  }
773 
774  if (!IsOpen()) {
775  Error("ReadBuffers","The remote file is not open");
776  return kTRUE;
777  }
778 
779  Double_t start = 0;
780  if (gPerfStats) start = TTimeStamp();
781 
782  if (fArchiveOffset) {
783  for (Int_t i = 0; i < nbuf; i++)
784  pos[i] += fArchiveOffset;
785  }
786 
787  // A null buffer means that we want to use the async stuff
788  // hence we have to sync the cache size in XrdClient with the supposed
789  // size in TFile.
790  if (!buf) {
791  // Null buffer + 0 blocks means 'reset cache'
792  if (!nbuf) ResetCache();
794  }
795 
796  // Read for the remote xrootd
797  Long64_t nr = fClient->ReadV(buf, pos, len, nbuf);
798 
799  if (gDebug > 1)
800  Info("ReadBuffers", "response from ReadV(%d) nr: %lld", nbuf, nr);
801 
802  if (nr > 0) {
803 
804  if (gDebug > 1)
805  Info("ReadBuffers", "%lld bytes of data read from a list of %d buffers",
806  nr, nbuf);
807 
808  if (GetCacheRead() && GetCacheRead()->GetBufferSize() < nr)
809  Info("ReadBuffers", "%lld bytes of data read with a smaller (%d) TFileCacheRead buffer size?",
810  nr, GetCacheRead()->GetBufferSize());
811 
812  // Where should we leave the offset ?
813  // fOffset += bufferLength;
814  fBytesRead += nr;
815  fReadCalls++;
816 #ifdef WIN32
819 #else
820  fgBytesRead += nr;
821  fgReadCalls++;
822 #endif
823 
824  if (gPerfStats) {
825  fOffset = pos[0];
826  gPerfStats->FileReadEvent(this, (Int_t)nr, start);
827  }
828 
829  if (gMonitoringWriter)
831 
832  return kFALSE;
833  }
834 
835  if (gDebug > 1)
836  Info("ReadBuffers", "XrdClient->ReadV failed, executing TFile::ReadBuffers");
837 
838  // If it wasnt able to use the specialized call
839  // then use the generic one that is a plain loop
840  // of individual requests
841  if (buf && nbuf)
842  return TFile::ReadBuffers(buf, pos, len, nbuf);
843  // If the async call was needed (buf == 0) and it got an error,
844  // just return error
845  else return kTRUE;
846 }
847 
848 ////////////////////////////////////////////////////////////////////////////////
849 /// Override TNetFile::WriteBuffer to deal with the xrootd server.
850 /// Returns kTRUE in case of errors.
851 
852 Bool_t TXNetFile::WriteBuffer(const char *buffer, Int_t bufferLength)
853 {
854  if (IsZombie()) {
855  Error("WriteBuffer", "WriteBuffer is not possible because object"
856  " is in 'zombie' state");
857  return kTRUE;
858  }
859 
860  if (!fWritable) {
861  if (gDebug > 1)
862  Info("WriteBuffer","file not writable");
863  return kTRUE;
864  }
865 
866  if (fIsRootd) {
867  if (gDebug > 1)
868  Info("WriteBuffer","Calling TNetFile::WriteBuffer");
869  return TNetFile::WriteBuffer(buffer, bufferLength );
870  }
871 
872  if (!IsOpen()) {
873  Error("WriteBuffer","The remote file is not open");
874  return kTRUE;
875  }
876 
877  Int_t st;
878  if ((st = WriteBufferViaCache(buffer, bufferLength))) {
879  if (st == 2)
880  return kTRUE;
881  return kFALSE;
882  }
883 
884  // Read for the remote xrootd
885  if (!fClient->Write(buffer, fOffset, bufferLength)) {
886  if (gDebug > 0)
887  Info("WriteBuffer",
888  "error writing %d bytes of data wrote to offset %lld",
889  bufferLength , fOffset);
890  return kTRUE;
891  }
892 
893  if (gDebug > 1)
894  Info("WriteBuffer", " %d bytes of data wrote to offset"
895  " %lld", bufferLength , fOffset);
896 
897  fOffset += bufferLength;
898  fBytesWrite += bufferLength;
899 #ifdef WIN32
900  SetFileBytesWritten(GetFileBytesWritten() + bufferLength);
901 #else
902  fgBytesWrite += bufferLength;
903 #endif
904 
905  return kFALSE;
906 }
907 
908 ////////////////////////////////////////////////////////////////////////////////
909 /// Initialize the file. Makes sure that the file is really open before
910 /// calling TFile::Init. It may block.
911 
913 {
914  if (fInitDone) {
915  // TFile::Init already called once
916  if (gDebug > 1)
917  Info("Init","TFile::Init already called once");
918  return;
919  }
920 
921  if (fIsRootd) {
922  if (gDebug > 1)
923  Info("Init","rootd: calling directly TFile::Init");
924  return TNetFile::Init(create);
925  }
926 
927  if (fClient) {
928  // A mutex serializes this very delicate section
930 
931  // To safely perform the Init() we must make sure that
932  // the file is successfully open; this call may block
933  if (fClient->IsOpen_wait()) {
934 
935  // Notify the monitoring system
936  if (gMonitoringWriter)
938 
939  // Avoid big transfers at this level
940  bool usecachesave = fClient->UseCache(0);
941  // Note that Init will trigger recursive calls
942  TFile::Init(create);
943  // so TFile::IsOpen() returns true when in TFile::~TFile
944  fD = -2;
945  // Restore requested behaviour
946  fClient->UseCache(usecachesave);
947 
948  // Notify the monitoring system
949  if (gMonitoringWriter)
951 
952  // Set the Endpoint Url we are now connected to. Unless there was some opaque info
953  // which cannot be re-used
954  if (fClient->GetClientConn() && fClient->GetClientConn()->fRedirOpaque.length() <= 0) {
955  fEndpointUrl = fClient->GetClientConn()->GetCurrentUrl().GetUrl().c_str();
956  // Check equivalence of initial and end-point Url to see whether we have
957  // been redirected
958  if (fEndpointUrl.GetPort() != fUrl.GetPort() ||
961  }
962  } else {
963  if (gDebug > 0)
964  Info("Init","open request failed!");
966  MakeZombie();
967  gDirectory = gROOT;
968  }
969  }
970 }
971 
972 ////////////////////////////////////////////////////////////////////////////////
973 /// Return kTRUE if the file is open, kFALSE otherwise.
974 
976 {
977  if (fIsRootd) {
978  if (gDebug > 1)
979  Info("IsOpen","Calling TNetFile::IsOpen");
980  return TNetFile::IsOpen();
981  }
982 
983  if (!fClient)
984  return kFALSE;
985 
986  // We are done
987  return ((fClient && fInitDone) ? fClient->IsOpen() : kFALSE);
988 }
989 
990 ////////////////////////////////////////////////////////////////////////////////
991 /// Return status of asynchronous request
992 
994 {
996  if (fClient->IsOpen_inprogress()) {
997  return TFile::kAOSInProgress;
998  } else {
999  if (fClient->IsOpen())
1000  return TFile::kAOSSuccess;
1001  else
1002  return TFile::kAOSFailure;
1003  }
1004  }
1005 
1006  // Not asynchronous
1007  return TFile::kAOSNotAsync;
1008 }
1009 
1010 ////////////////////////////////////////////////////////////////////////////////
1011 /// Re-open the file (see TNetFile::ReOpen() or TFile::ReOpen()
1012 /// for more details).
1013 
1015 {
1016  if (fIsRootd) {
1017  if (gDebug > 1)
1018  Info("ReOpen","Calling TNetFile::ReOpen");
1019  return TNetFile::ReOpen(Mode);
1020  }
1021 
1022  return TFile::ReOpen(Mode);
1023 }
1024 
1025 ////////////////////////////////////////////////////////////////////////////////
1026 /// Close the file (see TNetFile::Close() or TFile::Close()
1027 /// for more details).
1028 
1029 void TXNetFile::Close(const Option_t *opt)
1030 {
1031  if (fIsRootd) {
1032  if (gDebug > 1)
1033  Info("Close","Calling TNetFile::Close");
1034  TNetFile::Close(opt);
1035  return;
1036  }
1037 
1038  if (!fClient) return;
1039 
1040  TFile::Close(opt);
1041 
1042  fIsRootd = kFALSE;
1043 
1044  if (IsOpen())
1045  fClient->Close();
1046 
1047  fD = -1; // so TFile::IsOpen() returns false when in TFile::~TFile
1048 }
1049 
1050 ////////////////////////////////////////////////////////////////////////////////
1051 /// Flushes un-written data.
1052 
1054 {
1055  if (IsZombie()) {
1056  Error("Flush", "Flush is not possible because object is"
1057  " in 'zombie' state");
1058  return;
1059  }
1060 
1061  if (!fWritable) {
1062  if (gDebug > 1)
1063  Info("Flush", "file not writable - do nothing");
1064  return;
1065  }
1066 
1067  if (fIsRootd) {
1068  if (gDebug > 1)
1069  Info("Flush","Calling TNetFile::Flush");
1070  TNetFile::Flush();
1071  return;
1072  }
1073 
1074  if (!IsOpen()) {
1075  Error("Flush","The remote file is not open");
1076  return;
1077  }
1078 
1079  FlushWriteCache();
1080 
1081  //
1082  // Flush via the remote xrootd
1083  fClient->Sync();
1084  if (gDebug > 1)
1085  Info("Flush", "XrdClient::Sync called.");
1086 }
1087 
1088 ////////////////////////////////////////////////////////////////////////////////
1089 /// Override TNetFile::SysStat (see parent's method for more details).
1090 
1092  Long_t *modtime)
1093 {
1094  if (IsZombie()) {
1095  Error("SysStat", "SysStat is not possible because object is"
1096  " in 'zombie' state");
1097  *size = 0;
1098  return 1;
1099  }
1100 
1101  if (fIsRootd) {
1102  if (gDebug > 1)
1103  Info("SysStat", "calling TNetFile::SysStat");
1104  return TNetFile::SysStat(fd, id, size, flags, modtime);
1105  }
1106 
1107  // Return file stat information. The interface and return value is
1108  // identical to TSystem::GetPathInfo().
1109  struct XrdClientStatInfo stinfo;
1110  if (fClient && fClient->Stat(&stinfo)) {
1111  *id = (Long_t)(stinfo.id);
1112  *size = (Long64_t)(stinfo.size);
1113  *flags = (Long_t)(stinfo.flags);
1114  *modtime = (Long_t)(stinfo.modtime);
1115  if (gDebug > 1)
1116  Info("SysStat", "got stats = %ld %lld %ld %ld",
1117  *id, *size, *flags, *modtime);
1118  } else {
1119 
1120  if (gDebug > 1) {
1121  if (!IsOpen()) Info("SysStat", "could not stat remote file. Not opened.");
1122  else
1123  Info("SysStat", "could not stat remote file");
1124  }
1125 
1126 
1127  *id = -1;
1128  return 1;
1129  }
1130 
1131  // We are done
1132  return 0;
1133 }
1134 
1135 ////////////////////////////////////////////////////////////////////////////////
1136 /// Override TNetFile::SysClose (see parent's method for more details).
1137 
1139 {
1140  if (IsZombie()) {
1141  Error("SysClose", "SysClose is not possible because object is"
1142  " in 'zombie' state");
1143  return 0;
1144  }
1145 
1146  if (fIsRootd) {
1147  if (gDebug > 1)
1148  Info("SysClose","Calling TNetFile::SysClose");
1149  return TNetFile::SysClose(fd);
1150  }
1151 
1152  // Send close to remote xrootd
1153  if (IsOpen())
1154  fClient->Close();
1155 
1156  return 0;
1157 }
1158 
1159 ////////////////////////////////////////////////////////////////////////////////
1160 /// Override TNetFile::SysOpen (see parent's method for more details).
1161 
1162 Int_t TXNetFile::SysOpen(const char* pathname, Int_t flags, UInt_t mode)
1163 {
1164  if (fIsRootd) {
1165  if (gDebug > 1)
1166  Info("SysOpen", "Calling TNetFile::SysOpen");
1167  return TNetFile::SysOpen(pathname, flags, mode);
1168  }
1169 
1170  if (!fClient) {
1171 
1172  // Create an instance of XrdClient
1174 
1175  } else {
1176 
1177  // url is not needed because already stored
1178  // fOption is set in TFile::ReOpen
1179  Open(fOption.Data(), kFALSE);
1180  }
1181 
1182  // If not successful, flag it
1183  if (!IsOpen())
1184  return -1;
1185 
1186  // This means ok for net files
1187  return -2; // set as fD in ReOpen
1188 }
1189 
1190 ////////////////////////////////////////////////////////////////////////////////
1191 /// Set the relevant environment variables
1192 
1194 {
1195  // List of domains where redirection is allowed
1196  TString allowRE = gEnv->GetValue("XNet.RedirDomainAllowRE", "");
1197  if (allowRE.Length() > 0)
1198  EnvPutString(NAME_REDIRDOMAINALLOW_RE, allowRE.Data());
1199 
1200  // List of domains where redirection is denied
1201  TString denyRE = gEnv->GetValue("XNet.RedirDomainDenyRE", "");
1202  if (denyRE.Length() > 0)
1203  EnvPutString(NAME_REDIRDOMAINDENY_RE, denyRE.Data());
1204 
1205  // List of domains where connection is allowed
1206  TString allowCO = gEnv->GetValue("XNet.ConnectDomainAllowRE", "");
1207  if (allowCO.Length() > 0)
1208  EnvPutString(NAME_CONNECTDOMAINALLOW_RE, allowCO.Data());
1209 
1210  // List of domains where connection is denied
1211  TString denyCO = gEnv->GetValue("XNet.ConnectDomainDenyRE", "");
1212  if (denyCO.Length() > 0)
1213  EnvPutString(NAME_CONNECTDOMAINDENY_RE, denyCO.Data());
1214 
1215  // Connect Timeout
1216  Int_t connTO = gEnv->GetValue("XNet.ConnectTimeout",
1217  DFLT_CONNECTTIMEOUT);
1218  EnvPutInt(NAME_CONNECTTIMEOUT, connTO);
1219 
1220  // Reconnect Timeout
1221  Int_t recoTO = gEnv->GetValue("XNet.ReconnectWait",
1222  DFLT_RECONNECTWAIT);
1223  if (recoTO == DFLT_RECONNECTWAIT) {
1224  // Check also the old variable name
1225  recoTO = gEnv->GetValue("XNet.ReconnectTimeout",
1226  DFLT_RECONNECTWAIT);
1227  }
1228  EnvPutInt(NAME_RECONNECTWAIT, recoTO);
1229 
1230  // Request Timeout
1231  Int_t requTO = gEnv->GetValue("XNet.RequestTimeout",
1232  DFLT_REQUESTTIMEOUT);
1233  EnvPutInt(NAME_REQUESTTIMEOUT, requTO);
1234 
1235  // Max number of redirections
1236  Int_t maxRedir = gEnv->GetValue("XNet.MaxRedirectCount",
1237  DFLT_MAXREDIRECTCOUNT);
1238  EnvPutInt(NAME_MAXREDIRECTCOUNT, maxRedir);
1239 
1240 
1241  // Read ahead size
1242  Int_t rAheadsiz = gEnv->GetValue("XNet.ReadAheadSize",
1243  DFLT_READAHEADSIZE);
1244  EnvPutInt(NAME_READAHEADSIZE, rAheadsiz);
1245 
1246 
1247  // Cache size (<= 0 disables cache)
1248  Int_t rCachesiz = gEnv->GetValue("XNet.ReadCacheSize",
1249  DFLT_READCACHESIZE);
1250 
1251  EnvPutInt(NAME_READCACHESIZE, rCachesiz);
1252 
1253  // Max number of retries on first connect
1254  Int_t maxRetries = gEnv->GetValue("XNet.FirstConnectMaxCnt",
1255  DFLT_FIRSTCONNECTMAXCNT);
1256  EnvPutInt(NAME_FIRSTCONNECTMAXCNT, maxRetries);
1257 
1258  // Parallel stream count
1259  Int_t parStreamsCnt = gEnv->GetValue("XNet.ParStreamsPerPhyConn",
1260  DFLT_MULTISTREAMCNT);
1261  EnvPutInt(NAME_MULTISTREAMCNT, parStreamsCnt);
1262 
1263  // Change the TCP window size (0 means 'scaling' on some platforms)
1264  Int_t tcpWindowSize = gEnv->GetValue("XNet.DfltTcpWindowSize",
1265  DFLT_DFLTTCPWINDOWSIZE);
1266  EnvPutInt(NAME_DFLTTCPWINDOWSIZE, tcpWindowSize);
1267 
1268  // Change the transaction timeout
1269  Int_t transactionTimeout = gEnv->GetValue("XNet.TransactionTimeout",
1270  DFLT_TRANSACTIONTIMEOUT);
1271  EnvPutInt(NAME_TRANSACTIONTIMEOUT, transactionTimeout);
1272 
1273  // Whether to activate automatic rootd backward-compatibility
1274  // (We override XrdClient default)
1275  fgRootdBC = gEnv->GetValue("XNet.RootdFallback", 1);
1276  EnvPutInt(NAME_KEEPSOCKOPENIFNOTXRD, fgRootdBC);
1277 
1278  // Dynamic forwarding (SOCKS4)
1279  TString socks4Host = gEnv->GetValue("XNet.SOCKS4Host","");
1280  Int_t socks4Port = gEnv->GetValue("XNet.SOCKS4Port",-1);
1281  if (socks4Port > 0) {
1282  if (socks4Host.IsNull())
1283  // Default
1284  socks4Host = "127.0.0.1";
1285  EnvPutString(NAME_SOCKS4HOST, socks4Host.Data());
1286  EnvPutInt(NAME_SOCKS4PORT, socks4Port);
1287  }
1288 
1289  const char *cenv = 0;
1290 
1291  // For password-based authentication
1292  TString autolog = gEnv->GetValue("XSec.Pwd.AutoLogin","1");
1293  if (autolog.Length() > 0 &&
1294  (!(cenv = gSystem->Getenv("XrdSecPWDAUTOLOG")) || strlen(cenv) <= 0))
1295  gSystem->Setenv("XrdSecPWDAUTOLOG",autolog.Data());
1296 
1297  // Old style netrc file
1298  TString netrc;
1299  netrc.Form("%s/.rootnetrc",gSystem->HomeDirectory());
1300  gSystem->Setenv("XrdSecNETRC", netrc.Data());
1301 
1302  TString alogfile = gEnv->GetValue("XSec.Pwd.ALogFile","");
1303  if (alogfile.Length() > 0)
1304  gSystem->Setenv("XrdSecPWDALOGFILE",alogfile.Data());
1305 
1306  TString verisrv = gEnv->GetValue("XSec.Pwd.VerifySrv","1");
1307  if (verisrv.Length() > 0 &&
1308  (!(cenv = gSystem->Getenv("XrdSecPWDVERIFYSRV")) || strlen(cenv) <= 0))
1309  gSystem->Setenv("XrdSecPWDVERIFYSRV",verisrv.Data());
1310 
1311  TString srvpuk = gEnv->GetValue("XSec.Pwd.ServerPuk","");
1312  if (srvpuk.Length() > 0)
1313  gSystem->Setenv("XrdSecPWDSRVPUK",srvpuk.Data());
1314 
1315  // For GSI authentication
1316  TString cadir = gEnv->GetValue("XSec.GSI.CAdir","");
1317  if (cadir.Length() > 0)
1318  gSystem->Setenv("XrdSecGSICADIR",cadir.Data());
1319 
1320  TString crldir = gEnv->GetValue("XSec.GSI.CRLdir","");
1321  if (crldir.Length() > 0)
1322  gSystem->Setenv("XrdSecGSICRLDIR",crldir.Data());
1323 
1324  TString crlext = gEnv->GetValue("XSec.GSI.CRLextension","");
1325  if (crlext.Length() > 0)
1326  gSystem->Setenv("XrdSecGSICRLEXT",crlext.Data());
1327 
1328  TString ucert = gEnv->GetValue("XSec.GSI.UserCert","");
1329  if (ucert.Length() > 0)
1330  gSystem->Setenv("XrdSecGSIUSERCERT",ucert.Data());
1331 
1332  TString ukey = gEnv->GetValue("XSec.GSI.UserKey","");
1333  if (ukey.Length() > 0)
1334  gSystem->Setenv("XrdSecGSIUSERKEY",ukey.Data());
1335 
1336  TString upxy = gEnv->GetValue("XSec.GSI.UserProxy","");
1337  if (upxy.Length() > 0)
1338  gSystem->Setenv("XrdSecGSIUSERPROXY",upxy.Data());
1339 
1340  TString valid = gEnv->GetValue("XSec.GSI.ProxyValid","");
1341  if (valid.Length() > 0)
1342  gSystem->Setenv("XrdSecGSIPROXYVALID",valid.Data());
1343 
1344  TString deplen = gEnv->GetValue("XSec.GSI.ProxyForward","0");
1345  if (deplen.Length() > 0 &&
1346  (!(cenv = gSystem->Getenv("XrdSecGSIPROXYDEPLEN")) || strlen(cenv) <= 0))
1347  gSystem->Setenv("XrdSecGSIPROXYDEPLEN",deplen.Data());
1348 
1349  TString pxybits = gEnv->GetValue("XSec.GSI.ProxyKeyBits","");
1350  if (pxybits.Length() > 0)
1351  gSystem->Setenv("XrdSecGSIPROXYKEYBITS",pxybits.Data());
1352 
1353  TString crlcheck = gEnv->GetValue("XSec.GSI.CheckCRL","1");
1354  if (crlcheck.Length() > 0 &&
1355  (!(cenv = gSystem->Getenv("XrdSecGSICRLCHECK")) || strlen(cenv) <= 0))
1356  gSystem->Setenv("XrdSecGSICRLCHECK",crlcheck.Data());
1357 
1358  TString delegpxy = gEnv->GetValue("XSec.GSI.DelegProxy","0");
1359  if (delegpxy.Length() > 0 &&
1360  (!(cenv = gSystem->Getenv("XrdSecGSIDELEGPROXY")) || strlen(cenv) <= 0))
1361  gSystem->Setenv("XrdSecGSIDELEGPROXY",delegpxy.Data());
1362 
1363  TString signpxy = gEnv->GetValue("XSec.GSI.SignProxy","1");
1364  if (signpxy.Length() > 0 &&
1365  (!(cenv = gSystem->Getenv("XrdSecGSISIGNPROXY")) || strlen(cenv) <= 0))
1366  gSystem->Setenv("XrdSecGSISIGNPROXY",signpxy.Data());
1367 
1368  // Using ROOT mechanism to IGNORE SIGPIPE signal
1370 }
1371 
1372 ////////////////////////////////////////////////////////////////////////////////
1373 /// Synchronize the cache size
1374 /// Alternative purging policy
1375 
1377 {
1378  if (fClient == 0) return;
1379 
1380  fClient->UseCache(TRUE);
1381  Int_t size;
1382  Long64_t bytessubmitted, byteshit, misscount, readreqcnt;
1383  Float_t missrate, bytesusefulness;
1384  int newbsz = -1;
1385  if (fClient->GetCacheInfo(size, bytessubmitted,
1386  byteshit, misscount,
1387  missrate, readreqcnt,
1388  bytesusefulness) ) {
1389 
1390  // To allow for some space for outstanding data
1391  TFileCacheRead *cacheRead = GetCacheRead();
1392  if (cacheRead) {
1393  newbsz = GetBufferSize() / 2 * 3;
1394  newbsz = std::max(newbsz, size);
1395  } else {
1396  newbsz = size;
1397  }
1398 
1399  }
1400 
1401  if (newbsz > 0)
1402  fClient->SetCacheParameters(newbsz, 0, XrdClientReadCache::kRmBlk_FIFO);
1403 }
1404 
1405 ////////////////////////////////////////////////////////////////////////////////
1406 /// Reset the cache
1407 
1409 {
1410  if (fClient)
1411  fClient->RemoveAllDataFromCache();
1412 }
1413 
1414 ////////////////////////////////////////////////////////////////////////////////
1415 /// Max number of bytes to prefetch.
1416 
1418 {
1419  Int_t size;
1420  Long64_t bytessubmitted, byteshit, misscount, readreqcnt;
1421  Float_t missrate, bytesusefulness;
1422  Int_t bytes = 0;
1423  if (fClient && fClient->GetCacheInfo(size, bytessubmitted,
1424  byteshit, misscount,
1425  missrate, readreqcnt,
1426  bytesusefulness) )
1427  bytes = size;
1428  return ((bytes < 0) ? 0 : bytes);
1429 }
1430 
1431 ////////////////////////////////////////////////////////////////////////////////
1432 /// Print the local statistics.
1433 
1434 void TXNetFile::Print(Option_t *option) const
1435 {
1436  Printf("TXNetFile caching information:");
1437 
1438  Int_t size;
1439  Long64_t bytessubmitted, byteshit, misscount, readreqcnt;
1440  Float_t missrate, bytesusefulness;
1441 
1442  if (fClient && fClient->GetCacheInfo(size, bytessubmitted,
1443  byteshit, misscount,
1444  missrate, readreqcnt,
1445  bytesusefulness)) {
1446  Printf(" Max size: %d", size);
1447  Printf(" Bytes submitted: %lld", bytessubmitted);
1448  Printf(" Bytes hit (estimation): %lld", byteshit);
1449  Printf(" Miss count: %lld", misscount);
1450  Printf(" Miss rate: %f", missrate);
1451  Printf(" Read requests count: %lld", readreqcnt);
1452  Printf(" Bytes usefulness: %f\n", bytesusefulness);
1453  } else
1454  Printf(" -- No Xrd client instance allocated --\n");
1455 
1456  TFile::Print(option);
1457 }
const char * GetHost() const
Definition: TUrl.h:76
virtual Bool_t IsStaged(const char *)
Just check if the file exists locally.
virtual ~TXNetFile()
Destructor.
Definition: TXNetFile.cxx:156
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1265
Int_t ParseOptions(const char *opts, Int_t &cachesz, Int_t &readaheadsz, Int_t &rmpolicy, Int_t &mxredir, Int_t &rastrategy, Int_t &readtrimblksz)
Parse input options for cache parameters.
Definition: TXNetFile.cxx:199
double read(const std::string &file_name)
reading
void Init(Bool_t create)
Initialize the file.
Definition: TXNetFile.cxx:912
void SetRemoteProtocol(Int_t rproto)
Definition: TSocket.h:181
Int_t SysClose(Int_t fd)
Close currently open file.
Definition: TNetFile.cxx:155
long long Long64_t
Definition: RtypesCore.h:69
Long64_t fBytesWrite
Number of bytes written to this file.
Definition: TFile.h:62
EAsyncOpenStatus
Asynchronous open request status.
Definition: TFile.h:51
static std::atomic< Long64_t > fgBytesRead
Number of bytes read by all TFile objects.
Definition: TFile.h:111
Ssiz_t Length() const
Definition: TString.h:390
virtual Int_t ReOpen(Option_t *mode)
Reopen a file with a different access mode.
Definition: TFile.cxx:1971
float Float_t
Definition: RtypesCore.h:53
Int_t SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime)
Override TNetFile::SysStat (see parent's method for more details).
Definition: TXNetFile.cxx:1091
XrdClient * fClient
Definition: TXNetFile.h:67
A cache when reading files over the network.
const char Option_t
Definition: RtypesCore.h:62
virtual Int_t SetOption(ESockOptions opt, Int_t val)
Set socket options.
Definition: TSocket.cxx:1017
This class represents a WWW compatible URL.
Definition: TUrl.h:41
virtual Bool_t SendFileOpenProgress(TFile *, TList *, const char *, Bool_t=kFALSE)
#define gDirectory
Definition: TDirectory.h:218
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual TFile::EAsyncOpenStatus GetAsyncOpenStatus()
Return status of asynchronous request.
Definition: TXNetFile.cxx:993
#define XrdSysRecMutex
Definition: XrdSysToOuc.h:18
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
static void SetFileReadCalls(Int_t readcalls=0)
Definition: TFile.cxx:4359
virtual const char * HomeDirectory(const char *userName=0)
Return the user's home directory.
Definition: TSystem.cxx:881
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1101
#define gROOT
Definition: TROOT.h:340
Int_t GetPort() const
Definition: TSocket.h:145
void Flush()
Flush file to disk.
Definition: TNetFile.cxx:236
Bool_t IsZombie() const
Definition: TObject.h:141
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
Int_t WriteBufferViaCache(const char *buf, Int_t len)
Write buffer via cache.
Definition: TFile.cxx:2331
static Int_t GetRootdProtocol(TSocket *s)
Find out the remote rootd protocol version.
Definition: TXNetFile.cxx:421
Int_t fReadCalls
Number of read calls ( not counting the cache calls )
Definition: TFile.h:76
virtual Int_t GetBufferSize() const
Return the buffer size to create new TKeys.
static Bool_t fgRootdBC
Definition: TXNetFile.h:72
const char * GetOptions() const
Definition: TUrl.h:80
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
virtual Int_t ReOpen(const Option_t *mode)
Re-open the file (see TNetFile::ReOpen() or TFile::ReOpen() for more details).
Definition: TXNetFile.cxx:1014
void SetServType(Int_t st)
Definition: TSocket.h:184
static void SetFileBytesWritten(Long64_t bytes=0)
Definition: TFile.cxx:4356
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Override TNetFile::ReadBuffer to deal with the xrootd server.
Definition: TXNetFile.cxx:591
const char * Data() const
Definition: TString.h:349
TFileCacheRead * GetCacheRead(TObject *tree=0) const
Return a pointer to the current read cache.
Definition: TFile.cxx:1196
virtual void Print(Option_t *option="") const
Print the local statistics.
Definition: TXNetFile.cxx:1434
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:620
#define SafeDelete(p)
Definition: RConfig.h:436
UShort_t net2host(UShort_t x)
Definition: Bytes.h:579
TUrl fUrl
!URL of file
Definition: TFile.h:97
Int_t fD
File descriptor.
Definition: TFile.h:69
static Bool_t fgInitDone
Definition: TXNetFile.h:71
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Definition: TFile.cxx:4319
R__EXTERN TVirtualMonitoringWriter * gMonitoringWriter
static TFileStager * fgFileStager
Definition: TXNetFile.h:73
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1627
static Long64_t GetFileBytesWritten()
Static function returning the total number of bytes written to all files.
Definition: TFile.cxx:4328
virtual Bool_t ReadBufferAsync(Long64_t offs, Int_t len)
Implementation dealing with the xrootd server.
Definition: TXNetFile.cxx:693
Int_t ReOpen(Option_t *mode)
Reopen a file with a different access mode, like from READ to UPDATE or from NEW, CREATE...
Definition: TNetFile.cxx:296
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1964
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
static void SetEnv()
Set the relevant environment variables.
Definition: TXNetFile.cxx:1193
virtual void ResetCache()
Reset the cache.
Definition: TXNetFile.cxx:1408
A doubly linked list.
Definition: TList.h:47
virtual Int_t GetBytesToPrefetch() const
Max number of bytes to prefetch.
Definition: TXNetFile.cxx:1417
static UInt_t GetOpenTimeout()
Returns open timeout (in ms).
Definition: TFile.cxx:4479
Int_t GetPort() const
Definition: TUrl.h:87
Int_t SysOpen(const char *pathname, Int_t flags, UInt_t mode)
Override TNetFile::SysOpen (see parent's method for more details).
Definition: TXNetFile.cxx:1162
Int_t fNetopt
Definition: TNetFile.h:52
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1611
Int_t SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime)
Return file stat information.
Definition: TNetFile.cxx:167
ClassImp(TXNetFile)
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
static void FormUrl(TUrl uut, TString &uu)
Form url for rootd socket.
Definition: TXNetFile.cxx:170
#define XrdSysMutexHelper
Definition: XrdSysToOuc.h:17
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
EAsyncOpenStatus fAsyncOpenStatus
!Status of an asynchronous open request
Definition: TFile.h:96
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2321
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Flush()
Flushes un-written data.
Definition: TXNetFile.cxx:1053
TMarker * m
Definition: textangle.C:8
char * Form(const char *fmt,...)
static std::atomic< Long64_t > fgBytesWrite
Number of bytes written by all TFile objects.
Definition: TFile.h:110
void * fInitMtx
Definition: TXNetFile.h:75
static std::atomic< Int_t > fgReadCalls
Number of bytes read from all TFile objects.
Definition: TFile.h:113
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:728
static Int_t GetFileReadCalls()
Static function returning the total number of read calls from all files.
Definition: TFile.cxx:4336
Bool_t IsNull() const
Definition: TString.h:387
TUrl fEndpointUrl
Definition: TNetFile.h:47
virtual void Init(Bool_t create)
Initialize a TFile object.
Definition: TFile.cxx:581
Bool_t WriteBuffer(const char *buf, Int_t len)
Write specified byte range to remote file via rootd daemon.
Definition: TNetFile.cxx:499
Int_t ReadBufferViaCache(char *buf, Int_t len)
Read buffer via cache.
Definition: TFile.cxx:1715
Bool_t fWritable
True if directory is writable.
#define Printf
Definition: TGeoToOCC.h:18
#define gPerfStats
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:385
Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Read a list of buffers given in pos[] and len[] and return it in a single buffer. ...
Definition: TNetFile.cxx:395
static Bool_t GetOnlyStaged()
Returns staged only flag.
Definition: TFile.cxx:4499
Bool_t fIsRootd
Definition: TXNetFile.h:68
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
Int_t SysOpen(const char *pathname, Int_t flags, UInt_t mode)
Open a remote file. Requires fOption to be set correctly.
Definition: TNetFile.cxx:120
virtual void Create(const char *url, Option_t *option, Int_t netopt)
Create a NetFile object.
Definition: TNetFile.cxx:671
void SetAnchor(const char *anchor)
Definition: TUrl.h:95
virtual Bool_t WriteBuffer(const char *buffer, Int_t BufferLength)
Override TNetFile::WriteBuffer to deal with the xrootd server.
Definition: TXNetFile.cxx:852
void Close(Option_t *option="")
Close remote file.
Definition: TNetFile.cxx:219
double Double_t
Definition: RtypesCore.h:55
Bool_t IsOpen() const
Retruns kTRUE if file is open, kFALSE otherwise.
Definition: TNetFile.cxx:258
virtual void Close(const Option_t *opt="")
Close the file (see TNetFile::Close() or TFile::Close() for more details).
Definition: TXNetFile.cxx:1029
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
virtual void Print(Option_t *option="") const
Print all objects in the file.
Definition: TFile.cxx:1532
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition: TTimeStamp.h:76
TList * fOpenPhases
!Time info about open phases
Definition: TFile.h:100
static TFileStager * Open(const char *stager)
Open a stager, after having loaded the relevant plug-in.
TString fOption
File options.
Definition: TFile.h:78
virtual Bool_t SendFileReadProgress(TFile *)
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
Bool_t Open(Option_t *option, Bool_t parallelopen)
The real creation work is done here.
Definition: TXNetFile.cxx:476
Bool_t FlushWriteCache()
Flush the write cache if active.
Definition: TFile.cxx:1097
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1806
Bool_t ReadBuffer(char *buf, Int_t len)
Read specified byte range from remote file via rootd daemon.
Definition: TNetFile.cxx:311
void CreateXClient(const char *url, Option_t *option, Int_t netopt, Bool_t parallelopen)
The real creation work is done here.
Definition: TXNetFile.cxx:251
const Ssiz_t kNPOS
Definition: Rtypes.h:115
Int_t SysClose(Int_t fd)
Override TNetFile::SysClose (see parent's method for more details).
Definition: TXNetFile.cxx:1138
virtual Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Read the nbuf blocks described in arrays pos and len.
Definition: TFile.cxx:1647
void MakeZombie()
Definition: TObject.h:68
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
virtual Bool_t Matches(const char *s)
Definition: TFileStager.h:50
static Int_t GetClientProtocol()
Static method returning supported client protocol.
Definition: TSocket.cxx:1494
Long64_t fArchiveOffset
!Offset at which file starts in archive
Definition: TFile.h:88
void SetUrl(const char *url)
Definition: TSocket.h:185
double result[121]
void Init(Bool_t create)
Initialize a TNetFile object.
Definition: TNetFile.cxx:247
Long64_t fOffset
!Seek offset cache
Definition: TFile.h:83
void SetService(const char *service)
Definition: TSocket.h:183
Bool_t fInitDone
!True if the file has been initialized
Definition: TFile.h:92
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
static void SetFileBytesRead(Long64_t bytes=0)
Definition: TFile.cxx:4353
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:901
TInetAddress GetInetAddress() const
Definition: TSocket.h:143
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual Bool_t IsOpen() const
Return kTRUE if the file is open, kFALSE otherwise.
Definition: TXNetFile.cxx:975
virtual Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Read the nbuf blocks described in arrays pos and len, where pos[i] is the seek position of block i of...
Definition: TXNetFile.cxx:760
const char * GetUser() const
Definition: TUrl.h:74
Long64_t fBytesRead
Number of bytes read from this file.
Definition: TFile.h:63
void SynchronizeCacheSize()
Synchronize the cache size Alternative purging policy.
Definition: TXNetFile.cxx:1376
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:898
virtual void IgnoreSignal(ESignals sig, Bool_t ignore=kTRUE)
If ignore is true ignore the specified signal, else restore previous behaviour.
Definition: TSystem.cxx:597
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904