XRootD
Loading...
Searching...
No Matches
XrdOssSpace Class Reference

#include <XrdOssSpace.hh>

+ Collaboration diagram for XrdOssSpace:

Classes

struct  uEnt
 

Public Types

enum  sType {
  Serv = 0 ,
  Pstg = 1 ,
  Purg = 2 ,
  Admin = 3 ,
  RsvA = 4 ,
  RsvB = 5 ,
  RsvC = 6 ,
  addT = 7 ,
  Totn = 8
}
 

Public Member Functions

 XrdOssSpace ()
 
 ~XrdOssSpace ()
 

Static Public Member Functions

static void Adjust (const char *GName, off_t Space, sType=Serv)
 
static void Adjust (int Gent, off_t Space, sType=Serv)
 
static int Init ()
 
static int Init (const char *aPath, const char *qFile, int isSOL, int us=0)
 
static int Quotas ()
 
static int Unassign (const char *GName)
 
static long long Usage (const char *GName, struct uEnt &uVal, int rrd=0)
 
static long long Usage (int gent)
 

Static Public Attributes

static const int haveQuota = 2
 
static const int haveUsage = 1
 
static const int maxSNlen = 63
 
static const int minSNbsz = 64
 

Friends

class XrdOssCache
 

Detailed Description

Definition at line 35 of file XrdOssSpace.hh.


Class Documentation

◆ XrdOssSpace::uEnt

struct XrdOssSpace::uEnt

Definition at line 64 of file XrdOssSpace.hh.

+ Collaboration diagram for XrdOssSpace::uEnt:
Class Members
long long Bytes[Totn]
char gName[minSNbsz]

Member Enumeration Documentation

◆ sType

Enumerator
Serv 
Pstg 
Purg 
Admin 
RsvA 
RsvB 
RsvC 
addT 
Totn 

Definition at line 40 of file XrdOssSpace.hh.

Constructor & Destructor Documentation

◆ XrdOssSpace()

XrdOssSpace::XrdOssSpace ( )
inline

Definition at line 70 of file XrdOssSpace.hh.

70{} // Everything is static

◆ ~XrdOssSpace()

XrdOssSpace::~XrdOssSpace ( )
inline

Definition at line 71 of file XrdOssSpace.hh.

71{} // Never gets deleted

Member Function Documentation

◆ Adjust() [1/2]

void XrdOssSpace::Adjust ( const char * GName,
off_t Space,
sType stNum = Serv )
static

Definition at line 142 of file XrdOssSpace.cc.

143{
144 int i;
145
146// Try to find the current entry in the file
147//
148 if ((i = findEnt(GName)) >= 0) Adjust(i, Space, stNum);
149}
static void Adjust(int Gent, off_t Space, sType=Serv)

References Adjust().

+ Here is the call graph for this function:

◆ Adjust() [2/2]

void XrdOssSpace::Adjust ( int Gent,
off_t Space,
sType stNum = Serv )
static

Definition at line 81 of file XrdOssSpace.cc.

82{
83 XrdSysMutexHelper uHelp(uMutex);
84 int offset, unlk = 0;
85 int uOff = offsetof(uEnt,Bytes[0]) + (sizeof(long long)*stNum);
86
87// Verify the entry number
88//
89 if (Gent < 0 || Gent >= fencEnt) return;
90 offset = sizeof(uEnt)*Gent + uOff;
91
92// For stand-alone processes, we need to convert server adjustments to make
93// the update inter-process safe.
94//
95 if (Solitary && stNum == Serv) stNum = (Space > 0 ? Pstg : Purg);
96
97// Check if we need a lock and a refresh. For admin stats we need to make the
98// result idempotent w.r.t. updates by convoluting pstg/purg space numbers.
99//
100 if (stNum != Serv)
101 {if (!UsageLock()) return;
102 if (pread(aFD, &uData[Gent], sizeof(uEnt), offset-uOff) < 0)
103 {OssEroute.Emsg("Adjust", errno, "read usage file", uFname);
104 UsageLock(0); return;
105 }
106 if (stNum == Admin)
107 {uData[Gent].Bytes[Admin] = 0;
108 Space = Space - uData[Gent].Bytes[Pstg] + uData[Gent].Bytes[Purg];
109 }
110 unlk = 1;
111 }
112
113// Update the space statistic (protected by caller's mutex)
114//
115 if ((uData[Gent].Bytes[stNum] += Space) < 0 && stNum != Admin)
116 uData[Gent].Bytes[stNum] = 0;
117
118// Write out the the changed field. For servers, we can do this without a lock
119// because we are the only ones allowed to write this field.
120//
121 if (pwrite(aFD, &uData[Gent].Bytes[stNum], ULen, offset) < 0)
122 OssEroute.Emsg("Adjust", errno, "update usage file", uFname);
123
124// Update the time this occurred if we are not a server
125//
126 if (stNum != Serv) utimes(uUname, 0);
127
128// Check if we need to sync the file
129//
130 if (uSync)
131 {uAdj++;
132 if (uAdj >= uSync) {fsync(aFD); uAdj = 0;}
133 }
134
135// Unlock the file if we locked it
136//
137 if (unlk) UsageLock(0);
138}
XrdSysError OssEroute
#define fsync(a)
Definition XrdPosix.hh:59
#define pwrite(a, b, c, d)
Definition XrdPosix.hh:102
#define pread(a, b, c, d)
Definition XrdPosix.hh:75
long long Bytes[Totn]
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)

