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