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