References Admin, XrdOssSpace::uEnt::Bytes, XrdSysError::Emsg(), fsync, OssEroute, pread, Pstg, Purg, pwrite, and Serv.

Referenced by XrdOssCache::Adjust(), XrdOssCache::Adjust(), and Adjust().

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

◆ Init() [1/2]

int XrdOssSpace::Init ( )
static

Definition at line 224 of file XrdOssSpace.cc.

224{return (uFname ? haveUsage:0) | (qFname ? haveQuota:0);}
static const int haveQuota
static const int haveUsage

References haveQuota, and haveUsage.

Referenced by XrdOssCache::Init().

+ Here is the caller graph for this function:

◆ Init() [2/2]

int XrdOssSpace::Init ( const char * aPath,
const char * qFile,
int isSOL,
int us = 0 )
static

Definition at line 228 of file XrdOssSpace.cc.

229{
230 static const mode_t theMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
231 struct stat buf;
232 const char *iP;
233 char *aP, buff[1048];
234 int i, opts, updt = 0;
235
236// Initialize th usage array now
237//
238 memset(uData, 0, sizeof(uData));
239
240// Indicate whether we are solitary or not
241//
242 Solitary = isSOL;
243
244// Handle quota file first
245//
246 if (qPath)
247 {qFname = strdup(qPath);
248 if (!Quotas()) return 0;
249 XrdOucEnv::Export("XRDOSSQUOTAFILE", qFname);
250 }
251
252// Construct the file path for the usage file
253//
254 if (!aPath) return 1;
255 strcpy(buff, aPath);
256 aP = buff + strlen(aPath);
257 if (*(aP-1) != '/') *aP++ = '/';
258 if ((iP = XrdOucUtils::InstName(-1)))
259 {strcpy(aP, iP); aP += strlen(iP); *aP++ = '/'; *aP = '\0';
260 mkdir(buff, S_IRWXU | S_IRWXG);
261 }
262 strcpy(aP, ".Usage");
263 uFname = strdup(buff);
264 strcpy(aP, ".Usage.upd");
265 uUname = strdup(buff);
266 XrdOucEnv::Export("XRDOSSUSAGEFILE", uFname);
267
268// Create the usage update file if it does not exist
269//
270 if ((i = open(uUname, O_CREAT|O_TRUNC|O_RDWR, theMode)) < 0)
271 {OssEroute.Emsg("Init", errno, "create", uUname);
272 return 0;
273 } else {
274 if (!fstat(i, &buf)) lastUtime = buf.st_mtime;
275 close(i);
276 utimes(uUname, 0);
277 }
278
279// First check if the file really exists, if not, create it
280//
281 if (stat(uFname, &buf))
282 if (errno != ENOENT)
283 {OssEroute.Emsg("Init", errno, "open", uFname);
284 return 0;
285 } else opts = O_CREAT|O_TRUNC;
286 else if ( buf.st_size != DataSz && buf.st_size)
287 {OssEroute.Emsg("Init", uFname, "has invalid size."); return 0;}
288 else opts = 0;
289
290// Handle synchornization
291//
292 if (us > 1) uSync = us;
293 else opts |= O_DSYNC;
294
295// Open the target file
296//
297 if ((aFD = XrdSysFD_Open(uFname, opts|O_RDWR, theMode)) < 0)
298 {OssEroute.Emsg("Init", errno, "open", uFname);
299 return 0;
300 }
301
302// Lock the file
303//
304 UsageLock();
305
306// Either read the contents or initialize the contents
307//
308 if (opts & O_CREAT || buf.st_size == 0)
309 {if (!write(aFD, uData, sizeof(uData)))
310 {OssEroute.Emsg("Init", errno, "create", uFname);
311 UsageLock(0); return 0;
312 }
313 fencEnt = 0; freeEnt = 0;
314 } else {
315 if (!read(aFD, uData, sizeof(uData)))
316 {OssEroute.Emsg("Init", errno, "read", uFname);
317 UsageLock(0); return 0;
318 }
319 for (i = 0; i < maxEnt; i++)
320 {if (*uData[i].gName != '\0')
321 {uDvec[fencEnt++] = i; updt |= Readjust(i);}
322 else if (freeEnt < 0) freeEnt = i;
323 }
324 if (freeEnt < 0) OssEroute.Emsg("Init", uFname, "is full.");
325 }
326
327// If we need to rewrite the data, do so
328//
329 if (updt && pwrite(aFD, uData, sizeof(uData), 0) < 0)
330 OssEroute.Emsg("Init", errno, "rewrite", uFname);
331
332// All done
333//
334 UsageLock(0);
335 sprintf(buff, "%d usage log entries in use; %d available.",
336 fencEnt, maxEnt-fencEnt);
337 OssEroute.Emsg("Init", buff);
338 return 1;
339}
#define close(a)
Definition XrdPosix.hh:43
#define fstat(a, b)
Definition XrdPosix.hh:57
#define write(a, b, c)
Definition XrdPosix.hh:110
#define mkdir(a, b)
Definition XrdPosix.hh:69
#define open
Definition XrdPosix.hh:71
#define stat(a, b)
Definition XrdPosix.hh:96
#define read(a, b, c)
Definition XrdPosix.hh:77
struct myOpts opts
static int Quotas()
static int Export(const char *Var, const char *Val)
Definition XrdOucEnv.cc:170
static const char * InstName(int TranOpt=0)

