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