XRootD
XrdCmsBaseFS Class Reference

#include <XrdCmsBaseFS.hh>

+ Collaboration diagram for XrdCmsBaseFS:

Public Member Functions

 XrdCmsBaseFS (void(*theCB)(XrdCmsBaseFR *, int))
 
 ~XrdCmsBaseFS ()
 
int dfsTries ()
 
int Exists (char *Path, int fnPos, int UpAT=0)
 
int Exists (XrdCmsRRData &Arg, XrdCmsPInfo &Who, int noLim=0)
 
void Init (int Opts, int DMlife, int DPLife)
 
int isDFS ()
 
int Limit ()
 
void Limit (int rLim, int qMax)
 
int Local ()
 
void Pacer ()
 
void Runner ()
 
void SetTries (bool xdfs, int tcnt)
 
void Start ()
 
int stgTries ()
 
int Traverse ()
 
int Trim ()
 

Static Public Attributes

static const int Cntrl = 0x0001
 
static const int dfltDfsTries = 2
 
static const int dfltStgTries = 3
 
static const int DFSys = 0x0002
 
static const int Immed = 0x0004
 
static const int Servr = 0x0100
 

Detailed Description

Definition at line 87 of file XrdCmsBaseFS.hh.

Constructor & Destructor Documentation

◆ XrdCmsBaseFS()

XrdCmsBaseFS::XrdCmsBaseFS ( void(*)(XrdCmsBaseFR *, int)  theCB)
inline

Definition at line 149 of file XrdCmsBaseFS.hh.

150  : cBack(theCB), dfsMaxTries(dfltDfsTries),
151  stgMaxTries(dfltStgTries),
152  dmLife(0), dpLife(0), lclStat(0), preSel(1),
153  dfsSys(0), Server(0), Fixed(0), Punt(0) {}
static const int dfltStgTries
static const int dfltDfsTries

◆ ~XrdCmsBaseFS()

XrdCmsBaseFS::~XrdCmsBaseFS ( )
inline

Definition at line 154 of file XrdCmsBaseFS.hh.

154 {}

Member Function Documentation

◆ dfsTries()

int XrdCmsBaseFS::dfsTries ( )
inline

Definition at line 91 of file XrdCmsBaseFS.hh.

91 {return dfsMaxTries;}

Referenced by XrdCmsCluster::Select().

+ Here is the caller graph for this function:

◆ Exists() [1/2]

int XrdCmsBaseFS::Exists ( char *  Path,
int  fnPos,
int  UpAT = 0 
)

Definition at line 151 of file XrdCmsBaseFS.cc.

