Logo ROOT   6.14/05
Reference Guide
TChirpFile.cxx
Go to the documentation of this file.
1 // @(#)root/chirp:$Id$
2 // Authors: Dan Bradley, Michael Albrecht, Douglas Thain
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2002, 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 TChirpFile
14 \ingroup IO
15 
16 Read and write data via a Chirp server.
17 
18 A TChirpFile is like a normal TFile except that it may read and
19 write its data via a Chirp server. The primary API for accessing
20 Chirp is through the chirp_reli interface, which corresponds closely
21 to Unix. Most operations return an integer where >=0 indicates
22 success and <0 indicates failure, setting the global errno.
23 This allows most TFile methods to be implemented with a single
24 line or two of Chirp (for more on the Chirp filesystem.
25 Note that this class overrides ReadBuffers so as to take advantage
26 of the Chirp "bulk I/O" feature which does multiple remote ops
27 in a single call.
28 Most users of Chirp will access a named remote server url:
29  chirp://host.somewhere.edu/path
30 The special host CONDOR is used to indicate a connection to the
31 Chirp I/O proxy service when running inside of Condor:
32  chirp://CONDOR/path
33 
34 This module recognizes the following environment variables:
35  - \b CHIRP_DEBUG_FILE: Send debugging output to this file.
36  - \b CHIRP_DEBUG_FLAGS: Turn on select debugging flags (e.g. 'all').
37  - \b CHIRP_AUTH: Select a specific auth type (e.g. 'globus').
38  - \b CHIRP_TIMEOUT: Specify how long to attempt each op, in secs.
39 
40 For more information about the Chirp fileystem and protocol:
41  http://www.cse.nd.edu/~ccl/software/chirp
42 */
43 
44 #include "TChirpFile.h"
45 #include "TError.h"
46 #include "TSystem.h"
47 #include "TROOT.h"
48 
49 #include <errno.h>
50 #include <sys/stat.h>
51 #include <unistd.h>
52 #include <stdlib.h>
53 #include <sys/types.h>
54 
55 extern "C" {
56 #include "chirp_reli.h"
57 #include "auth_all.h"
58 #include "debug.h"
59 }
60 
61 // If the path component of a url is a blank string,
62 // then convert it to the root directory of that server.
63 #define FIXPATH(x) ( x[0]==0 ? "/" : x )
64 
65 static int chirp_root_timeout = 3600;
66 
68 {
69  static int did_setup = 0;
70  if (did_setup) return;
71 
72  debug_config("chirp_root");
73 
74  const char *debug_file = getenv("CHIRP_DEBUG_FILE");
75  if (debug_file) debug_config_file(debug_file);
76 
77  const char *debug_flags = getenv("CHIRP_DEBUG_FLAGS");
78  if (debug_flags) debug_flags_set(debug_flags);
79 
80  const char *auth_flags = getenv("CHIRP_AUTH");
81  if (auth_flags) {
82  auth_register_byname(auth_flags);
83  } else {
84  auth_register_all();
85  }
86 
87  const char *timeout_string = getenv("CHIRP_TIMEOUT");
88  if (timeout_string) chirp_root_timeout = atoi(timeout_string);
89 
90  did_setup = 1;
91 }
92 
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Constructor.
97 
98 TChirpFile::TChirpFile(const char *path, Option_t * option, const char *ftitle, Int_t compress):TFile(path, "NET", ftitle, compress)
99 {
101 
102  chirp_file_ptr = 0;
103 
104  fOption = option;
105  fOption.ToUpper();
106 
107  if (fOption == "NEW")
108  fOption = "CREATE";
109 
110  Bool_t create = (fOption == "CREATE") ? kTRUE : kFALSE;
111  Bool_t recreate = (fOption == "RECREATE") ? kTRUE : kFALSE;
112  Bool_t update = (fOption == "UPDATE") ? kTRUE : kFALSE;
113  Bool_t read = (fOption == "READ") ? kTRUE : kFALSE;
114 
115  if (!create && !recreate && !update && !read) {
116  read = kTRUE;
117  fOption = "READ";
118  }
119 
120  fRealName = path;
121 
122  if (create || update || recreate) {
123  Int_t mode = O_RDWR | O_CREAT;
124  if (recreate)
125  mode |= O_TRUNC;
126 
127 #ifndef WIN32
128  fD = SysOpen(path, mode, 0644);
129 #else
130  fD = SysOpen(path, mode | O_BINARY, S_IREAD | S_IWRITE);
131 #endif
132  if (fD == -1) {
133  SysError("TChirpFile", "file %s can not be created", path);
134  goto zombie;
135  }
136  fWritable = kTRUE;
137  } else {
138 #ifndef WIN32
139  fD = SysOpen(path, O_RDONLY, 0644);
140 #else
141  fD = SysOpen(path, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
142 #endif
143  if (fD == -1) {
144  SysError("TChirpFile", "file %s can not be opened for reading", path);
145  goto zombie;
146  }
147  fWritable = kFALSE;
148  }
149 
150  Init(create || recreate);
151 
152  return;
153 
154 zombie:
155  MakeZombie();
156  gDirectory = gROOT;
157 }
158 
159 ////////////////////////////////////////////////////////////////////////////////
160 /// Destructor.
161 
163 {
164  Close();
165 }
166 
167 ////////////////////////////////////////////////////////////////////////////////
168 
169 Bool_t TChirpFile::ReadBuffers(char *buf, Long64_t * pos, Int_t * len, Int_t nbuf)
170 {
171  struct chirp_bulkio bulkio[nbuf];
172  int i;
173 
174  char *nextbuf = buf;
175 
176  for (i = 0; i < nbuf; i++) {
177  bulkio[i].type = CHIRP_BULKIO_PREAD;
178  bulkio[i].file = chirp_file_ptr;
179  bulkio[i].offset = pos[i];
180  bulkio[i].length = len[i];
181  bulkio[i].buffer = nextbuf;
182  nextbuf += len[i];
183  }
184 
185  INT64_T result = chirp_reli_bulkio(bulkio, nbuf, time(0) + chirp_root_timeout);
186 
187  if (result >= 0) {
188  return kFALSE;
189  } else {
190  return kTRUE;
191  }
192 }
193 
194 ////////////////////////////////////////////////////////////////////////////////
195 
196 Int_t TChirpFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode)
197 {
198  TUrl url(pathname);
199  chirp_file_ptr = chirp_reli_open(url.GetHost(), FIXPATH(url.GetFile()), flags, (Int_t) mode, time(0) + chirp_root_timeout);
200  if (chirp_file_ptr) {
201  return 1;
202  } else {
203  return -1;
204  }
205 }
206 
207 ////////////////////////////////////////////////////////////////////////////////
208 
210 {
211  return chirp_reli_close(chirp_file_ptr, time(0) + chirp_root_timeout);
212 }
213 
214 ////////////////////////////////////////////////////////////////////////////////
215 
217 {
218  Int_t rc = chirp_reli_pread(chirp_file_ptr, buf, len, fOffset, time(0) + chirp_root_timeout);
219  if (rc > 0) fOffset += rc;
220  return rc;
221 }
222 
223 ////////////////////////////////////////////////////////////////////////////////
224 
225 Int_t TChirpFile::SysWrite(Int_t, const void *buf, Int_t len)
226 {
227  Int_t rc = chirp_reli_pwrite(chirp_file_ptr, buf, len, fOffset, time(0) + chirp_root_timeout);
228  if (rc > 0) fOffset += rc;
229  return rc;
230 }
231 
232 ////////////////////////////////////////////////////////////////////////////////
233 
235 {
236  if (whence == SEEK_SET) {
237  fOffset = offset;
238  } else if(whence == SEEK_CUR) {
239  fOffset += offset;
240  } else if(whence == SEEK_END) {
241  struct chirp_stat info;
242 
243  Int_t rc = chirp_reli_fstat(chirp_file_ptr, &info, time(0) + chirp_root_timeout);
244  if (rc < 0) {
245  SysError("TChirpFile", "Unable to seek from end of file");
246  return -1;
247  }
248 
249  fOffset = info.cst_size + offset;
250 
251  } else {
252  SysError("TChirpFile", "Unknown whence!");
253  return -1;
254  }
255 
256  return fOffset;
257 }
258 
259 ////////////////////////////////////////////////////////////////////////////////
260 
262 {
263  return chirp_reli_fsync(chirp_file_ptr, time(0) + chirp_root_timeout);
264 }
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 
268 Int_t TChirpFile::SysStat(Int_t, Long_t * id, Long64_t * size, Long_t * flags, Long_t * modtime)
269 {
270  struct chirp_stat cst;
271 
272  int rc = chirp_reli_fstat(chirp_file_ptr, &cst, time(0) + chirp_root_timeout);
273 
274  if (rc < 0) return rc;
275 
276  *id =::Hash(fRealName);
277  *size = cst.cst_size;
278  *flags = cst.cst_mode;
279  *modtime = cst.cst_mtime;
280 
281  return 0;
282 }
283 
285 
286 ////////////////////////////////////////////////////////////////////////////////
287 
288 TChirpSystem::TChirpSystem():TSystem("-chirp", "Chirp Helper System")
289 {
290  SetName("chirp");
292 }
293 
294 ////////////////////////////////////////////////////////////////////////////////
295 
296 TChirpSystem::~TChirpSystem()
297 {
298 }
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 
303 {
304  TUrl url(path);
305  return chirp_reli_mkdir(url.GetHost(), FIXPATH(url.GetFile()), 0777, time(0) + chirp_root_timeout);
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 
310 void *TChirpSystem::OpenDirectory(const char *path)
311 {
312  TUrl url(path);
313  return chirp_reli_opendir(url.GetHost(), FIXPATH(url.GetFile()), time(0) + chirp_root_timeout);
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 
319 {
320  return chirp_reli_closedir((struct chirp_dir *) dirp);
321 }
322 
323 ////////////////////////////////////////////////////////////////////////////////
324 
325 const char *TChirpSystem::GetDirEntry(void *dirp)
326 {
327  struct chirp_dirent *d = chirp_reli_readdir((struct chirp_dir *) dirp);
328  if (d) {
329  return d->name;
330  } else {
331  return 0;
332  }
333 }
334 
335 ////////////////////////////////////////////////////////////////////////////////
336 
338 {
339  TUrl url(path);
340  struct chirp_stat info;
341  Int_t rc = chirp_reli_stat(url.GetHost(), FIXPATH(url.GetFile()), &info, time(0) + chirp_root_timeout);
342  if (rc >= 0) {
343  buf.fDev = info.cst_dev;
344  buf.fIno = info.cst_ino;
345  buf.fMode = info.cst_mode;
346  buf.fUid = info.cst_uid;
347  buf.fGid = info.cst_gid;
348  buf.fSize = info.cst_size;
349  buf.fMtime = info.cst_mtime;
350  buf.fIsLink = S_ISLNK(info.cst_mode);
351  buf.fUrl = TString(path);
352  }
353  return rc;
354 }
355 
356 ////////////////////////////////////////////////////////////////////////////////
357 
359 {
360  TUrl url(path);
361 
362  int cmode = F_OK;
363 
364  if (mode & kExecutePermission) cmode |= X_OK;
365  if (mode & kWritePermission) cmode |= W_OK;
366  if (mode & kReadPermission) cmode |= R_OK;
367 
368  if (chirp_reli_access(url.GetHost(), FIXPATH(url.GetFile()), cmode, time(0) + chirp_root_timeout) == 0) {
369  return kFALSE;
370  } else {
371  return kTRUE;
372  }
373 }
374 
375 ////////////////////////////////////////////////////////////////////////////////
376 
377 Int_t TChirpSystem::Unlink(const char *path)
378 {
379  TUrl url(path);
380  Int_t rc = chirp_reli_unlink(url.GetHost(), FIXPATH(url.GetFile()), time(0) + chirp_root_timeout);
381  if (rc < 0 && errno == EISDIR) {
382  rc = chirp_reli_rmdir(url.GetHost(), FIXPATH(url.GetFile()), time(0) + chirp_root_timeout);
383  }
384  return rc;
385 }
386 
387 ////////////////////////////////////////////////////////////////////////////////
388 
389 int TChirpSystem::Rename(const char *from, const char *to)
390 {
391  TUrl fromurl(from);
392  TUrl tourl(to);
393 
394  if (strcmp(fromurl.GetHost(), tourl.GetHost())) {
395  errno = EXDEV;
396  return -1;
397  }
398 
399  return chirp_reli_rename(fromurl.GetHost(), FIXPATH(fromurl.GetFile()), FIXPATH(tourl.GetFile()), time(0) + chirp_root_timeout);
400 }
401 
402 ////////////////////////////////////////////////////////////////////////////////
403 
404 int TChirpSystem::Link(const char *from, const char *to)
405 {
406  TUrl fromurl(from);
407  TUrl tourl(to);
408 
409  if (strcmp(fromurl.GetHost(), tourl.GetHost())) {
410  errno = EXDEV;
411  return -1;
412  }
413 
414  return chirp_reli_link(fromurl.GetHost(), FIXPATH(fromurl.GetFile()), FIXPATH(tourl.GetFile()), time(0) + chirp_root_timeout);
415 }
416 
417 ////////////////////////////////////////////////////////////////////////////////
418 
419 int TChirpSystem::Symlink(const char *from, const char *to)
420 {
421  TUrl fromurl(from);
422  TUrl tourl(to);
423 
424  if (strcmp(fromurl.GetHost(), tourl.GetHost())) {
425  errno = EXDEV;
426  return -1;
427  }
428 
429  return chirp_reli_symlink(fromurl.GetHost(), FIXPATH(fromurl.GetFile()), FIXPATH(tourl.GetFile()), time(0) + chirp_root_timeout);
430 }
431 
432 ////////////////////////////////////////////////////////////////////////////////
433 
434 int TChirpSystem::GetFsInfo(const char *path, Long_t * id, Long_t * bsize, Long_t * blocks, Long_t * bfree)
435 {
436  TUrl url(path);
437 
438  struct chirp_statfs info;
439 
440  int rc = chirp_reli_statfs(url.GetHost(), FIXPATH(url.GetFile()), &info, time(0) + chirp_root_timeout);
441  if (rc >= 0) {
442  *id = info.f_type;
443  *bsize = info.f_bsize;
444  *blocks = info.f_blocks;
445  *bfree = info.f_bfree;
446  }
447  return rc;
448 }
449 
450 ////////////////////////////////////////////////////////////////////////////////
451 
452 int TChirpSystem::Chmod(const char *path, UInt_t mode)
453 {
454  TUrl url(path);
455  return chirp_reli_chmod(url.GetHost(), FIXPATH(url.GetFile()), mode, time(0) + chirp_root_timeout);
456 }
457 
458 ////////////////////////////////////////////////////////////////////////////////
459 
460 int TChirpSystem::Utime(const char *path, Long_t modtime, Long_t actime)
461 {
462  TUrl url(path);
463  return chirp_reli_utime(url.GetHost(), FIXPATH(url.GetFile()), modtime, actime, time(0) + chirp_root_timeout);
464 }
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:894
Int_t SysClose(Int_t fd)
Interface to system close. All arguments like in POSIX close().
Definition: TChirpFile.cxx:209
Int_t Unlink(const char *path)
Unlink, i.e. remove, a file.
Definition: TChirpFile.cxx:377
long long Long64_t
Definition: RtypesCore.h:69
Int_t SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime)
Return file stat information.
Definition: TChirpFile.cxx:268
Int_t SysRead(Int_t fd, void *buf, Int_t len)
Interface to system read. All arguments like in POSIX read().
Definition: TChirpFile.cxx:216
int Link(const char *from, const char *to)
Create a link from file1 to file2.
Definition: TChirpFile.cxx:404
const char Option_t
Definition: RtypesCore.h:62
This class represents a WWW compatible URL.
Definition: TUrl.h:35
Int_t fUid
Definition: TSystem.h:129
void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TChirpFile.cxx:310
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:47
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1113
#define gROOT
Definition: TROOT.h:410
Bool_t AccessPathName(const char *path, EAccessMode mode)
Returns FALSE if one can access a file using the specified access mode.
Definition: TChirpFile.cxx:358
#define O_BINARY
Definition: civetweb.c:652
Basic string class.
Definition: TString.h:131
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Long_t fMtime
Definition: TSystem.h:132
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: TChirpFile.cxx:169
Int_t SysSync(Int_t fd)
Interface to system fsync. All arguments like in POSIX fsync().
Definition: TChirpFile.cxx:261
Long64_t fSize
Definition: TSystem.h:131
static int chirp_root_timeout
Definition: TChirpFile.cxx:65
Int_t fMode
Definition: TSystem.h:128
const char * GetFile() const
Definition: TUrl.h:72
const char * GetHost() const
Definition: TUrl.h:70
Int_t fD
File descriptor.
Definition: TFile.h:76
Read and write data via a Chirp server.
Definition: TChirpFile.h:19
static void chirp_root_global_setup()
Definition: TChirpFile.cxx:67
TString fRealName
Effective real file name (not original url)
Definition: TFile.h:84
int Rename(const char *from, const char *to)
Rename a file.
Definition: TChirpFile.cxx:389
TString fUrl
Definition: TSystem.h:134
Int_t GetPathInfo(const char *path, FileStat_t &buf)
Get info about a file.
Definition: TChirpFile.cxx:337
Int_t fGid
Definition: TSystem.h:130
void FreeDirectory(void *dirp)
Free a directory.
Definition: TChirpFile.cxx:318
Bool_t fIsLink
Definition: TSystem.h:133
const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TChirpFile.cxx:325
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
Long64_t SysSeek(Int_t fd, Long64_t offset, Int_t whence)
Interface to system lseek.
Definition: TChirpFile.cxx:234
#define FIXPATH(x)
Definition: TChirpFile.cxx:63
virtual void Init(Bool_t create)
Initialize a TFile object.
Definition: TFile.cxx:597
Bool_t fWritable
True if directory is writable.
virtual ULong_t Hash() const
Return hash value for this object.
Definition: TNamed.h:49
const Bool_t kFALSE
Definition: RtypesCore.h:88
struct chirp_file * chirp_file_ptr
Definition: TChirpFile.h:22
long Long_t
Definition: RtypesCore.h:50
#define d(i)
Definition: RSha256.hxx:102
#define ClassImp(name)
Definition: Rtypes.h:359
TString fOption
File options.
Definition: TFile.h:85
Int_t MakeDirectory(const char *name)
Make a directory.
Definition: TChirpFile.cxx:302
EAccessMode
Definition: TSystem.h:44
int Utime(const char *file, Long_t modtime, Long_t actime)
Set the a files modification and access times.
Definition: TChirpFile.cxx:460
void MakeZombie()
Definition: TObject.h:49
int Symlink(const char *from, const char *to)
Create a symbolic link from file1 to file2.
Definition: TChirpFile.cxx:419
~TChirpFile()
Destructor.
Definition: TChirpFile.cxx:162
Long_t fIno
Definition: TSystem.h:127
Int_t SysWrite(Int_t fd, const void *buf, Int_t len)
Interface to system write. All arguments like in POSIX write().
Definition: TChirpFile.cxx:225
#define gDirectory
Definition: TDirectory.h:213
int GetFsInfo(const char *path, Long_t *id, Long_t *bsize, Long_t *blocks, Long_t *bfree)
Get info about a file system: fs type, block size, number of blocks, number of free blocks...
Definition: TChirpFile.cxx:434
Long64_t fOffset
!Seek offset cache
Definition: TFile.h:90
Int_t SysOpen(const char *pathname, Int_t flags, UInt_t mode)
Interface to system open. All arguments like in POSIX open().
Definition: TChirpFile.cxx:196
Long_t fDev
Definition: TSystem.h:126
Abstract base class defining a generic interface to the underlying Operating System.
Definition: TSystem.h:248
const Bool_t kTRUE
Definition: RtypesCore.h:87
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:917
int Chmod(const char *file, UInt_t mode)
Set the file permission bits. Returns -1 in case or error, 0 otherwise.
Definition: TChirpFile.cxx:452