References close, XrdSysError::Emsg(), XrdOucEnv::Export(), fstat, XrdOucUtils::InstName(), mkdir, open, opts, OssEroute, pwrite, Quotas(), read, stat, and write.

+ Here is the call graph for this function:

◆ Quotas()

int XrdOssSpace::Quotas ( )
static

Definition at line 345 of file XrdOssSpace.cc.

346{
349 struct stat buf;
350 long long qval;
351 char cgroup[minSNbsz], *val;
352 int qFD, NoGo = 0;
353
354// See if the file has changed (note the firs time through it will have)
355//
356 if (stat(qFname,&buf))
357 {OssEroute.Emsg("Quotas", errno, "process quota file", qFname);
358 return 0;
359 }
360 if (buf.st_mtime == lastMtime) return 0;
361 lastMtime = buf.st_mtime;
362
363// Try to open the quota file.
364//
365 if ( (qFD = open(qFname, O_RDONLY, 0)) < 0)
366 {OssEroute.Emsg("Quotas", errno, "open quota file", qFname);
367 return 0;
368 }
369
370// Attach the file to a stream and tell people what we are doing
371//
372 OssEroute.Emsg("Quotas", "Processing quota file", qFname);
373 Config.Attach(qFD);
374 XrdOucString *capstr = Config.Capture((XrdOucString *)0);
375
376// Now start reading records until eof.
377//
378 while((val = Config.GetMyFirstWord()))
379 {if (strlen(val) >= sizeof(cgroup))
380 {OssEroute.Emsg("Quotas", "invalid quota group =", val);
381 NoGo = 1; continue;
382 }
383 strcpy(cgroup, val);
384
385 if (!(val = Config.GetWord()))
386 {OssEroute.Emsg("Quotas", "quota value not specified for", cgroup);
387 NoGo = 1; continue;
388 }
389 if (XrdOuca2x::a2sz(OssEroute, "quota", val, &qval))
390 {NoGo = 1; continue;
391 }
393 while(fsg && strcmp(cgroup, fsg->group)) fsg = fsg->next;
394 if (fsg) fsg->Quota = qval;
395 if (!strcmp("public", cgroup)) XrdOssCache_Group::PubQuota = qval;
396 else if (!fsg) OssEroute.Emsg("Quotas", cgroup,
397 "cache group not found; quota ignored");
398 }
399 close(qFD);
400 Config.Capture(capstr);
401 return (NoGo ? 0 : 1);
402}
static long long PubQuota
static XrdOssCache_Group * fsgroups
XrdOssCache_Group * next
static const int minSNbsz
static int a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
Definition XrdOuca2x.cc:257
XrdCmsConfig Config

