Logo ROOT   6.14/05
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>
62 #include <XProtocol/XProtocol.hh>
63 
64 #include "XpdSysPthread.h"
65 #include "XrdSysToOuc.h"
66 
68 
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 
170 void TXNetFile::FormUrl(TUrl uu, TString &uus)
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 != bufferLength) {
651  Error("ReadBuffer", "error reading all requested bytes, got %d of %d",
652  nr, bufferLength);
653  return kTRUE;
654  }
655 
656  if (gDebug > 1)
657  Info("ReadBuffer", "%d bytes of data read from offset"
658  " %lld (%d requested)", nr, fOffset, bufferLength);
659 
660  fOffset += bufferLength;
661 
662  fBytesRead += nr;
663  fReadCalls++;
664 #ifdef WIN32
667 #else
668  fgBytesRead += nr;
669  fgReadCalls++;
670 #endif
671 
672  if (gPerfStats)
673  gPerfStats->FileReadEvent(this, bufferLength, start);
674 
675  if (gMonitoringWriter)
677 
678  return result;
679 }
680 
681 ////////////////////////////////////////////////////////////////////////////////
682 /// Pass through to TNetFile implementation which will call back eventually
683 /// to our ReadBuffer with 2 arguments to deal with xrootd errors.
684 
685 Bool_t TXNetFile::ReadBuffer(char *buffer, Long64_t pos, Int_t bufferLength)
686 {
687  return TNetFile::ReadBuffer(buffer, pos, bufferLength);
688 }
689 
690 ////////////////////////////////////////////////////////////////////////////////
691 /// Implementation dealing with the xrootd server.
692 /// Returns kTRUE in case of errors.
693 /// This is the same as TXNetFile::ReadBuffer but using the async
694 /// call from xrootd
695 
697 {
698  if (IsZombie()) {
699  Error("ReadBuffer", "ReadBuffer is not possible because object"
700  " is in 'zombie' state");
701  return kTRUE;
702  }
703 
704  if (fIsRootd) {
705  if (gDebug > 1)
706  Error("ReadBufferAsync","Not supported for rootd");
707  return kTRUE;
708  }
709 
710  if (!IsOpen()) {
711  Error("ReadBuffer","The remote file is not open");
712  return kTRUE;
713  }
714 
715  Double_t start = 0;
716  if (gPerfStats) start = TTimeStamp();
717 
718  Bool_t result = kFALSE;
719 
720  if (bufferLength==0)
721  return 0;
722 
724 
725  // Read for the remote xrootd
726  // This doesnt return the number of bytes read...
727  // and even if it did we dont want to update fBytesRead
728  // because that would be updated in the real read
729  XReqErrorType nr = fClient->Read_Async(offs+fArchiveOffset, bufferLength);
730 
731  if (nr != kOK)
732  return kTRUE;
733 
734  fBytesRead += bufferLength;
735  fReadCalls++;
736 #ifdef WIN32
737  SetFileBytesRead(GetFileBytesRead() + bufferLength);
739 #else
740  fgBytesRead += bufferLength;
741  fgReadCalls++;
742 #endif
743 
744  if (gPerfStats)
745  gPerfStats->FileReadEvent(this, bufferLength, start);
746 
747  if (gDebug > 1)
748  Info("ReadBufferAsync", "%d bytes of data read request from offset"
749  " %lld", bufferLength, offs);
750  return result;
751 }
752 
753 ////////////////////////////////////////////////////////////////////////////////
754 /// Read the nbuf blocks described in arrays pos and len,
755 /// where pos[i] is the seek position of block i of length len[i].
756 /// Note that for nbuf=1, this call is equivalent to TFile::ReadBuffer
757 /// This function is overloaded by TNetFile, TWebFile, etc.
758 /// Returns kTRUE in case of failure.
759 /// Note: This is the overloading made in TXNetFile. If ReadBuffers
760 /// is supported by xrootd it will try to get the whole list from one single
761 /// call avoiding the latency of multiple calls
762 
763 Bool_t TXNetFile::ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
764 {
765  if (IsZombie()) {
766  Error("ReadBuffers", "ReadBuffers is not possible because object"
767  " is in 'zombie' state");
768  return kTRUE;
769  }
770 
771  if (fIsRootd) {
772  if (gDebug > 1)
773  Info("ReadBuffers","Calling TNetFile::ReadBuffers");
774  return TNetFile::ReadBuffers(buf, pos, len, nbuf);
775  }
776 
777  if (!IsOpen()) {
778  Error("ReadBuffers","The remote file is not open");
779  return kTRUE;
780  }
781 
782  Double_t start = 0;
783  if (gPerfStats) start = TTimeStamp();
784 
785  if (fArchiveOffset) {
786  for (Int_t i = 0; i < nbuf; i++)
787  pos[i] += fArchiveOffset;
788  }
789 
790  Long64_t expected_nr = 0;
791  for (Int_t i = 0; i < nbuf; i++) {
792  expected_nr += len[i];
793  }
794 
795  // A null buffer means that we want to use the async stuff
796  // hence we have to sync the cache size in XrdClient with the supposed
797  // size in TFile.
798  if (!buf) {
799  // Null buffer + 0 blocks means 'reset cache'
800  if (!nbuf) ResetCache();
802  }
803 
804  // Read for the remote xrootd
805  Long64_t nr = fClient->ReadV(buf, pos, len, nbuf);
806 
807  if (gDebug > 1)
808  Info("ReadBuffers", "response from ReadV(%d) nr: %lld", nbuf, nr);
809 
810  if (nr == expected_nr) {
811 
812  if (gDebug > 1)
813  Info("ReadBuffers", "%lld bytes of data read from a list of %d buffers",
814  nr, nbuf);
815 
816  if (GetCacheRead() && GetCacheRead()->GetBufferSize() < nr)
817  Info("ReadBuffers", "%lld bytes of data read with a smaller (%d) TFileCacheRead buffer size?",
818  nr, GetCacheRead()->GetBufferSize());
819 
820  // Where should we leave the offset ?
821  // fOffset += bufferLength;
822  fBytesRead += nr;
823  fReadCalls++;
824 #ifdef WIN32
827 #else
828  fgBytesRead += nr;
829  fgReadCalls++;
830 #endif
831 
832  if (gPerfStats) {
833  fOffset = pos[0];
834  gPerfStats->FileReadEvent(this, (Int_t)nr, start);
835  }
836 
837  if (gMonitoringWriter)
839 
840  return kFALSE;
841  }
842 
843  if (gDebug > 1)
844  Info("ReadBuffers", "XrdClient->ReadV failed, executing TFile::ReadBuffers");
845 
846  // If it wasnt able to use the specialized call
847  // then use the generic one that is a plain loop
848  // of individual requests
849  if (buf && nbuf)
850  return TFile::ReadBuffers(buf, pos, len, nbuf);
851  // If the async call was needed (buf == 0) and it got an error,
852  // just return error
853  else return kTRUE;
854 }
855 
856 ////////////////////////////////////////////////////////////////////////////////
857 /// Override TNetFile::WriteBuffer to deal with the xrootd server.
858 /// Returns kTRUE in case of errors.
859 
860 Bool_t TXNetFile::WriteBuffer(const char *buffer, Int_t bufferLength)
861 {
862  if (IsZombie()) {
863  Error("WriteBuffer", "WriteBuffer is not possible because object"
864  " is in 'zombie' state");
865  return kTRUE;
866  }
867 
868  if (!fWritable) {
869  if (gDebug > 1)
870  Info("WriteBuffer","file not writable");
871  return kTRUE;
872  }
873 
874  if (fIsRootd) {
875  if (gDebug > 1)
876  Info("WriteBuffer","Calling TNetFile::WriteBuffer");
877  return TNetFile::WriteBuffer(buffer, bufferLength );
878  }
879 
880  if (!IsOpen()) {
881  Error("WriteBuffer","The remote file is not open");
882  return kTRUE;
883  }
884 
885  Int_t st;
886  if ((st = WriteBufferViaCache(buffer, bufferLength))) {
887  if (st == 2)
888  return kTRUE;
889  return kFALSE;
890  }
891 
892  // Read for the remote xrootd
893  if (!fClient->Write(buffer, fOffset, bufferLength)) {
894  if (gDebug > 0)
895  Info("WriteBuffer",
896  "error writing %d bytes of data wrote to offset %lld",
897  bufferLength , fOffset);
898  return kTRUE;
899  }
900 
901  if (gDebug > 1)
902  Info("WriteBuffer", " %d bytes of data wrote to offset"
903  " %lld", bufferLength , fOffset);
904 
905  fOffset += bufferLength;
906  fBytesWrite += bufferLength;
907 #ifdef WIN32
908  SetFileBytesWritten(GetFileBytesWritten() + bufferLength);
909 #else
910  fgBytesWrite += bufferLength;
911 #endif
912 
913  return kFALSE;
914 }
915 
916 ////////////////////////////////////////////////////////////////////////////////
917 /// Initialize the file. Makes sure that the file is really open before
918 /// calling TFile::Init. It may block.
919 
921 {
922  if (fInitDone) {
923  // TFile::Init already called once
924  if (gDebug > 1)
925  Info("Init","TFile::Init already called once");
926  return;
927  }
928 
929  if (fIsRootd) {
930  if (gDebug > 1)
931  Info("Init","rootd: calling directly TFile::Init");
932  return TNetFile::Init(create);
933  }
934 
935  if (fClient) {
936  // A mutex serializes this very delicate section
938 
939  // To safely perform the Init() we must make sure that
940  // the file is successfully open; this call may block
941  if (fClient->IsOpen_wait()) {
942 
943  // Notify the monitoring system
944  if (gMonitoringWriter)
946 
947  // Avoid big transfers at this level
948  bool usecachesave = fClient->UseCache(0);
949  // Note that Init will trigger recursive calls
950  TFile::Init(create);
951  // so TFile::IsOpen() returns true when in TFile::~TFile
952  fD = -2;
953  // Restore requested behaviour
954  fClient->UseCache(usecachesave);
955 
956  // Notify the monitoring system
957  if (gMonitoringWriter)
959 
960  // Set the Endpoint Url we are now connected to. Unless there was some opaque info
961  // which cannot be re-used
962  if (fClient->GetClientConn() && fClient->GetClientConn()->fRedirOpaque.length() <= 0) {
963  fEndpointUrl = fClient->GetClientConn()->GetCurrentUrl().GetUrl().c_str();
964  // Check equivalence of initial and end-point Url to see whether we have
965  // been redirected
966  if (fEndpointUrl.GetPort() != fUrl.GetPort() ||
969  }
970  } else {
971  if (gDebug > 0)
972  Info("Init","open request failed!");
974  MakeZombie();
975  gDirectory = gROOT;
976  }
977  }
978 }
979 
980 ////////////////////////////////////////////////////////////////////////////////
981 /// Return kTRUE if the file is open, kFALSE otherwise.
982 
984 {
985  if (fIsRootd) {
986  if (gDebug > 1)
987  Info("IsOpen","Calling TNetFile::IsOpen");
988  return TNetFile::IsOpen();
989  }
990 
991  if (!fClient)
992  return kFALSE;
993 
994  // We are done
995  return ((fClient && fInitDone) ? fClient->IsOpen() : kFALSE);
996 }
997 
998 ////////////////////////////////////////////////////////////////////////////////
999 /// Return status of asynchronous request
1000 
1002 {
1004  if (fClient->IsOpen_inprogress()) {
1005  return TFile::kAOSInProgress;
1006  } else {
1007  if (fClient->IsOpen())
1008  return TFile::kAOSSuccess;
1009  else
1010  return TFile::kAOSFailure;
1011  }
1012  }
1013 
1014  // Not asynchronous
1015  return TFile::kAOSNotAsync;
1016 }
1017 
1018 ////////////////////////////////////////////////////////////////////////////////
1019 /// Re-open the file (see TNetFile::ReOpen() or TFile::ReOpen()
1020 /// for more details).
1021 
1023 {
1024  if (fIsRootd) {
1025  if (gDebug > 1)
1026  Info("ReOpen","Calling TNetFile::ReOpen");
1027  return TNetFile::ReOpen(Mode);
1028  }
1029 
1030  return TFile::ReOpen(Mode);
1031 }
1032 
1033 ////////////////////////////////////////////////////////////////////////////////
1034 /// Close the file (see TNetFile::Close() or TFile::Close()
1035 /// for more details).
1036 
1037 void TXNetFile::Close(const Option_t *opt)
1038 {
1039  if (fIsRootd) {
1040  if (gDebug > 1)
1041  Info("Close","Calling TNetFile::Close");
1042  TNetFile::Close(opt);
1043  return;
1044  }
1045 
1046  if (!fClient) return;
1047 
1048  TFile::Close(opt);
1049 
1050  fIsRootd = kFALSE;
1051 
1052  if (IsOpen())
1053  fClient->Close();
1054 
1055  fD = -1; // so TFile::IsOpen() returns false when in TFile::~TFile
1056 }
1057 
1058 ////////////////////////////////////////////////////////////////////////////////
1059 /// Flushes un-written data.
1060 
1062 {
1063  if (IsZombie()) {
1064  Error("Flush", "Flush is not possible because object is"
1065  " in 'zombie' state");
1066  return;
1067  }
1068 
1069  if (!fWritable) {
1070  if (gDebug > 1)
1071  Info("Flush", "file not writable - do nothing");
1072  return;
1073  }
1074 
1075  if (fIsRootd) {
1076  if (gDebug > 1)
1077  Info("Flush","Calling TNetFile::Flush");
1078  TNetFile::Flush();
1079  return;
1080  }
1081 
1082  if (!IsOpen()) {
1083  Error("Flush","The remote file is not open");
1084  return;
1085  }
1086 
1087  FlushWriteCache();
1088 
1089  //
1090  // Flush via the remote xrootd
1091  fClient->Sync();
1092  if (gDebug > 1)
1093  Info("Flush", "XrdClient::Sync called.");
1094 }
1095 
1096 ////////////////////////////////////////////////////////////////////////////////
1097 /// Override TNetFile::SysStat (see parent's method for more details).
1098 
1100  Long_t *modtime)
1101 {
1102  if (IsZombie()) {
1103  Error("SysStat", "SysStat is not possible because object is"
1104  " in 'zombie' state");
1105  *size = 0;
1106  return 1;
1107  }
1108 
1109  if (fIsRootd) {
1110  if (gDebug > 1)
1111  Info("SysStat", "calling TNetFile::SysStat");
1112  return TNetFile::SysStat(fd, id, size, flags, modtime);
1113  }
1114 
1115  // Return file stat information. The interface and return value is
1116  // identical to TSystem::GetPathInfo().
1117  struct XrdClientStatInfo stinfo;
1118  if (fClient && fClient->Stat(&stinfo)) {
1119  *id = (Long_t)(stinfo.id);
1120  *size = (Long64_t)(stinfo.size);
1121  *flags = (Long_t)(stinfo.flags);
1122  *modtime = (Long_t)(stinfo.modtime);
1123  if (gDebug > 1)
1124  Info("SysStat", "got stats = %ld %lld %ld %ld",
1125  *id, *size, *flags, *modtime);
1126  } else {
1127 
1128  if (gDebug > 1) {
1129  if (!IsOpen()) Info("SysStat", "could not stat remote file. Not opened.");
1130  else
1131  Info("SysStat", "could not stat remote file");
1132  }
1133 
1134 
1135  *id = -1;
1136  return 1;
1137  }
1138 
1139  // We are done
1140  return 0;
1141 }
1142 
1143 ////////////////////////////////////////////////////////////////////////////////
1144 /// Override TNetFile::SysClose (see parent's method for more details).
1145 
1147 {
1148  if (IsZombie()) {
1149  Error("SysClose", "SysClose is not possible because object is"
1150  " in 'zombie' state");
1151  return 0;
1152  }
1153 
1154  if (fIsRootd) {
1155  if (gDebug > 1)
1156  Info("SysClose","Calling TNetFile::SysClose");
1157  return TNetFile::SysClose(fd);
1158  }
1159 
1160  // Send close to remote xrootd
1161  if (IsOpen())
1162  fClient->Close();
1163 
1164  return 0;
1165 }
1166 
1167 ////////////////////////////////////////////////////////////////////////////////
1168 /// Override TNetFile::SysOpen (see parent's method for more details).
1169 
1170 Int_t TXNetFile::SysOpen(const char* pathname, Int_t flags, UInt_t mode)
1171 {
1172  if (fIsRootd) {
1173  if (gDebug > 1)
1174  Info("SysOpen", "Calling TNetFile::SysOpen");
1175  return TNetFile::SysOpen(pathname, flags, mode);
1176  }
1177 
1178  if (!fClient) {
1179 
1180  // Create an instance of XrdClient
1182 
1183  } else {
1184 
1185  // url is not needed because already stored
1186  // fOption is set in TFile::ReOpen
1187  Open(fOption.Data(), kFALSE);
1188  }
1189 
1190  // If not successful, flag it
1191  if (!IsOpen())
1192  return -1;
1193 
1194  // This means ok for net files
1195  return -2; // set as fD in ReOpen
1196 }
1197 
1198 ////////////////////////////////////////////////////////////////////////////////
1199 /// Set the relevant environment variables
1200 
1202 {
1203  // List of domains where redirection is allowed
1204  TString allowRE = gEnv->GetValue("XNet.RedirDomainAllowRE", "");
1205  if (allowRE.Length() > 0)
1206  EnvPutString(NAME_REDIRDOMAINALLOW_RE, allowRE.Data());
1207 
1208  // List of domains where redirection is denied
1209  TString denyRE = gEnv->GetValue("XNet.RedirDomainDenyRE", "");
1210  if (denyRE.Length() > 0)
1211  EnvPutString(NAME_REDIRDOMAINDENY_RE, denyRE.Data());
1212 
1213  // List of domains where connection is allowed
1214  TString allowCO = gEnv->GetValue("XNet.ConnectDomainAllowRE", "");
1215  if (allowCO.Length() > 0)
1216  EnvPutString(NAME_CONNECTDOMAINALLOW_RE, allowCO.Data());
1217 
1218  // List of domains where connection is denied
1219  TString denyCO = gEnv->GetValue("XNet.ConnectDomainDenyRE", "");
1220  if (denyCO.Length() > 0)
1221  EnvPutString(NAME_CONNECTDOMAINDENY_RE, denyCO.Data());
1222 
1223  // Connect Timeout
1224  Int_t connTO = gEnv->GetValue("XNet.ConnectTimeout",
1226  EnvPutInt(NAME_CONNECTTIMEOUT, connTO);
1227 
1228  // Reconnect Timeout
1229  Int_t recoTO = gEnv->GetValue("XNet.ReconnectWait",
1231  if (recoTO == DFLT_RECONNECTWAIT) {
1232  // Check also the old variable name
1233  recoTO = gEnv->GetValue("XNet.ReconnectTimeout",
1235  }
1236  EnvPutInt(NAME_RECONNECTWAIT, recoTO);
1237 
1238  // Request Timeout
1239  Int_t requTO = gEnv->GetValue("XNet.RequestTimeout",
1241  EnvPutInt(NAME_REQUESTTIMEOUT, requTO);
1242 
1243  // Max number of redirections
1244  Int_t maxRedir = gEnv->GetValue("XNet.MaxRedirectCount",
1246  EnvPutInt(NAME_MAXREDIRECTCOUNT, maxRedir);
1247 
1248 
1249  // Read ahead size
1250  Int_t rAheadsiz = gEnv->GetValue("XNet.ReadAheadSize",
1252  EnvPutInt(NAME_READAHEADSIZE, rAheadsiz);
1253 
1254 
1255  // Cache size (<= 0 disables cache)
1256  Int_t rCachesiz = gEnv->GetValue("XNet.ReadCacheSize",
1258 
1259  EnvPutInt(NAME_READCACHESIZE, rCachesiz);
1260 
1261  // Max number of retries on first connect
1262  Int_t maxRetries = gEnv->GetValue("XNet.FirstConnectMaxCnt",
1264  EnvPutInt(NAME_FIRSTCONNECTMAXCNT, maxRetries);
1265 
1266  // Parallel stream count
1267  Int_t parStreamsCnt = gEnv->GetValue("XNet.ParStreamsPerPhyConn",
1269  EnvPutInt(NAME_MULTISTREAMCNT, parStreamsCnt);
1270 
1271  // Change the TCP window size (0 means 'scaling' on some platforms)
1272  Int_t tcpWindowSize = gEnv->GetValue("XNet.DfltTcpWindowSize",
1274  EnvPutInt(NAME_DFLTTCPWINDOWSIZE, tcpWindowSize);
1275 
1276  // Change the transaction timeout
1277  Int_t transactionTimeout = gEnv->GetValue("XNet.TransactionTimeout",
1279  EnvPutInt(NAME_TRANSACTIONTIMEOUT, transactionTimeout);
1280 
1281  // Whether to activate automatic rootd backward-compatibility
1282  // (We override XrdClient default)
1283  fgRootdBC = gEnv->GetValue("XNet.RootdFallback", 1);
1285 
1286  // Dynamic forwarding (SOCKS4)
1287  TString socks4Host = gEnv->GetValue("XNet.SOCKS4Host","");
1288  Int_t socks4Port = gEnv->GetValue("XNet.SOCKS4Port",-1);
1289  if (socks4Port > 0) {
1290  if (socks4Host.IsNull())
1291  // Default
1292  socks4Host = "127.0.0.1";
1293  EnvPutString(NAME_SOCKS4HOST, socks4Host.Data());
1294  EnvPutInt(NAME_SOCKS4PORT, socks4Port);
1295  }
1296 
1297  const char *cenv = 0;
1298 
1299  // For password-based authentication
1300  TString autolog = gEnv->GetValue("XSec.Pwd.AutoLogin","1");
1301  if (autolog.Length() > 0 &&
1302  (!(cenv = gSystem->Getenv("XrdSecPWDAUTOLOG")) || strlen(cenv) <= 0))
1303  gSystem->Setenv("XrdSecPWDAUTOLOG",autolog.Data());
1304 
1305  // Old style netrc file
1306  TString netrc;
1307  netrc.Form("%s/.rootnetrc",gSystem->HomeDirectory());
1308  gSystem->Setenv("XrdSecNETRC", netrc.Data());
1309 
1310  TString alogfile = gEnv->GetValue("XSec.Pwd.ALogFile","");
1311  if (alogfile.Length() > 0)
1312  gSystem->Setenv("XrdSecPWDALOGFILE",alogfile.Data());
1313 
1314  TString verisrv = gEnv->GetValue("XSec.Pwd.VerifySrv","1");
1315  if (verisrv.Length() > 0 &&
1316  (!(cenv = gSystem->Getenv("XrdSecPWDVERIFYSRV")) || strlen(cenv) <= 0))
1317  gSystem->Setenv("XrdSecPWDVERIFYSRV",verisrv.Data());
1318 
1319  TString srvpuk = gEnv->GetValue("XSec.Pwd.ServerPuk","");
1320  if (srvpuk.Length() > 0)
1321  gSystem->Setenv("XrdSecPWDSRVPUK",srvpuk.Data());
1322 
1323  // For GSI authentication
1324  TString cadir = gEnv->GetValue("XSec.GSI.CAdir","");
1325  if (cadir.Length() > 0)
1326  gSystem->Setenv("XrdSecGSICADIR",cadir.Data());
1327 
1328  TString crldir = gEnv->GetValue("XSec.GSI.CRLdir","");
1329  if (crldir.Length() > 0)
1330  gSystem->Setenv("XrdSecGSICRLDIR",crldir.Data());
1331 
1332  TString crlext = gEnv->GetValue("XSec.GSI.CRLextension","");
1333  if (crlext.Length() > 0)
1334  gSystem->Setenv("XrdSecGSICRLEXT",crlext.Data());
1335 
1336  TString ucert = gEnv->GetValue("XSec.GSI.UserCert","");
1337  if (ucert.Length() > 0)
1338  gSystem->Setenv("XrdSecGSIUSERCERT",ucert.Data());
1339 
1340  TString ukey = gEnv->GetValue("XSec.GSI.UserKey","");
1341  if (ukey.Length() > 0)
1342  gSystem->Setenv("XrdSecGSIUSERKEY",ukey.Data());
1343 
1344  TString upxy = gEnv->GetValue("XSec.GSI.UserProxy","");
1345  if (upxy.Length() > 0)
1346  gSystem->Setenv("XrdSecGSIUSERPROXY",upxy.Data());
1347 
1348  TString valid = gEnv->GetValue("XSec.GSI.ProxyValid","");
1349  if (valid.Length() > 0)
1350  gSystem->Setenv("XrdSecGSIPROXYVALID",valid.Data());
1351 
1352  TString deplen = gEnv->GetValue("XSec.GSI.ProxyForward","0");
1353  if (deplen.Length() > 0 &&
1354  (!(cenv = gSystem->Getenv("XrdSecGSIPROXYDEPLEN")) || strlen(cenv) <= 0))
1355  gSystem->Setenv("XrdSecGSIPROXYDEPLEN",deplen.Data());
1356 
1357  TString pxybits = gEnv->GetValue("XSec.GSI.ProxyKeyBits","");
1358  if (pxybits.Length() > 0)
1359  gSystem->Setenv("XrdSecGSIPROXYKEYBITS",pxybits.Data());
1360 
1361  TString crlcheck = gEnv->GetValue("XSec.GSI.CheckCRL","1");
1362  if (crlcheck.Length() > 0 &&
1363  (!(cenv = gSystem->Getenv("XrdSecGSICRLCHECK")) || strlen(cenv) <= 0))
1364  gSystem->Setenv("XrdSecGSICRLCHECK",crlcheck.Data());
1365 
1366  TString delegpxy = gEnv->GetValue("XSec.GSI.DelegProxy","0");
1367  if (delegpxy.Length() > 0 &&
1368  (!(cenv = gSystem->Getenv("XrdSecGSIDELEGPROXY")) || strlen(cenv) <= 0))
1369  gSystem->Setenv("XrdSecGSIDELEGPROXY",delegpxy.Data());
1370 
1371  TString signpxy = gEnv->GetValue("XSec.GSI.SignProxy","1");
1372  if (signpxy.Length() > 0 &&
1373  (!(cenv = gSystem->Getenv("XrdSecGSISIGNPROXY")) || strlen(cenv) <= 0))
1374  gSystem->Setenv("XrdSecGSISIGNPROXY",signpxy.Data());
1375 
1376  // Using ROOT mechanism to IGNORE SIGPIPE signal
1378 }
1379 
1380 ////////////////////////////////////////////////////////////////////////////////
1381 /// Synchronize the cache size
1382 /// Alternative purging policy
1383 
1385 {
1386  if (fClient == 0) return;
1387 
1388  fClient->UseCache(TRUE);
1389  Int_t size;
1390  Long64_t bytessubmitted, byteshit, misscount, readreqcnt;
1391  Float_t missrate, bytesusefulness;
1392  int newbsz = -1;
1393  if (fClient->GetCacheInfo(size, bytessubmitted,
1394  byteshit, misscount,
1395  missrate, readreqcnt,
1396  bytesusefulness) ) {
1397 
1398  // To allow for some space for outstanding data
1399  TFileCacheRead *cacheRead = GetCacheRead();
1400  if (cacheRead) {
1401  newbsz = GetBufferSize() / 2 * 3;
1402  newbsz = std::max(newbsz, size);
1403  } else {
1404  newbsz = size;
1405  }
1406 
1407  }
1408 
1409  if (newbsz > 0)
1410  fClient->SetCacheParameters(newbsz, 0, XrdClientReadCache::kRmBlk_FIFO);
1411 }
1412 
1413 ////////////////////////////////////////////////////////////////////////////////
1414 /// Reset the cache
1415 
1417 {
1418  if (fClient)
1419  fClient->RemoveAllDataFromCache();
1420 }
1421 
1422 ////////////////////////////////////////////////////////////////////////////////
1423 /// Max number of bytes to prefetch.
1424 
1426 {
1427  Int_t size;
1428  Long64_t bytessubmitted, byteshit, misscount, readreqcnt;
1429  Float_t missrate, bytesusefulness;
1430  Int_t bytes = 0;
1431  if (fClient && fClient->GetCacheInfo(size, bytessubmitted,
1432  byteshit, misscount,
1433  missrate, readreqcnt,
1434  bytesusefulness) )
1435  bytes = size;
1436  return ((bytes < 0) ? 0 : bytes);
1437 }
1438 
1439 ////////////////////////////////////////////////////////////////////////////////
1440 /// Print the local statistics.
1441 
1442 void TXNetFile::Print(Option_t *option) const
1443 {
1444  Printf("TXNetFile caching information:");
1445 
1446  Int_t size;
1447  Long64_t bytessubmitted, byteshit, misscount, readreqcnt;
1448  Float_t missrate, bytesusefulness;
1449 
1450  if (fClient && fClient->GetCacheInfo(size, bytessubmitted,
1451  byteshit, misscount,
1452  missrate, readreqcnt,
1453  bytesusefulness)) {
1454  Printf(" Max size: %d", size);
1455  Printf(" Bytes submitted: %lld", bytessubmitted);
1456  Printf(" Bytes hit (estimation): %lld", byteshit);
1457  Printf(" Miss count: %lld", misscount);
1458  Printf(" Miss rate: %f", missrate);
1459  Printf(" Read requests count: %lld", readreqcnt);
1460  Printf(" Bytes usefulness: %f\n", bytesusefulness);
1461  } else
1462  Printf(" -- No Xrd client instance allocated --\n");
1463 
1464  TFile::Print(option);
1465 }
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:1276
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
void Init(Bool_t create)
Initialize the file.
Definition: TXNetFile.cxx:920
#define DFLT_READCACHESIZE
void SetRemoteProtocol(Int_t rproto)
Definition: TSocket.h:170
Int_t SysClose(Int_t fd)
Close currently open file.
Definition: TNetFile.cxx:155
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
long long Long64_t
Definition: RtypesCore.h:69
auto * m
Definition: textangle.C:8
Long64_t fBytesWrite
Number of bytes written to this file.
Definition: TFile.h:69
EAsyncOpenStatus
Asynchronous open request status.
Definition: TFile.h:58
Int_t GetPort() const
Definition: TSocket.h:134
static std::atomic< Long64_t > fgBytesRead
Number of bytes read by all TFile objects.
Definition: TFile.h:124
virtual Int_t ReOpen(Option_t *mode)
Reopen a file with a different access mode.
Definition: TFile.cxx:2059
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&#39;s method for more details).
Definition: TXNetFile.cxx:1099
XrdClient * fClient
Definition: TXNetFile.h:66
A cache when reading files over the network.
const char Option_t
Definition: RtypesCore.h:62
#define DFLT_CONNECTTIMEOUT
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
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:35
virtual Bool_t SendFileOpenProgress(TFile *, TList *, const char *, Bool_t=kFALSE)
#define NAME_READAHEADSIZE
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
#define NAME_TRANSACTIONTIMEOUT
virtual TFile::EAsyncOpenStatus GetAsyncOpenStatus()
Return status of asynchronous request.
Definition: TXNetFile.cxx:1001
#define XrdSysRecMutex
Definition: XrdSysToOuc.h:18
static void SetFileReadCalls(Int_t readcalls=0)
Definition: TFile.cxx:4484
virtual const char * HomeDirectory(const char *userName=0)
Return the user&#39;s home directory.
Definition: TSystem.cxx:885
#define DFLT_READAHEADSIZE
#define gROOT
Definition: TROOT.h:410
#define NAME_KEEPSOCKOPENIFNOTXRD
#define NAME_SOCKS4HOST
void Flush()
Flush file to disk.
Definition: TNetFile.cxx:236
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Int_t WriteBufferViaCache(const char *buf, Int_t len)
Write buffer via cache.
Definition: TFile.cxx:2419
static Int_t GetRootdProtocol(TSocket *s)
Find out the remote rootd protocol version.
Definition: TXNetFile.cxx:421
const char * GetOptions() const
Definition: TUrl.h:74
#define NAME_READCACHESIZE
#define NAME_DEBUG
#define NAME_FIRSTCONNECTMAXCNT
Int_t fReadCalls
Number of read calls ( not counting the cache calls )
Definition: TFile.h:83
static Bool_t fgRootdBC
Definition: TXNetFile.h:62
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:469
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:387
virtual Int_t ReOpen(const Option_t *mode)
Re-open the file (see TNetFile::ReOpen() or TFile::ReOpen() for more details).
Definition: TXNetFile.cxx:1022
void SetServType(Int_t st)
Definition: TSocket.h:173
static void SetFileBytesWritten(Long64_t bytes=0)
Definition: TFile.cxx:4481
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Override TNetFile::ReadBuffer to deal with the xrootd server.
Definition: TXNetFile.cxx:591
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:625
const char * GetHost() const
Definition: TUrl.h:70
UShort_t net2host(UShort_t x)
Definition: Bytes.h:577
#define NAME_MAXREDIRECTCOUNT
TXNetFile()
Definition: TXNetFile.h:97
#define DFLT_DFLTTCPWINDOWSIZE
TUrl fUrl
!URL of file
Definition: TFile.h:104
Int_t fD
File descriptor.
Definition: TFile.h:76
static Bool_t fgInitDone
Definition: TXNetFile.h:61
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Definition: TFile.cxx:4444
R__EXTERN TVirtualMonitoringWriter * gMonitoringWriter
static TFileStager * fgFileStager
Definition: TXNetFile.h:63
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1638
#define NAME_REDIRDOMAINALLOW_RE
static Long64_t GetFileBytesWritten()
Static function returning the total number of bytes written to all files.
Definition: TFile.cxx:4453
#define EnvPutInt(name, val)
Definition: XrdClientEnv.hh:47
virtual Bool_t ReadBufferAsync(Long64_t offs, Int_t len)
Implementation dealing with the xrootd server.
Definition: TXNetFile.cxx:696
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
#define DFLT_RECONNECTWAIT
#define NAME_RECONNECTWAIT
static void SetEnv()
Set the relevant environment variables.
Definition: TXNetFile.cxx:1201
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
virtual void ResetCache()
Reset the cache.
Definition: TXNetFile.cxx:1416
A doubly linked list.
Definition: TList.h:44
const char * GetUser() const
Definition: TUrl.h:68
static UInt_t GetOpenTimeout()
Returns open timeout (in ms).
Definition: TFile.cxx:4604
Int_t SysOpen(const char *pathname, Int_t flags, UInt_t mode)
Override TNetFile::SysOpen (see parent&#39;s method for more details).
Definition: TXNetFile.cxx:1170
#define NAME_CONNECTDOMAINALLOW_RE
Int_t fNetopt
Definition: TNetFile.h:42
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1622
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
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
static void FormUrl(TUrl uut, TString &uu)
Form url for rootd socket.
Definition: TXNetFile.cxx:170
#define XrdSysMutexHelper
Definition: XrdSysToOuc.h:17
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
#define EnvPutString(name, val)
Definition: XrdClientEnv.hh:46
EAsyncOpenStatus fAsyncOpenStatus
!Status of an asynchronous open request
Definition: TFile.h:103
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Flush()
Flushes un-written data.
Definition: TXNetFile.cxx:1061
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
char * Form(const char *fmt,...)
static std::atomic< Long64_t > fgBytesWrite
Number of bytes written by all TFile objects.
Definition: TFile.h:123
void * fInitMtx
Definition: TXNetFile.h:68
virtual Int_t GetBytesToPrefetch() const
Max number of bytes to prefetch.
Definition: TXNetFile.cxx:1425
static std::atomic< Int_t > fgReadCalls
Number of bytes read from all TFile objects.
Definition: TFile.h:126
TFileCacheRead * GetCacheRead(const TObject *tree=0) const
Return a pointer to the current read cache.
Definition: TFile.cxx:1215
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:732
static Int_t GetFileReadCalls()
Static function returning the total number of read calls from all files.
Definition: TFile.cxx:4461
TUrl fEndpointUrl
Definition: TNetFile.h:37
virtual void Init(Bool_t create)
Initialize a TFile object.
Definition: TFile.cxx:597
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:1789
Bool_t fWritable
True if directory is writable.
#define Printf
Definition: TGeoToOCC.h:18
#define gPerfStats
const Bool_t kFALSE
Definition: RtypesCore.h:88
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:4624
#define SafeDelete(p)
Definition: RConfig.h:529
Bool_t fIsRootd
Definition: TXNetFile.h:67
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
#define NAME_CONNECTDOMAINDENY_RE
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:89
virtual Bool_t WriteBuffer(const char *buffer, Int_t BufferLength)
Override TNetFile::WriteBuffer to deal with the xrootd server.
Definition: TXNetFile.cxx:860
#define ClassImp(name)
Definition: Rtypes.h:359
void Close(Option_t *option="")
Close remote file.
Definition: TNetFile.cxx:219
#define NAME_MULTISTREAMCNT
#define NAME_CONNECTTIMEOUT
#define NAME_SOCKS4PORT
double Double_t
Definition: RtypesCore.h:55
virtual Bool_t IsOpen() const
Return kTRUE if the file is open, kFALSE otherwise.
Definition: TXNetFile.cxx:983
virtual Int_t GetBufferSize() const
Return the buffer size to create new TKeys.
#define NAME_DFLTTCPWINDOWSIZE
virtual void Close(const Option_t *opt="")
Close the file (see TNetFile::Close() or TFile::Close() for more details).
Definition: TXNetFile.cxx:1037
#define TRUE
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition: TTimeStamp.h:71
TList * fOpenPhases
!Time info about open phases
Definition: TFile.h:107
static constexpr double s
static TFileStager * Open(const char *stager)
Open a stager, after having loaded the relevant plug-in.
TString fOption
File options.
Definition: TFile.h:85
virtual Bool_t SendFileReadProgress(TFile *)
Int_t GetPort() const
Definition: TUrl.h:81
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:1116
#define NAME_REQUESTTIMEOUT
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
Int_t SysClose(Int_t fd)
Override TNetFile::SysClose (see parent&#39;s method for more details).
Definition: TXNetFile.cxx:1146
virtual void Print(Option_t *option="") const
Print all objects in the file.
Definition: TFile.cxx:1606
#define DFLT_REQUESTTIMEOUT
#define DFLT_FIRSTCONNECTMAXCNT
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:1721
virtual void Print(Option_t *option="") const
Print the local statistics.
Definition: TXNetFile.cxx:1442
void MakeZombie()
Definition: TObject.h:49
#define DFLT_MULTISTREAMCNT
R__EXTERN Int_t gDebug
Definition: Rtypes.h:86
virtual Bool_t Matches(const char *s)
Definition: TFileStager.h:46
static Int_t GetClientProtocol()
Static method returning supported client protocol.
Definition: TSocket.cxx:1494
TInetAddress GetInetAddress() const
Definition: TSocket.h:132
Long64_t fArchiveOffset
!Offset at which file starts in archive
Definition: TFile.h:95
#define gDirectory
Definition: TDirectory.h:213
Bool_t IsOpen() const
Retruns kTRUE if file is open, kFALSE otherwise.
Definition: TNetFile.cxx:258
void SetUrl(const char *url)
Definition: TSocket.h:174
void Init(Bool_t create)
Initialize a TNetFile object.
Definition: TNetFile.cxx:247
Long64_t fOffset
!Seek offset cache
Definition: TFile.h:90
void SetService(const char *service)
Definition: TSocket.h:172
Bool_t fInitDone
!True if the file has been initialized
Definition: TFile.h:99
static void SetFileBytesRead(Long64_t bytes=0)
Definition: TFile.cxx:4478
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:902
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define DFLT_TRANSACTIONTIMEOUT
#define NAME_REDIRDOMAINDENY_RE
static constexpr double ns
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:763
Long64_t fBytesRead
Number of bytes read from this file.
Definition: TFile.h:70
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
#define DFLT_MAXREDIRECTCOUNT
void SynchronizeCacheSize()
Synchronize the cache size Alternative purging policy.
Definition: TXNetFile.cxx:1384
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:917
virtual void IgnoreSignal(ESignals sig, Bool_t ignore=kTRUE)
If ignore is true ignore the specified signal, else restore previous behaviour.
Definition: TSystem.cxx:601