Logo ROOT   6.10/09
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 "RConfig.h"
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 
80 TGFALFile::TGFALFile(const char *url, Option_t *option, const char *ftitle,
81  Int_t compress)
82  : TFile(url, "NET", ftitle, compress)
83 {
84  fStatCached = kFALSE;
85 
86  fOption = option;
87  fOption.ToUpper();
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  }
159  fWritable = kTRUE;
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  }
170  fWritable = kFALSE;
171  }
172 
173  Init(create);
174 
175  return;
176 
177 zombie:
178  // error in file opening occured, make this object a zombie
179  MakeZombie();
180  gDirectory = gROOT;
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 
194 Int_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 
214 Int_t TGFALFile::SysRead(Int_t fd, void *buf, Int_t len)
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 
224 Int_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 
247 Int_t TGFALFile::SysStat(Int_t /*fd*/, Long_t *id, Long64_t *size, Long_t *flags,
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)
257  fStatCached = kTRUE;
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 
320 Bool_t TGFALFile::WriteBuffer(const char *buf, Int_t len)
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 
338 Directory handler for GFAL.
339 */
340 
341 ////////////////////////////////////////////////////////////////////////////////
342 /// Create helper class that allows directory access via GFAL.
343 
344 TGFALSystem::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 
368 void *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 
409 const 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 }
double read(const std::string &file_name)
reading
struct stat64 fStatBuffer
! (transient) Cached file status buffer (for performance)
Definition: TGFALFile.h:23
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:204
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:214
virtual void SetOffset(Long64_t offset, ERelativeTo pos=kBeg)
Set position from where to start reading.
Definition: TFile.cxx:2088
This class represents a WWW compatible URL.
Definition: TUrl.h:35
Int_t fUid
Definition: TSystem.h:129
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:46
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read a buffer from the file.
Definition: TFile.cxx:1606
const char * GetFileAndOptions() const
Return the file and its options (the string specified behind the ?).
Definition: TUrl.cxx:501
#define gROOT
Definition: TROOT.h:375
#define O_BINARY
Definition: civetweb.c:451
Basic string class.
Definition: TString.h:129
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Int_t WriteBufferViaCache(const char *buf, Int_t len)
Write buffer via cache.
Definition: TFile.cxx:2355
TGFALSystem()
Create helper class that allows directory access via GFAL.
Definition: TGFALFile.cxx:344
Long64_t SysSeek(Int_t fd, Long64_t offset, Int_t whence)
Interface to system lseek.
Definition: TGFALFile.cxx:236
Long_t fMtime
Definition: TSystem.h:132
Bool_t WriteBuffer(const char *buf, Int_t len)
Write specified byte range to remote file via GFAL.
Definition: TGFALFile.cxx:320
Long64_t fSize
Definition: TSystem.h:131
void SysError(const char *location, const char *msgfmt,...)
Int_t fMode
Definition: TSystem.h:128
const char * GetDirEntry(void *dirp)
Get directory entry via GFAL. Returns 0 in case no more entries.
Definition: TGFALFile.cxx:409
TString fRealName
Effective real file name (not original url)
Definition: TFile.h:83
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:247
Bool_t fStatCached
! (transient) is file status cached?
Definition: TGFALFile.h:22
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:287
Int_t fGid
Definition: TSystem.h:130
Read and write data via the underlying Grid access mechanism.
Definition: TGFALFile.h:19
void FreeDirectory(void *dirp)
Free directory via GFAL.
Definition: TGFALFile.cxx:393
void * fDirp
Definition: TGFALFile.h:52
Int_t GetPathInfo(const char *path, FileStat_t &buf)
Get info about a file.
Definition: TGFALFile.cxx:433
Bool_t fIsLink
Definition: TSystem.h:133
R__EXTERN TSystem * gSystem
Definition: TSystem.h:539
virtual Bool_t WriteBuffer(const char *buf, Int_t len)
Write a buffer to the file.
Definition: TFile.cxx:2312
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:186
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:873
Int_t MakeDirectory(const char *name)
Make a directory via GFAL.
Definition: TGFALFile.cxx:355
Int_t ReadBufferViaCache(char *buf, Int_t len)
Read buffer via cache.
Definition: TFile.cxx:1725
Bool_t fWritable
True if directory is writable.
const Bool_t kFALSE
Definition: RtypesCore.h:92
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:1383
#define ClassImp(name)
Definition: Rtypes.h:336
TString fOption
File options.
Definition: TFile.h:84
EAccessMode
Definition: TSystem.h:44
Long_t fIno
Definition: TSystem.h:127
Directory handler for GFAL.
Definition: TGFALFile.h:49
#define gDirectory
Definition: TDirectory.h:211
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1250
Long_t fDev
Definition: TSystem.h:126
Abstract base class defining a generic interface to the underlying Operating System.
Definition: TSystem.h:248
void * OpenDirectory(const char *name)
Open a directory via GFAL.
Definition: TGFALFile.cxx:368
const Bool_t kTRUE
Definition: RtypesCore.h:91
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:194
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:224
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:460
const char * Data() const
Definition: TString.h:347