152 {
153  EPNAME("Exists");
154  static struct dMoP dirMiss = {0}, dirPres = {1};
155  static int badDStat = 0;
156  static int badFStat = 0;
157  struct stat buf;
158  int eCnt, fRC, dRC;
160 
161 // If directory checking is enabled, find where the directory component ends
162 // if so requested.
163 //
164  if (fnPos < 0 && dmLife)
165  {for (fnPos = -(fnPos+1); fnPos >= 0 && Path[fnPos] != '/'; fnPos--) {}
166  if (fnPos > 0 && !hasDir(Path, fnPos)) return -1;
167  }
168 
169 // Issue stat() via oss plugin. If it succeeds, return result.
170 //
171  if (!(fRC = Config.ossFS->Stat(Path, &buf, Opts)))
172  {if ((buf.st_mode & S_IFMT) == S_IFREG)
173  return (buf.st_mode & XRDSFS_POSCPEND ? CmsHaveRequest::Pending
174  : CmsHaveRequest::Online);
175 
176  return (buf.st_mode & S_IFMT) == S_IFDIR ? CmsHaveRequest::Online : -1;
177  }
178 
179 // The entry does not exist but if we are a staging server then it may be in
180 // the prepare queue in which case we must say that it is pending arrival.
181 //
182  if (Config.DiskSS && PrepQ.Exists(Path)) return CmsHaveRequest::Pending;
183 
184 // The entry does not exist. Check if the directory exists and if not, put it
185 // in our directory missing table so we don't keep hitting this directory.
186 // This is disabled by default and enabled by the cms.dfs directive.
187 //
188  if (fnPos > 0 && dmLife)
189  {struct dMoP *xVal = &dirMiss;
190  int xLife = dmLife;
191  Path[fnPos] = '\0';
192  if (!(dRC = Config.ossFS->Stat(Path, &buf, XRDOSS_resonly)))
193  {xLife = dpLife; xVal = &dirPres;}
194  if (dRC && dRC != -ENOENT)
195  {fsMutex.Lock(); eCnt = badDStat++; fsMutex.UnLock();
196  if (!(eCnt & 0xff))
197  {char buff[80];
198  snprintf(buff, sizeof(buff), "to stat dir (events=%d)", eCnt+1);
199  Say.Emsg("Exists", dRC, buff, Path);
200  Path[fnPos] = '/';
201  }
202  } else {
203  fsMutex.Lock();
204  fsDirMP.Rep(Path, xVal, xLife, Hash_keepdata);
205  fsMutex.UnLock();
206  DEBUG("add " <<xLife <<(xVal->Present ? " okdir ":" nodir ") <<Path);
207  Path[fnPos] = '/';
208  }
209  } else {
210  if (fRC && fRC != -ENOENT)
211  {fsMutex.Lock(); eCnt = badFStat++; fsMutex.UnLock();
212  if (!(eCnt & 0xff))
213  {char buff[80];
214  snprintf(buff, sizeof(buff), "to stat file (events=%d)", eCnt+1);
215  Say.Emsg("Exists", fRC, buff, Path);
216  }
217  }
218  }
219  return -1;
220 }
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
#define XRDOSS_resonly
Definition: XrdOss.hh:486
#define XRDOSS_updtatm
Definition: XrdOss.hh:487
@ Hash_keepdata
Definition: XrdOucHash.hh:57
int stat(const char *path, struct stat *buf)
XrdOucString Path
#define XRDSFS_POSCPEND
Definition: XrdSfsFlags.hh:89
XrdOss * ossFS
int Exists(char *path)
virtual int Stat(const char *path, struct stat *buff, int opts=0, XrdOucEnv *envP=0)=0
T * Rep(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
Definition: XrdOucHash.hh:166
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
XrdSysError Say
XrdCmsPrepare PrepQ
XrdCmsConfig Config
int Opts
Definition: XrdMpxStats.cc:58

References XrdCms::Config, DEBUG, XrdCmsConfig::DiskSS, XrdSysError::Emsg(), EPNAME, XrdCmsPrepare::Exists(), Hash_keepdata, XrdCms::CmsHaveRequest::Online, XrdMpx::Opts, XrdCmsConfig::ossFS, Path, XrdCms::CmsHaveRequest::Pending, XrdCms::PrepQ, XrdCms::Say, stat(), XrdOss::Stat(), XRDOSS_resonly, XRDOSS_updtatm, and XRDSFS_POSCPEND.

+ Here is the call graph for this function:

◆ Exists() [2/2]

int XrdCmsBaseFS::Exists ( XrdCmsRRData Arg,
XrdCmsPInfo Who,
int  noLim = 0 
)

Definition at line 115 of file XrdCmsBaseFS.cc.

116 {
117  int aOK, fnPos;
118 
119 // If we cannot do this locally, then we need to forward the request but only
120 // if we have a route. Otherwise, just indicate that queueing is necessary.
121 //
122  if (!lclStat)
123  {aOK = (!theQ.rLimit || noLim || (!Fixed && Bypass()));
124  if (Who.rovec) Queue(Arg, Who, -(Arg.PathLen-1), !aOK);
125  return 0;
126  }
127 
128 // If directory checking is enabled, find where the directory component ends
129 // and then check if we even have this directory.
130 //
131  if (dmLife)
132  {for (fnPos=Arg.PathLen-2;fnPos >= 0 && Arg.Path[fnPos] != '/';fnPos--) {}
133  if (fnPos > 0 && !hasDir(Arg.Path, fnPos)) return -1;
134  } else fnPos = 0;
135 
136 // If we are not limiting requests, or not limiting everyone and this is not
137 // a meta-manager, or we are not timing requests and can skip the queue; then
138 // issue the fstat() inline and report back the result.
139 //
140  if (!theQ.rLimit || noLim || (Fixed && Bypass()))
141  return Exists(Arg.Path, fnPos);
142 
143 // We can't do this now, so forcibly queue the request
144 //
145  if (Who.rovec) Queue(Arg, Who, fnPos, 1);
146  return 0;
147 }
int Exists(XrdCmsRRData &Arg, XrdCmsPInfo &Who, int noLim=0)
SMask_t rovec
Definition: XrdCmsPList.hh:47

References Exists, XrdCmsRRData::Path, XrdCmsRRData::PathLen, and XrdCmsPInfo::rovec.

Referenced by XrdCmsNode::do_State(), and XrdCmsNode::do_StateFWD().

+ Here is the caller graph for this function:

◆ Init()

void XrdCmsBaseFS::Init ( int  Opts,
int  DMlife,
int  DPLife 
)

Definition at line 245 of file XrdCmsBaseFS.cc.

246 {
247 
248 // Set values.
249 //
250  dmLife = DMLife;
251  dpLife = DPLife ? DPLife : DMLife * 10;
252  Server = (Opts & Servr) != 0;
253  lclStat = (Opts & Cntrl) != 0 || Server;
254  preSel = (Opts & Immed) == 0;
255  dfsSys = (Opts & DFSys) != 0;
256 }
static const int Immed
static const int Servr
static const int Cntrl
static const int DFSys

References XrdMpx::Opts.

Referenced by XrdCmsConfig::Configure1().

+ Here is the caller graph for this function:

◆ isDFS()

int XrdCmsBaseFS::isDFS ( )
inline

Definition at line 119 of file XrdCmsBaseFS.hh.

119 {return dfsSys;}

Referenced by XrdCmsConfig::Configure2(), XrdCmsNode::do_Gone(), XrdCmsNode::do_Have(), XrdCmsNode::do_Locate(), XrdCmsNode::do_SelAvoid(), XrdCmsNode::do_StateFWD(), XrdCmsCluster::Locate(), XrdCmsCluster::Select(), and XrdCmsCluster::Space().

+ Here is the caller graph for this function:

◆ Limit() [1/2]

int XrdCmsBaseFS::Limit ( )
inline

Definition at line 121 of file XrdCmsBaseFS.hh.

121 {return theQ.rLimit;}

Referenced by XrdCmsNode::do_State().

+ Here is the caller graph for this function:

◆ Limit() [2/2]

void XrdCmsBaseFS::Limit ( int  rLim,
int  qMax 
)

Definition at line 262 of file XrdCmsBaseFS.cc.

263 {
264 
265 // Establish the limits
266 //
267  if (rLim < 0) {theQ.rAgain=theQ.rLeft = -1; rLim = -rLim; Fixed = 1;}
268  else {theQ.rAgain = theQ.rLeft = (rLim > 1 ? rLim/2 : 1); Fixed = 0;}
269  theQ.rLimit = (rLim <= 1000 ? rLim : 0);
270  if (Qmax > 0) theQ.qMax = Qmax;
271  else if (!(theQ.qMax = theQ.rLimit*2 + theQ.rLimit/2)) theQ.qMax = 1;
272 }

◆ Local()

int XrdCmsBaseFS::Local ( )
inline

Definition at line 125 of file XrdCmsBaseFS.hh.

125 {return lclStat;}

Referenced by XrdCmsConfig::Configure1().

+ Here is the caller graph for this function:

◆ Pacer()

void XrdCmsBaseFS::Pacer ( )

Definition at line 278 of file XrdCmsBaseFS.cc.

279 {
280  XrdCmsBaseFR *rP;
281  int inQ, rqRate = 1000/theQ.rLimit;
282 
283 // Process requests at the given rate
284 //
285 do{theQ.pqAvail.Wait();
286  theQ.Mutex.Lock(); inQ = 1;
287  while((rP = theQ.pqFirst))
288  {if (!(theQ.pqFirst = rP->Next)) {theQ.pqLast = 0; inQ = 0;}
289  theQ.Mutex.UnLock();
290  if (rP->PDirLen > 0 && !hasDir(rP->Path, rP->PDirLen))
291  {delete rP; continue;}
292  theQ.Mutex.Lock();
293  if (theQ.rqFirst) {theQ.rqLast->Next = rP; theQ.rqLast = rP;}
294  else {theQ.rqFirst = theQ.rqLast = rP; theQ.rqAvail.Post();}
295  theQ.Mutex.UnLock();
296  XrdSysTimer::Wait(rqRate);
297  if (!inQ) break;
298  theQ.Mutex.Lock();
299  }
300  if (inQ) theQ.Mutex.UnLock();
301  } while(1);
302 }
XrdCmsBaseFR * Next
Definition: XrdCmsBaseFS.hh:54
static void Wait(int milliseconds)
Definition: XrdSysTimer.cc:227

References XrdCmsBaseFR::Next, XrdCmsBaseFR::Path, XrdCmsBaseFR::PDirLen, and XrdSysTimer::Wait().

+ Here is the call graph for this function:

◆ Runner()

void XrdCmsBaseFS::Runner ( )

Definition at line 354 of file XrdCmsBaseFS.cc.

355 {
356  XrdCmsBaseFR *rP;
357  int inQ;
358 
359 // Process requests at the given rate
360 //
361 do{theQ.rqAvail.Wait();
362  theQ.Mutex.Lock(); inQ = 1;
363  while((rP = theQ.rqFirst))
364  {if (!(theQ.rqFirst = rP->Next)) {theQ.rqLast = 0; inQ = 0;}
365  theQ.qNum--;
366  theQ.Mutex.UnLock();
367  Xeq(rP); delete rP;
368  if (!inQ) break;
369  theQ.Mutex.Lock();
370  }
371  if (inQ) theQ.Mutex.UnLock();
372  } while(1);
373 }

References XrdCmsBaseFR::Next.

◆ SetTries()

void XrdCmsBaseFS::SetTries ( bool  xdfs,
int  tcnt 
)
inline

Definition at line 134 of file XrdCmsBaseFS.hh.

135  {if (xdfs) dfsMaxTries =
136  (tcnt < 0 ? dfltDfsTries : tcnt);
137  else stgMaxTries =
138  (tcnt < 1 ? dfltStgTries : tcnt);
139  }

References dfltDfsTries, and dfltStgTries.

◆ Start()

void XrdCmsBaseFS::Start ( )

Definition at line 379 of file XrdCmsBaseFS.cc.

380 {
381  EPNAME("Start");
382  void *Me = (void *)this;
383  pthread_t tid;
384 
385 // Issue some debugging here so we know how we are starting up
386 //
387  DEBUG("Srv=" <<int(Server) <<" dfs=" <<int(dfsSys) <<" lcl=" <<int(lclStat)
388  <<" Pre=" <<int(preSel) <<" dmLife=" <<dmLife <<' ' <<dpLife);
389  DEBUG("Lim=" <<theQ.rLimit <<' ' <<theQ.rAgain <<" fix=" <<int(Fixed)
390  <<" Qmax=" <<theQ.qMax);
391 
392 // Set the passthru option if we can't do this locally and have no limit
393 //
394  Punt = (!theQ.rLimit && !lclStat);
395 
396 // If we need to throttle we will need two threads for the queue. The first is
397 // the pacer thread that feeds the runner thread at a fixed rate.
398 //
399  if (theQ.rLimit)
400  {if (XrdSysThread::Run(&tid, XrdCmsBasePacer, Me, 0, "fsQ pacer")
401  || XrdSysThread::Run(&tid, XrdCmsBaseRunner, Me, 0, "fsQ runner"))
402  {Say.Emsg("cmsd", errno, "start baseFS queue handler");
403  theQ.rLimit = 0;
404  }
405  }
406 }
void * XrdCmsBaseRunner(void *carg)
Definition: XrdCmsBaseFS.cc:63
void * XrdCmsBasePacer(void *carg)
Definition: XrdCmsBaseFS.cc:58
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)

