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