00001 #ifndef XRD_CLIENT_H 00002 #define XRD_CLIENT_H 00003 /******************************************************************************/ 00004 /* */ 00005 /* X r d C l i e n t . h h */ 00006 /* */ 00007 /* Author: Fabrizio Furano (INFN Padova, 2004) */ 00008 /* Adapted from TXNetFile (root.cern.ch) originally done by */ 00009 /* Alvise Dorigo, Fabrizio Furano */ 00010 /* INFN Padova, 2003 */ 00011 /* */ 00012 /* This file is part of the XRootD software suite. */ 00013 /* */ 00014 /* XRootD is free software: you can redistribute it and/or modify it under */ 00015 /* the terms of the GNU Lesser General Public License as published by the */ 00016 /* Free Software Foundation, either version 3 of the License, or (at your */ 00017 /* option) any later version. */ 00018 /* */ 00019 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ 00020 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ 00021 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ 00022 /* License for more details. */ 00023 /* */ 00024 /* You should have received a copy of the GNU Lesser General Public License */ 00025 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ 00026 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */ 00027 /* */ 00028 /* The copyright holder's institutional names and contributor's names may not */ 00029 /* be used to endorse or promote products derived from this software without */ 00030 /* specific prior written permission of the institution or contributor. */ 00031 /******************************************************************************/ 00032 00034 // // 00035 // A UNIX reference client for xrootd. // 00036 // // 00038 00040 // // 00041 // // 00042 // Some features: // 00043 // - Automatic server kind recognition (xrootd load balancer, xrootd // 00044 // data server, old rootd) // 00045 // - Fault tolerance for read/write operations (read/write timeouts // 00046 // and retry) // 00047 // - Internal connection timeout (tunable indipendently from the OS // 00048 // one) // 00049 // - Full implementation of the xrootd protocol // 00050 // - handling of redirections from server // 00051 // - Connection multiplexing // 00052 // - Asynchronous operation mode // 00053 // - High performance read caching with read-ahead // 00054 // - Thread safe // 00055 // - Tunable log verbosity level (0 = nothing, 3 = dump read/write // 00056 // buffers too!) // 00057 // - Many parameters configurable. But the default are OK for nearly // 00058 // all the situations. // 00059 // // 00061 00062 #include "XProtocol/XProtocol.hh" 00063 00064 #include "XrdClient/XrdClientAbs.hh" 00065 #include "XrdClient/XrdClientConst.hh" 00066 #include "XrdOuc/XrdOucString.hh" 00067 #include "XrdSys/XrdSysSemWait.hh" 00068 #include "XrdVersion.hh" 00069 #include <vector> 00070 #include <string> 00071 00072 class XrdClientReadAheadMgr; 00073 class XrdClientThread; 00074 00075 struct XrdClientOpenInfo { 00076 bool inprogress; 00077 bool opened; 00078 kXR_unt16 mode; 00079 kXR_unt16 options; 00080 }; 00081 00082 struct XrdClientStatInfo { 00083 int stated; 00084 long long size; 00085 long id; 00086 long flags; 00087 long modtime; 00088 }; 00089 00090 struct XrdClientCounters { 00091 int CacheSize; 00092 00093 // This does not take into account the 'suggestions' 00094 // like async read or async readV 00095 // We count only for functions which return data, eventually 00096 // taken from the cache 00097 long long ReadBytes; 00098 long long WrittenBytes; 00099 long long WriteRequests; 00100 00101 long long ReadRequests; 00102 long long ReadMisses; 00103 long long ReadHits; 00104 float ReadMissRate; 00105 00106 long long ReadVRequests; // How many readVs (sync) were requested 00107 long long ReadVSubRequests; // In how many sub-readVs they were split 00108 long long ReadVSubChunks; // How many subchunks in total 00109 long long ReadVBytes; // How many bytes were requested (sync) 00110 00111 long long ReadVAsyncRequests; // How many readVs (async) were requested 00112 long long ReadVAsyncSubRequests; // In how many sub-readVs they were split 00113 long long ReadVAsyncSubChunks; // How many subchunks in total 00114 long long ReadVAsyncBytes; // How many bytes were requested (async) 00115 00116 long long ReadAsyncRequests; 00117 long long ReadAsyncBytes; 00118 }; 00119 00120 00121 class XrdClient : public XrdClientAbs { 00122 friend void *FileOpenerThread(void*, XrdClientThread*); 00123 00124 00125 private: 00126 00127 struct XrdClientOpenInfo fOpenPars; // Just a container for the last parameters 00128 // passed to a Open method 00129 00130 // The open request can be in progress. Further requests must be delayed until 00131 // finished. 00132 XrdSysCondVar *fOpenProgCnd; 00133 00134 // Used to open a file in parallel 00135 XrdClientThread *fOpenerTh; 00136 00137 // Used to limit the maximum number of concurrent opens 00138 static XrdSysSemWait fConcOpenSem; 00139 00140 bool fOpenWithRefresh; 00141 00142 XrdSysCondVar *fReadWaitData; // Used to wait for outstanding data 00143 00144 struct XrdClientStatInfo fStatInfo; 00145 00146 long fReadTrimBlockSize; 00147 00148 bool fUseCache; 00149 00150 XrdOucString fInitialUrl; 00151 XrdClientUrlInfo fUrl; 00152 00153 bool TryOpen(kXR_unt16 mode, 00154 kXR_unt16 options, 00155 bool doitparallel); 00156 00157 bool LowOpen(const char *file, 00158 kXR_unt16 mode, 00159 kXR_unt16 options, 00160 char *additionalquery = 0); 00161 00162 void TerminateOpenAttempt(); 00163 00164 void WaitForNewAsyncData(); 00165 00166 // Real implementation for ReadV 00167 // To call it we need to be aware of the restrictions so the public 00168 // interface should be ReadV() 00169 kXR_int64 ReadVEach(char *buf, kXR_int64 *offsets, int *lens, int &nbuf); 00170 00171 bool IsOpenedForWrite() { 00172 // This supposes that no options means read only 00173 if (!fOpenPars.options) return false; 00174 00175 if (fOpenPars.options & kXR_open_read) return false; 00176 00177 return true; 00178 } 00179 00180 XrdClientReadAheadMgr *fReadAheadMgr; 00181 00182 void PrintCounters(); 00183 protected: 00184 00185 XrdClientCounters fCounters; 00186 00187 virtual bool OpenFileWhenRedirected(char *newfhandle, 00188 bool &wasopen); 00189 00190 virtual bool CanRedirOnError() { 00191 // Can redir away on error if no file is opened 00192 // or the file is opened in read mode 00193 00194 if ( !fOpenPars.opened ) return true; 00195 00196 return !IsOpenedForWrite(); 00197 00198 } 00199 00200 00201 public: 00202 00203 XrdClient(const char *url, XrdClientCallback *XrdCcb = 0, void *XrdCcbArg = 0); 00204 virtual ~XrdClient(); 00205 00206 UnsolRespProcResult ProcessUnsolicitedMsg(XrdClientUnsolMsgSender *sender, 00207 XrdClientMessage *unsolmsg); 00208 00209 bool Close(); 00210 00211 // Ask the server to flush its cache 00212 bool Sync(); 00213 00214 // Copy the whole file to the local filesystem. Not very efficient. 00215 bool Copy(const char *localpath); 00216 00217 // Returns low level information about the cache 00218 bool GetCacheInfo( 00219 // The actual cache size 00220 int &size, 00221 00222 // The number of bytes submitted since the beginning 00223 long long &bytessubmitted, 00224 00225 // The number of bytes found in the cache (estimate) 00226 long long &byteshit, 00227 00228 // The number of reads which did not find their data 00229 // (estimate) 00230 long long &misscount, 00231 00232 // miss/totalreads ratio (estimate) 00233 float &missrate, 00234 00235 // number of read requests towards the cache 00236 long long &readreqcnt, 00237 00238 // ratio between bytes found / bytes submitted 00239 float &bytesusefulness 00240 ); 00241 00242 00243 00244 // Returns client-level information about the activity performed up to now 00245 bool GetCounters( XrdClientCounters *cnt ); 00246 00247 // Quickly tells if the file is open 00248 inline bool IsOpen() { return fOpenPars.opened; } 00249 00250 // Tells if the file opening is in progress 00251 bool IsOpen_inprogress(); 00252 00253 // Tells if the file is open, waiting for the completion of the parallel open 00254 bool IsOpen_wait(); 00255 00256 // Open the file. See the xrootd documentation for mode and options 00257 // If parallel, then the open is done by a separate thread, and 00258 // all the operations are delayed until the open has finished 00259 bool Open(kXR_unt16 mode, kXR_unt16 options, bool doitparallel=true); 00260 00261 // Read a block of data. If no error occurs, it returns all the requested bytes. 00262 int Read(void *buf, long long offset, int len); 00263 00264 // Read multiple blocks of data compressed into a sinle one. It's up 00265 // to the application to do the logistic (having the offset and len to find 00266 // the position of the required buffer given the big one). If no error 00267 // occurs, it returns all the requested bytes. 00268 // NOTE: if buf == 0 then the req will be carried out asynchronously, i.e. 00269 // the result of the request will only populate the internal cache. A subsequent read() 00270 // of that chunk will get the data from the cache 00271 kXR_int64 ReadV(char *buf, long long *offsets, int *lens, int nbuf); 00272 00273 // Submit an asynchronous read request. Its result will only populate the cache 00274 // (if any!!) 00275 XReqErrorType Read_Async(long long offset, int len, bool updatecounters=true); 00276 00277 // Get stat info about the file. Normally it tries to guess the file size variations 00278 // unless force==true 00279 bool Stat(struct XrdClientStatInfo *stinfo, bool force = false); 00280 00281 // On-the-fly enabling/disabling of the cache 00282 bool UseCache(bool u = true); 00283 00284 // To instantly remove all the chunks in the cache 00285 void RemoveAllDataFromCache(); 00286 00287 // To remove pieces of data from the cache 00288 void RemoveDataFromCache(long long begin_offs, 00289 long long end_offs, 00290 bool remove_overlapped = false); 00291 00292 // To set at run time the cache/readahead parameters for this instance only 00293 // If a parameter is < 0 then it's left untouched. 00294 // To simply enable/disable the caching, just use UseCache(), not this function 00295 void SetCacheParameters(int CacheSize, int ReadAheadSize, int RmPolicy); 00296 00297 // To enable/disable different read ahead strategies. Defined in XrdClientReadAhead.hh 00298 void SetReadAheadStrategy(int strategy); 00299 00300 // To enable the trimming of the blocks to read. Blocksize will be rounded to a multiple of 512. 00301 // Each read request will have the offset and length aligned with a multiple of blocksize 00302 // This strategy is similar to a read ahead, but not quite. Here we see it as a transformation 00303 // of the stream of the read accesses to request 00304 void SetBlockReadTrimming(int blocksize); 00305 00306 // Truncates the open file at a specified length 00307 bool Truncate(long long len); 00308 00309 // Write data to the file 00310 bool Write(const void *buf, long long offset, int len); 00311 00312 std::vector<std::string> fExcludedHosts; 00313 00314 }; 00315 #endif