References DEBUG, XrdSysError::Emsg(), EPNAME, XrdSysThread::Run(), XrdCms::Say, XrdCmsBasePacer(), and XrdCmsBaseRunner().

Referenced by XrdCmsConfig::Configure2().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ stgTries()

int XrdCmsBaseFS::stgTries ( )
inline

Definition at line 143 of file XrdCmsBaseFS.hh.

143 {return stgMaxTries;}

Referenced by XrdCmsCluster::Select().

+ Here is the caller graph for this function:

◆ Traverse()

int XrdCmsBaseFS::Traverse ( )
inline

Definition at line 147 of file XrdCmsBaseFS.hh.

147 {return Punt;}

Referenced by XrdCmsNode::do_StateFWD().

+ Here is the caller graph for this function:

◆ Trim()

int XrdCmsBaseFS::Trim ( )
inline

Definition at line 145 of file XrdCmsBaseFS.hh.

145 {return preSel;}

Referenced by XrdCmsCluster::Select().

+ Here is the caller graph for this function:

Member Data Documentation

◆ Cntrl

const int XrdCmsBaseFS::Cntrl = 0x0001
static

Definition at line 112 of file XrdCmsBaseFS.hh.

Referenced by XrdCmsConfig::Configure1().

◆ dfltDfsTries

const int XrdCmsBaseFS::dfltDfsTries = 2
static

Definition at line 131 of file XrdCmsBaseFS.hh.

Referenced by SetTries().

◆ dfltStgTries

const int XrdCmsBaseFS::dfltStgTries = 3
static

Definition at line 132 of file XrdCmsBaseFS.hh.

Referenced by SetTries().

◆ DFSys

const int XrdCmsBaseFS::DFSys = 0x0002
static

Definition at line 113 of file XrdCmsBaseFS.hh.

Referenced by XrdCmsConfig::Configure1().

◆ Immed

const int XrdCmsBaseFS::Immed = 0x0004
static

Definition at line 114 of file XrdCmsBaseFS.hh.

Referenced by XrdCmsConfig::Configure1().

◆ Servr

const int XrdCmsBaseFS::Servr = 0x0100
static

Definition at line 115 of file XrdCmsBaseFS.hh.


The documentation for this class was generated from the following files: