Logo ROOT  
Reference Guide
TNetXNGFile.cxx
Go to the documentation of this file.
1 // @(#)root/netxng:$Id$
2 /*************************************************************************
3  * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
4  * All rights reserved. *
5  * *
6  * For the licensing terms see $ROOTSYS/LICENSE. *
7  * For the list of contributors see $ROOTSYS/README/CREDITS. *
8  *************************************************************************/
9 
10 ////////////////////////////////////////////////////////////////////////////////
11 // //
12 // TNetXNGFile //
13 // //
14 // Authors: Justin Salmon, Lukasz Janyst //
15 // CERN, 2013 //
16 // //
17 // Enables access to XRootD files using the new client. //
18 // //
19 ////////////////////////////////////////////////////////////////////////////////
20 
21 #include "TArchiveFile.h"
22 #include "TNetXNGFile.h"
23 #include "TEnv.h"
24 #include "TSystem.h"
25 #include "TTimeStamp.h"
26 #include "TVirtualPerfStats.h"
27 #include "TVirtualMonitoring.h"
28 #include <XrdCl/XrdClURL.hh>
29 #include <XrdCl/XrdClFile.hh>
30 #include <XrdCl/XrdClXRootDResponses.hh>
31 #include <XrdCl/XrdClDefaultEnv.hh>
32 #include <XrdVersion.hh>
33 #include <iostream>
34 
35 //------------------------------------------------------------------------------
36 // Open handler for async open requests
37 ////////////////////////////////////////////////////////////////////////////////
38 
39 class TAsyncOpenHandler: public XrdCl::ResponseHandler
40 {
41  public:
42  //------------------------------------------------------------------------
43  // Constructor
44  //////////////////////////////////////////////////////////////////////////
45 
46  TAsyncOpenHandler(TNetXNGFile *file)
47  {
48  fFile = file;
49  fFile->SetAsyncOpenStatus(TFile::kAOSInProgress);
50  }
51 
52  //------------------------------------------------------------------------
53  // Called when a response to open arrives
54  //////////////////////////////////////////////////////////////////////////
55 
56  virtual void HandleResponse(XrdCl::XRootDStatus *status,
57  XrdCl::AnyObject *response)
58  {
59  if (status->IsOK())
60  {
61  fFile->SetAsyncOpenStatus(TFile::kAOSSuccess);
62  }
63  else
64  {
65  fFile->SetAsyncOpenStatus(TFile::kAOSFailure);
66  }
67 
68  delete response;
69  delete status;
70  delete this;
71  }
72 
73  private:
74  TNetXNGFile *fFile;
75 };
76 
77 //------------------------------------------------------------------------------
78 // Async readv handler
79 ////////////////////////////////////////////////////////////////////////////////
80 
81 class TAsyncReadvHandler: public XrdCl::ResponseHandler
82 {
83  public:
84  //------------------------------------------------------------------------
85  // Constructor
86  //////////////////////////////////////////////////////////////////////////
87 
88  TAsyncReadvHandler(std::vector<XrdCl::XRootDStatus*> *statuses,
89  Int_t statusIndex,
90  TSemaphore *semaphore):
91  fStatuses(statuses), fStatusIndex(statusIndex), fSemaphore(semaphore) {}
92 
93 
94  //------------------------------------------------------------------------
95  // Handle readv response
96  //////////////////////////////////////////////////////////////////////////
97 
98  virtual void HandleResponse(XrdCl::XRootDStatus *status,
99  XrdCl::AnyObject *response)
100  {
101  fStatuses->at(fStatusIndex) = status;
102  fSemaphore->Post();
103  delete response;
104  delete this;
105  }
106 
107  private:
108  std::vector<XrdCl::XRootDStatus*> *fStatuses; // Pointer to status vector
109  Int_t fStatusIndex; // Index into status vector
110  TSemaphore *fSemaphore; // Synchronize the responses
111 };
112 
113 
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 /// Constructor
118 ///
119 /// param url: URL of the entry-point server to be contacted
120 /// param mode: initial file access mode
121 /// param title: title of the file (shown by ROOT browser)
122 /// param compress: compression level and algorithm
123 /// param netopt: TCP window size in bytes (unused)
124 /// param parallelopen: open asynchronously
125 
126 TNetXNGFile::TNetXNGFile(const char *url,
127  Option_t *mode,
128  const char *title,
129  Int_t compress,
130  Int_t netopt,
131  Bool_t parallelopen) :
132  TNetXNGFile(url,0,mode,title,compress,netopt,parallelopen){}
133 
134 TNetXNGFile::TNetXNGFile(const char *url,
135  const char *lurl,
136  Option_t *mode,
137  const char *title,
138  Int_t compress,
139  Int_t /*netopt*/,
140  Bool_t parallelopen) :
141  TFile((lurl ? lurl : url), "NET", title, compress)
142 {
143  using namespace XrdCl;
144 
145  // Set the log level
146  TString val = gSystem->Getenv("XRD_LOGLEVEL");
147  if (val.IsNull()) val = gEnv->GetValue("NetXNG.Debug", "");
148  if (!val.IsNull()) XrdCl::DefaultEnv::SetLogLevel(val.Data());
149 
150  // Remove any anchor from the url. It may have been used by the base TFile
151  // constructor to setup a TArchiveFile but we should not pass it to the xroot
152  // client as a part of the filename
153  {
154  TUrl urlnoanchor(url);
155  urlnoanchor.SetAnchor("");
156  fUrl = new URL(std::string(urlnoanchor.GetUrl()));
157  }
158 
159  fFile = new File();
160  fInitCondVar = new XrdSysCondVar();
161  fUrl->SetProtocol(std::string("root"));
162  fQueryReadVParams = 1;
163  fReadvIorMax = 2097136;
164  fReadvIovMax = 1024;
165 
166  if (ParseOpenMode(mode, fOption, fMode, kTRUE)<0) {
167  Error("Open", "could not parse open mode %s", mode);
168  MakeZombie();
169  return;
170  }
171 
172  // Map ROOT and xrootd environment
173  SetEnv();
174 
175  // Init the monitoring system
176  if (gMonitoringWriter) {
177  if (!fOpenPhases) {
178  fOpenPhases = new TList;
180  }
182  kFALSE);
183  }
184 
185  XRootDStatus status;
186  if (parallelopen) {
187  // Open the file asynchronously
188  TAsyncOpenHandler *handler = new TAsyncOpenHandler(this);
189  status = fFile->Open(fUrl->GetURL(), fMode, Access::None, handler);
190  if (!status.IsOK()) {
191  Error("Open", "%s", status.ToStr().c_str());
192  MakeZombie();
193  }
194  return;
195  }
196 
197  // Open the file synchronously
198  status = fFile->Open(fUrl->GetURL(), fMode);
199  if (!status.IsOK()) {
200 #if XrdVNUMBER >= 40000
201  if( status.code == errRedirect )
202  fNewUrl = status.GetErrorMessage().c_str();
203  else
204  Error("Open", "%s", status.ToStr().c_str());
205 #else
206  Error("Open", "%s", status.ToStr().c_str());
207 #endif
208  MakeZombie();
209  return;
210  }
211 
212  if( (fMode & OpenFlags::New) || (fMode & OpenFlags::Delete) ||
213  (fMode & OpenFlags::Update) )
214  fWritable = true;
215 
216  // Initialize the file
217  bool create = false;
218  if( (fMode & OpenFlags::New) || (fMode & OpenFlags::Delete) )
219  create = true;
220  TFile::Init(create);
221 
222  // Get the vector read limits
224 }
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// Destructor
228 
230 {
231  if (IsOpen())
232  Close();
233  delete fFile;
234  delete fUrl;
235  delete fInitCondVar;
236 }
237 
238 ////////////////////////////////////////////////////////////////////////////////
239 /// Initialize the file. Makes sure that the file is really open before
240 /// calling TFile::Init. It may block.
241 
243 {
244  using namespace XrdCl;
245 
246  if (fInitDone) {
247  if (gDebug > 1) Info("Init", "TFile::Init already called once");
248  return;
249  }
250 
251  // If the async open didn't return yet, wait for it
252  if (!IsOpen() && fAsyncOpenStatus == kAOSInProgress) {
253  fInitCondVar->Wait();
254  }
255 
256  // Notify the monitoring system
257  if (gMonitoringWriter)
259  kFALSE);
260 
261  // Initialize the file
262  TFile::Init(create);
263 
264  // Notify the monitoring system
265  if (gMonitoringWriter)
267  kTRUE);
268 
269  // Get the vector read limits
271 }
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 /// Get the file size. Returns -1 in the case that the file could not be
275 /// stat'ed.
276 
278 {
279  if (fArchive && fArchive->GetMember()) {
281  }
282 
283  using namespace XrdCl;
284 
285  // Check the file isn't a zombie or closed
286  if (!IsUseable())
287  return -1;
288 
289  bool forceStat = true;
290  if( fMode == XrdCl::OpenFlags::Read )
291  forceStat = false;
292 
293  StatInfo *info = 0;
294  if( !fFile->Stat( forceStat, info ).IsOK() )
295  return -1;
296  Long64_t size = info->GetSize();
297  delete info;
298  return size;
299 }
300 
301 ////////////////////////////////////////////////////////////////////////////////
302 /// Check if the file is open
303 
305 {
306  return fFile->IsOpen();
307 }
308 
309 ////////////////////////////////////////////////////////////////////////////////
310 /// Set the status of an asynchronous file open
311 
313 {
314  fAsyncOpenStatus = status;
315  // Unblock Init() if it is waiting
316  fInitCondVar->Signal();
317 }
318 
319 ////////////////////////////////////////////////////////////////////////////////
320 /// Close the file
321 ///
322 /// param option: if == "R", all TProcessIDs referenced by this file are
323 /// deleted (is this valid in xrootd context?)
324 
325 void TNetXNGFile::Close(const Option_t */*option*/)
326 {
327  TFile::Close();
328 
329  XrdCl::XRootDStatus status = fFile->Close();
330  if (!status.IsOK()) {
331  Error("Close", "%s", status.ToStr().c_str());
332  MakeZombie();
333  }
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// Reopen the file with the new access mode
338 ///
339 /// param mode: the new access mode
340 /// returns: 0 in case the mode was successfully modified, 1 in case
341 /// the mode did not change (was already as requested or wrong
342 /// input arguments) and -1 in case of failure, in which case
343 /// the file cannot be used anymore
344 
346 {
347  using namespace XrdCl;
348  TString newOpt;
349  OpenFlags::Flags mode;
350 
351  Int_t parseres = ParseOpenMode(modestr, newOpt, mode, kFALSE);
352 
353  // Only Read and Update are valid modes
354  if (parseres<0 || (mode != OpenFlags::Read && mode != OpenFlags::Update)) {
355  Error("ReOpen", "mode must be either READ or UPDATE, not %s", modestr);
356  return 1;
357  }
358 
359  // The mode is not really changing
360  if (mode == fMode || (mode == OpenFlags::Update
361  && fMode == OpenFlags::New)) {
362  return 1;
363  }
364 
365  XRootDStatus st = fFile->Close();
366  if (!st.IsOK()) {
367  Error("ReOpen", "%s", st.ToStr().c_str());
368  return 1;
369  }
370  fOption = newOpt;
371  fMode = mode;
372 
373  st = fFile->Open(fUrl->GetURL(), fMode);
374  if (!st.IsOK()) {
375  Error("ReOpen", "%s", st.ToStr().c_str());
376  return 1;
377  }
378 
379  return 0;
380 }
381 
382 ////////////////////////////////////////////////////////////////////////////////
383 /// Read a data chunk of the given size
384 ///
385 /// param buffer: a pointer to a buffer big enough to hold the data
386 /// param length: number of bytes to be read
387 /// returns: kTRUE in case of failure
388 
389 Bool_t TNetXNGFile::ReadBuffer(char *buffer, Int_t length)
390 {
391  return ReadBuffer(buffer, GetRelOffset(), length);
392 }
393 
394 ////////////////////////////////////////////////////////////////////////////////
395 /// Read a data chunk of the given size, starting from the given offset
396 ///
397 /// param buffer: a pointer to a buffer big enough to hold the data
398 /// param position: offset from the beginning of the file
399 /// param length: number of bytes to be read
400 /// returns: kTRUE in case of failure
401 
402 Bool_t TNetXNGFile::ReadBuffer(char *buffer, Long64_t position, Int_t length)
403 {
404  using namespace XrdCl;
405  if (gDebug > 0)
406  Info("ReadBuffer", "offset: %lld length: %d", position, length);
407 
408  // Check the file isn't a zombie or closed
409  if (!IsUseable())
410  return kTRUE;
411 
412  // Try to read from cache
413  SetOffset(position);
414  Int_t status;
415  if ((status = ReadBufferViaCache(buffer, length))) {
416  if (status == 2)
417  return kTRUE;
418  return kFALSE;
419  }
420 
421  Double_t start = 0;
422  if (gPerfStats) start = TTimeStamp();
423 
424  // Read the data
425  uint32_t bytesRead = 0;
426  XRootDStatus st = fFile->Read(fOffset, length, buffer, bytesRead);
427  if (gDebug > 0)
428  Info("ReadBuffer", "%s bytes read: %u", st.ToStr().c_str(), bytesRead);
429 
430  if (!st.IsOK()) {
431  Error("ReadBuffer", "%s", st.ToStr().c_str());
432  return kTRUE;
433  }
434 
435  if ((Int_t)bytesRead != length) {
436  Error("ReadBuffer", "error reading all requested bytes, got %u of %d",
437  bytesRead, length);
438  return kTRUE;
439  }
440 
441  // Bump the globals
442  fOffset += bytesRead;
443  fBytesRead += bytesRead;
444  fgBytesRead += bytesRead;
445  fReadCalls ++;
446  fgReadCalls ++;
447 
448  if (gPerfStats)
449  gPerfStats->FileReadEvent(this, (Int_t)bytesRead, start);
450 
451  if (gMonitoringWriter)
453 
454  return kFALSE;
455 }
456 
457 ////////////////////////////////////////////////////////////////////////////////
458 /// Read scattered data chunks in one operation
459 ///
460 /// param buffer: a pointer to a buffer big enough to hold all of the
461 /// requested data
462 /// param position: position[i] is the seek position of chunk i of len
463 /// length[i]
464 /// param length: length[i] is the length of the chunk at offset
465 /// position[i]
466 /// param nbuffs: number of chunks
467 /// returns: kTRUE in case of failure
468 
469 Bool_t TNetXNGFile::ReadBuffers(char *buffer, Long64_t *position, Int_t *length,
470  Int_t nbuffs)
471 {
472  using namespace XrdCl;
473 
474  // Check the file isn't a zombie or closed
475  if (!IsUseable())
476  return kTRUE;
477 
478  std::vector<ChunkList> chunkLists;
479  ChunkList chunks;
480  std::vector<XRootDStatus*> *statuses;
481  TSemaphore *semaphore;
482  Int_t totalBytes = 0;
483  Long64_t offset = 0;
484  char *cursor = buffer;
485 
486  Double_t start = 0;
487  if (gPerfStats) start = TTimeStamp();
488 
489  if (fArchiveOffset)
490  for (Int_t i = 0; i < nbuffs; i++)
491  position[i] += fArchiveOffset;
492 
493  // Build a list of chunks. Put the buffers in the ChunkInfo's
494  for (Int_t i = 0; i < nbuffs; ++i) {
495  totalBytes += length[i];
496 
497  // If the length is bigger than max readv size, split into smaller chunks
498  if (length[i] > fReadvIorMax) {
499  Int_t nsplit = length[i] / fReadvIorMax;
500  Int_t rem = length[i] % fReadvIorMax;
501  Int_t j;
502 
503  // Add as many max-size chunks as are divisible
504  for (j = 0; j < nsplit; ++j) {
505  offset = position[i] + (j * fReadvIorMax);
506  chunks.push_back(ChunkInfo(offset, fReadvIorMax, cursor));
507  cursor += fReadvIorMax;
508  }
509 
510  // Add the remainder
511  offset = position[i] + (j * fReadvIorMax);
512  chunks.push_back(ChunkInfo(offset, rem, cursor));
513  cursor += rem;
514  } else {
515  chunks.push_back(ChunkInfo(position[i], length[i], cursor));
516  cursor += length[i];
517  }
518 
519  // If there are more than or equal to max chunks, make another chunk list
520  if ((Int_t) chunks.size() == fReadvIovMax) {
521  chunkLists.push_back(chunks);
522  chunks = ChunkList();
523  } else if ((Int_t) chunks.size() > fReadvIovMax) {
524  chunkLists.push_back(ChunkList(chunks.begin(),
525  chunks.begin() + fReadvIovMax));
526  chunks = ChunkList(chunks.begin() + fReadvIovMax, chunks.end());
527  }
528  }
529 
530  // Push back the last chunk list
531  if( !chunks.empty() )
532  chunkLists.push_back(chunks);
533 
534  TAsyncReadvHandler *handler;
535  XRootDStatus status;
536  semaphore = new TSemaphore(0);
537  statuses = new std::vector<XRootDStatus*>(chunkLists.size());
538 
539  // Read asynchronously but wait for all responses
540  std::vector<ChunkList>::iterator it;
541  for (it = chunkLists.begin(); it != chunkLists.end(); ++it)
542  {
543  handler = new TAsyncReadvHandler(statuses, it - chunkLists.begin(),
544  semaphore);
545  status = fFile->VectorRead(*it, 0, handler);
546 
547  if (!status.IsOK()) {
548  Error("ReadBuffers", "%s", status.ToStr().c_str());
549  return kTRUE;
550  }
551  }
552 
553  // Wait for all responses
554  for (it = chunkLists.begin(); it != chunkLists.end(); ++it) {
555  semaphore->Wait();
556  }
557 
558  // Check for errors
559  for (it = chunkLists.begin(); it != chunkLists.end(); ++it) {
560  XRootDStatus *st = statuses->at(it - chunkLists.begin());
561 
562  if (!st->IsOK()) {
563  Error("ReadBuffers", "%s", st->ToStr().c_str());
564  for( ; it != chunkLists.end(); ++it )
565  {
566  st = statuses->at( it - chunkLists.begin() );
567  delete st;
568  }
569  delete statuses;
570  delete semaphore;
571 
572  return kTRUE;
573  }
574  delete st;
575  }
576 
577  // Bump the globals
578  fBytesRead += totalBytes;
579  fgBytesRead += totalBytes;
580  fReadCalls ++;
581  fgReadCalls ++;
582 
583  if (gPerfStats) {
584  fOffset = position[0];
585  gPerfStats->FileReadEvent(this, totalBytes, start);
586  }
587 
588  if (gMonitoringWriter)
590 
591  delete statuses;
592  delete semaphore;
593  return kFALSE;
594 }
595 
596 ////////////////////////////////////////////////////////////////////////////////
597 /// Write a data chunk
598 ///
599 /// param buffer: the data to be written
600 /// param length: the size of the buffer
601 /// returns: kTRUE in case of failure
602 
603 Bool_t TNetXNGFile::WriteBuffer(const char *buffer, Int_t length)
604 {
605  using namespace XrdCl;
606 
607  // Check the file isn't a zombie or closed
608  if (!IsUseable())
609  return kTRUE;
610 
611  if (!fWritable) {
612  if (gDebug > 1)
613  Info("WriteBuffer", "file not writable");
614  return kTRUE;
615  }
616 
617  // Check the write cache
618  Int_t status;
619  if ((status = WriteBufferViaCache(buffer, length))) {
620  if (status == 2)
621  return kTRUE;
622  return kFALSE;
623  }
624 
625  // Write the data
626  XRootDStatus st = fFile->Write(fOffset, length, buffer);
627  if (!st.IsOK()) {
628  Error("WriteBuffer", "%s", st.ToStr().c_str());
629  return kTRUE;
630  }
631 
632  // Bump the globals
633  fOffset += length;
634  fBytesWrite += length;
635  fgBytesWrite += length;
636 
637  return kFALSE;
638 }
639 
640 ////////////////////////////////////////////////////////////////////////////////
641 
643 {
644  if (!IsUseable())
645  return;
646 
647  if (!fWritable) {
648  if (gDebug > 1)
649  Info("Flush", "file not writable - do nothing");
650  return;
651  }
652 
653  FlushWriteCache();
654 
655  //
656  // Flush via the remote xrootd
657  XrdCl::XRootDStatus status = fFile->Sync();
658  if( !status.IsOK() )
659  Error("Flush", "%s", status.ToStr().c_str());
660 
661  if (gDebug > 1)
662  Info("Flush", "XrdClient::Sync succeeded.");
663 }
664 
665 ////////////////////////////////////////////////////////////////////////////////
666 /// Set the position within the file
667 ///
668 /// param offset: the new offset relative to position
669 /// param position: the relative position, either kBeg, kCur or kEnd
670 
671 void TNetXNGFile::Seek(Long64_t offset, ERelativeTo position)
672 {
673  SetOffset(offset, position);
674 }
675 
676 ////////////////////////////////////////////////////////////////////////////////
677 /// Parse a file open mode given as a string into a canonically formatted
678 /// output mode string and an integer code that the xroot client can use
679 ///
680 /// param in: the file open mode as a string (in)
681 /// modestr: open mode string after parsing (out)
682 /// mode: correctly parsed option mode code (out)
683 /// assumeRead: if the open mode is not recognised assume read (in)
684 /// returns: 0 in case the mode was successfully parsed,
685 /// -1 in case of failure
686 
688  XrdCl::OpenFlags::Flags &mode,
689  Bool_t assumeRead)
690 {
691  using namespace XrdCl;
692  modestr = ToUpper(TString(in));
693 
694  if (modestr == "NEW" || modestr == "CREATE") mode = OpenFlags::New;
695  else if (modestr == "RECREATE") mode = OpenFlags::Delete;
696  else if (modestr == "UPDATE") mode = OpenFlags::Update;
697  else if (modestr == "READ") mode = OpenFlags::Read;
698  else {
699  if (!assumeRead) {
700  return -1;
701  }
702  modestr = "READ";
703  mode = OpenFlags::Read;
704  }
705 
706  return 0;
707 }
708 
709 ////////////////////////////////////////////////////////////////////////////////
710 /// Check the file is open and isn't a zombie
711 
713 {
714  if (IsZombie()) {
715  Error("TNetXNGFile", "Object is in 'zombie' state");
716  return kFALSE;
717  }
718 
719  if (!IsOpen()) {
720  Error("TNetXNGFile", "The remote file is not open");
721  return kFALSE;
722  }
723 
724  return kTRUE;
725 }
726 
727 ////////////////////////////////////////////////////////////////////////////////
728 /// Find the server-specific readv config params. Returns kFALSE in case of
729 /// error, kTRUE otherwise.
730 
732 {
733  using namespace XrdCl;
734 
735  // Check the file isn't a zombie or closed
736  if (!IsUseable())
737  return kFALSE;
738 
739  if (!fQueryReadVParams)
740  return kTRUE;
741 
742 #if XrdVNUMBER >= 40000
743  std::string lasturl;
744  fFile->GetProperty("LastURL",lasturl);
745  URL lrl(lasturl);
746  //local redirect will split vector reads into multiple local reads anyway,
747  // so we are fine with the default values
748  if(lrl.GetProtocol().compare("file") == 0 &&
749  lrl.GetHostId().compare("localhost") == 0){
750  if (gDebug >= 1)
751  Info("GetVectorReadLimits","Local redirect, using default values");
752  return kTRUE;
753  }
754 
755  std::string dataServerStr;
756  if( !fFile->GetProperty( "DataServer", dataServerStr ) )
757  return kFALSE;
758  URL dataServer(dataServerStr);
759 #else
760  URL dataServer(fFile->GetDataServer());
761 #endif
762  FileSystem fs(dataServer);
763  Buffer arg;
764  Buffer *response;
765  arg.FromString(std::string("readv_ior_max readv_iov_max"));
766 
767  XRootDStatus status = fs.Query(QueryCode::Config, arg, response);
768  if (!status.IsOK())
769  return kFALSE;
770 
771  Ssiz_t from = 0;
772  TString token;
773 
774  std::vector<TString> resps;
775  while (TString(response->ToString()).Tokenize(token, from, "\n"))
776  resps.push_back(token);
777 
778  if (resps.size() != 2)
779  return kFALSE;
780 
781  if (resps[0].IsDigit())
782  fReadvIorMax = resps[0].Atoi();
783 
784  if (resps[1].IsDigit())
785  fReadvIovMax = resps[1].Atoi();
786 
787  delete response;
788 
789  // this is to workaround a dCache bug reported here:
790  // https://sft.its.cern.ch/jira/browse/ROOT-6639
791  if( fReadvIovMax == 0x7FFFFFFF )
792  {
793  fReadvIovMax = 1024;
794  fReadvIorMax = 2097136;
795  }
796 
797  return kTRUE;
798 }
799 
800 ////////////////////////////////////////////////////////////////////////////////
801 /// Map ROOT and xrootd environment variables
802 
804 {
805  XrdCl::Env *env = XrdCl::DefaultEnv::GetEnv();
806  const char *cenv = 0;
807  TString val;
808 
809  val = gEnv->GetValue("NetXNG.ConnectionWindow", "");
810  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_CONNECTIONWINDOW"))
811  || strlen(cenv) <= 0))
812  env->PutInt("ConnectionWindow", val.Atoi());
813 
814  val = gEnv->GetValue("NetXNG.ConnectionRetry", "");
815  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_CONNECTIONRETRY"))
816  || strlen(cenv) <= 0))
817  env->PutInt("RequestTimeout", val.Atoi());
818 
819  val = gEnv->GetValue("NetXNG.RequestTimeout", "");
820  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_REQUESTTIMEOUT"))
821  || strlen(cenv) <= 0))
822  env->PutInt("RequestTimeout", val.Atoi());
823 
824  val = gEnv->GetValue("NetXNG.SubStreamsPerChannel", "");
825  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_SUBSTREAMSPERCHANNEL"))
826  || strlen(cenv) <= 0))
827  env->PutInt("SubStreamsPerChannel", val.Atoi());
828 
829  val = gEnv->GetValue("NetXNG.TimeoutResolution", "");
830  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_TIMEOUTRESOLUTION"))
831  || strlen(cenv) <= 0))
832  env->PutInt("TimeoutResolution", val.Atoi());
833 
834  val = gEnv->GetValue("NetXNG.StreamErrorWindow", "");
835  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_STREAMERRORWINDOW"))
836  || strlen(cenv) <= 0))
837  env->PutInt("StreamErrorWindow", val.Atoi());
838 
839  val = gEnv->GetValue("NetXNG.RunForkHandler", "");
840  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_RUNFORKHANDLER"))
841  || strlen(cenv) <= 0))
842  env->PutInt("RunForkHandler", val.Atoi());
843 
844  val = gEnv->GetValue("NetXNG.RedirectLimit", "");
845  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_REDIRECTLIMIT"))
846  || strlen(cenv) <= 0))
847  env->PutInt("RedirectLimit", val.Atoi());
848 
849  val = gEnv->GetValue("NetXNG.WorkerThreads", "");
850  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_WORKERTHREADS"))
851  || strlen(cenv) <= 0))
852  env->PutInt("WorkerThreads", val.Atoi());
853 
854  val = gEnv->GetValue("NetXNG.CPChunkSize", "");
855  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_CPCHUNKSIZE"))
856  || strlen(cenv) <= 0))
857  env->PutInt("CPChunkSize", val.Atoi());
858 
859  val = gEnv->GetValue("NetXNG.CPParallelChunks", "");
860  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_CPPARALLELCHUNKS"))
861  || strlen(cenv) <= 0))
862  env->PutInt("CPParallelChunks", val.Atoi());
863 
864  val = gEnv->GetValue("NetXNG.PollerPreference", "");
865  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_POLLERPREFERENCE"))
866  || strlen(cenv) <= 0))
867  env->PutString("PollerPreference", val.Data());
868 
869  val = gEnv->GetValue("NetXNG.ClientMonitor", "");
870  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_CLIENTMONITOR"))
871  || strlen(cenv) <= 0))
872  env->PutString("ClientMonitor", val.Data());
873 
874  val = gEnv->GetValue("NetXNG.ClientMonitorParam", "");
875  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XRD_CLIENTMONITORPARAM"))
876  || strlen(cenv) <= 0))
877  env->PutString("ClientMonitorParam", val.Data());
878 
879  fQueryReadVParams = gEnv->GetValue("NetXNG.QueryReadVParams", 1);
880  env->PutInt( "MultiProtocol", gEnv->GetValue("TFile.CrossProtocolRedirects", 1));
881 
882  // Old style netrc file
883  TString netrc;
884  netrc.Form("%s/.rootnetrc", gSystem->HomeDirectory());
885  gSystem->Setenv("XrdSecNETRC", netrc.Data());
886 
887  // For authentication
888  val = gEnv->GetValue("XSec.Pwd.ALogFile", "");
889  if (val.Length() > 0)
890  gSystem->Setenv("XrdSecPWDALOGFILE", val.Data());
891 
892  val = gEnv->GetValue("XSec.Pwd.ServerPuk", "");
893  if (val.Length() > 0)
894  gSystem->Setenv("XrdSecPWDSRVPUK", val.Data());
895 
896  val = gEnv->GetValue("XSec.GSI.CAdir", "");
897  if (val.Length() > 0)
898  gSystem->Setenv("XrdSecGSICADIR", val.Data());
899 
900  val = gEnv->GetValue("XSec.GSI.CRLdir", "");
901  if (val.Length() > 0)
902  gSystem->Setenv("XrdSecGSICRLDIR", val.Data());
903 
904  val = gEnv->GetValue("XSec.GSI.CRLextension", "");
905  if (val.Length() > 0)
906  gSystem->Setenv("XrdSecGSICRLEXT", val.Data());
907 
908  val = gEnv->GetValue("XSec.GSI.UserCert", "");
909  if (val.Length() > 0)
910  gSystem->Setenv("XrdSecGSIUSERCERT", val.Data());
911 
912  val = gEnv->GetValue("XSec.GSI.UserKey", "");
913  if (val.Length() > 0)
914  gSystem->Setenv("XrdSecGSIUSERKEY", val.Data());
915 
916  val = gEnv->GetValue("XSec.GSI.UserProxy", "");
917  if (val.Length() > 0)
918  gSystem->Setenv("XrdSecGSIUSERPROXY", val.Data());
919 
920  val = gEnv->GetValue("XSec.GSI.ProxyValid", "");
921  if (val.Length() > 0)
922  gSystem->Setenv("XrdSecGSIPROXYVALID", val.Data());
923 
924  val = gEnv->GetValue("XSec.GSI.ProxyKeyBits", "");
925  if (val.Length() > 0)
926  gSystem->Setenv("XrdSecGSIPROXYKEYBITS", val.Data());
927 
928  val = gEnv->GetValue("XSec.GSI.ProxyForward", "0");
929  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XrdSecGSIPROXYDEPLEN"))
930  || strlen(cenv) <= 0))
931  gSystem->Setenv("XrdSecGSIPROXYDEPLEN", val.Data());
932 
933  val = gEnv->GetValue("XSec.GSI.CheckCRL", "1");
934  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XrdSecGSICRLCHECK"))
935  || strlen(cenv) <= 0))
936  gSystem->Setenv("XrdSecGSICRLCHECK", val.Data());
937 
938  val = gEnv->GetValue("XSec.GSI.DelegProxy", "0");
939  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XrdSecGSIDELEGPROXY"))
940  || strlen(cenv) <= 0))
941  gSystem->Setenv("XrdSecGSIDELEGPROXY", val.Data());
942 
943  val = gEnv->GetValue("XSec.GSI.SignProxy", "1");
944  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XrdSecGSISIGNPROXY"))
945  || strlen(cenv) <= 0))
946  gSystem->Setenv("XrdSecGSISIGNPROXY", val.Data());
947 
948  val = gEnv->GetValue("XSec.Pwd.AutoLogin", "1");
949  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XrdSecPWDAUTOLOG"))
950  || strlen(cenv) <= 0))
951  gSystem->Setenv("XrdSecPWDAUTOLOG", val.Data());
952 
953  val = gEnv->GetValue("XSec.Pwd.VerifySrv", "1");
954  if (val.Length() > 0 && (!(cenv = gSystem->Getenv("XrdSecPWDVERIFYSRV"))
955  || strlen(cenv) <= 0))
956  gSystem->Setenv("XrdSecPWDVERIFYSRV", val.Data());
957 }
TArchiveFile.h
TFile::fBytesWrite
Long64_t fBytesWrite
Number of bytes written to this file.
Definition: TFile.h:76
TVirtualPerfStats.h
TFile::fgBytesRead
static std::atomic< Long64_t > fgBytesRead
Number of bytes read by all TFile objects.
Definition: TFile.h:130
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TSystem::Setenv
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1645
Option_t
const char Option_t
Definition: RtypesCore.h:66
TFile::fReadCalls
Int_t fReadCalls
Number of read calls ( not counting the cache calls )
Definition: TFile.h:90
TString::Atoi
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1941
TFile::fBytesRead
Long64_t fBytesRead
Number of bytes read from this file.
Definition: TFile.h:77
TNetXNGFile::IsUseable
virtual Bool_t IsUseable() const
Check the file is open and isn't a zombie.
Definition: TNetXNGFile.cxx:712
gEnv
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
TTimeStamp.h
TString::Data
const char * Data() const
Definition: TString.h:369
TNetXNGFile::fReadvIorMax
Int_t fReadvIorMax
Definition: TNetXNGFile.h:51
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TFile::GetRelOffset
Long64_t GetRelOffset() const
Definition: TFile.h:243
TObject::Info
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:864
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:890
TFile::ERelativeTo
ERelativeTo
Definition: TFile.h:191
TCollection::SetOwner
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Definition: TCollection.cxx:746
TFile::kAOSInProgress
@ kAOSInProgress
Definition: TFile.h:66
TNetXNGFile::Init
virtual void Init(Bool_t create)
Initialize the file.
Definition: TNetXNGFile.cxx:242
TUrl::SetAnchor
void SetAnchor(const char *anchor)
Definition: TUrl.h:86
Int_t
int Int_t
Definition: RtypesCore.h:45
TNetXNGFile::IsOpen
virtual Bool_t IsOpen() const
Check if the file is open.
Definition: TNetXNGFile.cxx:304
TString::Length
Ssiz_t Length() const
Definition: TString.h:410
TEnv::GetValue
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
TNetXNGFile::SetEnv
virtual void SetEnv()
Map ROOT and xrootd environment variables.
Definition: TNetXNGFile.cxx:803
TEnv.h
TString
Basic string class.
Definition: TString.h:136
TNetXNGFile::Close
virtual void Close(const Option_t *option="")
Close the file.
Definition: TNetXNGFile.cxx:325
bool
TFile::WriteBufferViaCache
Int_t WriteBufferViaCache(const char *buf, Int_t len)
Write buffer via cache.
Definition: TFile.cxx:2435
TNetXNGFile::GetSize
virtual Long64_t GetSize() const
Get the file size.
Definition: TNetXNGFile.cxx:277
TArchiveMember::GetDecompressedSize
Long64_t GetDecompressedSize() const
Definition: TArchiveFile.h:92
TFile::fArchive
TArchiveFile * fArchive
!Archive file from which we read this file
Definition: TFile.h:98
TString::Form
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2309
TNetXNGFile::ParseOpenMode
Int_t ParseOpenMode(Option_t *in, TString &modestr, XrdCl::OpenFlags::Flags &mode, Bool_t assumeRead)
Parse a file open mode given as a string into a canonically formatted output mode string and an integ...
Definition: TNetXNGFile.cxx:687
TArchiveFile::GetMember
TArchiveMember * GetMember() const
Definition: TArchiveFile.h:51
TNetXNGFile::fReadvIovMax
Int_t fReadvIovMax
Definition: TNetXNGFile.h:52
TString::Tokenize
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2217
TFile::Init
virtual void Init(Bool_t create)
Initialize a TFile object.
Definition: TFile.cxx:555
TSystem.h
TVirtualMonitoringWriter::SendFileOpenProgress
virtual Bool_t SendFileOpenProgress(TFile *, TList *, const char *, Bool_t=kFALSE)
Definition: TVirtualMonitoring.h:72
TNetXNGFile::Seek
virtual void Seek(Long64_t offset, ERelativeTo position=kBeg)
Set the position within the file.
Definition: TNetXNGFile.cxx:671
TNetXNGFile::TNetXNGFile
TNetXNGFile()
Definition: TNetXNGFile.h:57
TNetXNGFile::ReadBuffers
virtual Bool_t ReadBuffers(char *buffer, Long64_t *position, Int_t *length, Int_t nbuffs)
Read scattered data chunks in one operation.
Definition: TNetXNGFile.cxx:469
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TNetXNGFile::fUrl
XrdCl::URL * fUrl
Definition: TNetXNGFile.h:47
gDebug
Int_t gDebug
Definition: TROOT.cxx:590
TNetXNGFile::fInitCondVar
XrdSysCondVar * fInitCondVar
Definition: TNetXNGFile.h:49
TNetXNGFile::fFile
XrdCl::File * fFile
Definition: TNetXNGFile.h:46
TNetXNGFile::ReOpen
virtual Int_t ReOpen(Option_t *modestr)
Reopen the file with the new access mode.
Definition: TNetXNGFile.cxx:345
TObject::MakeZombie
void MakeZombie()
Definition: TObject.h:49
TNetXNGFile::ReadBuffer
virtual Bool_t ReadBuffer(char *buffer, Int_t length)
Read a data chunk of the given size.
Definition: TNetXNGFile.cxx:389
TUrl::GetUrl
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:389
TUrl
This class represents a WWW compatible URL.
Definition: TUrl.h:33
TFile
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:54
TNetXNGFile::GetVectorReadLimits
virtual Bool_t GetVectorReadLimits()
Find the server-specific readv config params.
Definition: TNetXNGFile.cxx:731
TSemaphore
Definition: TSemaphore.h:29
TObject::IsZombie
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
gSystem
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
TFile::ReadBufferViaCache
Int_t ReadBufferViaCache(char *buf, Int_t len)
Read buffer via cache.
Definition: TFile.cxx:1805
TSystem::Getenv
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1661
XrdCl
Definition: TNetXNGFile.h:30
TFile::fOption
TString fOption
File options.
Definition: TFile.h:92
TNetXNGFile.h
TNetXNGFile::fMode
XrdCl::OpenFlags::Flags fMode
Definition: TNetXNGFile.h:48
TString::IsNull
Bool_t IsNull() const
Definition: TString.h:407
TFile::kAOSFailure
@ kAOSFailure
Definition: TFile.h:65
Double_t
double Double_t
Definition: RtypesCore.h:59
TFile::fAsyncOpenStatus
EAsyncOpenStatus fAsyncOpenStatus
!Status of an asynchronous open request
Definition: TFile.h:110
TSemaphore::Wait
Int_t Wait()
If the semaphore value is > 0 then decrement it and carry on, else block, waiting on the condition un...
Definition: TSemaphore.cxx:35
TFile::FlushWriteCache
Bool_t FlushWriteCache()
Flush the write cache if active.
Definition: TFile.cxx:1078
TFile::fgBytesWrite
static std::atomic< Long64_t > fgBytesWrite
Number of bytes written by all TFile objects.
Definition: TFile.h:129
TFile::fgReadCalls
static std::atomic< Int_t > fgReadCalls
Number of bytes read from all TFile objects.
Definition: TFile.h:132
TNetXNGFile::~TNetXNGFile
virtual ~TNetXNGFile()
Destructor.
Definition: TNetXNGFile.cxx:229
TDirectoryFile::fWritable
Bool_t fWritable
True if directory is writable.
Definition: TDirectoryFile.h:36
file
Definition: file.py:1
Long64_t
gMonitoringWriter
R__EXTERN TVirtualMonitoringWriter * gMonitoringWriter
Definition: TVirtualMonitoring.h:116
TNetXNGFile::SetAsyncOpenStatus
virtual void SetAsyncOpenStatus(EAsyncOpenStatus status)
Set the status of an asynchronous file open.
Definition: TNetXNGFile.cxx:312
ToUpper
TString ToUpper(const TString &s)
Return an upper-case version of str.
Definition: TString.cxx:1464
TFile::Close
void Close(Option_t *option="") override
Close a file.
Definition: TFile.cxx:879
TVirtualMonitoring.h
TNetXNGFile::Flush
virtual void Flush()
Synchronize a file's in-memory and on-disk states.
Definition: TNetXNGFile.cxx:642
TFile::kAOSSuccess
@ kAOSSuccess
Definition: TFile.h:66
TVirtualMonitoringWriter::SendFileReadProgress
virtual Bool_t SendFileReadProgress(TFile *)
Definition: TVirtualMonitoring.h:57
TFile::fArchiveOffset
Long64_t fArchiveOffset
!Offset at which file starts in archive
Definition: TFile.h:102
TNetXNGFile
Definition: TNetXNGFile.h:44
TTimeStamp
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition: TTimeStamp.h:71
TFile::fOpenPhases
TList * fOpenPhases
!Time info about open phases
Definition: TFile.h:114
TNetXNGFile::fNewUrl
TString fNewUrl
Definition: TNetXNGFile.h:54
TNetXNGFile::fQueryReadVParams
Int_t fQueryReadVParams
Definition: TNetXNGFile.h:53
TFile::EAsyncOpenStatus
EAsyncOpenStatus
Asynchronous open request status.
Definition: TFile.h:65
TSystem::HomeDirectory
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition: TSystem.cxx:886
TNetXNGFile::WriteBuffer
virtual Bool_t WriteBuffer(const char *buffer, Int_t length)
Write a data chunk.
Definition: TNetXNGFile.cxx:603
gPerfStats
#define gPerfStats
Definition: TVirtualPerfStats.h:98
TFile::fOffset
Long64_t fOffset
!Seek offset cache
Definition: TFile.h:97
TFile::fInitDone
Bool_t fInitDone
!True if the file has been initialized
Definition: TFile.h:106
TList
A doubly linked list.
Definition: TList.h:44
TFile::SetOffset
virtual void SetOffset(Long64_t offset, ERelativeTo pos=kBeg)
Set position from where to start reading.
Definition: TFile.cxx:2169
int