Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGFALFile.cxx
Go to the documentation of this file.
1// @(#)root/gfal:$Id$
2// Author: Fons Rademakers 8/12/2005
3
4/*************************************************************************
5 * Copyright (C) 1995-2005, 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\class TGFALFile
14\ingroup IO
15
16Read and write data via the underlying Grid access mechanism.
17
18A TGFALFile is like a normal TFile except that it reads and writes
19its data via the underlying Grid access mechanism.
20TGFALFile file names are either a logical file name, a guid, an
21SURL or a TURL, like:
22 gfal:/lfn/user/r/rdm/galice.root
23Grid storage interactions today require using several existing
24software components:
25 - The replica catalog services to locate valid replicas of files.
26 - The SRM software to ensure:
27 - Files exist on disk (they are recalled from mass storage if necessary) or
28 - Space is allocated on disk for new files (they are possibly migrated to mass storage later).
29 - A file access mechanism to access files from the storage system on the worker node.
30The GFAL library hides these interactions and presents a Posix
31interface for the I/O operations. The currently supported protocols
32are: file for local access, dcap, gsidcap and kdcap (dCache access
33protocol).
34
35### File naming convention
36A file name can be a Logical File Name (LFN), a Grid Unique
37IDentifier (GUID), a file replica (SURL) or a Transport file
38name (TURL):
39 - an LFN starts with lfn. Example: \a lfn:baud/testgfal15
40 - a GUID starts with guid. Example: \a guid:2cd59291-7ae7-4778-af6d-b1f423719441
41 - an SURL starts with srm://. Example: \a srm://wacdr002d.cern.ch:8443/castor/cern.ch/user/b/baud/testgfal15
42 - a TURL starts with a protocol name. Example: \a gfal:/lfn/user/r/rdm/galice.root
43Note that for the TGFALFile plugin to work, all these pathnames
44should be prepended by gfal:.
45*/
46
47#include <ROOT/RConfig.hxx>
48#include "TROOT.h"
49#include "TUrl.h"
50
51#include <gfal_api.h>
52
53// GFAL2 doesn't use special names for 64 bit versions
54#if defined(_GFAL2_API_) || defined(GFAL2_API_) || defined(_GFAL2_API) || defined(_GFAL2_API_H_) || defined(GFAL2_API_H_) || defined(_GFAL2_API_H)
55#define gfal_lseek64 gfal_lseek
56#define gfal_open64 gfal_open
57#define gfal_readdir64 gfal_readdir
58#define gfal_stat64 gfal_stat
59#define dirent64 dirent
60#define stat64 stat
61#endif
62
63#include "TGFALFile.h"
64
67
68////////////////////////////////////////////////////////////////////////////////
69/// Create a GFAL file object.
70///
71/// A GFAL file is the same as a TFile
72/// except that it is being accessed via the underlaying Grid access
73/// mechanism. The url argument must be of the form: gfal:/lfn/file.root
74/// If the file specified in the URL does not exist, is not accessable
75/// or can not be created the kZombie bit will be set in the TGFALFile
76/// object. Use IsZombie() to see if the file is accessable.
77/// For a description of the option and other arguments see the TFile ctor.
78/// The preferred interface to this constructor is via TFile::Open().
79
80TGFALFile::TGFALFile(const char *url, Option_t *option, const char *ftitle,
81 Int_t compress)
82 : TFile(url, "NET", ftitle, compress)
83{
85
86 fOption = option;
88
89 if (fOption == "NEW")
90 fOption = "CREATE";
91
92 Bool_t create = (fOption == "CREATE") ? kTRUE : kFALSE;
93 Bool_t recreate = (fOption == "RECREATE") ? kTRUE : kFALSE;
94 Bool_t update = (fOption == "UPDATE") ? kTRUE : kFALSE;
95 Bool_t read = (fOption == "READ") ? kTRUE : kFALSE;
96 if (!create && !recreate && !update && !read) {
97 read = kTRUE;
98 fOption = "READ";
99 }
100
101 TString stmp;
102 char *fname;
103 if ((fname = gSystem->ExpandPathName(fUrl.GetFileAndOptions()))) {
104 stmp = fname;
105 delete [] fname;
106 fname = (char *)stmp.Data();
107 } else {
108 Error("TGFALFile", "error expanding path %s", fUrl.GetFileAndOptions());
109 goto zombie;
110 }
111
112 if (recreate) {
113 if (::gfal_access(fname, kFileExists) == 0)
114 ::gfal_unlink(fname);
115 recreate = kFALSE;
116 create = kTRUE;
117 fOption = "CREATE";
118 }
119 if (create && ::gfal_access(fname, kFileExists) == 0) {
120 Error("TGFALFile", "file %s already exists", fname);
121 goto zombie;
122 }
123 if (update) {
124 if (::gfal_access(fname, kFileExists) != 0) {
125 update = kFALSE;
126 create = kTRUE;
127 }
128 if (update && ::gfal_access(fname, kWritePermission) != 0) {
129 Error("TGFALFile", "no write permission, could not open file %s", fname);
130 goto zombie;
131 }
132 }
133 if (read) {
134#ifdef GFAL_ACCESS_FIXED
135 if (::gfal_access(fname, kFileExists) != 0) {
136 Error("TGFALFile", "file %s does not exist", fname);
137 goto zombie;
138 }
139 if (::gfal_access(fname, kReadPermission) != 0) {
140 Error("TGFALFile", "no read permission, could not open file %s", fname);
141 goto zombie;
142 }
143#endif
144 }
145
146 // Connect to file system stream
147 fRealName = fname;
148
149 if (create || update) {
150#ifndef WIN32
151 fD = SysOpen(fname, O_RDWR | O_CREAT, 0644);
152#else
153 fD = SysOpen(fname, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
154#endif
155 if (fD == -1) {
156 SysError("TGFALFile", "file %s can not be opened", fname);
157 goto zombie;
158 }
160 } else {
161#ifndef WIN32
162 fD = SysOpen(fname, O_RDONLY, 0644);
163#else
164 fD = SysOpen(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
165#endif
166 if (fD == -1) {
167 SysError("TGFALFile", "file %s can not be opened for reading", fname);
168 goto zombie;
169 }
171 }
172
173 Init(create);
174
175 return;
176
177zombie:
178 // error in file opening occured, make this object a zombie
179 MakeZombie();
181}
182
183////////////////////////////////////////////////////////////////////////////////
184/// GFAL file dtor. Close and flush directory structure.
185
187{
188 Close();
189}
190
191////////////////////////////////////////////////////////////////////////////////
192/// Interface to system open. All arguments like in POSIX open.
193
194Int_t TGFALFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode)
195{
196 Int_t ret = ::gfal_open64(pathname, flags, (Int_t) mode);
197
198 return ret;
199}
200
201////////////////////////////////////////////////////////////////////////////////
202/// Interface to system close. All arguments like in POSIX close.
203
205{
206 Int_t ret = ::gfal_close(fd);
207
208 return ret;
209}
210
211////////////////////////////////////////////////////////////////////////////////
212/// Interface to system read. All arguments like in POSIX read.
213
215{
216 Int_t ret = ::gfal_read(fd, buf, len);
217
218 return ret;
219}
220
221////////////////////////////////////////////////////////////////////////////////
222/// Interface to system write. All arguments like in POSIX write.
223
224Int_t TGFALFile::SysWrite(Int_t fd, const void *buf, Int_t len)
225{
226 Int_t ret = ::gfal_write(fd, buf, len);
227
228 return ret;
229}
230
231////////////////////////////////////////////////////////////////////////////////
232/// Interface to system lseek. All arguments like in POSIX lseek
233/// except that the offset and return value are Long_t to be able to
234/// handle 64 bit file systems.
235
237{
238 Long64_t ret = ::gfal_lseek64(fd, offset, whence);
239
240 return ret;
241}
242
243////////////////////////////////////////////////////////////////////////////////
244/// Interface to TSystem:GetPathInfo(). Generally implemented via
245/// stat() or fstat().
246
248 Long_t *modtime)
249{
250 struct stat64 &statbuf = fStatBuffer;
251
252 if (fOption != "READ" || !fStatCached) {
253 // We are not in read mode, or the file status information is not yet
254 // in the cache. Update or read the status information with gfal_stat().
255
256 if (::gfal_stat64(fRealName, &statbuf) >= 0)
258 }
259
260 if (fStatCached) {
261 if (id)
262 *id = (statbuf.st_dev << 24) + statbuf.st_ino;
263 if (size)
264 *size = statbuf.st_size;
265 if (modtime)
266 *modtime = statbuf.st_mtime;
267 if (flags) {
268 *flags = 0;
269 if (statbuf.st_mode & ((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6)))
270 *flags |= 1;
271 if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
272 *flags |= 2;
273 if ((statbuf.st_mode & S_IFMT) != S_IFREG &&
274 (statbuf.st_mode & S_IFMT) != S_IFDIR)
275 *flags |= 4;
276 }
277 return 0;
278 }
279
280 return 1;
281}
282
283////////////////////////////////////////////////////////////////////////////////
284/// Read specified byte range from remote file via GFAL.
285/// Returns kTRUE in case of error.
286
288{
289 Int_t st;
290 if ((st = ReadBufferViaCache(buf, len))) {
291 if (st == 2)
292 return kTRUE;
293 return kFALSE;
294 }
295
296 return TFile::ReadBuffer(buf, len);
297}
298
299////////////////////////////////////////////////////////////////////////////////
300/// Read specified byte range from remote file via GFAL.
301/// Returns kTRUE in case of error.
302
304{
305 SetOffset(pos);
306 Int_t st;
307 if ((st = ReadBufferViaCache(buf, len))) {
308 if (st == 2)
309 return kTRUE;
310 return kFALSE;
311 }
312
313 return TFile::ReadBuffer(buf, pos, len);
314}
315
316////////////////////////////////////////////////////////////////////////////////
317/// Write specified byte range to remote file via GFAL.
318/// Returns kTRUE in case of error.
319
321{
322 if (!IsOpen() || !fWritable) return kTRUE;
323
324 Int_t st;
325 if ((st = WriteBufferViaCache(buf, len))) {
326 if (st == 2)
327 return kTRUE;
328 return kFALSE;
329 }
330
331 return TFile::WriteBuffer(buf, len);
332}
333
334/**
335\class TGFALSystem
336\ingroup IO
337
338Directory handler for GFAL.
339*/
340
341////////////////////////////////////////////////////////////////////////////////
342/// Create helper class that allows directory access via GFAL.
343
344TGFALSystem::TGFALSystem() : TSystem("-gfal", "GFAL Helper System")
345{
346 // name must start with '-' to bypass the TSystem singleton check
347 SetName("gfal");
348
349 fDirp = 0;
350}
351
352////////////////////////////////////////////////////////////////////////////////
353/// Make a directory via GFAL.
354
356{
357 TUrl url(dir);
358
359 Int_t ret = ::gfal_mkdir(url.GetFileAndOptions(), 0755);
360
361 return ret;
362}
363
364////////////////////////////////////////////////////////////////////////////////
365/// Open a directory via GFAL. Returns an opaque pointer to a dir
366/// structure. Returns 0 in case of error.
367
368void *TGFALSystem::OpenDirectory(const char *dir)
369{
370 if (fDirp) {
371 Error("OpenDirectory", "invalid directory pointer (should never happen)");
372 fDirp = 0;
373 }
374
375 TUrl url(dir);
376
377 struct stat64 finfo;
378
379 if (::gfal_stat64(url.GetFileAndOptions(), &finfo) < 0)
380 return 0;
381
382 if ((finfo.st_mode & S_IFMT) != S_IFDIR)
383 return 0;
384
385 fDirp = (void*) ::gfal_opendir(url.GetFileAndOptions());
386
387 return fDirp;
388}
389
390////////////////////////////////////////////////////////////////////////////////
391/// Free directory via GFAL.
392
394{
395 if (dirp != fDirp) {
396 Error("FreeDirectory", "invalid directory pointer (should never happen)");
397 return;
398 }
399
400 if (dirp)
401 ::gfal_closedir((DIR*)dirp);
402
403 fDirp = 0;
404}
405
406////////////////////////////////////////////////////////////////////////////////
407/// Get directory entry via GFAL. Returns 0 in case no more entries.
408
409const char *TGFALSystem::GetDirEntry(void *dirp)
410{
411 if (dirp != fDirp) {
412 Error("GetDirEntry", "invalid directory pointer (should never happen)");
413 return 0;
414 }
415
416 struct dirent64 *dp;
417
418 if (dirp) {
419 dp = ::gfal_readdir64((DIR*)dirp);
420 if (!dp)
421 return 0;
422 return dp->d_name;
423 }
424 return 0;
425}
426
427////////////////////////////////////////////////////////////////////////////////
428/// Get info about a file. Info is returned in the form of a FileStat_t
429/// structure (see TSystem.h).
430/// The function returns 0 in case of success and 1 if the file could
431/// not be stat'ed.
432
434{
435 TUrl url(path);
436
437 struct stat64 sbuf;
438
439 if (path && ::gfal_stat64(url.GetFileAndOptions(), &sbuf) >= 0) {
440
441 buf.fDev = sbuf.st_dev;
442 buf.fIno = sbuf.st_ino;
443 buf.fMode = sbuf.st_mode;
444 buf.fUid = sbuf.st_uid;
445 buf.fGid = sbuf.st_gid;
446 buf.fSize = sbuf.st_size;
447 buf.fMtime = sbuf.st_mtime;
448 buf.fIsLink = kFALSE;
449
450 return 0;
451 }
452 return 1;
453}
454
455////////////////////////////////////////////////////////////////////////////////
456/// Returns FALSE if one can access a file using the specified access mode.
457/// Mode is the same as for the Unix access(2) function.
458/// Attention, bizarre convention of return value!!
459
461{
462 TUrl url(path);
463
464 if (::gfal_access(url.GetFileAndOptions(), mode) == 0)
465 return kFALSE;
466
467 return kTRUE;
468}
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
const Bool_t kFALSE
Definition RtypesCore.h:92
long Long_t
Definition RtypesCore.h:54
long long Long64_t
Definition RtypesCore.h:73
const Bool_t kTRUE
Definition RtypesCore.h:91
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:364
#define gDirectory
Definition TDirectory.h:290
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:187
void SysError(const char *location, const char *msgfmt,...)
Use this function in case a system (OS or GUI) related error occurred.
Definition TError.cxx:198
#define gROOT
Definition TROOT.h:406
EAccessMode
Definition TSystem.h:43
@ kFileExists
Definition TSystem.h:44
@ kReadPermission
Definition TSystem.h:47
@ kWritePermission
Definition TSystem.h:46
R__EXTERN TSystem * gSystem
Definition TSystem.h:559
#define O_BINARY
Definition civetweb.c:799
Bool_t fWritable
True if directory is writable.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:54
TUrl fUrl
!URL of file
Definition TFile.h:111
Int_t WriteBufferViaCache(const char *buf, Int_t len)
Write buffer via cache.
Definition TFile.cxx:2435
Int_t ReadBufferViaCache(char *buf, Int_t len)
Read buffer via cache.
Definition TFile.cxx:1805
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition TFile.cxx:1385
virtual void Init(Bool_t create)
Initialize a TFile object.
Definition TFile.cxx:555
TString fOption
File options.
Definition TFile.h:92
virtual Bool_t WriteBuffer(const char *buf, Int_t len)
Write a buffer to the file.
Definition TFile.cxx:2392
Int_t fD
File descriptor.
Definition TFile.h:83
TString fRealName
Effective real file name (not original url)
Definition TFile.h:91
virtual void SetOffset(Long64_t offset, ERelativeTo pos=kBeg)
Set position from where to start reading.
Definition TFile.cxx:2169
void Close(Option_t *option="") override
Close a file.
Definition TFile.cxx:879
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read a buffer from the file.
Definition TFile.cxx:1686
Read and write data via the underlying Grid access mechanism.
Definition TGFALFile.h:19
Long64_t SysSeek(Int_t fd, Long64_t offset, Int_t whence)
Interface to system lseek.
~TGFALFile()
GFAL file dtor. Close and flush directory structure.
Int_t SysClose(Int_t fd)
Interface to system close. All arguments like in POSIX close.
struct stat64 fStatBuffer
! (transient) Cached file status buffer (for performance)
Definition TGFALFile.h:23
Int_t SysWrite(Int_t fd, const void *buf, Int_t len)
Interface to system write. All arguments like in POSIX write.
Int_t SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime)
Interface to TSystem:GetPathInfo().
Bool_t WriteBuffer(const char *buf, Int_t len)
Write specified byte range to remote file via GFAL.
Int_t SysRead(Int_t fd, void *buf, Int_t len)
Interface to system read. All arguments like in POSIX read.
Bool_t ReadBuffer(char *buf, Int_t len)
Read specified byte range from remote file via GFAL.
Int_t SysOpen(const char *pathname, Int_t flags, UInt_t mode)
Interface to system open. All arguments like in POSIX open.
Bool_t fStatCached
! (transient) is file status cached?
Definition TGFALFile.h:22
Directory handler for GFAL.
Definition TGFALFile.h:49
void * OpenDirectory(const char *name)
Open a directory via GFAL.
const char * GetDirEntry(void *dirp)
Get directory entry via GFAL. Returns 0 in case no more entries.
Int_t GetPathInfo(const char *path, FileStat_t &buf)
Get info about a file.
Bool_t AccessPathName(const char *path, EAccessMode mode)
Returns FALSE if one can access a file using the specified access mode.
TGFALSystem()
Create helper class that allows directory access via GFAL.
void * fDirp
Definition TGFALFile.h:52
void FreeDirectory(void *dirp)
Free directory via GFAL.
Int_t MakeDirectory(const char *name)
Make a directory via GFAL.
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:893
void MakeZombie()
Definition TObject.h:49
Basic string class.
Definition TString.h:136
const char * Data() const
Definition TString.h:369
void ToUpper()
Change string to upper case.
Definition TString.cxx:1158
Abstract base class defining a generic interface to the underlying Operating System.
Definition TSystem.h:266
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1272
This class represents a WWW compatible URL.
Definition TUrl.h:33
const char * GetFileAndOptions() const
Return the file and its options (the string specified behind the ?).
Definition TUrl.cxx:503
Int_t fMode
Definition TSystem.h:127
Long64_t fSize
Definition TSystem.h:130
Long_t fDev
Definition TSystem.h:125
Int_t fGid
Definition TSystem.h:129
Long_t fMtime
Definition TSystem.h:131
Long_t fIno
Definition TSystem.h:126
Bool_t fIsLink
Definition TSystem.h:132
Int_t fUid
Definition TSystem.h:128