diff --git a/Makefile b/Makefile index 3304ddf2749be71d2885e56922bfcf9e30c24a9c..d91143641ea15ca9dd587869309538425c1cea82 100644 --- a/Makefile +++ b/Makefile @@ -82,6 +82,11 @@ ifneq ($(DCAPLIB),) MODULES += dcache endif endif +ifneq ($(CHIRPINCDIR),) +ifneq ($(CHIRPCLILIB),) +MODULES += chirp +endif +endif ifneq ($(ALIENINCDIR),) ifneq ($(ALIENCLILIB),) MODULES += alien @@ -125,7 +130,7 @@ endif ifneq ($(findstring $(MAKECMDGOALS),distclean maintainer-clean),) MODULES += unix winnt x11 x11ttf win32 win32gdk gl rfio thread pythia \ pythia6 venus table mysql pgsql sapdb srputils x3d rootx \ - rootd proofd dcache hbook alien asimage ldap + rootd proofd dcache chirp hbook alien asimage ldap MODULES := $(sort $(MODULES)) # removes duplicates endif diff --git a/chirp/Module.mk b/chirp/Module.mk new file mode 100644 index 0000000000000000000000000000000000000000..ef2af87321618ae59c1c01f2d355b7ead2793cff --- /dev/null +++ b/chirp/Module.mk @@ -0,0 +1,64 @@ +# Module.mk for chirp module +# +# Author: Dan Bradley <dan@hep.wisc.edu>, 16/12/2002 + +MODDIR := chirp +MODDIRS := $(MODDIR)/src +MODDIRI := $(MODDIR)/inc + +CHIRPDIR := $(MODDIR) +CHIRPDIRS := $(CHIRPDIR)/src +CHIRPDIRI := $(CHIRPDIR)/inc + +##### libChirp ##### +CHIRPL := $(MODDIRI)/LinkDef.h +CHIRPDS := $(MODDIRS)/G__Chirp.cxx +CHIRPDO := $(CHIRPDS:.cxx=.o) +CHIRPDH := $(CHIRPDS:.cxx=.h) + +CHIRPH := $(filter-out $(MODDIRI)/LinkDef%,$(wildcard $(MODDIRI)/*.h)) +CHIRPS := $(filter-out $(MODDIRS)/G__%,$(wildcard $(MODDIRS)/*.cxx)) +CHIRPO := $(CHIRPS:.cxx=.o) + +CHIRPDEP := $(CHIRPO:.o=.d) $(CHIRPDO:.o=.d) + +CHIRPLIB := $(LPATH)/libChirp.$(SOEXT) + +# used in the main Makefile +ALLHDRS += $(patsubst $(MODDIRI)/%.h,include/%.h,$(CHIRPH)) +ALLLIBS += $(CHIRPLIB) + +# include all dependency files +INCLUDEFILES += $(CHIRPDEP) + +##### local rules ##### +include/%.h: $(CHIRPDIRI)/%.h + cp $< $@ + +$(CHIRPLIB): $(CHIRPO) $(CHIRPDO) $(MAINLIBS) + @$(MAKELIB) $(PLATFORM) $(LD) "$(LDFLAGS)" \ + "$(SOFLAGS)" libChirp.$(SOEXT) $@ "$(CHIRPO) $(CHIRPDO)" \ + "$(CHIRPLIBEXTRA) $(CHIRPLIBDIR) $(CHIRPCLILIB)" + +$(CHIRPDS): $(CHIRPH) $(CHIRPL) $(ROOTCINTTMP) + @echo "Generating dictionary $@..." + $(ROOTCINTTMP) -f $@ -c $(CHIRPH) $(CHIRPL) + +$(CHIRPDO): $(CHIRPDS) + $(CXX) $(NOOPT) $(CXXFLAGS) -I$(CHIRPINCDIR) -I. -o $@ -c $< + +all-chirp: $(CHIRPLIB) + +clean-chirp: + @rm -f $(CHIRPO) $(CHIRPDO) + +clean:: clean-chirp + +distclean-chirp: clean-chirp + @rm -f $(CHIRPDEP) $(CHIRPDS) $(CHIRPDH) $(CHIRPLIB) + +distclean:: distclean-chirp + +##### extra rules ###### +$(CHIRPO): %.o: %.cxx + $(CXX) $(OPT) $(CXXFLAGS) -I$(CHIRPINCDIR) -o $@ -c $< diff --git a/chirp/inc/LinkDef.h b/chirp/inc/LinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..d63f862411a1a6b50cca81fb3452d4e88390888a --- /dev/null +++ b/chirp/inc/LinkDef.h @@ -0,0 +1,9 @@ +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class TChirpFile; + +#endif diff --git a/chirp/inc/TChirpFile.h b/chirp/inc/TChirpFile.h new file mode 100644 index 0000000000000000000000000000000000000000..bce63e4ac9149682e1a9121b762895ea204a1a15 --- /dev/null +++ b/chirp/inc/TChirpFile.h @@ -0,0 +1,64 @@ +// Author: Dan Bradley 17/12/2002 + +/************************************************************************* + * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TChirpFile +#define ROOT_TChirpFile + + +////////////////////////////////////////////////////////////////////////// +// // +// TChirpFile // +// // +// A TChirpFile is like a normal TFile except that it reads and writes // +// its data via a Chirp server. For more information, see // +// http://www.cs.wisc.edu/condor/chirp. // +// // +////////////////////////////////////////////////////////////////////////// + + +#ifndef ROOT_TFile +#include "TFile.h" +#endif + +class TChirpFile : public TFile { + +private: + Seek_t fOffset; + struct chirp_client *chirp_client; + + TChirpFile() : fOffset(0), chirp_client(0) { } + + // Interface to basic system I/O routines + Int_t SysOpen(const char *pathname, Int_t flags, UInt_t mode); + Int_t SysClose(Int_t fd); + Int_t SysRead(Int_t fd, void *buf, Int_t len); + Int_t SysWrite(Int_t fd, const void *buf, Int_t len); + Seek_t SysSeek(Int_t fd, Seek_t offset, Int_t whence); + Int_t SysStat(Int_t fd, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime); + Int_t SysSync(Int_t fd); + + Int_t OpenChirpClient(const char *URL,char const **path); + Int_t CloseChirpClient(); + +public: + TChirpFile(const char *path, Option_t *option="", + const char *ftitle="", Int_t compress=1); + + ~TChirpFile(); + + Bool_t ReadBuffer(char *buf, Int_t len); + Bool_t WriteBuffer(const char *buf, Int_t len); + + void ResetErrno() const; + + ClassDef(TChirpFile,0) //A ROOT file that reads/writes via a Chirp server +}; + +#endif diff --git a/chirp/src/TChirpFile.cxx b/chirp/src/TChirpFile.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0b39a07f55e0253c3da74ee105cbde911bda400a --- /dev/null +++ b/chirp/src/TChirpFile.cxx @@ -0,0 +1,316 @@ +// Author: Dan Bradley 17/12/2002 + +/************************************************************************* + * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// TChirpFile // +// // +// A TChirpFile is like a normal TFile except that it may read and // +// write its data via a Chirp server (for more on the Chirp protocol // +// see http://www.cs.wisc.edu/condor/chirp). // +// // +////////////////////////////////////////////////////////////////////////// + +#include "TChirpFile.h" +#include "TError.h" +#include "TSystem.h" +#include "TROOT.h" + +#include <errno.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "chirp_client.h" + + +static const char* const CHIRP_PREFIX = "chirp:"; +static const size_t CHIRP_PREFIX_LEN = 6; + + +ClassImp(TChirpFile) + +//______________________________________________________________________________ +TChirpFile::TChirpFile(const char *path, Option_t *option, + const char *ftitle, Int_t compress): + TFile(path, "NET", ftitle, compress) +{ + //Passing option "NET" to prevent base-class from doing any local access. + + fOffset = 0; + chirp_client = 0; + + fOption = option; + fOption.ToUpper(); + + if (fOption == "NEW") + fOption = "CREATE"; + + Bool_t create = (fOption == "CREATE") ? kTRUE : kFALSE; + Bool_t recreate = (fOption == "RECREATE") ? kTRUE : kFALSE; + Bool_t update = (fOption == "UPDATE") ? kTRUE : kFALSE; + Bool_t read = (fOption == "READ") ? kTRUE : kFALSE; + if (!create && !recreate && !update && !read) { + read = kTRUE; + fOption = "READ"; + } + + char const *path_part; + const char *fname; + + if (OpenChirpClient(path, &path_part)) { + SysError("TChirpFile", "chirp client for %s can not be opened", path); + goto zombie; + } + + SetName(path_part); + + fname = GetName(); + + if (create || update || recreate) { + Int_t mode = O_RDWR | O_CREAT; + if (recreate) mode |= O_TRUNC; + +#ifndef WIN32 + fD = SysOpen(fname, mode, 0644); +#else + fD = SysOpen(fname, mode | O_BINARY, S_IREAD | S_IWRITE); +#endif + if (fD == -1) { + SysError("TChirpFile", "file %s can not be opened", fname); + goto zombie; + } + fWritable = kTRUE; + } else { +#ifndef WIN32 + fD = SysOpen(fname, O_RDONLY, 0644); +#else + fD = SysOpen(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); +#endif + if (fD == -1) { + SysError("TFile", "file %s can not be opened for reading", fname); + goto zombie; + } + fWritable = kFALSE; + } + + Init(create || recreate); + + return; + +zombie: + // error in file opening occured, make this object a zombie + MakeZombie(); + gDirectory = gROOT; +} + +//______________________________________________________________________________ +TChirpFile::~TChirpFile() +{ + // Close and cleanup Chirp file. + + Close(); + CloseChirpClient(); +} + +//______________________________________________________________________________ +Bool_t TChirpFile::ReadBuffer(char *buf, Int_t len) +{ + // Read specified byte range from remote file via Chirp daemon. + // Returns kTRUE in case of error. + + if (fCache) { + Int_t st; + Seek_t off = fOffset; + if ((st = fCache->ReadBuffer(fOffset, buf, len)) < 0) { + Error("ReadBuffer", "error reading from cache"); + return kTRUE; + } + if (st > 0) { + // fOffset might have been changed via TCache::ReadBuffer(), reset it + fOffset = off + len; + return kFALSE; + } + } + + return TFile::ReadBuffer(buf, len); +} + +//______________________________________________________________________________ +Bool_t TChirpFile::WriteBuffer(const char *buf, Int_t len) +{ + // Write specified byte range to remote file via Chirp daemon. + // Returns kTRUE in case of error. + + if (!IsOpen() || !fWritable) return kTRUE; + + if (fCache) { + Int_t st; + Seek_t off = fOffset; + if ((st = fCache->WriteBuffer(fOffset, buf, len)) < 0) { + Error("WriteBuffer", "error writing to cache"); + return kTRUE; + } + if (st > 0) { + // fOffset might have been changed via TCache::WriteBuffer(), reset it + fOffset = off + len; + return kFALSE; + } + } + + return TFile::WriteBuffer(buf, len); +} + +//______________________________________________________________________________ +Int_t TChirpFile::OpenChirpClient(char const *URL, char const **path_part) +{ + // Caller should delete [] path when finished. + // URL format: chirp:machine.name:port/path + // or: chirp:path (use default connection to Condor job manager) + + *path_part = 0; + + CloseChirpClient(); + + chirp_client = chirp_client_connect_url(URL, path_part); + + if (!chirp_client) { + gSystem->SetErrorStr(strerror(errno)); + return -1; + } + return 0; +} + +//______________________________________________________________________________ +Int_t TChirpFile::CloseChirpClient() +{ + if (chirp_client) { + struct chirp_client *c = chirp_client; + chirp_client = 0; + + chirp_client_disconnect(c); + } + + return 0; +} + +//______________________________________________________________________________ +Int_t TChirpFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode) +{ + char open_flags[8]; + char *f = open_flags; + + if ((flags & O_WRONLY) || (flags & O_RDWR)) *(f++) = 'w'; + if ((flags & O_RDONLY) || (flags & O_RDWR) || !flags) *(f++) = 'r'; + if (flags & O_APPEND) *(f++) = 'a'; + if (flags & O_CREAT) *(f++) = 'c'; + if (flags & O_TRUNC) *(f++) = 't'; + if (flags & O_EXCL) *(f++) = 'x'; + + *f = '\0'; + + Int_t rc = chirp_client_open(chirp_client, pathname, open_flags, (Int_t) mode); + + if (rc < 0) { + gSystem->SetErrorStr(strerror(errno)); + } + + return rc; +} + +//______________________________________________________________________________ +Int_t TChirpFile::SysClose(Int_t fd) +{ + Int_t rc = chirp_client_close(chirp_client,fd); + + if (rc < 0) { + gSystem->SetErrorStr(strerror(errno)); + } + + return rc; +} + +//______________________________________________________________________________ +Int_t TChirpFile::SysRead(Int_t fd, void *buf, Int_t len) +{ + fOffset += len; + + Int_t rc = chirp_client_read(chirp_client, fd, buf, len); + + if (rc < 0) { + gSystem->SetErrorStr(strerror(errno)); + } + + return rc; +} + +//______________________________________________________________________________ +Int_t TChirpFile::SysWrite(Int_t fd, const void *buf, Int_t len) +{ + fOffset += len; + + Int_t rc = chirp_client_write(chirp_client, fd, (char *)buf, len); + + if (rc < 0) { + gSystem->SetErrorStr(strerror(errno)); + } + + return rc; +} + +//______________________________________________________________________________ +Seek_t TChirpFile::SysSeek(Int_t fd, Seek_t offset, Int_t whence) +{ + if(whence == SEEK_SET && offset == fOffset) return offset; + + Int_t rc = chirp_client_lseek(chirp_client, fd, offset, whence); + + if (rc < 0) { + gSystem->SetErrorStr(strerror(errno)); + } else { + fOffset = rc; + } + + return rc; +} + +//______________________________________________________________________________ +Int_t TChirpFile::SysSync(Int_t fd) +{ + Int_t rc = chirp_client_fsync(chirp_client, fd); + + if (rc < 0) { + gSystem->SetErrorStr(strerror(errno)); + } + + return rc; +} + +//______________________________________________________________________________ +Int_t TChirpFile::SysStat(Int_t fd, Long_t *id, Long_t *size, + Long_t *flags, Long_t *modtime) +{ + // FIXME: chirp library doesn't (yet) provide any stat() capabilities. + + *id = ::Hash(GetName()); + + Seek_t offset = fOffset; + *size = SysSeek(fd, 0, SEEK_END); + SysSeek(fd, offset, SEEK_SET); + + *flags = 0; + *modtime = 0; + return 0; +} + +//______________________________________________________________________________ +void TChirpFile::ResetErrno() const +{ + TSystem::ResetErrno(); +} diff --git a/config/Makefile.in b/config/Makefile.in index 52a9615c9ce8b234fe06d38740de0e82dd8d9fc5..4970d4cf5e940c52b3404dfe10a42ace466b4ac5 100644 --- a/config/Makefile.in +++ b/config/Makefile.in @@ -77,6 +77,10 @@ DCAPLIBDIR := @dcaplibdir@ DCAPLIB := @dcaplib@ DCAPINCDIR := @dcapincdir@ +CHIRPLIBDIR := @chirplibdir@ +CHIRPCLILIB := @chirplib@ +CHIRPINCDIR := @chirpincdir@ + ALIENLIBDIR := @alienlibdir@ ALIENCLILIB := @alienlib@ ALIENINCDIR := @alienincdir@ diff --git a/config/rootrc.in b/config/rootrc.in index c7697bed15e943f585de94f678f32820c66f3054..aaee74ece9e19c4e181ccab5f143e049c2dfcdb4 100644 --- a/config/rootrc.in +++ b/config/rootrc.in @@ -1,4 +1,4 @@ -# @(#)root/config:$Name: $:$Id: rootrc.in,v 1.36 2002/12/08 16:51:42 rdm Exp $ +# @(#)root/config:$Name: $:$Id: rootrc.in,v 1.37 2002/12/12 12:02:04 rdm Exp $ # Author: Fons Rademakers 22/09/95 # ROOT Environment settings are handled via the class TEnv. To see @@ -135,6 +135,7 @@ Proofd.Authentication: 0 # Plugin library handlers Plugin.TFile: ^rfio: TRFIOFile RFIO "TRFIOFile(const char*,Option_t*,const char*,Int_t)" +Plugin.TFile: ^dcache: TDCacheFile DCache "TDCacheFile(const char*,Option_t*,const char*,Int_t)" ++Plugin.TFile: ^chirp: TChirpFile Chirp "TChirpFile(const char*,Option_t*,const char*,Int_t)" Plugin.TSystem: ^rfio: TRFIOSystem RFIO "TRFIOSystem()" Plugin.TSQLServer: ^mysql: TMySQLServer MySQL "TMySQLServer(const char*,const char*,const char*)" +Plugin.TSQLServer: ^pgsql: TPgSQLServer PgSQL "TPgSQLServer(const char*,const char*,const char*)" diff --git a/configure b/configure index e454484207b42889460e27903136ac7392ce78bd..5e9c508f364a3dc242e0cad3208642c1fe40adc2 100755 --- a/configure +++ b/configure @@ -23,6 +23,7 @@ enable_afs=no enable_alien=yes enable_asimage=yes enable_cern=yes +enable_chirp=yes enable_dcache=yes enable_krb5=yes enable_ldap=yes @@ -41,9 +42,9 @@ enable_soversion=no enable_srp=yes enable_table=no enable_thread= # must be set explicitely via --enable-thread -enable_exceptions=yes enable_ttf=yes enable_venus=yes +enable_exceptions=yes show_pkglist=no options="enable_afs enable_cern enable_mysql enable_opengl enable_pgsql \ @@ -51,7 +52,7 @@ options="enable_afs enable_cern enable_mysql enable_opengl enable_pgsql \ enable_sapdb enable_shadowpw enable_shared enable_soversion \ enable_srp enable_table enable_thread enable_ttf enable_venus \ enable_krb5 enable_ldap enable_exceptions enable_openiv enable_alien \ - enable_asimage" + enable_asimage enable_chirp" ###################################################################### @@ -356,6 +357,7 @@ enable/disable options, prefix with either --enable- or --disable- alien AliEn support, requires libAliEn from ALICE asimage Image processing support, requires libAfterImage cern CERNLIB usage, build h2root and g2root + chirp Chirp support (Condor remote I/O), requires libchirp_client dcache dCache support, requires libdcap from DESY krb5 Kerberos5 support, requires Kerberos libs ldap LDAP support, requires (Open)LDAP libs @@ -383,6 +385,8 @@ with options, prefix with --with-, enables corresponding support asimage-incdir Image processing support, location of afterimage.h asimage-libdir Image processing support, location of libAfterImage cern-libdir HBOOK converter, location of CERNLIB libraries + chirp-incdir Chirp support, location of chirp_client.h + chirp-libdir Chirp support, location of libchirp_client dcap-incdir dCache support, location of dcap.h dcap-libdir dCache support, location of libdcap krb5 Kerberos5 support, location of Kerberos distribution @@ -478,6 +482,8 @@ if test $# -gt 0 ; then --with-asimage-incdir=*) asimageincdir=$optarg ; enable_asimage="yes" ;; --with-asimage-libdir=*) asimagelibdir=$optarg ; enable_asimage="yes" ;; --with-cern-libdir=*) cernlibdir=$optarg ; enable_cern="yes" ;; + --with-chirp-incdir=*) chirpincdir=$optarg ; enable_chirp="yes" ;; + --with-chirp-libdir=*) chirplibdir=$optarg ; enable_chirp="yes" ;; --with-dcap-incdir=*) dcapincdir=$optarg ; enable_dcache="yes" ;; --with-dcap-libdir=*) dcaplibdir=$optarg ; enable_dcache="yes" ;; --with-krb5=*) krb5dir=$optarg ; enable_krb5="yes" ;; @@ -1073,6 +1079,32 @@ if test ! "x$enable_dcache" = "xno" ; then fi fi +###################################################################### +# +### echo %%% Chirp Support - Third party libraries +# +# (See http://www.cs.wisc.edu/condor/chirp) +# +# Check for libchirp_client +# +if test ! "x$enable_chirp" = "xno" ; then + check_header "chirp_client.h" "$chirpincdir" $CHIRP $CHIRP/include \ + /opt/chirp/include /usr/include /usr/local/include + chirpincdir=$found_dir + + #At this time, libchirp_client.a should always be prefered over .so, + #to avoid problems with linkage on grid execute machines. + + check_library "libchirp_client" "no" "$chirplibdir" $CHIRP $CHIRP/lib \ + /opt/chirp/lib /usr/lib /usr/local/lib + chirplib=$found_lib + chirplibdir=$found_dir + + if test "x$chirpincdir" = "x" || test "x$chirplib" = "x"; then + enable_chirp="no" + fi +fi + ###################################################################### # ### echo %%% AliEn Support - Third party libraries @@ -1595,6 +1627,9 @@ sed \ -e "s|@bindir@|$bindir|" \ -e "s|@cernlibdir@|$cernlibdir|" \ -e "s|@cernlibs@|$cernlib|" \ + -e "s|@chirpincdir@|$chirpincdir|" \ + -e "s|@chirplib@|$chirplib|" \ + -e "s|@chirplibdir@|$chirplibdir|" \ -e "s|@cintincdir@|$cintincdir|" \ -e "s|@datadir@|$datadir|" \ -e "s|@dcapincdir@|$dcapincdir|" \