Logo ROOT   6.08/07
Reference Guide
TDavixFile.cxx
Go to the documentation of this file.
1 // @(#)root/net:$Id$
2 // Author: Adrien Devresse and Tigran Mkrtchyan
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2013, 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 // TDavixFile //
15 // //
16 // A TDavixFile is like a normal TFile except that it uses //
17 // libdavix to read/write remote files. //
18 // It supports HTTP and HTTPS in a number of dialects and options //
19 // e.g. S3 is one of them //
20 // Other caracteristics come from the full support of Davix, //
21 // e.g. full redirection support in any circumstance //
22 // //
23 // Authors: Adrien Devresse (CERN IT/SDC) //
24 // Tigran Mkrtchyan (DESY) //
25 // //
26 // Checks and ROOT5 porting: //
27 // Fabrizio Furano (CERN IT/SDC) //
28 // //
29 // September 2013 //
30 // //
31 //////////////////////////////////////////////////////////////////////////
32 
33 
34 #include "TDavixFile.h"
35 #include "TROOT.h"
36 #include "TSocket.h"
37 #include "Bytes.h"
38 #include "TError.h"
39 #include "TSystem.h"
40 #include "TEnv.h"
41 #include "TBase64.h"
42 #include "TVirtualPerfStats.h"
43 #include "TDavixFileInternal.h"
44 #include "TSocket.h"
45 
46 #include <errno.h>
47 #include <stdlib.h>
48 #include <unistd.h>
49 #include <fcntl.h>
50 #include <davix.hpp>
51 #include <sstream>
52 #include <string>
53 #include <cstring>
54 
55 
56 static const std::string VERSION = "0.2.0";
57 
58 static const std::string gUserAgent = "ROOT/" + std::string(gROOT->GetVersion()) +
59 " TDavixFile/" + VERSION + " davix/" + Davix::version();
60 
61 // The prefix that is used to find the variables in the gEnv
62 #define ENVPFX "Davix."
63 
65 
66 using namespace Davix;
67 
68 const char* grid_mode_opt = "grid_mode=yes";
69 const char* ca_check_opt = "ca_check=no";
70 const char* s3_seckey_opt = "s3seckey=";
71 const char* s3_acckey_opt = "s3acckey=";
72 const char* s3_region_opt = "s3region=";
73 const char* s3_token_opt = "s3token=";
74 const char* open_mode_read = "READ";
75 const char* open_mode_create = "CREATE";
76 const char* open_mode_new = "NEW";
77 const char* open_mode_update = "UPDATE";
78 
81 
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 
85 bool isno(const char *str)
86 {
87  if (!str) return false;
88 
89  if (!strcmp(str, "n") || !strcmp(str, "no") || !strcmp(str, "0") || !strcmp(str, "false")) return true;
90 
91  return false;
92 
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 
97 int configure_open_flag(const std::string &str, int old_flag)
98 {
99  if (strcasecmp(str.c_str(), open_mode_read) == 0)
100  old_flag |= O_RDONLY;
101  if ((strcasecmp(str.c_str(), open_mode_create) == 0)
102  || (strcasecmp(str.c_str(), open_mode_new) == 0)) {
103  old_flag |= (O_CREAT | O_WRONLY | O_TRUNC);
104  }
105  if ((strcasecmp(str.c_str(), open_mode_update) == 0)) {
106  old_flag |= (O_RDWR);
107  }
108  return old_flag;
109 }
110 
111 ////////////////////////////////////////////////////////////////////////////////
112 
114 {
115  Int_t log_level = (gEnv) ? gEnv->GetValue("Davix.Debug", 0) : 0;
116 
117  switch (log_level) {
118  case 0:
119  davix_set_log_level(0);
120  break;
121  case 1:
122  davix_set_log_level(DAVIX_LOG_WARNING);
123  break;
124  case 2:
125  davix_set_log_level(DAVIX_LOG_VERBOSE);
126  break;
127  case 3:
128  davix_set_log_level(DAVIX_LOG_DEBUG);
129  break;
130  default:
131  davix_set_log_level(DAVIX_LOG_ALL);
132  break;
133  }
134 }
135 
136 ///////////////////////////////////////////////////////////////////
137 // Authn implementation, Locate and get VOMS cred if exist
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 
141 static void TDavixFile_http_get_ucert(std::string &ucert, std::string &ukey)
142 {
143  char default_proxy[64];
144  const char *genvvar = 0, *genvvar1 = 0;
145  // The gEnv has higher priority, let's look for a proxy cert
146  genvvar = gEnv->GetValue("Davix.GSI.UserProxy", (const char *) NULL);
147  if (genvvar) {
148  ucert = ukey = genvvar;
149  if (gDebug > 0)
150  Info("TDavixFile_http_get_ucert", "Found proxy in gEnv");
151  return;
152  }
153 
154  // Try explicit environment for proxy
155  if (getenv("X509_USER_PROXY")) {
156  if (gDebug > 0)
157  Info("TDavixFile_http_get_ucert", "Found proxy in X509_USER_PROXY");
158  ucert = ukey = getenv("X509_USER_PROXY");
159  return;
160  }
161 
162  // Try with default location
163  snprintf(default_proxy, sizeof(default_proxy), "/tmp/x509up_u%d",
164  geteuid());
165 
166  if (access(default_proxy, R_OK) == 0) {
167  if (gDebug > 0)
168  Info("TDavixFile_http_get_ucert", "Found proxy in /tmp");
169  ucert = ukey = default_proxy;
170  return;
171  }
172 
173  // It seems we got no proxy, let's try to gather the keys
174  genvvar = gEnv->GetValue("Davix.GSI.UserCert", (const char *) NULL);
175  genvvar1 = gEnv->GetValue("Davix.GSI.UserKey", (const char *) NULL);
176  if (genvvar || genvvar1) {
177  if (gDebug > 0)
178  Info("TDavixFile_http_get_ucert", "Found cert and key in gEnv");
179 
180  ucert = genvvar;
181  ukey = genvvar1;
182  return;
183  }
184 
185  // try with X509_* environment
186  if (getenv("X509_USER_CERT"))
187  ucert = getenv("X509_USER_CERT");
188  if (getenv("X509_USER_KEY"))
189  ukey = getenv("X509_USER_KEY");
190 
191  if ((ucert.size() > 0) || (ukey.size() > 0)) {
192  if (gDebug > 0)
193  Info("TDavixFile_http_get_ucert", "Found cert and key in gEnv");
194  }
195  return;
196 
197 }
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 
201 static int TDavixFile_http_authn_cert_X509(void *userdata, const Davix::SessionInfo &info,
202  Davix::X509Credential *cert, Davix::DavixError **err)
203 {
204  (void) userdata; // keep quiete compilation warnings
205  (void) info;
206  std::string ucert, ukey;
207  TDavixFile_http_get_ucert(ucert, ukey);
208 
209  if (ucert.empty() || ukey.empty()) {
210  Davix::DavixError::setupError(err, "TDavixFile",
211  Davix::StatusCode::AuthentificationError,
212  "Could not set the user's proxy or certificate");
213  return -1;
214  }
215  return cert->loadFromFilePEM(ukey, ucert, "", err);
216 }
217 /////////////////////////////////////////////////////////////////////////////////////////////
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 
222 {
223  delete davixPosix;
224  delete davixParam;
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 
230 {
231  if (davix_context_s == NULL) {
232  TLockGuard guard(&createLock);
233  if (davix_context_s == NULL) {
234  davix_context_s = new Context();
235  }
236  }
237  return davix_context_s;
238 }
239 
240 ////////////////////////////////////////////////////////////////////////////////
241 
243 {
244  DavixError *davixErr = NULL;
245  Davix_fd *fd = davixPosix->open(davixParam, fUrl.GetUrl(), oflags, &davixErr);
246  if (fd == NULL) {
247  // An error has occurred.. We might be able to recover with metalinks.
248  // Try to populate the replicas vector. If successful, TFile will try
249  // the replicas one by one
250 
251  replicas.clear();
252  DavixError *davixErr2 = NULL;
253  try {
254  DavFile file(*davixContext, Davix::Uri(fUrl.GetUrl()));
255  std::vector<DavFile> replicasLocal = file.getReplicas(NULL, &davixErr2);
256  for(size_t i = 0; i < replicasLocal.size(); i++) {
257  replicas.push_back(replicasLocal[i].getUri().getString());
258  }
259  }
260  catch(...) {}
261  DavixError::clearError(&davixErr2);
262 
263  if(replicas.empty()) {
264  // I was unable to retrieve a list of replicas: propagate the original
265  // error.
266  Error("DavixOpen", "can not open file with davix: %s (%d)",
267  davixErr->getErrMsg().c_str(), davixErr->getStatus());
268  }
269  DavixError::clearError(&davixErr);
270  } else {
271  // setup ROOT style read
272  davixPosix->fadvise(fd, 0, 300, Davix::AdviseRandom);
273  }
274 
275  return fd;
276 }
277 
278 ////////////////////////////////////////////////////////////////////////////////
279 
281 {
282  DavixError *davixErr = NULL;
283  if (davixFd != NULL && davixPosix->close(davixFd, &davixErr)) {
284  Error("DavixClose", "can not to close file with davix: %s (%d)",
285  davixErr->getErrMsg().c_str(), davixErr->getStatus());
286  DavixError::clearError(&davixErr);
287  }
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 
293 {
294  const char *env_var = NULL;
295 
296  if (gDebug > 1)
297  Info("enableGridMode", " grid mode enabled !");
298 
299  if( ( env_var = getenv("X509_CERT_DIR")) == NULL){
300  env_var= "/etc/grid-security/certificates/";
301  }
302  davixParam->addCertificateAuthorityPath(env_var);
303  if (gDebug > 0)
304  Info("enableGridMode", "Adding CAdir %s", env_var);
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 
309 // Only newer versions of davix support setting the S3 region and STS tokens.
310 // But it's only possible to check the davix version through a #define starting from
311 // 0.6.4.
312 // I have no way to check if setAwsRegion is available, so let's use SFINAE. :-)
313 // The first overload will always take priority - if "substitution" fails, meaning
314 // setAwsRegion is not there, the compiler will pick the second overload with
315 // the ellipses. (...)
316 
317 template<typename TRequestParams = Davix::RequestParams>
318 static auto awsRegion(TRequestParams *parameters, const char *region)
319  -> decltype(parameters->setAwsRegion(region), void())
320 {
321  if (gDebug > 1) Info("awsRegion", "Setting S3 Region to '%s' - v4 signature will be used", region);
322  parameters->setAwsRegion(region);
323 }
324 
325 template<typename TRequestParams = Davix::RequestParams>
326 static void awsRegion(...) {
327  Warning("setAwsRegion", "Unable to set AWS region, not supported by this version of davix");
328 }
329 
330 // Identical SFINAE trick as above for setAwsToken
331 template<typename TRequestParams = Davix::RequestParams>
332 static auto awsToken(TRequestParams *parameters, const char *token)
333  -> decltype(parameters->setAwsToken(token), void())
334 {
335  if (gDebug > 1) Info("awsToken", "Setting S3 STS temporary credentials");
336  parameters->setAwsToken(token);
337 }
338 
339 template<typename TRequestParams = Davix::RequestParams>
340 static void awsToken(...) {
341  Warning("awsToken", "Unable to set AWS token, not supported by this version of davix");
342 }
343 
344 void TDavixFileInternal::setAwsRegion(const std::string & region) {
345  if(!region.empty()) {
346  awsRegion(davixParam, region.c_str());
347  }
348 }
349 
350 void TDavixFileInternal::setAwsToken(const std::string & token) {
351  if(!token.empty()) {
352  awsToken(davixParam, token.c_str());
353  }
354 }
355 
356 void TDavixFileInternal::setS3Auth(const std::string &secret, const std::string &access,
357  const std::string &region, const std::string &token)
358 {
359  if (gDebug > 1) {
360  Info("setS3Auth", " Aws S3 tokens configured");
361  }
362  davixParam->setAwsAuthorizationKeys(secret, access);
363  davixParam->setProtocol(RequestProtocol::AwsS3);
364 
365  setAwsRegion(region);
366  setAwsToken(token);
367 }
368 
369 ////////////////////////////////////////////////////////////////////////////////
370 
372 {
373  const char *env_var = NULL, *env_var2 = NULL;
374  // default opts
375  davixParam->setTransparentRedirectionSupport(true);
376  davixParam->setClientCertCallbackX509(&TDavixFile_http_authn_cert_X509, NULL);
377 
378  // setup CADIR
379  env_var = gEnv->GetValue("Davix.GSI.CAdir", (const char *) NULL);
380  if (env_var) {
381  davixParam->addCertificateAuthorityPath(env_var);
382  if (gDebug > 0)
383  Info("parseConfig", "Add CAdir: %s", env_var);
384  }
385  // CA Check
386  bool ca_check_local = !isno(gEnv->GetValue("Davix.GSI.CACheck", (const char *)"y"));
387  davixParam->setSSLCAcheck(ca_check_local);
388  if (gDebug > 0)
389  Info("parseConfig", "Setting CAcheck to %s", ((ca_check_local) ? ("true") : ("false")));
390 
391  // S3 Auth
392  if (((env_var = gEnv->GetValue("Davix.S3.SecretKey", getenv("S3_SECRET_KEY"))) != NULL)
393  && ((env_var2 = gEnv->GetValue("Davix.S3.AccessKey", getenv("S3_ACCESS_KEY"))) != NULL)) {
394  Info("parseConfig", "Setting S3 SecretKey and AccessKey. Access Key : %s ", env_var2);
395  davixParam->setAwsAuthorizationKeys(env_var, env_var2);
396 
397  // need to set region?
398  if ( (env_var = gEnv->GetValue("Davix.S3.Region", getenv("S3_REGION"))) != NULL) {
399  setAwsRegion(env_var);
400  }
401  // need to set STS token?
402  if( (env_var = gEnv->GetValue("Davix.S3.Token", getenv("S3_TOKEN"))) != NULL) {
403  setAwsToken(env_var);
404  }
405  }
406 
407  env_var = gEnv->GetValue("Davix.GSI.GridMode", (const char *)"y");
408  if (!isno(env_var))
409  enableGridMode();
410 }
411 
412 ////////////////////////////////////////////////////////////////////////////////
413 /// intput params
414 
416 {
417  std::stringstream ss(option);
418  std::string item;
419  std::vector<std::string> parsed_options;
420  // parameters
421  std::string s3seckey, s3acckey, s3region, s3token;
422 
423  while (std::getline(ss, item, ' ')) {
424  parsed_options.push_back(item);
425  }
426 
427  for (std::vector<std::string>::iterator it = parsed_options.begin(); it < parsed_options.end(); ++it) {
428  // grid mode option
429  if ((strcasecmp(it->c_str(), grid_mode_opt)) == 0) {
430  enableGridMode();
431  }
432  // ca check option
433  if ((strcasecmp(it->c_str(), ca_check_opt)) == 0) {
434  davixParam->setSSLCAcheck(false);
435  }
436  // s3 sec key
437  if (strncasecmp(it->c_str(), s3_seckey_opt, strlen(s3_seckey_opt)) == 0) {
438  s3seckey = std::string(it->c_str() + strlen(s3_seckey_opt));
439  }
440  // s3 access key
441  if (strncasecmp(it->c_str(), s3_acckey_opt, strlen(s3_acckey_opt)) == 0) {
442  s3acckey = std::string(it->c_str() + strlen(s3_acckey_opt));
443  }
444  // s3 region
445  if (strncasecmp(it->c_str(), s3_region_opt, strlen(s3_region_opt)) == 0) {
446  s3region = std::string(it->c_str() + strlen(s3_region_opt));
447  }
448  // s3 sts token
449  if (strncasecmp(it->c_str(), s3_token_opt, strlen(s3_token_opt)) == 0) {
450  s3token = std::string(it->c_str() + strlen(s3_token_opt));
451  }
452  // open mods
453  oflags = configure_open_flag(*it, oflags);
454  }
455 
456  if (s3seckey.size() > 0) {
457  setS3Auth(s3seckey, s3acckey, s3region, s3token);
458  }
459 
460  if (oflags == 0) // default open mode
461  oflags = O_RDONLY;
462 }
463 
464 ////////////////////////////////////////////////////////////////////////////////
465 
467 {
468  davixPosix = new DavPosix(davixContext);
469  davixParam = new RequestParams();
470  davixParam->setUserAgent(gUserAgent);
471  davixParam->setMetalinkMode(Davix::MetalinkMode::Disable);
473  parseConfig();
474  parseParams(opt);
475 }
476 
477 ////////////////////////////////////////////////////////////////////////////////
478 
479 Int_t TDavixFileInternal::DavixStat(const char *url, struct stat *st)
480 {
481  DavixError *davixErr = NULL;
482 
483  if (davixPosix->stat(davixParam, url, st, &davixErr) < 0) {
484 
485  Error("DavixStat", "can not stat the file with davix: %s (%d)",
486  davixErr->getErrMsg().c_str(), davixErr->getStatus());
487  DavixError::clearError(&davixErr);
488  return 0;
489  }
490  return 1;
491 }
492 
493 /////////////////////////////////////////////////////////////////////////////////////////////
494 
495 ////////////////////////////////////////////////////////////////////////////////
496 
497 TDavixFile::TDavixFile(const char *url, Option_t *opt, const char *ftitle, Int_t compress) : TFile(url, "WEB"),
498  d_ptr(new TDavixFileInternal(fUrl, opt))
499 {
500  (void) ftitle;
501  (void) compress;
502  Init(kFALSE);
503 }
504 
505 ////////////////////////////////////////////////////////////////////////////////
506 
508 {
509  d_ptr->Close();
510  delete d_ptr;
511 }
512 
513 ////////////////////////////////////////////////////////////////////////////////
514 
516 {
517  (void) init;
518  //initialize davix
519  d_ptr->init();
520  // pre-open file
521  if ((d_ptr->getDavixFileInstance()) == NULL){
522  MakeZombie();
523  gDirectory = gROOT;
524  return;
525  }
527  fOffset = 0;
528  fD = -2; // so TFile::IsOpen() will return true when in TFile::~TFi */
529 }
530 
532  std::vector<std::string> replicas = d_ptr->getReplicas();
533  TString newUrl;
534  if(!replicas.empty()) {
535  std::stringstream ss;
536  for(size_t i = 0; i < replicas.size(); i++) {
537  ss << replicas[i];
538  if(i != replicas.size()-1) ss << "|";
539  }
540  newUrl = ss.str();
541  }
542  return newUrl;
543 }
544 
545 ////////////////////////////////////////////////////////////////////////////////
546 /// Set position from where to start reading.
547 
549 {
550  TLockGuard guard(&(d_ptr->positionLock));
551  switch (pos) {
552  case kBeg:
553  fOffset = offset + fArchiveOffset;
554  break;
555  case kCur:
556  fOffset += offset;
557  break;
558  case kEnd:
559  // this option is not used currently in the ROOT code
560  if (fArchiveOffset)
561  Error("Seek", "seeking from end in archive is not (yet) supported");
562  fOffset = fEND - offset; // is fEND really EOF or logical EOF?
563  break;
564  }
565 
566  if (gDebug > 1)
567  Info("Seek", " move cursor to %lld"
568  , fOffset);
569 }
570 
571 ////////////////////////////////////////////////////////////////////////////////
572 /// Read specified byte range from remote file via HTTP.
573 /// Returns kTRUE in case of error.
574 
576 {
577  TLockGuard guard(&(d_ptr->positionLock));
578  Davix_fd *fd;
579  if ((fd = d_ptr->getDavixFileInstance()) == NULL)
580  return kTRUE;
581  Long64_t ret = DavixReadBuffer(fd, buf, len);
582  if (ret < 0)
583  return kTRUE;
584 
585  if (gDebug > 1)
586  Info("ReadBuffer", "%lld bytes of data read sequentially"
587  " (%d requested)", ret, len);
588 
589  return kFALSE;
590 }
591 
592 ////////////////////////////////////////////////////////////////////////////////
593 
595 {
596  Davix_fd *fd;
597  if ((fd = d_ptr->getDavixFileInstance()) == NULL)
598  return kTRUE;
599 
600  Long64_t ret = DavixPReadBuffer(fd, buf, pos, len);
601  if (ret < 0)
602  return kTRUE;
603 
604  if (gDebug > 1)
605  Info("ReadBuffer", "%lld bytes of data read from offset"
606  " %lld (%d requested)", ret, pos, len);
607  return kFALSE;
608 }
609 
610 ////////////////////////////////////////////////////////////////////////////////
611 
613 {
614  Davix_fd *fd;
615  if ((fd = d_ptr->getDavixFileInstance()) == NULL)
616  return kFALSE;
617 
618  d_ptr->davixPosix->fadvise(fd, static_cast<dav_off_t>(offs), static_cast<dav_size_t>(len), Davix::AdviseRandom);
619 
620  if (gDebug > 1)
621  Info("ReadBufferAsync", "%d bytes of data prefected from offset"
622  " %lld ", len, offs);
623  return kFALSE;
624 }
625 
626 ////////////////////////////////////////////////////////////////////////////////
627 
628 Bool_t TDavixFile::ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
629 {
630  Davix_fd *fd;
631  if ((fd = d_ptr->getDavixFileInstance()) == NULL)
632  return kTRUE;
633 
634  Long64_t ret = DavixReadBuffers(fd, buf, pos, len, nbuf);
635  if (ret < 0)
636  return kTRUE;
637 
638  if (gDebug > 1)
639  Info("ReadBuffers", "%lld bytes of data read from a list of %d buffers",
640  ret, nbuf);
641 
642  return kFALSE;
643 }
644 
645 ////////////////////////////////////////////////////////////////////////////////
646 
647 Bool_t TDavixFile::WriteBuffer(const char *buf, Int_t len)
648 {
649  Davix_fd *fd;
650  if ((fd = d_ptr->getDavixFileInstance()) == NULL)
651  return kTRUE;
652 
653  Long64_t ret = DavixWriteBuffer(fd, buf, len);
654  if (ret < 0)
655  return kTRUE;
656 
657  if (gDebug > 1)
658  Info("WriteBuffer", "%lld bytes of data write"
659  " %d requested", ret, len);
660  return kFALSE;
661 }
662 
663 ////////////////////////////////////////////////////////////////////////////////
664 
666 {
667  d_ptr->davixParam->setSSLCAcheck((bool)check);
668 }
669 
670 ////////////////////////////////////////////////////////////////////////////////
671 
673 {
675 }
676 
677 ////////////////////////////////////////////////////////////////////////////////
678 
680 {
681  TLockGuard l(&(openLock));
682  std::vector<void *>::iterator f = std::find(dirdVec.begin(), dirdVec.end(), fd);
683  return (f != dirdVec.end());
684 }
685 
686 ////////////////////////////////////////////////////////////////////////////////
687 
689 {
690  TLockGuard l(&(openLock));
691  dirdVec.push_back(fd);
692 }
693 
694 ////////////////////////////////////////////////////////////////////////////////
695 
697 {
698  TLockGuard l(&(openLock));
699  std::vector<void *>::iterator f = std::find(dirdVec.begin(), dirdVec.end(), fd);
700  if (f != dirdVec.end())
701  dirdVec.erase(f);
702 }
703 
704 ////////////////////////////////////////////////////////////////////////////////
705 
707 {
708  struct stat st;
709  Int_t ret = d_ptr->DavixStat(fUrl.GetUrl(), &st);
710  if (ret) {
711  if (gDebug > 1)
712  Info("GetSize", "file size requested: %lld", (Long64_t)st.st_size);
713  return st.st_size;
714  }
715  return -1;
716 }
717 
718 ////////////////////////////////////////////////////////////////////////////////
719 
721 {
722  if (gPerfStats)
723  return TTimeStamp();
724  return 0;
725 }
726 
727 ////////////////////////////////////////////////////////////////////////////////
728 /// set TFile state info
729 
730 void TDavixFile::eventStop(Double_t t_start, Long64_t len, bool read)
731 {
732  if(read) {
733  fBytesRead += len;
734  fReadCalls += 1;
735 
738 
739  if (gPerfStats)
740  gPerfStats->FileReadEvent(this, (Int_t) len, t_start);
741  } else {
742  fBytesWrite += len;
744  }
745 }
746 
747 ////////////////////////////////////////////////////////////////////////////////
748 
749 Long64_t TDavixFile::DavixReadBuffer(Davix_fd *fd, char *buf, Int_t len)
750 {
751  DavixError *davixErr = NULL;
752  Double_t start_time = eventStart();
753 
754  Long64_t ret = d_ptr->davixPosix->pread(fd, buf, len, fOffset, &davixErr);
755  if (ret < 0) {
756  Error("DavixReadBuffer", "can not read data with davix: %s (%d)",
757  davixErr->getErrMsg().c_str(), davixErr->getStatus());
758  DavixError::clearError(&davixErr);
759  } else {
760  fOffset += ret;
761  eventStop(start_time, ret);
762  }
763 
764  return ret;
765 }
766 
767 ////////////////////////////////////////////////////////////////////////////////
768 
769 Long64_t TDavixFile::DavixWriteBuffer(Davix_fd *fd, const char *buf, Int_t len)
770 {
771  DavixError *davixErr = NULL;
772  Double_t start_time = eventStart();
773 
774  Long64_t ret = d_ptr->davixPosix->pwrite(fd, buf, len, fOffset, &davixErr);
775  if (ret < 0) {
776  Error("DavixWriteBuffer", "can not write data with davix: %s (%d)",
777  davixErr->getErrMsg().c_str(), davixErr->getStatus());
778  DavixError::clearError(&davixErr);
779  } else {
780  fOffset += ret;
781  eventStop(start_time, ret, false);
782  }
783 
784  return ret;
785 }
786 
787 ////////////////////////////////////////////////////////////////////////////////
788 
789 Long64_t TDavixFile::DavixPReadBuffer(Davix_fd *fd, char *buf, Long64_t pos, Int_t len)
790 {
791  DavixError *davixErr = NULL;
792  Double_t start_time = eventStart();
793 
794  Long64_t ret = d_ptr->davixPosix->pread(fd, buf, len, pos, &davixErr);
795  if (ret < 0) {
796  Error("DavixPReadBuffer", "can not read data with davix: %s (%d)",
797  davixErr->getErrMsg().c_str(), davixErr->getStatus());
798  DavixError::clearError(&davixErr);
799  } else {
800  eventStop(start_time, ret);
801  }
802 
803 
804  return ret;
805 }
806 
807 ////////////////////////////////////////////////////////////////////////////////
808 
809 Long64_t TDavixFile::DavixReadBuffers(Davix_fd *fd, char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
810 {
811  DavixError *davixErr = NULL;
812  Double_t start_time = eventStart();
813  DavIOVecInput in[nbuf];
814  DavIOVecOuput out[nbuf];
815 
816  int lastPos = 0;
817  for (Int_t i = 0; i < nbuf; ++i) {
818  in[i].diov_buffer = &buf[lastPos];
819  in[i].diov_offset = pos[i];
820  in[i].diov_size = len[i];
821  lastPos += len[i];
822  }
823 
824  Long64_t ret = d_ptr->davixPosix->preadVec(fd, in, out, nbuf, &davixErr);
825  if (ret < 0) {
826  Error("DavixReadBuffers", "can not read data with davix: %s (%d)",
827  davixErr->getErrMsg().c_str(), davixErr->getStatus());
828  DavixError::clearError(&davixErr);
829  } else {
830  eventStop(start_time, ret);
831  }
832 
833  return ret;
834 }
static void ConfigureDavixLogLevel()
Definition: TDavixFile.cxx:113
Definition: TMutex.h:34
double read(const std::string &file_name)
reading
virtual Long64_t GetSize() const
Returns the current file size.
Definition: TDavixFile.cxx:706
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:899
static const std::string gUserAgent
Definition: TDavixFile.cxx:58
const char * s3_seckey_opt
Definition: TDavixFile.cxx:70
long long Long64_t
Definition: RtypesCore.h:69
Long64_t fBytesWrite
Number of bytes written to this file.
Definition: TFile.h:67
const char * open_mode_read
Definition: TDavixFile.cxx:74
const char * open_mode_update
Definition: TDavixFile.cxx:77
void Init(Bool_t init)
Initialize a TFile object.
Definition: TDavixFile.cxx:515
const char Option_t
Definition: RtypesCore.h:62
static void TDavixFile_http_get_ucert(std::string &ucert, std::string &ukey)
Definition: TDavixFile.cxx:141
void setS3Auth(const std::string &secret, const std::string &access, const std::string &region, const std::string &token)
Definition: TDavixFile.cxx:356
static auto awsToken(TRequestParams *parameters, const char *token) -> decltype(parameters->setAwsToken(token), void())
Definition: TDavixFile.cxx:332
Davix::RequestParams * davixParam
Small helper to keep current directory context.
Davix_fd * Open()
Definition: TDavixFile.cxx:242
static void SetFileReadCalls(Int_t readcalls=0)
Definition: TFile.cxx:4415
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read specified byte range from remote file via HTTP.
Definition: TDavixFile.cxx:575
#define gROOT
Definition: TROOT.h:364
void addDird(void *fd)
Definition: TDavixFile.cxx:688
Double_t eventStart()
Definition: TDavixFile.cxx:720
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TDavixFileInternal * d_ptr
Definition: TDavixFile.h:68
const Bool_t kFALSE
Definition: Rtypes.h:92
Long64_t DavixReadBuffer(Davix_fd *fd, char *buf, Int_t len)
Definition: TDavixFile.cxx:749
ERelativeTo
Definition: TFile.h:169
Int_t fReadCalls
Number of read calls ( not counting the cache calls )
Definition: TFile.h:81
virtual Bool_t WriteBuffer(const char *buffer, Int_t bufferLength)
Write a buffer to the file.
Definition: TDavixFile.cxx:647
Davix_fd * getDavixFileInstance()
void setAwsRegion(const std::string &region)
Definition: TDavixFile.cxx:344
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:387
const char * open_mode_create
Definition: TDavixFile.cxx:75
Long64_t DavixReadBuffers(Davix_fd *fd, char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Definition: TDavixFile.cxx:809
static void SetFileBytesWritten(Long64_t bytes=0)
Definition: TFile.cxx:4412
TUrl fUrl
!URL of file
Definition: TFile.h:102
Int_t fD
File descriptor.
Definition: TFile.h:74
Davix::DavPosix * davixPosix
virtual void Seek(Long64_t offset, ERelativeTo pos=kBeg)
Set position from where to start reading.
Definition: TDavixFile.cxx:548
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Definition: TFile.cxx:4375
static Long64_t GetFileBytesWritten()
Static function returning the total number of bytes written to all files.
Definition: TFile.cxx:4384
void Info(const char *location, const char *msgfmt,...)
static TMutex createLock
Definition: TDavixFile.cxx:79
void Error(const char *location, const char *msgfmt,...)
Int_t DavixStat(const char *url, struct stat *st)
Definition: TDavixFile.cxx:479
static Context * davix_context_s
Definition: TDavixFile.cxx:80
Long64_t DavixWriteBuffer(Davix_fd *fd, const char *buf, Int_t len)
Definition: TDavixFile.cxx:769
Long64_t fEND
Last used byte in file.
Definition: TFile.h:71
virtual Bool_t ReadBufferAsync(Long64_t offs, Int_t len)
Definition: TDavixFile.cxx:612
const char * s3_token_opt
Definition: TDavixFile.cxx:73
virtual TString GetNewUrl()
Definition: TDavixFile.cxx:531
static Davix::Context * getDavixInstance()
Definition: TDavixFile.cxx:229
std::vector< std::string > getReplicas()
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:496
void removeDird(void *fd)
Definition: TDavixFile.cxx:696
static auto awsRegion(TRequestParams *parameters, const char *region) -> decltype(parameters->setAwsRegion(region), void())
Definition: TDavixFile.cxx:318
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
bool isMyDird(void *fd)
Definition: TDavixFile.cxx:679
TLine * l
Definition: textangle.C:4
static Int_t GetFileReadCalls()
Static function returning the total number of read calls from all files.
Definition: TFile.cxx:4392
void eventStop(Double_t t, Long64_t len, bool read=true)
set TFile state info
Definition: TDavixFile.cxx:730
void Warning(const char *location, const char *msgfmt,...)
bool isno(const char *str)
Definition: TDavixFile.cxx:85
virtual void Init(Bool_t create)
Initialize a TFile object.
Definition: TFile.cxx:584
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: TDavixFile.cxx:628
#define gPerfStats
const char * grid_mode_opt
Definition: TDavixFile.cxx:68
static const std::string VERSION
Definition: TDavixFile.cxx:56
#define ClassImp(name)
Definition: Rtypes.h:279
double f(double x)
static Int_t init()
double Double_t
Definition: RtypesCore.h:55
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition: TTimeStamp.h:76
const char * s3_acckey_opt
Definition: TDavixFile.cxx:71
int configure_open_flag(const std::string &str, int old_flag)
Definition: TDavixFile.cxx:97
const char * s3_region_opt
Definition: TDavixFile.cxx:72
void enableGridMode()
Enable the grid mode The grid Mode configure automatically all grid-CA path, VOMS authentication and ...
Definition: TDavixFile.cxx:672
typedef void((*Func_t)())
Definition: file.py:1
void setAwsToken(const std::string &token)
Definition: TDavixFile.cxx:350
const char * ca_check_opt
Definition: TDavixFile.cxx:69
void MakeZombie()
Definition: TObject.h:47
#define NULL
Definition: Rtypes.h:82
#define snprintf
Definition: civetweb.c:822
static int TDavixFile_http_authn_cert_X509(void *userdata, const Davix::SessionInfo &info, Davix::X509Credential *cert, Davix::DavixError **err)
Definition: TDavixFile.cxx:201
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
Long64_t fArchiveOffset
!Offset at which file starts in archive
Definition: TFile.h:93
#define gDirectory
Definition: TDirectory.h:221
TDavixFile(const char *url, Option_t *option="", const char *ftitle="", Int_t compress=1)
Open function for TDavixFile.
Definition: TDavixFile.cxx:497
Long64_t fOffset
!Seek offset cache
Definition: TFile.h:88
static void SetFileBytesRead(Long64_t bytes=0)
Definition: TFile.cxx:4409
const Bool_t kTRUE
Definition: Rtypes.h:91
Long64_t DavixPReadBuffer(Davix_fd *fd, char *buf, Long64_t pos, Int_t len)
Definition: TDavixFile.cxx:789
void setCACheck(Bool_t check)
Enable or disable certificate authority check.
Definition: TDavixFile.cxx:665
void parseParams(Option_t *option)
intput params
Definition: TDavixFile.cxx:415
Long64_t fBytesRead
Number of bytes read from this file.
Definition: TFile.h:68
const char * open_mode_new
Definition: TDavixFile.cxx:76