XRootD
XrdFrmAdminAudit.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d F r m A d m i n A u d i t . c c */
4 /* */
5 /* (c) 2009 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <cstdio>
32 #include <cstring>
33 #include <sys/param.h>
34 
35 #include "XrdFrc/XrdFrcTrace.hh"
36 #include "XrdFrc/XrdFrcUtils.hh"
37 #include "XrdFrm/XrdFrmAdmin.hh"
38 #include "XrdFrm/XrdFrmConfig.hh"
39 #include "XrdFrm/XrdFrmFiles.hh"
40 #include "XrdOss/XrdOssPath.hh"
41 #include "XrdOss/XrdOssSpace.hh"
42 #include "XrdOuc/XrdOucNSWalk.hh"
43 #include "XrdOuc/XrdOucTList.hh"
44 
45 using namespace XrdFrc;
46 using namespace XrdFrm;
47 
48 /******************************************************************************/
49 /* A u d i t N a m e N B */
50 /******************************************************************************/
51 
52 int XrdFrmAdmin::AuditNameNB(XrdFrmFileset *sP)
53 {
54  char Resp, buff[80];
55  int num = 0, rem;
56 
57 // Report what is orphaned
58 //
59  if (sP->lockFile())
60  {num++; Msg("Orphaned lock file: ", sP->lockPath());}
61  if (sP->pfnFile() )
62  {num++; Msg("Orphaned pfn file: ", sP->pfnPath());
63  Msg("PFN file refers to: ", sP->pfnFile()->Link);
64  }
65  if (sP->pinFile() )
66  {num++; Msg("Orphaned pin file: ", sP->pinPath());}
67 
68 // Return if no fix is needed, otherwise check if we should ask before removal
69 //
70  numProb += num;
71  if (!Opt.Fix || !num) return 1;
72  if (!Opt.Force)
73  {Resp = XrdFrcUtils::Ask('n', "Remove orphaned files?");
74  if (Resp != 'y') return Resp != 'a';
75  }
76 
77 // Remove the orphaned files
78 //
79  rem = AuditRemove(sP);
80  numFix += rem;
81 
82 // Indicate final resolution
83 //
84  sprintf(buff, "%d of %d orphaned files removed.", rem, num);
85  Msg(buff);
86  return 1;
87 }
88 
89 /******************************************************************************/
90 /* A u d i t N a m e N F */
91 /******************************************************************************/
92 
93 int XrdFrmAdmin::AuditNameNF(XrdFrmFileset *sP)
94 {
95  char Resp;
96 
97 // Indicate what is wrong
98 //
99  Msg("Dangling link: ", sP->basePath());
100  Msg("Missing target: ", sP->baseFile()->Link);
101  numProb++;
102 
103 // Return if no fix is needed, otherwise check if we should ask before removal
104 //
105  if (!Opt.Fix) return 1;
106  if (!Opt.Force)
107  {Resp = XrdFrcUtils::Ask('n', "Remove symlink?");
108  if (Resp != 'y') return Resp != 'a';
109  }
110 
111 // Remove the symlink and associated files
112 //
113  if (unlink(sP->basePath()))
114  Emsg(errno,"remove symlink", sP->basePath());
115  else if (AuditRemove(sP))
116  {Msg("Symlink removed.");
117  numFix++;
118  return 1;
119  }
120  return 1;
121 }
122 
123 /******************************************************************************/
124 /* A u d i t N a m e N L */
125 /******************************************************************************/
126 
127 int XrdFrmAdmin::AuditNameNL(XrdFrmFileset *sP)
128 {
129  static const char *noCPT = "No copy time for: ";
130  static const char *mkCPT = "Set copy time?";
131  char Resp;
132 
133 // Indicate what is wrong
134 //
135  Msg(noCPT, sP->basePath());
136  numProb++;
137 
138 // Return if no fix is needed, otherwise check if we should ask before removal
139 //
140  if (!Opt.Fix) return -1;
141  if (!Opt.Force)
142  {Resp = XrdFrcUtils::Ask('y', mkCPT);
143  if (Resp != 'y') return Resp != 'a';
144  }
145 
146 // Set copy time
147 //
148  if (XrdFrcUtils::updtCpy(sP->basePath(),(Opt.MPType == 'p' ? 0 : -113)))
149  {numFix++;
150  Msg("Copy time set.");
151  }
152  return 1;
153 }
154 
155 /******************************************************************************/
156 /* A u d i t N a m e s */
157 /******************************************************************************/
158 
159 int XrdFrmAdmin::AuditNames()
160 {
161  static const int fsetOpts = XrdFrmFiles::GetCpyTim | XrdFrmFiles::NoAutoDel;
162  XrdFrmFileset *sP;
163  XrdFrmFiles *fP;
164  char pDir[MAXPATHLEN], *lDir = Opt.Args[1];
165  int opts = (Opt.Recurse ? XrdFrmFiles::Recursive : 0) | fsetOpts;
166  int ec = 0, Act = 1;
167 
168 // Initialization
169 //
170  numProb = 0; numFix = 0;
171  if (VerifyMP("audit", lDir) != 'y') return 0;
172 
173 // Process the directory
174 //
175  if (!Config.LocalPath(lDir, pDir, sizeof(pDir))) {finalRC = 4; return 1;}
176  fP = new XrdFrmFiles(pDir, opts);
177  while(Act && (sP = fP->Get(ec,1)))
178  {if (!(sP->baseFile())) Act = AuditNameNB(sP);
179  else {if (sP->baseFile()->Type == XrdOucNSWalk::NSEnt::isLink)
180  Act = AuditNameNF(sP);
181  if (Act && Opt.MPType && !(sP->cpyInfo.Attr.cpyTime))
182  Act = AuditNameNL(sP);
183  if (Act && sP->baseFile()->Link && isXA(sP->baseFile()))
184  Act = AuditNameXA(sP);
185  }
186  delete sP;
187  }
188  if (ec) finalRC = 4;
189  delete fP;
190 
191 // All done
192 //
193  if (!Act) Msg("Audit names aborted!");
194  sprintf(pDir,"%d problem%s found; %d fixed.", numProb,
195  (numProb == 1 ? "" : "s"), numFix);
196  Msg(pDir);
197  return !Act;
198 }
199 
200 /******************************************************************************/
201 /* A u d i t N a m e X A */
202 /******************************************************************************/
203 
204 int XrdFrmAdmin::AuditNameXA(XrdFrmFileset *sP)
205 {
207  const char *doWhat = "Recreate pfn xref?";
208  char Resp, dfltAns = 'n';
209  int rc;
210 
211 // Make sure there is a PFN attribute is here and references the file
212 //
213  if ((rc = pfnInfo.Get(sP->baseFile()->Link)) > 0)
214  {if (!strcmp(pfnInfo.Attr.Pfn,sP->basePath())) return 1;
215  Msg("Incorrect pfn xref to ", sP->basePath());
216  Msg("Data file refers to ", pfnInfo.Attr.Pfn);
217  } else {
218  if (rc) Emsg(-rc, "get pfn xattr for ",sP->basePath());
219  else {Msg("Missing pfn xref to ", sP->basePath());
220  doWhat = "Create pfn xref?"; dfltAns = 'y';
221  }
222  }
223 
224 // Check if we can fix this problem
225 //
226  if (!Opt.Fix || rc < 0) return 1;
227  if (!Opt.Force)
228  {Resp = XrdFrcUtils::Ask(dfltAns, doWhat);
229  if (Resp != 'y') return Resp != 'a';
230  }
231 
232 // Reset the pfn xattr
233 //
234  strcpy(pfnInfo.Attr.Pfn, sP->basePath());
235  if (!(rc = pfnInfo.Set(sP->baseFile()->Link)))
236  {Msg("pfn xref set."); numFix++;}
237  else Emsg(-rc, "set pfn xref to ", sP->basePath());
238 
239 
240 // All done.
241 //
242  return 1;
243 }
244 
245 /******************************************************************************/
246 /* A u d i t R e m o v e */
247 /******************************************************************************/
248 
249 int XrdFrmAdmin::AuditRemove(XrdFrmFileset *sP)
250 {
251  int rem = 0;
252 
253 // Remove the orphaned files
254 //
255  if (sP->lockFile())
256  {if (unlink(sP->lockPath())) Emsg(errno,"remove lock file.");
257  else rem++;
258  }
259  if (sP-> pinFile())
260  {if (unlink(sP-> pinPath())) Emsg(errno,"remove pin file.");
261  else rem++;
262  }
263  if (sP-> pfnFile())
264  {if (unlink(sP-> pfnPath())) Emsg(errno,"remove pfn file.");
265  else rem++;
266  }
267 
268  return rem;
269 }
270 
271 /******************************************************************************/
272 /* A u d i t S p a c e */
273 /******************************************************************************/
274 
275 int XrdFrmAdmin::AuditSpace()
276 {
277  XrdOucTList *pP;
278  char buff[256], *Path = 0, *Space = Opt.Args[1];
279  int Act;
280 
281 // Parse the space specification
282 //
283  if (!(pP = ParseSpace(Space, &Path))) return 4;
284 
285 // Initialize
286 //
287  numBytes = 0; numFiles = 0; numProb = 0; numFix = 0;
288 
289 // Index the space via filesets
290 //
291  do {Act = (pP->val ? AuditSpaceXA(Space, pP->text) : AuditSpaceAX(pP->text));
292  pP = pP->next;
293  } while(pP && !Path && Act);
294 
295 // All done
296 //
297  sprintf(buff,"%d problem%s found; %d fixed.", numProb,
298  (numProb == 1 ? "" : "s"), numFix);
299  Msg(buff);
300  if (!Act) Msg("Audit space aborted!");
301  else {if (Path) *(--Path) = ':';
302  sprintf(buff, "Space %s has %d file%s with %lld byte%s in use "
303  "(%lld unreachable).",
304  Space,
305  numFiles, (numFiles == 1 ? "" : "s"),
306  numBytes, (numBytes == 1 ? "" : "s"),
307  numBLost);
308  Msg(buff);
309  }
310  return (Act ? 0 : 4);
311 }
312 
313 /******************************************************************************/
314 /* A u d i t S p a c e A X */
315 /******************************************************************************/
316 
317 int XrdFrmAdmin::AuditSpaceAX(const char *Path)
318 {
322  XrdOucNSWalk::NSEnt *nP, *pP;
323  char buff[1032];
324  int ec, Act = 1;
325 
326 // Get the files in this directory
327 //
328  if (!(nP = nsWalk.Index(ec))) {if (ec) finalRC = 4; return 1;}
329  pP = nP;
330 
331 // Now traverse through all of the files
332 //
333  while(nP && Act)
334  {Act = (XrdOssPath::genPFN(buff, sizeof(buff), nP->Path)
335  ? AuditSpaceAXDC(buff, nP) : AuditSpaceAXDB(nP->Path));
336  nP = nP->Next;
337  }
338 
339 // Delete the entries and return
340 //
341  while(pP) {nP = pP; pP = pP->Next; delete nP;}
342  return Act;
343 }
344 
345 /******************************************************************************/
346 /* A u d i t S p a c e A X D B */
347 /******************************************************************************/
348 
349 int XrdFrmAdmin::AuditSpaceAXDB(const char *Path)
350 {
351  char Resp;
352 
353 // Indicate the problem
354 //
355  Msg("Invalid name for data file ", Path);
356  numProb++;
357 
358 // Return if no fix is needed, otherwise check if we should ask before doing it
359 //
360  if (Opt.Fix)
361  {if (!Opt.Force)
362  {Resp = XrdFrcUtils::Ask('n', "Delete file?");
363  if (Resp != 'y') return Resp != 'a';
364  }
365  if (unlink(Path)) Emsg(errno, "remove ", Path);
366  else numFix++;
367  }
368  return 1;
369 }
370 
371 /******************************************************************************/
372 /* A u d i t S p a c e A X D C */
373 /******************************************************************************/
374 
375 int XrdFrmAdmin::AuditSpaceAXDC(const char *Path, XrdOucNSWalk::NSEnt *nP)
376 {
377  struct stat buf;
378  char lkbuff[1032], *Dest = nP->Path;
379  int n;
380 
381 // Assume we have a problem
382 //
383  numProb++;
384 
385 // Verify that the link to the file exists
386 //
387  if (lstat(Path,&buf))
388  {if (errno != ENOENT) {Emsg(errno, "stat ", Path); return -1;}
389  Msg("Missing pfn data link ", Path);
390  return AuditSpaceAXDL(0, Path, Dest);
391  }
392 
393 // Make sure the PFN file is a link
394 //
395  if ((buf.st_mode & S_IFMT) != S_IFLNK)
396  {Msg("Invalid pfn data link ", Path);
397  return AuditSpaceAXDL(1, Path, Dest);
398  }
399 
400 // Make sure tyhe link points to the right file
401 //
402  if ((n = readlink(Path, lkbuff, sizeof(lkbuff)-1)) < 0)
403  {Emsg(errno, "read link from ", Path); return -1;}
404  lkbuff[n] = '\0';
405  if (strcmp(Dest, lkbuff))
406  {Msg("Incorrect pfn data link ", Path);
407  return AuditSpaceAXDL(1, Path, Dest);
408  }
409 
410 // All went well
411 //
412  numProb--; numFiles++; numBytes += nP->Stat.st_size;
413  return 1;
414 }
415 
416 /******************************************************************************/
417 /* A u d i t S p a c e A X D L */
418 /******************************************************************************/
419 
420 int XrdFrmAdmin::AuditSpaceAXDL(int dorm, const char *Path, const char *Dest)
421 {
422  char Resp;
423 
424 // Return if no fix is needed, otherwise check if we should ask before doing it
425 //
426  if (!Opt.Fix) return -1;
427  if (!Opt.Force)
428  {if (dorm)
429  Resp = XrdFrcUtils::Ask('n', "Recreate pfn symlink?");
430  else
431  Resp = XrdFrcUtils::Ask('y', "Create pfn symlink?");
432  if (Resp != 'y') return Resp != 'a';
433  }
434 
435 // Create the pfn symlink
436 //
437  if (dorm) unlink(Path);
438  if (symlink(Dest, Path))
439  {Emsg(errno, "create symlink ", Path); return -1;}
440  Msg("pfn symlink created.");
441  numFix++;
442  return 1;
443 }
444 
445 /******************************************************************************/
446 /* A u d i t S p a c e X A */
447 /******************************************************************************/
448 
449 int XrdFrmAdmin::AuditSpaceXA(const char *Space, const char *Path)
450 {
451  XrdFrmFileset *sP;
452  XrdFrmFiles *fP;
453  char tmpv[8], *buff;
454  int ec = 0, Act = 1;
455 
456 // Construct the right space path and get a files object
457 //
458  buff = XrdOssPath::genPath(Path, Space, tmpv);
460 
461 // Go and check out the files
462 //
463  while(Act && (sP = fP->Get(ec,1)))
464  {if (!sP->baseFile()) Act = AuditNameNB(sP);
465  else {numFiles++;
466  if ((Act = AuditSpaceXA(sP)))
467  {if (Act < 0) numFiles--;
468  else numBytes += sP->baseFile()->Stat.st_size;
469  }
470  }
471  delete sP;
472  }
473 
474 // All done
475 //
476  if (ec) finalRC = 4;
477  free(buff);
478  delete fP;
479  return Act;
480 }
481 
482 /******************************************************************************/
483 
484 int XrdFrmAdmin::AuditSpaceXA(XrdFrmFileset *sP)
485 {
487  struct stat buf;
488  const char *Plug;
489  char Resp = 0, tempPath[1032], lkbuff[1032], *Pfn = pfnInfo.Attr.Pfn;
490  int n;
491 
492 // First step is to get the pfn extended attribute
493 //
494  if (pfnInfo.Get(sP->basePath()) <= 0)
495  {Msg("Missing pfn xref for data file ", sP->basePath());
496  numProb++;
497  return 1;
498  }
499 
500 // If there is no PFN file then recreate symlink if possible
501 //
502  if (lstat(Pfn,&buf))
503  {numProb++;
504  if (errno != ENOENT) {Emsg(errno, "stat ", Pfn); return 1;}
505  Msg("Data file xrefs missing pfn ", Pfn);
506  if (Opt.Fix)
507  {if (Opt.Force) Resp = 'y';
508  else Resp = XrdFrcUtils::Ask('y',"Create pfn symlink?");
509  if (Resp == 'y')
510  {if (!symlink(sP->basePath(), Pfn))
511  {Msg("pfn symlink created."); numFix++; return 1;}
512  Emsg(errno, "create symlink ", Pfn);
513  }
514  }
515  numBLost += sP->baseFile()->Stat.st_size;
516  return Resp != 'a';
517  }
518 
519 // If the PFN file is not a link, the see if we should remove the data file
520 //
521  if ((buf.st_mode & S_IFMT) != S_IFLNK)
522  {numProb++;
523  Msg("Data file xrefs non-symlink pfn ", Pfn);
524  if (Opt.Fix)
525  {if (Opt.Force) Resp = 'n';
526  else Resp = XrdFrcUtils::Ask('n',"Remove data file?");
527  if (Resp == 'y')
528  {if (unlink(sP->basePath())) Emsg(errno,"remove ",sP->basePath());
529  else {Msg("Data file removed."); numFix++; return -1;}
530  }
531  }
532  numBLost += sP->baseFile()->Stat.st_size;
533  return Resp != 'a';
534  }
535 
536 // Check if xrefs are consistent.
537 //
538  if ((n = readlink(Pfn, lkbuff, sizeof(lkbuff)-1)) < 0)
539  {Emsg(errno, "read link from ", Pfn); numProb++; return 1;}
540  lkbuff[n] = '\0';
541  if (!strcmp(sP->basePath(), lkbuff)) return 1;
542 
543 // Issue first message (there is value in seeing the data file path)
544 //
545  Msg("Inconsistent data file: ", sP->basePath());
546  numProb++;
547 
548 // Diagnose the problem and check if fix is possible
549 //
550  if (!stat(lkbuff, &buf)) Plug = "exists.";
551  else if (errno == ENOENT) Plug = "is missing.";
552  else {Emsg(errno, "stat ", lkbuff); return 1;}
553  Msg("Data file xrefs pfn ", Pfn);
554  Msg("Pfn points to a different data file that ", Plug);
555  if (!Opt.Fix) return 1;
556 
557 // If the data file is orphaned then check if we can remove it otherwise
558 // see if we can simply change the symlink to point to this file
559 //
560  if (*Plug == 'e')
561  {if (Opt.Force) Resp = 'n';
562  else Resp = XrdFrcUtils::Ask('n',"Remove unreferenced data file?");
563  if (Resp == 'y')
564  {if (unlink(sP->basePath())) Emsg(errno,"remove ",sP->basePath());
565  else {Msg("Data file removed."); numFix++; return -1;}
566  }
567  } else {
568  if (Opt.Force) Resp = 'n';
569  else Resp = XrdFrcUtils::Ask('n',"Change pfn symlink?");
570  if (Resp == 'y')
571  {*tempPath = ' '; strcpy(tempPath+1, Pfn); unlink(tempPath);
572  if (symlink(sP->basePath(), tempPath) || rename(tempPath, Pfn))
573  {Emsg(errno, "create symlink ", Pfn); unlink(tempPath);}
574  else {Msg("pfn symlink changed."); numFix++; return 1;}
575  }
576  }
577 
578 // Space for this file is definitely lost
579 //
580  numBLost += sP->baseFile()->Stat.st_size;
581  return Resp != 'a';
582 }
583 
584 /******************************************************************************/
585 /* A u d i t U s a g e */
586 /******************************************************************************/
587 
588 int XrdFrmAdmin::AuditUsage()
589 {
590  XrdFrmConfig::VPInfo *vP = Config.VPList;
591  char Sbuff[1024];
592  int retval, rc;
593 
594 // Check if we have a space or we should do all spaces
595 //
596  if (Opt.Args[1]) return AuditUsage(Opt.Args[1]);
597 
598 // If no cache configured say so
599 //
600  if (!vP) {Emsg("No outplace space has been configured."); return -1;}
601 
602 // Audit usage for each space
603 //
604  retval = 1;
605  while(vP)
606  {strcpy(Sbuff, vP->Name);
607  if (!(rc = AuditUsage(Sbuff))) return 0;
608  if (rc < 0) retval = rc;
609  vP = vP->Next;
610  }
611  return retval;
612 }
613 
614 /******************************************************************************/
615 
616 int XrdFrmAdmin::AuditUsage(char *Space)
617 {
618  XrdOucTList *pP;
619  const char *Sfx;
620  char Resp, buff[256], *Path = 0;
621  long long theClaim, theDiff;
622  int haveUsage, Probs = 0;
623 
624 // Parse the space specification
625 //
626  if (!(pP = ParseSpace(Space, &Path))) return -1;
627  if (Path) {Emsg("Path not allowed for audit usage."); return -1;}
628 
629 // Initialize
630 //
631  numBytes = 0; numFiles = 0; numProb = 0;
632  haveUsage = XrdOssSpace::Init();
633 
634 // Index the space via filesets
635 //
636  do {Probs |= (pP->val ? AuditUsageXA(pP->text, Space)
637  : AuditUsageAX(pP->text));
638  pP = pP->next;
639  } while(pP);
640 
641 // Print ending condition
642 //
643  sprintf(buff, "Audit of %d file%s in %s space completed with %serrors.",
644  numFiles, (numFiles == 1 ? "" : "s"), Space,
645  (Probs ? "" : "no "));
646  Msg(buff);
647 
648 // Print what is in the usage file
649 //
650  if (haveUsage)
651  {XrdOssSpace::uEnt myEnt;
652  XrdOssSpace::Usage(Space, myEnt);
653  theClaim = myEnt.Bytes[XrdOssSpace::Serv]
654  + myEnt.Bytes[XrdOssSpace::Pstg]
655  - myEnt.Bytes[XrdOssSpace::Purg]
656  + myEnt.Bytes[XrdOssSpace::Admin];
657  sprintf(buff, "%12lld", theClaim);
658  Msg("Claimed: ", buff);
659  } else theClaim = numBytes;
660 
661 // Print what we came up with
662 //
663  sprintf(buff, "%12lld", numBytes);
664  Msg("Actual: ", buff);
665 
666 // Check if fix is required and wanted
667 //
668  if (numBytes == theClaim || !Opt.Fix) return 1;
669  if (!haveUsage)
670  {Emsg(0, "No usage file present to fix!"); return -1;}
671 
672 // Compute difference
673 //
674  if (theClaim < numBytes) theDiff = numBytes - theClaim;
675  else theDiff = theClaim - numBytes;
676 
677 // See if we should fix this
678 //
679  if (!Opt.Force)
680  {if (theDiff < 500000) Sfx = "byte";
681  {theDiff = (theDiff+512)/1024; Sfx = "KB";}
682  sprintf(buff, "Fix %lld %s difference?", theDiff, Sfx);
683  Resp = XrdFrcUtils::Ask('n', "Fix usage information?");
684  if (Resp != 'y') return Resp != 'a';
685  }
686 
687 // Fix the problem
688 //
689  XrdOssSpace::Adjust(Space, numBytes-theClaim, XrdOssSpace::Admin);
690  return 1;
691 }
692 
693 /******************************************************************************/
694 /* A u d i t U s a g e A X */
695 /******************************************************************************/
696 
697 int XrdFrmAdmin::AuditUsageAX(const char *Path)
698 {
702  XrdOucNSWalk::NSEnt *nP, *pP;
703  int ec;
704 
705 // Get the files in this directory
706 //
707  if (!(nP = nsWalk.Index(ec))) {if (ec) finalRC = 4; return 1;}
708 
709 // Now traverse through all of the files
710 //
711  while(nP)
712  {numBytes += nP->Stat.st_size;
713  numFiles++;
714  pP = nP;
715  nP = nP->Next;
716  delete pP;
717  }
718 
719 // All done
720 //
721  return 0;
722 }
723 
724 /******************************************************************************/
725 /* A u d i t U s a g e X A */
726 /******************************************************************************/
727 
728 int XrdFrmAdmin::AuditUsageXA(const char *Path, const char *Space)
729 {
730  XrdFrmFileset *sP;
731  XrdFrmFiles *fP;
732  char tmpv[8], *buff;
733  int ec = 0;
734 
735 // Construct the right space path and get a files object
736 //
737  buff = XrdOssPath::genPath(Path, Space, tmpv);
739 
740 // Go and check out the files
741 //
742  while((sP = fP->Get(ec)))
743  {if ((sP->baseFile()))
744  {numFiles++; numBytes += sP->baseFile()->Stat.st_size;}
745  delete sP;
746  }
747 
748 // All done
749 //
750  free(buff);
751  delete fP;
752  return ec;
753 }
754 
755 /******************************************************************************/
756 /* i s X A */
757 /******************************************************************************/
758 
759 int XrdFrmAdmin::isXA(XrdOucNSWalk::NSEnt *nP)
760 {
761  char *lP;
762 
763  if (!(nP->Link)) return 0;
764  lP = nP->Link + nP->Lksz -1;
765  return (*lP == XrdOssPath::xChar);
766 }
int stat(const char *path, struct stat *buf)
int lstat(const char *path, struct stat *buf)
int unlink(const char *path)
int rename(const char *oldpath, const char *newpath)
XrdOucString Path
struct myOpts opts
static char Ask(char dflt, const char *Msg1, const char *Msg2="", const char *Msg3="")
Definition: XrdFrcUtils.cc:56
static int updtCpy(const char *Pfn, int Adj)
Definition: XrdFrcUtils.cc:277
long long cpyTime
Definition: XrdFrcXAttr.hh:55
static const int NoAutoDel
Definition: XrdFrmFiles.hh:123
static const int GetCpyTim
Definition: XrdFrmFiles.hh:124
XrdFrmFileset * Get(int &rc, int noBase=0)
Definition: XrdFrmFiles.cc:340
static const int Recursive
Definition: XrdFrmFiles.hh:121
const char * pfnPath()
Definition: XrdFrmFiles.hh:67
XrdOucXAttr< XrdFrcXAttrCpy > cpyInfo
Definition: XrdFrmFiles.hh:55
XrdOucNSWalk::NSEnt * pfnFile()
Definition: XrdFrmFiles.hh:66
XrdOucNSWalk::NSEnt * pinFile()
Definition: XrdFrmFiles.hh:68
XrdOucNSWalk::NSEnt * baseFile()
Definition: XrdFrmFiles.hh:60
const char * lockPath()
Definition: XrdFrmFiles.hh:65
const char * basePath()
Definition: XrdFrmFiles.hh:61
XrdOucNSWalk::NSEnt * lockFile()
Definition: XrdFrmFiles.hh:64
const char * pinPath()
Definition: XrdFrmFiles.hh:69
static char * genPFN(fnInfo &Info, char *buff, int blen, const char *Path=0)
Definition: XrdOssPath.cc:172
static const char xChar
Definition: XrdOssPath.hh:47
static char * genPath(const char *inPath, const char *cgrp, char *sfx)
Definition: XrdOssPath.cc:134
static long long Usage(int gent)
Definition: XrdOssSpace.cc:521
static int Init()
Definition: XrdOssSpace.cc:224
long long Bytes[Totn]
Definition: XrdOssSpace.hh:65
static void Adjust(int Gent, off_t Space, sType=Serv)
Definition: XrdOssSpace.cc:81
static const int retFile
static const int skpErrs
static const int retStat
XrdOucTList * next
Definition: XrdOucTList.hh:45
char * text
Definition: XrdOucTList.hh:46
int Get(const char *Path, int fd=-1)
Definition: XrdOucXAttr.hh:128
int Set(const char *Path, int fd=-1)
Definition: XrdOucXAttr.hh:139
XrdCmsConfig Config
XrdSysError Say
struct NSEnt * Next
Definition: XrdOucNSWalk.hh:48