References XrdOuca2x::a2sz(), close, XrdSysError::Emsg(), XrdOssCache_Group::fsgroups, XrdOssCache_Group::group, minSNbsz, XrdOssCache_Group::next, open, OssEroute, XrdOssCache_Group::PubQuota, XrdOssCache_Group::Quota, and stat.

Referenced by Init(), and XrdOssCache::Scan().

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

◆ Unassign()

int XrdOssSpace::Unassign ( const char * GName)
static

Definition at line 486 of file XrdOssSpace.cc.

487{
488 off_t offset;
489 int k, i;
490
491// Try to find the current entry in the file
492//
493 for (k = 0; k < fencEnt; k++)
494 if (!strcmp(uData[uDvec[k]].gName, GName)) break;
495 if (k >= fencEnt) return -1;
496 i = uDvec[k];
497
498// Create the entry
499//
500 if (!UsageLock()) return -1;
501 memset(&uData[i], 0, sizeof(uEnt));
502 offset = sizeof(uEnt) * i;
503 if (pwrite(aFD, &uData[freeEnt], sizeof(uEnt), offset) < 0)
504 {OssEroute.Emsg("Unassign", errno, "update usage file", uFname);
505 UsageLock(0); return -1;
506 }
507 UsageLock(0);
508
509// Squish out the uDvec
510//
511 if (i < freeEnt) freeEnt = i;
512 for (i = k+1; i < fencEnt; i++) uDvec[k++] = uDvec[i];
513 fencEnt--;
514 return 0;
515}

References XrdSysError::Emsg(), OssEroute, and pwrite.

+ Here is the call graph for this function:

◆ Usage() [1/2]

long long XrdOssSpace::Usage ( const char * GName,
struct uEnt & uVal,
int rrd = 0 )
static

Definition at line 535 of file XrdOssSpace.cc.

536{
537 XrdSysMutexHelper uHelp(uMutex);
538 int i, rwsz;
539
540// If we need to re-read the file, do so
541//
542 if (rrd)
543 {if (fencEnt <= 0) return -1;
544 UsageLock();
545 rwsz = sizeof(uEnt)*(uDvec[fencEnt-1] + 1);
546 if (!pread(aFD, uData, rwsz, 0))
547 {OssEroute.Emsg("Readjust", errno, "read", uFname);
548 UsageLock(0); return -1;
549 }
550 UsageLock(0);
551 }
552
553// Try to find the current entry in the file
554//
555 if ((i = findEnt(GName)) >= 0)
556 {uVal = uData[i];
557 return uData[i].Bytes[Serv];
558 }
559
560// Not found
561//
562 memset(&uVal, 0, sizeof(uEnt));
563 return -1;
564}

References XrdOssSpace::uEnt::Bytes, XrdSysError::Emsg(), OssEroute, pread, and Serv.

+ Here is the call graph for this function:

◆ Usage() [2/2]

long long XrdOssSpace::Usage ( int gent)
static

Definition at line 521 of file XrdOssSpace.cc.

522{
523 long long retVal;
524
525// Safelu get the value and return it
526//
527 uMutex.Lock();
528 retVal = (gent < 0 || gent >= maxEnt ? 0 : uData[gent].Bytes[Serv]);
529 uMutex.UnLock();
530 return retVal;
531}

References XrdOssSpace::uEnt::Bytes, and Serv.

Referenced by XrdOssCache::Scan().

+ Here is the caller graph for this function:

Friends And Related Symbol Documentation

◆ XrdOssCache

friend class XrdOssCache
friend

Definition at line 38 of file XrdOssSpace.hh.

Member Data Documentation

◆ haveQuota

const int XrdOssSpace::haveQuota = 2
static

Definition at line 52 of file XrdOssSpace.hh.

Referenced by Init().

◆ haveUsage

const int XrdOssSpace::haveUsage = 1
static

Definition at line 51 of file XrdOssSpace.hh.

Referenced by Init().

◆ maxSNlen

const int XrdOssSpace::maxSNlen = 63
static

Definition at line 44 of file XrdOssSpace.hh.

Referenced by XrdOssSys::getStats(), and XrdOssSys::xspace().

◆ minSNbsz

const int XrdOssSpace::minSNbsz = 64
static

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