XRootD
XrdOssConfig.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d O s s C o n f i g . c c */
4 /* */
5 /* */
6 /* (C) 2003 by the Board of Trustees of the Leland Stanford, Jr., University */
7 /* All Rights Reserved */
8 /* Produced by Andrew Hanushevsky for Stanford University under contract */
9 /* DE-AC02-76-SFO0515 with the Deprtment of Energy */
10 /* */
11 /* This file is part of the XRootD software suite. */
12 /* */
13 /* XRootD is free software: you can redistribute it and/or modify it under */
14 /* the terms of the GNU Lesser General Public License as published by the */
15 /* Free Software Foundation, either version 3 of the License, or (at your */
16 /* option) any later version. */
17 /* */
18 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
19 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
20 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
21 /* License for more details. */
22 /* */
23 /* You should have received a copy of the GNU Lesser General Public License */
24 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
25 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
26 /* */
27 /* The copyright holder's institutional names and contributor's names may not */
28 /* be used to endorse or promote products derived from this software without */
29 /* specific prior written permission of the institution or contributor. */
30 /******************************************************************************/
31 
32 #include <unistd.h>
33 #include <cctype>
34 #include <dirent.h>
35 #include <fcntl.h>
36 #include <string>
37 #include <strings.h>
38 #include <cstdio>
39 #include <sys/param.h>
40 #include <sys/resource.h>
41 #include <sys/stat.h>
42 #include <sys/types.h>
43 
44 #include "XrdVersion.hh"
45 
46 #include "XrdFrc/XrdFrcProxy.hh"
47 #include "XrdOss/XrdOssPath.hh"
48 #include "XrdOss/XrdOssApi.hh"
49 #include "XrdOss/XrdOssCache.hh"
50 #include "XrdOss/XrdOssConfig.hh"
51 #include "XrdOss/XrdOssError.hh"
52 #include "XrdOss/XrdOssMio.hh"
53 #include "XrdOss/XrdOssOpaque.hh"
54 #include "XrdOss/XrdOssSpace.hh"
55 #include "XrdOss/XrdOssTrace.hh"
56 #include "XrdOuc/XrdOuca2x.hh"
57 #include "XrdOuc/XrdOucEnv.hh"
58 #include "XrdSys/XrdSysError.hh"
59 #include "XrdOuc/XrdOucExport.hh"
60 #include "XrdOuc/XrdOucMsubs.hh"
63 #include "XrdOuc/XrdOucProg.hh"
64 #include "XrdOuc/XrdOucStream.hh"
65 #include "XrdOuc/XrdOucString.hh"
66 #include "XrdOuc/XrdOucUtils.hh"
67 #include "XrdSys/XrdSysE2T.hh"
68 #include "XrdSys/XrdSysHeaders.hh"
69 #include "XrdSys/XrdSysPthread.hh"
70 #include "XrdSys/XrdSysPlatform.hh"
71 
72 /******************************************************************************/
73 /* S t o r a g e S y s t e m O b j e c t */
74 /******************************************************************************/
75 
76 extern XrdOssSys *XrdOssSS;
77 
78 extern XrdSysTrace OssTrace;
79 
81 
82 /******************************************************************************/
83 /* E r r o r T e x t */
84 /******************************************************************************/
85 
86 const char *XrdOssErrorText[] =
87  {XRDOSS_T8001,
100  XRDOSS_T8014,
101  XRDOSS_T8015,
102  XRDOSS_T8016,
103  XRDOSS_T8017,
104  XRDOSS_T8018,
105  XRDOSS_T8019,
106  XRDOSS_T8020,
107  XRDOSS_T8021,
108  XRDOSS_T8022,
109  XRDOSS_T8023,
110  XRDOSS_T8024,
111  XRDOSS_T8025,
113  };
114 
115 /******************************************************************************/
116 /* d e f i n e s */
117 /******************************************************************************/
118 
119 #define Duplicate(x,y) if (y) free(y); y = strdup(x)
120 
121 #define TS_Xeq(x,m) if (!strcmp(x,var)) return m(Config, Eroute);
122 
123 #define TS_String(x,m) if (!strcmp(x,var)) {Duplicate(val,m); return 0;}
124 
125 #define TS_List(x,m,v) if (!strcmp(x,var)) \
126  {m.Insert(new XrdOucPList(val, v); return 0;}
127 
128 #define TS_Char(x,m) if (!strcmp(x,var)) {m = val[0]; return 0;}
129 
130 #define TS_Add(x,m,v,s) if (!strcmp(x,var)) {m |= (v|s); return 0;}
131 #define TS_Ade(x,m,v,s) if (!strcmp(x,var)) {m |= (v|s); Config.Echo(); return 0;}
132 #define TS_Rem(x,m,v,s) if (!strcmp(x,var)) {m = (m & ~v) | s; return 0;}
133 
134 #define TS_Set(x,m,v) if (!strcmp(x,var)) {m = v; Config.Echo(); return 0;}
135 
136 #define xrdmax(a,b) (a < b ? b : a)
137 
138 /******************************************************************************/
139 /* E x t e r n a l T h r e a d I n t e r f a c e s */
140 /******************************************************************************/
141 
142 void *XrdOssxfr(void *carg) {return XrdOssSS->Stage_In(carg);}
143 
144 void *XrdOssCacheScan(void *carg) {return XrdOssCache::Scan(*((int *)carg));}
145 
146 /******************************************************************************/
147 /* C o n s t r u c t o r */
148 /******************************************************************************/
149 
151 {
152  static XrdVERSIONINFODEF(myVer, XrdOss, XrdVNUMBER, XrdVERSION);
153  myVersion = &myVer;
154  xfrtcount = 0;
155  pndbytes = 0;
156  stgbytes = 0;
157  totbytes = 0;
158  totreqs = 0;
159  badreqs = 0;
160  MaxTwiddle = 3;
161  tryMmap = 0;
162  chkMmap = 0;
163  lcl_N2N = rmt_N2N = the_N2N = 0;
164  N2N_Lib = N2N_Parms = 0;
165  StageCmd = 0;
166  StageMsg = 0;
167  StageSnd = 0;
168  StageFrm = 0;
169  StageRealTime = 1;
170  StageAsync = 0;
171  StageCreate = 0;
172  StageEvents = (char *)"-";
173  StageEvSize = 1;
174  StageAction = (char *)"wq ";
175  StageActLen = 3;
176  RSSCmd = 0;
177  isMSSC = 0;
178  RSSTout =15*1000;
179  DirFlags = 0;
180  OptFlags = 0;
181  LocalRoot = 0;
182  RemoteRoot = 0;
183  cscanint = 600;
184  FDFence = -1;
185  FDLimit = -1;
186  MaxSize = 0;
187  minalloc = 0;
188  ovhalloc = 0;
189  fuzalloc = 0;
190  xfrspeed = 9*1024*1024;
191  xfrovhd = 30;
192  xfrhold = 3*60*60;
193  xfrkeep = 20*60;
194  xfrthreads = 1;
195  ConfigFN = 0;
196  QFile = 0;
197  UDir = 0;
198  USync = 0;
199  Solitary = 0;
200  DPList = 0;
201  lenDP = 0;
202  numCG = numDP = 0;
203  xfrFdir = 0;
204  xfrFdln = 0;
205  pfcMode = false;
206  RSSProg = 0;
207  StageProg = 0;
208  prPBits = (long long)sysconf(_SC_PAGESIZE);
209  prPSize = static_cast<int>(prPBits);
210  prPBits--;
211  prPMask = ~prPBits;
212  prBytes = 0;
213  prActive = 0;
214  prDepth = 0;
215  prQSize = 0;
216  STT_Lib = 0;
217  STT_Parms = 0;
218  STT_Func = 0;
219  STT_Fund = 0;
220  STT_PreOp = 0;
221  STT_DoN2N = 1;
222  STT_V2 = 0;
223  STT_DoARE = 0;
224 }
225 
226 /******************************************************************************/
227 /* C o n f i g u r e */
228 /******************************************************************************/
229 
230 int XrdOssSys::Configure(const char *configfn, XrdSysError &Eroute,
231  XrdOucEnv *envP)
232 {
233 /*
234  Function: Establish default values using a configuration file.
235 
236  Input: None.
237 
238  Output: 0 upon success or !0 otherwise.
239 */
242  static const int maxFD = 1048576;
243  struct rlimit rlim;
244  char *val;
245  int retc, NoGo = XrdOssOK;
246  pthread_t tid;
247  bool setfd = false;
248 
249 // Do the herald thing
250 //
251  Eroute.Say("++++++ Storage system initialization started.");
252  Eroute.addTable(ETab);
253  if (getenv("XRDDEBUG")) OssTrace.What = TRACE_ALL;
254 
255 // Preset all variables with common defaults
256 //
257  ConfigFN = (configfn && *configfn ? strdup(configfn) : 0);
258 
259 // Establish the FD limit and the fence (half way)
260 //
261  if (getrlimit(RLIMIT_NOFILE, &rlim))
262  {Eroute.Emsg("Config", errno, "get fd limit");
263  rlim.rlim_cur = maxFD;
264  }
265  else {if (rlim.rlim_max == RLIM_INFINITY)
266  {rlim.rlim_cur = maxFD;
267  setfd = true;
268  } else {
269  if (rlim.rlim_cur != rlim.rlim_max)
270  {rlim.rlim_cur = rlim.rlim_max;
271  setfd = true;
272  }
273  }
274  if (setfd)
275  {if (setrlimit(RLIMIT_NOFILE, &rlim))
276  Eroute.Emsg("Config", errno, "set fd limit");
277  else FDLimit = rlim.rlim_cur;
278  } else {FDFence = static_cast<int>(rlim.rlim_cur)>>1;
279  FDLimit = rlim.rlim_cur;
280  }
281  }
282  if (FDFence < 0 || FDFence >= FDLimit) FDFence = FDLimit >> 1;
283 
284 // Configure devices
285 //
287 
288 // Process the configuration file
289 //
290  NoGo = ConfigProc(Eroute);
291 
292 // Configure dependent plugins
293 //
294  if (!NoGo)
295  {if (N2N_Lib || LocalRoot || RemoteRoot) NoGo |= ConfigN2N(Eroute, envP);
296  if (STT_Lib && !NoGo) NoGo |= ConfigStatLib(Eroute, envP);
297  }
298 
299 // If the export list is empty, add at least "/tmp" to it otherwise we will
300 // fail to correctly track space.
301 //
302  if (RPList.First() == 0)
303  RPList.Insert(new XrdOucPList("/tmp", (unsigned long long)0));
304 
305 // Establish usage tracking and quotas, if need be. Note that if we are not
306 // a true data server, those services will be initialized but then disabled.
307 //
308  Solitary = ((val = getenv("XRDREDIRECT")) && !strcmp(val, "Q"));
309  pfcMode = (envP && (val = envP->Get("oss.runmode")) && !strcmp(val,"pfc"));
310  {const char *m1 = (Solitary ? "standalone " : 0);
311  const char *m2 = (pfcMode ? "pfc " : 0);
312  if (m1 || m2) Eroute.Say("++++++ Configuring ", m1, m2, "mode . . .");
313  }
316 
317 // Configure the MSS interface including staging
318 //
319  if (!NoGo) NoGo = ConfigStage(Eroute);
320 
321 // Configure async I/O
322 //
323  if (!NoGo) NoGo = !AioInit();
324 
325 // Initialize memory mapping setting to speed execution
326 //
327  if (!NoGo) ConfigMio(Eroute);
328 
329 // Provide support for the PFC. This also resolve cache attribute conflicts.
330 //
331  if (!NoGo) ConfigCache(Eroute);
332 
333 // Establish the actual default path settings (modified by the above)
334 //
336 
337 // Configure space (final pass)
338 //
339  ConfigSpace(Eroute);
340 
341 // Set the prefix for files in cache file systems
342  if ( OptFlags & XrdOss_CacheFS )
343  if (!NoGo) {
344  NoGo = XrdOssPath::InitPrefix();
345  if (NoGo) Eroute.Emsg("Config", "space initialization failed");
346  }
347 
348 // Configure statiscal reporting
349 //
350  if (!NoGo) ConfigStats(Eroute);
351 
352 // Start up the space scan thread unless specifically told not to. Some programs
353 // like the cmsd manually handle space updates.
354 //
355  if (!(val = getenv("XRDOSSCSCAN")) || strcmp(val, "off"))
356  {if ((retc = XrdSysThread::Run(&tid, XrdOssCacheScan,
357  (void *)&cscanint, 0, "space scan")))
358  Eroute.Emsg("Config", retc, "create space scan thread");
359  }
360 
361 // Display the final config if we can continue
362 //
363  if (!NoGo) Config_Display(Eroute);
364 
365 // Do final reset of paths if we are in proxy file cache mode
366 //
367  if (pfcMode && !NoGo) ConfigCache(Eroute, true);
368 
369 // Export the real path list (for frm et. al.)
370 //
371  XrdOssRPList = &RPList;
372  if (envP) envP->PutPtr("XrdOssRPList*", &RPList);
373 
374 // All done, close the stream and return the return code.
375 //
376  val = (NoGo ? (char *)"failed." : (char *)"completed.");
377  Eroute.Say("------ Storage system initialization ", val);
378  return NoGo;
379 }
380 
381 /******************************************************************************/
382 /* o o s s _ C o n f i g _ D i s p l a y */
383 /******************************************************************************/
384 
385 #define XrdOssConfig_Val(base, opt) \
386  (Have ## base ? " oss." #opt " " : ""), \
387  (Have ## base ? base : ""), \
388  (Have ## base ? "\n" : "")
389 
390 #define XrdOssConfig_Vop(base, opt, optchk0, opt1, opt2, optchk1, opt3, opt4) \
391  (Have ## base ? " oss." #opt " " : ""), \
392  (Have ## base ? (optchk0 ? opt1 : opt2) : ""), \
393  (Have ## base ? (optchk1 ? opt3 : opt4) : ""), \
394  (Have ## base ? base : ""), \
395  (Have ## base ? "\n" : "")
396 
398 {
399  char buff[4096], *cloc;
400  XrdOucPList *fp;
401 
402  // Preset some tests
403  //
404  int HaveRSSCmd = (RSSCmd && RSSCmd[0]);
405  int HaveStageCmd = (StageCmd && StageCmd[0]);
406  int HaveRemoteRoot = (RemoteRoot && RemoteRoot[0]);
407  int HaveLocalRoot = (LocalRoot && LocalRoot[0]);
408  int HaveStageMsg = (StageMsg && StageMsg[0]);
409  int HaveN2N_Lib = (N2N_Lib != 0);
410 
411  if (!ConfigFN || !ConfigFN[0]) cloc = (char *)"Default";
412  else cloc = ConfigFN;
413 
414  snprintf(buff, sizeof(buff), "Config effective %s oss configuration:\n"
415  " oss.alloc %lld %d %d\n"
416  " oss.spacescan %d\n"
417  " oss.fdlimit %d %d\n"
418  " oss.maxsize %lld\n"
419  "%s%s%s"
420  "%s%s%s"
421  "%s%s%s"
422  "%s%s%s%s%s"
423  "%s%s%s"
424  "%s%s%s"
425  " oss.trace %x\n"
426  " oss.xfr %d deny %d keep %d",
427  cloc,
429  cscanint,
431  XrdOssConfig_Val(N2N_Lib, namelib),
432  XrdOssConfig_Val(LocalRoot, localroot),
433  XrdOssConfig_Val(RemoteRoot, remoteroot),
434  XrdOssConfig_Vop(StageCmd, stagecmd, StageAsync, "async ","sync ",
435  StageCreate, "creates ", ""),
436  XrdOssConfig_Val(StageMsg, stagemsg),
437  XrdOssConfig_Val(RSSCmd, rsscmd),
438  OssTrace.What,
440 
441  Eroute.Say(buff);
442 
443  XrdOssMio::Display(Eroute);
444 
445  XrdOssCache::List(" oss.", Eroute);
446  List_Path(" oss.defaults ", "", DirFlags, Eroute);
447  fp = RPList.First();
448  while(fp)
449  {List_Path(" oss.path ", fp->Path(), fp->Flag(), Eroute);
450  fp = fp->Next();
451  }
452  fp = SPList.First();
453  while(fp)
454  {Eroute.Say(" oss.space ", fp->Name(),
455  (fp->Attr() == spAssign ? " assign " : " default "),
456  fp->Path());
457  fp = fp->Next();
458  }
459 }
460 
461 /******************************************************************************/
462 /* P r i v a t e F u n c t i o n s */
463 /******************************************************************************/
464 /******************************************************************************/
465 /* C o n f i g C a c h e */
466 /******************************************************************************/
467 
468 void XrdOssSys::ConfigCache(XrdSysError &Eroute, bool pass2)
469 {
470  const unsigned long long conFlags =
475 
476  XrdOucPList *fp = RPList.First();
477  unsigned long long oflag, pflag;
478 
479 // If this is pass 2 then if we are in pfcMode, then reset r/o flag to r/w
480 // to allow the pfc to actually write into the cache paths.
481 //
482  if (pass2)
483  {if (pfcMode)
484  {while(fp)
485  {pflag = fp->Flag();
486  if (pflag & XRDEXP_PFCACHE) fp->Set(pflag & ~XRDEXP_NOTRW);
487  fp = fp->Next();
488  }
489  }
490  return;
491  }
492 
493 // Run through all the paths and resolve any conflicts with a cache
494 //
495  while(fp)
496  {oflag = pflag = fp->Flag();
497  if ((pflag & XRDEXP_PFCACHE)
498  || (pfcMode && !(pflag & XRDEXP_PFCACHE_X)))
499  {if (!(pflag & XRDEXP_NOTRW)) pflag |= XRDEXP_READONLY;
500  pflag &= ~conFlags;
501  pflag |= XRDEXP_PFCACHE;
502  if (oflag != pflag) fp->Set(pflag);
503  }
504  fp = fp->Next();
505  }
506 
507 // Handle default settings
508 //
509  if (DirFlags & XRDEXP_PFCACHE)
511  DirFlags &= ~conFlags;
512  }
513 }
514 
515 /******************************************************************************/
516 /* C o n f i g M i o */
517 /******************************************************************************/
518 
520 {
521  XrdOucPList *fp;
522  unsigned long long flags = 0;
523  int setoff = 0;
524 
525 // Initialize memory mapping setting to speed execution
526 //
527  if (!(tryMmap = XrdOssMio::isOn())) return;
529 
530 // Run through all the paths and get the composite flags
531 //
532  fp = RPList.First();
533  while(fp)
534  {flags |= fp->Flag();
535  fp = fp->Next();
536  }
537 
538 // Handle default settings
539 //
542  flags |= DirFlags;
544 
545 // Produce warnings if unsupported features have been selected
546 //
547 #if !defined(_POSIX_MAPPED_FILES)
548  if (flags & XRDEXP_MEMAP)
549  {Eroute.Say("Config warning: memory mapped files not supported; "
550  "feature disabled.");
551  setoff = 1;
552  fp = RPList.First();
553  while(fp)
554  {fp->Set(fp->Flag() & ~XRDEXP_MEMAP);
555  fp = fp->Next();
556  }
558  }
559 #elif !defined(_POSIX_MEMLOCK)
560  if (flags & XRDEXP_MLOK)
561  {Eroute.Say("Config warning: memory locked files not supported; "
562  "feature disabled.");
563  fp = RPList.First();
564  while(fp)
565  {fp->Set(fp->Flag() & ~XRDEXP_MLOK);
566  fp = fp->Next();
567  }
569  }
570 #endif
571 
572 // If no memory flags are set, turn off memory mapped files
573 //
574  if (!(flags & XRDEXP_MEMAP) || setoff)
575  {XrdOssMio::Set(0, 0, 0);
576  tryMmap = 0; chkMmap = 0;
577  }
578 }
579 
580 /******************************************************************************/
581 /* C o n f i g N 2 N */
582 /******************************************************************************/
583 
585 {
587 
588 // Get the plugin
589 //
590  if (!(the_N2N = n2nLoader.Load(N2N_Lib, *myVersion, envP))) return 1;
591 
592 // Optimize the local case
593 //
594  if (N2N_Lib) rmt_N2N = lcl_N2N = the_N2N;
595  else {if (LocalRoot) lcl_N2N = the_N2N;
596  if (RemoteRoot) rmt_N2N = the_N2N;
597  }
598 
599 // All done
600 //
601  return 0;
602 }
603 
604 /******************************************************************************/
605 /* C o n f i g P r o c */
606 /******************************************************************************/
607 
609 {
610  char *var;
611  int cfgFD, retc, NoGo = XrdOssOK;
612  XrdOucEnv myEnv;
613  XrdOucStream Config(&Eroute, getenv("XRDINSTANCE"), &myEnv, "=====> ");
614 
615 // If there is no config file, return with the defaults sets.
616 //
617  if( !ConfigFN || !*ConfigFN)
618  {Eroute.Say("Config warning: config file not specified; defaults assumed.");
619  return XrdOssOK;
620  }
621 
622 // Try to open the configuration file.
623 //
624  if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
625  {Eroute.Emsg("Config", errno, "open config file", ConfigFN);
626  return 1;
627  }
628  Config.Attach(cfgFD);
629  static const char *cvec[] = { "*** oss plugin config:", 0 };
630  Config.Capture(cvec);
631 
632 // Now start reading records until eof.
633 //
634  while((var = Config.GetMyFirstWord()))
635  {if (!strncmp(var, "oss.", 4))
636  {if (ConfigXeq(var+4, Config, Eroute)) {Config.Echo(); NoGo = 1;}}
637  else if (!strcmp(var,"all.export")
638  && xpath(Config, Eroute)) {Config.Echo(); NoGo = 1;}
639  }
640 
641 // Now check if any errors occurred during file i/o
642 //
643  if ((retc = Config.LastError()))
644  NoGo = Eroute.Emsg("Config", retc, "read config file", ConfigFN);
645  Config.Close();
646 
647 // Return final return code
648 //
649  return NoGo;
650 }
651 
652 /******************************************************************************/
653 /* C o n f i g S p a c e */
654 /******************************************************************************/
655 
657 {
658  XrdOucPList *fp = RPList.First();
659  int noCacheFS = !(OptFlags & XrdOss_CacheFS);
660 
661 // Configure space for each non-cached exported path. We only keep track of
662 // space that can actually be modified in some way.
663 //
664  while(fp)
665  {if ( ((noCacheFS || (fp->Flag() & XRDEXP_INPLACE)) &&
666  (fp->Flag() & (XRDEXP_STAGE | XRDEXP_PURGE)))
667  || !(fp->Flag() & XRDEXP_NOTRW)
668  || (fp->Flag() & XRDEXP_PFCACHE) )
669  ConfigSpace(fp->Path());
670  fp = fp->Next();
671  }
672 
673 // If there is a space list then verify it
674 //
675  if ((fp = SPList.First()))
676  {XrdOssCache_Group *fsg;
677  const char *what;
678  bool zAssign = false;
679  while(fp)
680  {if (fp->Attr() != spAssign) what = "default space ";
681  else {zAssign = true; what = "assign space ";}
682  const char *grp = fp->Name();
684  while(fsg) {if (!strcmp(fsg->group,grp)) break; fsg = fsg->next;}
685  if (!fsg) Eroute.Say("Config warning: unable to ", what, grp,
686  " to ", fp->Path(), "; space not defined.");
687  fp = fp->Next();
688  }
689  if (zAssign) SPList.Default(static_cast<unsigned long long>(spAssign));
690  }
691 }
692 
693 /******************************************************************************/
694 
695 void XrdOssSys::ConfigSpace(const char *Lfn)
696 {
697  struct stat statbuff;
698  char Pfn[MAXPATHLEN+1+8], *Slash;
699 
700 // Get local path for this lfn
701 //
702  if (GenLocalPath(Lfn, Pfn)) return;
703 
704 // Now try to find the actual existing base path
705 //
706  while(stat(Pfn, &statbuff))
707  {if (!(Slash = rindex(Pfn, '/')) || Slash == Pfn) return;
708  *Slash = '\0';
709  }
710 
711 // Add this path to the file system data. We need to do this to track space
712 //
713  XrdOssCache_FS::Add(Pfn);
714 }
715 
716 /******************************************************************************/
717 /* C o n f i g S p a t h */
718 /******************************************************************************/
719 
720 void XrdOssSys::ConfigSpath(XrdSysError &Eroute, const char *Path,
721  unsigned long long &flags, int noMSS)
722 {
723 // mig+r/w -> check unless nocheck was specified
724 //
725  if (!(flags & XRDEXP_CHECK_X))
726  {if ((flags & XRDEXP_MIG) && !(flags & XRDEXP_NOTRW))
727  flags &= ~XRDEXP_NOCHECK;
728  else flags |= XRDEXP_NOCHECK;
729  }
730 // rsscmd -> dread unless nodread was specified
731 //
732  if (!(flags & XRDEXP_DREAD_X))
733  {if (RSSCmd) flags &= ~XRDEXP_NODREAD;
734  else flags |= XRDEXP_NODREAD;
735  }
736 
737 // If there is no mss then turn off all mss related optionss, otherwise check
738 // if the options may leave the system in an inconsistent state
739 //
740  if (noMSS) flags=(flags & ~XRDEXP_RCREATE)|XRDEXP_NOCHECK|XRDEXP_NODREAD;
741  else if ((flags & XRDEXP_MIG) && (flags & XRDEXP_NOCHECK)
742  && !(flags & XRDEXP_NOTRW))
743  Eroute.Say("Config warning: 'all.export ", Path,
744  " nocheck mig r/w' allows file inconsistentcy!");
745 }
746 
747 /******************************************************************************/
748 /* C o n f i g S t a g e */
749 /******************************************************************************/
750 
752 {
753  const char *What;
754  char *tp, *stgp = 0;
755  unsigned long long flags;
756  int noMSS, needRSS = 0, NoGo = 0;
757  XrdOucPList *fp;
758 
759 // Determine if we are a manager/supervisor. These never stage files so we
760 // really don't need (nor want) a stagecmd or an msscmd.
761 //
762  noMSS = ((tp = getenv("XRDREDIRECT"))
763  && (!strcmp(tp, "R") || !strcmp(tp, "M"))) | Solitary;
764 
765 // A rsscmd implies check+dread. Note that nostage is now always the default.
766 //
767  flags = (RSSCmd ? 0 : XRDEXP_NOCHECK | XRDEXP_NODREAD);
768  DirFlags = DirFlags | (flags & (~(DirFlags >> XRDEXP_MASKSHIFT)));
769 
770 // Set default flags
771 //
773 
774 // Reprocess the paths to set correct defaults
775 //
776  fp = RPList.First();
777  while(fp)
778  {flags = fp->Flag(); ConfigSpath(Eroute, fp->Path(), flags, noMSS);
779 
780  // Record the fact that we have a stageable path
781  //
782  if (flags & XRDEXP_STAGE) stgp = fp->Path();
783 
784  // Check if path requires rsscmd and complain if we don't have one
785  //
786  if (!(flags & XRDEXP_NOCHECK)) What = "has check";
787  else if (!(flags & XRDEXP_NODREAD)) What = "has dread";
788  else if (flags & XRDEXP_RCREATE) What = "has recreate";
789  else What = 0;
790  if (!noMSS && !RSSCmd && What)
791  {Eroute.Emsg("Config", fp->Path(), What,
792  "export attribute but rsscmd not specified.");
793  NoGo = 1;
794  } else if (What) needRSS = 1;
795 
796  // Update flags and proceed to next path
797  //
798  fp->Set(flags); fp = fp->Next();
799  }
800 
801 // If we are a manager/supervisor, short circuit MSS initialization
802 //
803  if (noMSS)
804  {if (RSSCmd) {free(RSSCmd); RSSCmd = 0;}
805  if (StageCmd) {free(StageCmd); StageCmd = 0;}
806  RSSProg = 0; StageCreate = 0;
807  return NoGo;
808  }
809 
810 // Check if we don't need the stagecmd but one was specified
811 //
812  if (StageCmd && !stgp)
813  {Eroute.Say("Config warning: 'stagecmd' ignored; no stageable paths present.");
814  free(StageCmd); StageCmd = 0;
815  }
816 
817 // Check if we don't need a remote storage service but one was specified
818 //
819  if (RSSCmd && !needRSS)
820  {Eroute.Say("Config warning: 'rsscmd' ignored; no path exported with "
821  "check, dread, or rcreate.");
822  free(RSSCmd); RSSCmd = 0;
823  }
824 
825 // If we have any errors at this point, just return failure
826 //
827  if (NoGo) return 1;
828  if (!RSSCmd && !StageCmd && !stgp) return 0;
829  Eroute.Say("++++++ Remote Storage System interface initialization started.");
830 
831 // Allocate a pr0gram object for the gateway command
832 //
833  if (RSSCmd)
834  {RSSProg = new XrdOucProg(&Eroute);
835  if (RSSProg->Setup(RSSCmd)) NoGo = 1;
836  }
837 
838 // Initialize staging if we need to
839 //
840  if (!NoGo && (StageCmd || stgp))
841  {const int AMode = S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH; // 775
842  if (StageCmd && *StageCmd) NoGo = ConfigStageC(Eroute);
843  else {StageFrm = new XrdFrcProxy(Eroute.logger(),
846  getenv("XRDADMINPATH"), AMode);
847  StageRealTime = 0; StageAsync = 1;
848  }
849 
850  // Set up the event path
851  //
852  StageAction = (char *)"wfn "; StageActLen = 4;
853  if ((tp = getenv("XRDOFSEVENTS")))
854  {char sebuff[MAXPATHLEN+8];
855  StageEvSize = sprintf(sebuff, "file:///%s", tp);
856  StageEvents = strdup(sebuff);
857  } else {StageEvents = (char *)"-"; StageEvSize = 1;}
858  }
859 
860 // All done
861 //
862  tp = (NoGo ? (char *)"failed." : (char *)"completed.");
863  Eroute.Say("------ Remote Storage System interface initialization ", tp);
864  return NoGo;
865 }
866 
867 /******************************************************************************/
868 /* C o n f i g S t a g e C */
869 /******************************************************************************/
870 
872 {
873  pthread_t tid;
874  char *sp, *tp;
875  int numt, retc, NoGo = 0;
876 
877 // The stage command is interactive if it starts with an | (i.e., pipe in)
878 //
879  tp = StageCmd;
880  while(*tp && *tp == ' ') tp++;
881  if (*tp == '|') {StageRealTime = 0;
882  do {tp++;} while(*tp == ' ');
883  }
884  StageCmd = tp;
885 
886 // This is a bit of hackery to get the traceid sent over to the
887 // new file residency manager (frm). Keeps the config simple.
888 //
889  if ((sp = index(StageCmd, ' '))) *sp = '\0';
890  if (!(tp = rindex (StageCmd, '/'))) tp = StageCmd;
891  else tp++;
892  if (!strncmp("frm_", tp, 4)) StageFormat = 1;
893  if (sp) *sp = ' ';
894 
895 // Set up a program object for the command
896 //
897  StageProg = new XrdOucProg(&Eroute);
898  if (StageProg->Setup(StageCmd)) NoGo = 1;
899 
900 // For old-style real-time staging, create threads to handle the staging
901 // For queue-style staging, start the program that handles the queue
902 //
903  if (!NoGo)
904  {if (StageRealTime)
905  {if ((numt = xfrthreads - xfrtcount) > 0) while(numt--)
906  {if ((retc = XrdSysThread::Run(&tid,XrdOssxfr,(void *)0,0,"staging")))
907  Eroute.Emsg("Config", retc, "create staging thread");
908  else xfrtcount++;
909  }
910  } else NoGo = StageProg->Start();
911  }
912 
913 // Setup the additional stage information vector. Variable substitution:
914 // <data>$var;<data>.... (max of MaxArgs substitutions). This is only relevant
915 // when using an actual stagecmd.
916 //
917  if (!NoGo && !StageRealTime && StageMsg)
918  {XrdOucMsubs *msubs = new XrdOucMsubs(&Eroute);
919  if (msubs->Parse("stagemsg", StageMsg)) StageSnd = msubs;
920  else NoGo = 1; // We will exit no need to delete msubs
921  }
922 
923 // All done
924 //
925  return NoGo;
926 }
927 
928 /******************************************************************************/
929 /* C o n f i g S t a t L i b */
930 /******************************************************************************/
931 
933 {
934  XrdOucPinLoader myLib(&Eroute, myVersion, "statlib", STT_Lib);
935  const char *stName2 = "?XrdOssStatInfoInit2";
936 
937 // Get the plugin and stat function. Let's try version 2 first
938 //
939  XrdOssStatInfoInit2_t siGet2;
940  if (STT_V2) stName2++;
941  if ((siGet2=(XrdOssStatInfoInit2_t)myLib.Resolve(stName2)))
942  {if (!(STT_Fund = siGet2(this,Eroute.logger(),ConfigFN,STT_Parms,envP)))
943  return 1;
944  if (STT_DoARE) envP->PutPtr("XrdOssStatInfo2*", (void *)STT_Fund);
945  STT_V2 = 1;
946  return 0;
947  }
948 
949 // If we are here but the -2 was specified on the config then we fail
950 //
951  if (STT_V2) return 1;
952 
953 // OK, so we better find version 1 in the shared library
954 //
955  XrdOssStatInfoInit_t siGet;
956  if (!(siGet = (XrdOssStatInfoInit_t)myLib.Resolve("XrdOssStatInfoInit"))
957  || !(STT_Func = siGet (this,Eroute.logger(),ConfigFN,STT_Parms)))
958  return 1;
959 
960 // Return success
961 //
962  return 0;
963 }
964 
965 /******************************************************************************/
966 /* C o n f i g S t a t s */
967 /******************************************************************************/
968 
970 {
971  struct StatsDev
972  {StatsDev *Next;
973  dev_t st_dev;
974  StatsDev(StatsDev *dP, dev_t dn) : Next(dP), st_dev(dn) {}
975  };
976 
978  XrdOucPList *fP = RPList.First();
979  StatsDev *dP1st = 0, *dP, *dPp;
980  struct stat Stat;
981  char LPath[MAXPATHLEN+1], PPath[MAXPATHLEN+1], *cP;
982 
983 // Count actual cache groups
984 //
985  while(fsg) {numCG++; fsg = fsg->next;}
986 
987 // Develop the list of paths that we will report on
988 //
989  if (fP) do
990  {strcpy(LPath, fP->Path());
991  if (GenLocalPath(LPath, PPath)) continue;
992  if (stat(PPath, &Stat) && (cP = rindex(LPath, '/')))
993  {*cP = '\0';
994  if (GenLocalPath(LPath, PPath) || stat(PPath, &Stat)) continue;
995  }
996  dP = dP1st;
997  while(dP && dP->st_dev != Stat.st_dev) dP = dP->Next;
998  if (dP) continue;
999  ConfigStats(Stat.st_dev, LPath);
1000  if (GenLocalPath(LPath, PPath)) continue;
1001  DPList = new OssDPath(DPList, strdup(LPath), strdup(PPath));
1002  lenDP += strlen(LPath) + strlen(PPath); numDP++;
1003  dP1st = new StatsDev(dP1st, Stat.st_dev);
1004  } while ((fP = fP->Next()));
1005 
1006 // If we have no exported paths then create a simple /tmp object
1007 //
1008  if (!numDP)
1009  {DPList = new OssDPath(0, strdup("/tmp"), strdup("/tmp"));
1010  lenDP = 4; numDP = 1;
1011  }
1012 
1013 // Now delete all of the device objects
1014 //
1015  dP = dP1st;
1016  while(dP) {dPp = dP; dP = dP->Next; delete dPp;}
1017 }
1018 
1019 /******************************************************************************/
1020 
1021 void XrdOssSys::ConfigStats(dev_t Devnum, char *lP)
1022 {
1023  struct stat Stat;
1024  char *Slash, pP[MAXPATHLEN+1];
1025 
1026 // Minimize the path
1027 //
1028  while((Slash = rindex(lP+1, '/')))
1029  {*Slash = '\0';
1030  if (GenLocalPath(lP, pP) || stat(pP, &Stat) || Stat.st_dev != Devnum)
1031  break;
1032  }
1033 
1034 // Extend path if need be and return
1035 //
1036  if (Slash) *Slash = '/';
1037 }
1038 
1039 /******************************************************************************/
1040 /* C o n f i g X e q */
1041 /******************************************************************************/
1042 
1044 {
1045  char myVar[80], buff[2048], *val;
1046  int nosubs;
1047  XrdOucEnv *myEnv = 0;
1048 
1049  TS_Xeq("alloc", xalloc);
1050  TS_Xeq("cache", xcache);
1051  TS_Xeq("cachescan", xcachescan); // Backward compatibility
1052  TS_Xeq("spacescan", xcachescan);
1053  TS_Xeq("defaults", xdefault);
1054  TS_Xeq("fdlimit", xfdlimit);
1055  TS_Xeq("maxsize", xmaxsz);
1056  TS_Xeq("memfile", xmemf);
1057  TS_Xeq("namelib", xnml);
1058  TS_Xeq("path", xpath);
1059  TS_Xeq("preread", xprerd);
1060  TS_Xeq("space", xspace);
1061  TS_Xeq("stagecmd", xstg);
1062  TS_Xeq("statlib", xstl);
1063  TS_Xeq("trace", xtrace);
1064  TS_Xeq("usage", xusage);
1065  TS_Xeq("xfr", xxfr);
1066 
1067  // Check if var substitutions are prohibited (e.g., stagemsg). Note that
1068  // TS_String() returns upon success so be careful when adding new opts.
1069  //
1070  if ((nosubs = !strcmp(var, "stagemsg"))) myEnv = Config.SetEnv(0);
1071 
1072  // Copy the variable name as this may change because it points to an
1073  // internal buffer in Config. The vagaries of effeciency.
1074  //
1075  strlcpy(myVar, var, sizeof(myVar));
1076  var = myVar;
1077 
1078  // We need to suck all the tokens to the end of the line for remaining
1079  // options. Do so, until we run out of space in the buffer.
1080  //
1081  if (!Config.GetRest(buff, sizeof(buff)))
1082  {Eroute.Emsg("Config", "arguments too long for", var);
1083  if (nosubs) Config.SetEnv(myEnv);
1084  return 1;
1085  }
1086  val = buff;
1087 
1088  // Restore substititions at this point if need be
1089  //
1090  if (nosubs) Config.SetEnv(myEnv);
1091 
1092  // At this point, make sure we have a value
1093  //
1094  if (!(*val))
1095  {Eroute.Emsg("Config", "no value for directive", var);
1096  return 1;
1097  }
1098 
1099  // Check for tokens taking a variable number of parameters
1100  //
1101  TS_String("localroot", LocalRoot);
1102  TS_String("remoteroot", RemoteRoot);
1103  TS_String("stagemsg", StageMsg);
1104 
1105  // The following differentiates between a deprecated and a preferred command
1106  //
1107  if (!strcmp("msscmd", var)) {isMSSC = 1; Duplicate(val, RSSCmd); return 0;}
1108  if (!strcmp("rsscmd", var)) {isMSSC = 0; Duplicate(val, RSSCmd); return 0;}
1109 
1110  // No match found, complain.
1111  //
1112  Eroute.Say("Config warning: ignoring unknown directive '",var,"'.");
1113  Config.Echo();
1114  return 0;
1115 }
1116 
1117 /******************************************************************************/
1118 /* x a l l o c */
1119 /******************************************************************************/
1120 
1121 /* Function: aalloc
1122 
1123  Purpose: To parse the directive: alloc <min> [<headroom> [<fuzz>]]
1124 
1125  <min> minimum amount of free space needed in a partition.
1126  (asterisk uses default).
1127  <headroom> percentage of requested space to be added to the
1128  free space amount (asterisk uses default).
1129  <fuzz> the percentage difference between two free space
1130  quantities that may be ignored when selecting a space
1131  0 - reduces to finding the largest free space
1132  100 - reduces to simple round-robin allocation
1133 
1134  Output: 0 upon success or !0 upon failure.
1135 */
1136 
1138 {
1139  char *val;
1140  long long mina = 0;
1141  int fuzz = 0;
1142  int hdrm = 0;
1143 
1144  if (!(val = Config.GetWord()))
1145  {Eroute.Emsg("Config", "alloc minfree not specified"); return 1;}
1146  if (strcmp(val, "*") &&
1147  XrdOuca2x::a2sz(Eroute, "alloc minfree", val, &mina, 0)) return 1;
1148 
1149  if ((val = Config.GetWord()))
1150  {if (strcmp(val, "*") &&
1151  XrdOuca2x::a2i(Eroute,"alloc headroom",val,&hdrm,0,100)) return 1;
1152 
1153  if ((val = Config.GetWord()))
1154  {if (strcmp(val, "*") &&
1155  XrdOuca2x::a2i(Eroute, "alloc fuzz", val, &fuzz, 0, 100)) return 1;
1156  }
1157  }
1158 
1159  minalloc = mina;
1160  ovhalloc = hdrm;
1161  fuzalloc = fuzz;
1162  return 0;
1163 }
1164 
1165 /******************************************************************************/
1166 /* x c a c h e */
1167 /******************************************************************************/
1168 
1169 /* Function: xcache
1170 
1171  Purpose: To parse the directive: cache <group> <path> [xa]
1172 
1173  <group> logical group name for the cache filesystem.
1174  <path> path to the cache.
1175  xa support extended attributes
1176 
1177  Output: 0 upon success or !0 upon failure.
1178 */
1179 
1181 {
1182  int rc, isXA = 0;
1183 
1184 // Skip out to process this entry and upon success indicate that it is
1185 // deprecated and "space" should be used instead if an XA-style space defined.
1186 //
1187  if (!(rc = xspace(Config, Eroute, &isXA)))
1188  {if (isXA) Eroute.Say("Config warning: 'oss.cache' is deprecated; "
1189  "use 'oss.space' instead!");
1190  else {Eroute.Say("Config failure: non-xa spaces are no longer "
1191  "supported!");
1192  rc = 1;
1193  }
1194  }
1195  return rc;
1196 }
1197 
1198 /******************************************************************************/
1199 /* x c a c h e s c a n */
1200 /******************************************************************************/
1201 
1202 /* Function: xcachescan
1203 
1204  Purpose: To parse the directive: cachescan <num>
1205 
1206  <num> number of seconds between cache scans.
1207 
1208  Output: 0 upon success or !0 upon failure.
1209 */
1211 { int cscan = 0;
1212  char *val;
1213 
1214  if (!(val = Config.GetWord()))
1215  {Eroute.Emsg("Config", "cachescan not specified"); return 1;}
1216  if (XrdOuca2x::a2tm(Eroute, "cachescan", val, &cscan, 30)) return 1;
1217  cscanint = cscan;
1218  return 0;
1219 }
1220 
1221 /******************************************************************************/
1222 /* x d e f a u l t */
1223 /******************************************************************************/
1224 
1225 /* Function: xdefault
1226 
1227  Purpose: Parse: defaults <default options>
1228 
1229  Notes: See the oss configuration manual for the meaning of each option.
1230  The actual implementation is defined in XrdOucExport.
1231 
1232  Output: 0 upon success or !0 upon failure.
1233 */
1234 
1236 {
1238  return 0;
1239 }
1240 
1241 /******************************************************************************/
1242 /* x f d l i m i t */
1243 /******************************************************************************/
1244 
1245 /* Function: xfdlimit
1246 
1247  Purpose: To parse the directive: fdlimit <fence> [ <max> ]
1248 
1249  <fence> lowest number to use for file fd's (0 -> max). If
1250  specified as * then max/2 is used.
1251  <max> highest number that can be used. The soft rlimit is set
1252  to this value. If not supplied, the limit is not changed.
1253  If supplied as 'max' then the hard limit is used.
1254 
1255  Output: 0 upon success or !0 upon failure.
1256 */
1257 
1259 {
1260  char *val;
1261  int fence = 0, FDHalf = FDLimit>>1;
1262 
1263  if (!(val = Config.GetWord()))
1264  {Eroute.Emsg("Config", "fdlimit fence not specified"); return 1;}
1265 
1266  if (!strcmp(val, "*")) FDFence = FDHalf;
1267  else {if (XrdOuca2x::a2i(Eroute,"fdlimit fence",val,&fence,0)) return 1;
1268  FDFence = (fence < FDHalf ? fence : FDHalf);
1269  }
1270 
1271  while(Config.GetWord()) {}
1272 
1273 // Eroute.Say("Config warning: ", "fdlimit directive no longer supported.");
1274 
1275  return 0;
1276 }
1277 
1278 /******************************************************************************/
1279 /* x m a x s z */
1280 /******************************************************************************/
1281 
1282 /* Function: xmaxsz
1283 
1284  Purpose: Parse the directive: maxsize <num>
1285 
1286  <num> Maximum number of bytes in a file.
1287 
1288  Output: 0 upon success or !0 upon failure.
1289 */
1290 
1292 { long long msz;
1293  char *val;
1294 
1295  if (!(val = Config.GetWord()))
1296  {Eroute.Emsg("Config", "maxsize value not specified"); return 1;}
1297  if (XrdOuca2x::a2sz(Eroute, "maxsize", val, &msz, 1024*1024)) return 1;
1298  MaxSize = msz;
1299  return 0;
1300 }
1301 
1302 /******************************************************************************/
1303 /* x m e m f */
1304 /******************************************************************************/
1305 
1306 /* Function: xmemf
1307 
1308  Purpose: Parse the directive: memfile [off] [max <msz>]
1309  [check xattr] [preload]
1310 
1311  check Applies memory mapping options based on file's xattrs.
1312  For backward compatibility, we also accept:
1313  "[check {keep | lock | map}]" which implies check xattr.
1314  all Preloads the complete file into memory.
1315  off Disables memory mapping regardless of other options.
1316  on Enables memory mapping
1317  preload Preloads the file after every opn reference.
1318  <msz> Maximum amount of memory to use (can be n% or real mem).
1319 
1320  Output: 0 upon success or !0 upon failure.
1321 */
1322 
1324 {
1325  char *val;
1326  int i, j, V_check=-1, V_preld = -1, V_on=-1;
1327  long long V_max = 0;
1328 
1329  static struct mmapopts {const char *opname; int otyp;
1330  const char *opmsg;} mmopts[] =
1331  {
1332  {"off", 0, ""},
1333  {"preload", 1, "memfile preload"},
1334  {"check", 2, "memfile check"},
1335  {"max", 3, "memfile max"}};
1336  int numopts = sizeof(mmopts)/sizeof(struct mmapopts);
1337 
1338  if (!(val = Config.GetWord()))
1339  {Eroute.Emsg("Config", "memfile option not specified"); return 1;}
1340 
1341  while (val)
1342  {for (i = 0; i < numopts; i++)
1343  if (!strcmp(val, mmopts[i].opname)) break;
1344  if (i >= numopts)
1345  Eroute.Say("Config warning: ignoring invalid memfile option '",val,"'.");
1346  else {if (mmopts[i].otyp > 1 && !(val = Config.GetWord()))
1347  {Eroute.Emsg("Config","memfile",mmopts[i].opname,
1348  "value not specified");
1349  return 1;
1350  }
1351  switch(mmopts[i].otyp)
1352  {case 1: V_preld = 1;
1353  break;
1354  case 2: if (!strcmp("xattr",val)
1355  || !strcmp("lock", val)
1356  || !strcmp("map", val)
1357  || !strcmp("keep", val)) V_check=1;
1358  else {Eroute.Emsg("Config",
1359  "mmap check argument not xattr");
1360  return 1;
1361  }
1362  break;
1363  case 3: j = strlen(val);
1364  if (val[j-1] == '%')
1365  {val[j-1] = '\0';
1366  if (XrdOuca2x::a2i(Eroute,mmopts[i].opmsg,
1367  val, &j, 1, 1000)) return 1;
1368  V_max = -j;
1369  } else if (XrdOuca2x::a2sz(Eroute,
1370  mmopts[i].opmsg, val, &V_max,
1371  10*1024*1024)) return 1;
1372  break;
1373  default: V_on = 0; break;
1374  }
1375  val = Config.GetWord();
1376  }
1377  }
1378 
1379 // Set the values
1380 //
1381  XrdOssMio::Set(V_on, V_preld, V_check);
1382  XrdOssMio::Set(V_max);
1383  return 0;
1384 }
1385 
1386 /******************************************************************************/
1387 /* x n m l */
1388 /******************************************************************************/
1389 
1390 /* Function: xnml
1391 
1392  Purpose: To parse the directive: namelib <path> [<parms>]
1393 
1394  <path> the path of the filesystem library to be used.
1395  <parms> optional parms to be passed
1396 
1397  Output: 0 upon success or !0 upon failure.
1398 */
1399 
1401 {
1402  char *val, parms[1040];
1403 
1404 // Get the path
1405 //
1406  if (!(val = Config.GetWord()) || !val[0])
1407  {Eroute.Emsg("Config", "namelib not specified"); return 1;}
1408 
1409 // Record the path
1410 //
1411  if (N2N_Lib) free(N2N_Lib);
1412  N2N_Lib = strdup(val);
1413 
1414 // Record any parms
1415 //
1416  if (!Config.GetRest(parms, sizeof(parms)))
1417  {Eroute.Emsg("Config", "namelib parameters too long"); return 1;}
1418  if (N2N_Parms) free(N2N_Parms);
1419  N2N_Parms = (*parms ? strdup(parms) : 0);
1420  return 0;
1421 }
1422 
1423 /******************************************************************************/
1424 /* x p a t h */
1425 /******************************************************************************/
1426 
1427 /* Function: xpath
1428 
1429  Purpose: To parse the directive: {export | path} <path> [<options>]
1430 
1431  <path> the full path that resides in a remote system.
1432  <options> a blank separated list of options (see XrdOucExport)
1433 
1434  Output: 0 upon success or !0 upon failure.
1435 */
1436 
1438 {
1439  XrdOucPList *pP;
1440 
1441 // Parse the arguments
1442 //
1444  if (!pP) return 1;
1445 
1446 // If this is an absolute path, we are done
1447 //
1448  if (*(pP->Path()) == '/') return 0;
1449 
1450 // If this is an objectid path then make sure to set the default for these
1451 //
1452  if (*(pP->Path()) == '*')
1453  {RPList.Defstar(pP->Flag());
1454  return 0;
1455  }
1456 
1457 // We do not (yet) support exporting specific object ID's
1458 //
1459  Eroute.Emsg("Config", "Unsupported export -", pP->Path());
1460  return 1;
1461 }
1462 
1463 /******************************************************************************/
1464 /* x p r e r d */
1465 /******************************************************************************/
1466 
1467 /* Function: xprerd
1468 
1469  Purpose: To parse the directive: preread {<depth> | on} [limit <bytes>]
1470  [ qsize [=]<qsz> ]
1471 
1472  <depth> the number of request to preread ahead of the read.
1473  A value of 0, the inital default, turns off prereads.
1474  Specifying "on" sets the value (currently) to 3.
1475  <bytes> Maximum number of bytes to preread. Prereading stops,
1476  regardless of depth, once <bytes> have been preread.
1477  The default is 1M (i.e.1 megabyte). The max is 16M.
1478  <qsz> the queue size after which preread blocking would occur.
1479  The value must be greater than or equal to <depth>.
1480  The value is adjusted to max(<qsz>/(<depth>/2+1),<depth>)
1481  unless the number is preceeded by an equal sign. The
1482  default <qsz> is 128.
1483 
1484  Output: 0 upon success or !0 upon failure.
1485 */
1486 
1488 {
1489  static const long long m16 = 16777216LL;
1490  char *val;
1491  long long lim = 1048576;
1492  int depth, qeq = 0, qsz = 128;
1493 
1494  if (!(val = Config.GetWord()))
1495  {Eroute.Emsg("Config", "preread depth not specified"); return 1;}
1496 
1497  if (!strcmp(val, "on")) depth = 3;
1498  else if (XrdOuca2x::a2i(Eroute,"preread depth",val,&depth,0, 1024))
1499  return 1;
1500 
1501  while((val = Config.GetWord()))
1502  { if (!strcmp(val, "limit"))
1503  {if (!(val = Config.GetWord()))
1504  {Eroute.Emsg("Config","preread limit not specified");
1505  return 1;
1506  }
1507  if (XrdOuca2x::a2sz(Eroute,"preread limit",val,&lim,0,m16))
1508  return 1;
1509  }
1510  else if (!strcmp(val, "qsize"))
1511  {if (!(val = Config.GetWord()))
1512  {Eroute.Emsg("Config","preread qsize not specified");
1513  return 1;
1514  }
1515  if (XrdOuca2x::a2i(Eroute,"preread qsize",val,&qsz,0,1024))
1516  return 1;
1517  if (qsz < depth)
1518  {Eroute.Emsg("Config","preread qsize must be >= depth");
1519  return 1;
1520  }
1521  }
1522  else {Eroute.Emsg("Config","invalid preread option -",val); return 1;}
1523  }
1524 
1525  if (lim < prPSize || !qsz) depth = 0;
1526  if (!qeq && depth)
1527  {qsz = qsz/(depth/2+1);
1528  if (qsz < depth) qsz = depth;
1529  }
1530 
1531  prDepth = depth;
1532  prQSize = qsz;
1533  prBytes = lim;
1534  return 0;
1535 }
1536 
1537 /******************************************************************************/
1538 /* x s p a c e */
1539 /******************************************************************************/
1540 
1541 /* Function: xspace
1542 
1543  Purpose: To parse the directive: space <name> <path> {chkmount <id> [nofail]
1544  or: space <name> {assign}default} <lfn> [...]
1545 
1546  <name> logical name for the filesystem.
1547  <path> path to the filesystem.
1548  <id> mountpoint name in order to be considered valid
1549 
1550  Output: 0 upon success or !0 upon failure.
1551 
1552  Note: This is the new and prefered way to say "cache <group> <path> xa".
1553 */
1554 
1556 {
1557  XrdOucString grp, fn, mn;
1558  OssSpaceConfig sInfo(grp, fn, mn);
1559  char *val;
1560  int k;
1561  bool isAsgn, isStar;
1562 
1563 // Get the space name
1564 //
1565  if (!(val = Config.GetWord()))
1566  {Eroute.Emsg("Config", "space name not specified"); return 1;}
1567  if ((int)strlen(val) > XrdOssSpace::maxSNlen)
1568  {Eroute.Emsg("Config","excessively long space name - ",val); return 1;}
1569  grp = val;
1570 
1571 // Get the path to the space
1572 //
1573  if (!(val = Config.GetWord()) || !(*val))
1574  {Eroute.Emsg("Config", "space path not specified"); return 1;}
1575 
1576 // Check if assignment
1577 //
1578  if (((isAsgn = !strcmp("assign",val)) || ! strcmp("default",val)) && !isCD)
1579  return xspace(Config, Eroute, grp.c_str(), isAsgn);
1580 
1581 // Preprocess this path and validate it
1582 //
1583  k = strlen(val)-1;
1584  if ((isStar = val[k] == '*')) val[k--] = 0;
1585  else while(k > 0 && val[k] == '/') val[k--] = 0;
1586 
1587  if (k >= MAXPATHLEN || val[0] != '/' || (k < 2 && !isStar))
1588  {Eroute.Emsg("Config", "invalid space path - ", val); return 1;}
1589  fn = val;
1590 
1591 // Sanitize the path as we are sensitive to proper placement of slashes
1592 //
1593  do {k = fn.replace("/./", "/");} while(k);
1594  do {k = fn.replace("//", "/");} while(k);
1595 
1596 // Additional options (for now) are only available to the old-style cache
1597 // directive. So, ignore any unless we entered via the directive.
1598 //
1599  if (isCD)
1600  {if ((val = Config.GetWord()))
1601  {if (strcmp("xa", val))
1602  {Eroute.Emsg("Config","invalid cache option - ",val); return 1;}
1603  else *isCD = 1;
1604  } else {*isCD = 0; sInfo.isXA = false;}
1605  } else {
1606  if ((val = Config.GetWord()) && !strcmp("chkmount", val))
1607  {if (!(val = Config.GetWord()))
1608  {Eroute.Emsg("Config","chkmount ID not specified"); return 1;}
1609  if ((int)strlen(val) > XrdOssSpace::maxSNlen)
1610  {Eroute.Emsg("Config","excessively long mount name - ",val);
1611  return 1;
1612  }
1613  mn = val;
1614  sInfo.chkMnt = true;
1615  if ((val = Config.GetWord()))
1616  {if (!strcmp("nofail", val)) sInfo.noFail = true;
1617  else {Eroute.Emsg("Config","invalid space option - ",val);
1618  return 1;
1619  }
1620  }
1621  }
1622  }
1623 
1624 // Check if this directory in the parent is only to be used for the space
1625 //
1626  if (!isStar)
1627  {if (!fn.endswith('/')) fn += '/';
1628  return !xspaceBuild(sInfo, Eroute);
1629  }
1630 
1631 // We now need to build a space for each directory in the parent
1632 //
1633  struct dirent *dp;
1634  struct stat Stat;
1635  XrdOucString pfx, basepath(fn);
1636  DIR *dirP;
1637  int dFD, rc, snum = 0;
1638  bool chkPfx, failed = false;
1639 
1640  if (basepath.endswith('/')) chkPfx = false;
1641  else {int pos = basepath.rfind('/');
1642  pfx = &basepath[pos+1];
1643  basepath.keep(0, pos+1);
1644  chkPfx = true;
1645  }
1646 
1647  if ((dFD=open(basepath.c_str(),O_DIRECTORY)) < 0 || !(dirP=fdopendir(dFD)))
1648  {Eroute.Emsg("Config",errno,"open space directory",fn.c_str()); return 1;}
1649 
1650  errno = 0;
1651  while((dp = readdir(dirP)))
1652  {if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")
1653  || (chkPfx && strncmp(dp->d_name,pfx.c_str(),pfx.length()))) continue;
1654 
1655  if (fstatat(dFD, dp->d_name, &Stat, AT_SYMLINK_NOFOLLOW))
1656  {basepath += dp->d_name;
1657  break;
1658  }
1659 
1660  if ((Stat.st_mode & S_IFMT) == S_IFDIR)
1661  {fn = basepath; fn += dp->d_name; fn += '/';
1662  if (!xspaceBuild(sInfo, Eroute)) failed = true;
1663  snum++;
1664  }
1665  errno = 0;
1666  }
1667 
1668 // Make sure we built all space successfully and have at least one space
1669 //
1670  if ((rc = errno))
1671  Eroute.Emsg("Config", errno, "process space directory", fn.c_str());
1672  else if (!snum)
1673  Eroute.Say("Config warning: no space directories found in ",
1674  fn.c_str());
1675 
1676  closedir(dirP);
1677  return rc != 0 || failed;
1678 }
1679 
1680 /******************************************************************************/
1681 
1683  const char *grp, bool isAsgn)
1684 {
1685  XrdOucPList *pl;
1686  char *path;
1687 
1688 // Get the path
1689 //
1690  path = Config.GetWord();
1691  if (!path || !path[0])
1692  {Eroute.Emsg("Config", "space path not specified"); return 1;}
1693 
1694 // Create a new path list object and add it to list of paths
1695 //
1696 do{if ((pl = SPList.Match(path))) pl->Set(path, grp);
1697  else {pl = new XrdOucPList(path, grp);
1698  SPList.Insert(pl);
1699  }
1700  pl->Set((isAsgn ? spAssign : 0));
1701  } while((path = Config.GetWord()));
1702 
1703 // All done
1704 //
1705  return 0;
1706 }
1707 
1708 /******************************************************************************/
1709 
1711 {
1714  int rc = 0;
1715 
1716 // Check if we need to verify the mount. Note: sPath must end with a '/'!
1717 //
1718  if (sInfo.chkMnt)
1719  {XrdOucString mFile(sInfo.mName), mPath(sInfo.sPath);
1720  struct stat Stat;
1721  mPath.erasefromend(1);
1722  mFile += '.';
1723  mFile += rindex(mPath.c_str(), '/')+1;
1724  mPath += '/'; mPath += mFile;
1725  if (stat(mPath.c_str(), &Stat))
1726  {char buff[2048];
1727  snprintf(buff, sizeof(buff), "%s@%s; ",
1728  mFile.c_str(), sInfo.sPath.c_str());
1729  Eroute.Say((sInfo.noFail ? "Config warning:" : "Config failure:"),
1730  " Unable to verify mount point ", buff, XrdSysE2T(errno));
1731  return (sInfo.noFail ? 1 : 0);
1732  }
1733  }
1734 
1735 // Add the space to the configuration
1736 
1737  XrdOssCache_FS *fsp = new XrdOssCache_FS(rc, sInfo.sName.c_str(),
1738  sInfo.sPath.c_str(), fopts);
1739  if (rc)
1740  {char buff[256];
1741  snprintf(buff, sizeof(buff), "create %s space at", sInfo.sName.c_str());
1742  Eroute.Emsg("Config", rc, buff, sInfo.sPath.c_str());
1743  if (fsp) delete fsp;
1744  return 0;
1745  }
1747  return 1;
1748 }
1749 
1750 /******************************************************************************/
1751 /* x s t g */
1752 /******************************************************************************/
1753 
1754 /* Function: xstg
1755 
1756  Purpose: To parse the directive:
1757  stagecmd [async | sync] [creates] [|]<cmd>
1758 
1759  async Client is to be notified when <cmd> sends an event
1760  sync Client is to poll for <cmd> completion.
1761  creates Route file creation requests to <cmd>.
1762  <cmd> The command and args to stage in the file. If the
1763  <cmd> is prefixed ny '|' then pipe in the requests.
1764 
1765  Output: 0 upon success or !0 upon failure.
1766 */
1767 
1769 {
1770  char *val, buff[2048], *bp = buff;
1771  int vlen, blen = sizeof(buff)-1, isAsync = 0, isCreate = 0;
1772 
1773 // Get the aync or async option
1774 //
1775  if ((val = Config.GetWord()))
1776  if ((isAsync = !strcmp(val, "async")) || !strcmp(val, "sync"))
1777  val = Config.GetWord();
1778 
1779 // Get the create option
1780 //
1781  if (val)
1782  if ((isCreate = !strcmp(val, "creates"))) val = Config.GetWord();
1783 
1784 // Get the command
1785 //
1786  if (!val) {Eroute.Emsg("Config", "stagecmd not specified"); return 1;}
1787 
1788 // Copy the command and all of it's arguments
1789 //
1790  do {if ((vlen = strlen(val)) >= blen)
1791  {Eroute.Emsg("Config", "stagecmd arguments too long"); break;}
1792  *bp = ' '; bp++; strcpy(bp, val); bp += vlen; blen -= vlen;
1793  } while((val = Config.GetWord()));
1794 
1795  if (val) return 1;
1796  *bp = '\0'; val = buff+1;
1797 
1798 // Record the command and operating mode
1799 //
1800  StageAsync = (isAsync ? 1 : 0);
1801  StageCreate= isCreate;
1802  if (StageCmd) free(StageCmd);
1803  StageCmd = strdup(val);
1804  return 0;
1805 }
1806 
1807 /******************************************************************************/
1808 /* x s t l */
1809 /******************************************************************************/
1810 
1811 /* Function: xstl
1812 
1813  Purpose: To parse the directive: statlib <Options> <path> [<parms>]
1814 
1815  Options: -2 use version 2 initialization interface (deprecated).
1816  -arevents forward add/remove events (server role cmsd only)
1817  -non2n do not apply name2name prior to calling plug-in.
1818  -preopen issue the stat() prior to opening the file.
1819 
1820  <path> the path of the stat library to be used.
1821  <parms> optional parms to be passed
1822 
1823  Output: 0 upon success or !0 upon failure.
1824 */
1825 
1827 {
1828  char *val, parms[1040];
1829 
1830 // Get the path or preopen option
1831 //
1832  if (!(val = Config.GetWord()) || !val[0])
1833  {Eroute.Emsg("Config", "statlib not specified"); return 1;}
1834 
1835 // Check for options we support the old and new versions here
1836 //
1837  STT_V2 = 0; STT_PreOp = 0; STT_DoN2N = 1; STT_DoARE = 0;
1838 do{ if (!strcmp(val, "-2")) STT_V2 = 1;
1839  else if (!strcmp(val, "arevents") || !strcmp(val, "-arevents")) STT_DoARE=1;
1840  else if (!strcmp(val, "non2n") || !strcmp(val, "-non2n")) STT_DoN2N=0;
1841  else if (!strcmp(val, "preopen") || !strcmp(val, "-preopen")) STT_PreOp=1;
1842  else break;
1843  } while((val = Config.GetWord()) && val[0]);
1844 
1845 // Make sure we have a statlib
1846 //
1847  if (!val || !(*val))
1848  {Eroute.Emsg("Config", "statlib not specified"); return 1;}
1849 
1850 // Record the path
1851 //
1852  if (STT_Lib) free(STT_Lib);
1853  STT_Lib = strdup(val);
1854 
1855 // Record any parms
1856 //
1857  if (!Config.GetRest(parms, sizeof(parms)))
1858  {Eroute.Emsg("Config", "statlib parameters too long"); return 1;}
1859  if (STT_Parms) free(STT_Parms);
1860  STT_Parms = (*parms ? strdup(parms) : 0);
1861  return 0;
1862 }
1863 
1864 /******************************************************************************/
1865 /* x t r a c e */
1866 /******************************************************************************/
1867 
1868 /* Function: xtrace
1869 
1870  Purpose: To parse the directive: trace <events>
1871 
1872  <events> the blank separated list of events to trace. Trace
1873  directives are cummalative.
1874 
1875  Output: retc upon success or -EINVAL upon failure.
1876 */
1877 
1879 {
1880  char *val;
1881  static struct traceopts {const char *opname; int opval;} tropts[] =
1882  {
1883  {"all", TRACE_ALL},
1884  {"debug", TRACE_Debug},
1885  {"open", TRACE_Open},
1886  {"opendir", TRACE_Opendir}
1887  };
1888  int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
1889 
1890  if (!(val = Config.GetWord()))
1891  {Eroute.Emsg("Config", "trace option not specified"); return 1;}
1892  while (val)
1893  {if (!strcmp(val, "off")) trval = 0;
1894  else {if ((neg = (val[0] == '-' && val[1]))) val++;
1895  for (i = 0; i < numopts; i++)
1896  {if (!strcmp(val, tropts[i].opname))
1897  {if (neg) trval &= ~tropts[i].opval;
1898  else trval |= tropts[i].opval;
1899  break;
1900  }
1901  }
1902  if (i >= numopts)
1903  Eroute.Say("Config warning: ignoring invalid trace option '",val,"'.");
1904  }
1905  val = Config.GetWord();
1906  }
1907  OssTrace.What = trval;
1908  return 0;
1909 }
1910 
1911 /******************************************************************************/
1912 /* x u s a g e */
1913 /******************************************************************************/
1914 
1915 /* Function: xusage
1916 
1917  Purpose: To parse the directive: usage <parms>
1918 
1919  <parms>: [nolog | log <path> [sync <num>]]
1920  [noquotafile | quotafile <qfile>]
1921 
1922  nolog does not save usage info across restarts
1923  log saves usages information in the <path> directory
1924  sync sync the usage file to disk every <num> changes.
1925  qfile where the quota file resides.
1926 
1927  Output: 0 upon success or !0 upon failure.
1928 */
1929 
1931 {
1932  char *val;
1933  int usval;
1934 
1935  if (!(val = Config.GetWord()))
1936  {Eroute.Emsg("Config", "usage option not specified"); return 1;}
1937 
1938  while(val)
1939  { if (!strcmp("nolog", val))
1940  {if (UDir) {free(UDir); UDir = 0;}}
1941  else if (!strcmp("log" , val))
1942  {if (UDir) {free(UDir); UDir = 0;}
1943  if (!(val = Config.GetWord()))
1944  {Eroute.Emsg("Config", "usage log path not specified");
1945  return 1;
1946  }
1947  if (*val != '/')
1948  {Eroute.Emsg("Config", "usage log path not absolute");
1949  return 1;
1950  }
1951  UDir = strdup(val);
1952  if (!(val = Config.GetWord()) || strcmp("sync", val))
1953  continue;
1954  if (!(val = Config.GetWord()))
1955  {Eroute.Emsg("Config", "log sync value not specified");
1956  return 1;
1957  }
1958  if (XrdOuca2x::a2i(Eroute,"sync value",val,&usval,1,32767))
1959  return 1;
1960  USync = usval;
1961  }
1962  else if (!strcmp("noquotafile",val))
1963  {if (QFile) {free(QFile); QFile= 0;}}
1964  else if (!strcmp("quotafile",val))
1965  {if (QFile) {free(QFile); QFile= 0;}
1966  if (!(val = Config.GetWord()))
1967  {Eroute.Emsg("Config", "quota file not specified");
1968  return 1;
1969  }
1970  QFile = strdup(val);
1971  }
1972  else {Eroute.Emsg("Config", "invalid usage option -",val); return 1;}
1973 
1974  val = Config.GetWord();
1975  }
1976  return 0;
1977 }
1978 
1979 /******************************************************************************/
1980 /* x x f r */
1981 /******************************************************************************/
1982 
1983 /* Function: xxfr
1984 
1985  Purpose: To parse the directive: xfr [deny <sec>] [keep <sec>] [up]
1986  [fdir <path>]
1987  [<threads> [<speed> [<ovhd> [<hold>]]]]
1988 
1989  deny number of seconds to deny staging requests in the
1990  presence of a '.fail' file.
1991  keep number of seconds to keep queued requests
1992  fdir the base directory where '.fail' files are to be written
1993  <threads> number of threads for staging (* uses default).
1994 
1995 The following are deprecated and allowed for backward compatibility:
1996 
1997  <speed> average speed in bytes/second (* uses default).
1998  <ovhd> minimum seconds of overhead (* uses default).
1999  <hold> seconds to hold failing requests (* uses default).
2000 
2001  Output: 0 upon success or !0 upon failure.
2002 */
2003 
2005 {
2006  static const int maxfdln = 256;
2007  const char *wantParm = 0;
2008  char *val;
2009  int thrds = 1;
2010  long long speed = 9*1024*1024;
2011  int ovhd = 30;
2012  int htime = 3*60*60;
2013  int ktime;
2014  int upon = 0;
2015 
2016  while((val = Config.GetWord())) // deny |fdir | keep | up
2017  { if (!strcmp("deny", val))
2018  {wantParm = "xfr deny";
2019  if ((val = Config.GetWord())) // keep time
2020  {if (XrdOuca2x::a2tm(Eroute,wantParm,val,&htime,0))
2021  return 1;
2022  wantParm=0;
2023  }
2024  }
2025  else if (!strcmp("fdir", val))
2026  {wantParm = "xfr fdir";
2027  if ((val = Config.GetWord())) // fdir path
2028  {if (xfrFdir) free(xfrFdir);
2029  xfrFdln = strlen(val);
2030  if (xfrFdln > maxfdln)
2031  {Eroute.Emsg("Config","xfr fdir path too long");
2032  xfrFdir = 0; xfrFdln = 0; return 1;
2033  }
2034  xfrFdir = strdup(val);
2035  wantParm = 0;
2036  }
2037  }
2038  else if (!strcmp("keep", val))
2039  {wantParm = "xfr keep";
2040  if ((val = Config.GetWord())) // keep time
2041  {if (XrdOuca2x::a2tm(Eroute,wantParm,val,&ktime,0))
2042  return 1;
2043  xfrkeep=ktime; wantParm=0;
2044  }
2045  }
2046  else if (!strcmp("up", val)) {upon = 1; wantParm = 0;}
2047  else break;
2048  };
2049 
2050  xfrhold = htime;
2051  if (upon) OptFlags |= XrdOss_USRPRTY;
2052 
2053  if (!val) {if (!wantParm) return 0;
2054  else {Eroute.Emsg("Config", wantParm, "value not specified");
2055  return 1;
2056  }
2057  }
2058 
2059  if (strcmp(val, "*") && XrdOuca2x::a2i(Eroute,"xfr threads",val,&thrds,1))
2060  return 1;
2061 
2062  if ((val = Config.GetWord())) // <speed>
2063  {if (strcmp(val, "*") &&
2064  XrdOuca2x::a2sz(Eroute,"xfr speed",val,&speed,1024)) return 1;
2065 
2066  if ((val = Config.GetWord())) // <ovhd>
2067  {if (strcmp(val, "*") &&
2068  XrdOuca2x::a2tm(Eroute,"xfr overhead",val,&ovhd,0)) return 1;
2069 
2070  if ((val = Config.GetWord())) // <hold>
2071  if (strcmp(val, "*") &&
2072  XrdOuca2x::a2tm(Eroute,"xfr hold",val,&htime,0)) return 1;
2073  }
2074  }
2075 
2076  xfrhold = htime;
2077  xfrthreads = thrds;
2078  xfrspeed = speed;
2079  xfrovhd = ovhd;
2080  return 0;
2081 }
2082 
2083 /******************************************************************************/
2084 /* L i s t _ P a t h */
2085 /******************************************************************************/
2086 
2087 void XrdOssSys::List_Path(const char *pfx, const char *pname,
2088  unsigned long long flags, XrdSysError &Eroute)
2089 {
2090  std::string ss;
2091  const char *rwmode;
2092 
2093  if (flags & XRDEXP_FORCERO) rwmode = " forcero";
2094  else if (flags & XRDEXP_READONLY) rwmode = " r/o";
2095  else rwmode = " r/w";
2096 
2097  if (flags & XRDEXP_INPLACE) ss += " inplace";
2098  if (flags & XRDEXP_LOCAL) ss += " local";
2099  if (flags & XRDEXP_GLBLRO) ss += " globalro";
2100 
2101  if (!(flags & XRDEXP_PFCACHE))
2102  {if (flags & XRDEXP_PFCACHE_X) ss += " nocache";
2103  ss += (flags & XRDEXP_NOCHECK ? " nocheck" : " check");
2104  ss += (flags & XRDEXP_NODREAD ? " nodread" : " dread");
2105  ss += (flags & XRDEXP_MIG ? " mig" : " nomig");
2106  ss += (flags & XRDEXP_PURGE ? " purge" : " nopurge");
2107  ss += (flags & XRDEXP_RCREATE ? " rcreate" : " norcreate");
2108  ss += (flags & XRDEXP_STAGE ? " stage" : " nostage");
2109  } else ss += " cache";
2110 
2111 
2112  if (flags & XRDEXP_MMAP)
2113  {ss += " mmap";
2114  ss += (flags & XRDEXP_MKEEP ? " mkeep" : " nomkeep");
2115  ss += (flags & XRDEXP_MLOK ? " mlock" : " nomlock");
2116  }
2117 
2118  Eroute.Say(pfx, pname, rwmode, ss.c_str());
2119 }
#define TRACE_Debug
Definition: XrdCmsTrace.hh:37
#define spAssign
Definition: XrdOssApi.hh:250
#define TS_String(x, m)
void * XrdOssxfr(void *carg)
#define XrdOssConfig_Vop(base, opt, optchk0, opt1, opt2, optchk1, opt3, opt4)
XrdSysTrace OssTrace
const char * XrdOssErrorText[]
Definition: XrdOssConfig.cc:86
#define TS_Xeq(x, m)
#define XrdOssConfig_Val(base, opt)
#define Duplicate(x, y)
XrdOssSys * XrdOssSS
Definition: XrdOssApi.cc:77
void * XrdOssCacheScan(void *carg)
XrdOucPListAnchor * XrdOssRPList
Definition: XrdOssConfig.cc:80
#define XrdOss_USRPRTY
Definition: XrdOssConfig.hh:43
#define XrdOss_CacheFS
Definition: XrdOssConfig.hh:44
#define XRDOSS_T8001
Definition: XrdOssError.hh:66
#define XRDOSS_ELAST
Definition: XrdOssError.hh:64
#define XRDOSS_T8003
Definition: XrdOssError.hh:68
#define XRDOSS_T8026
Definition: XrdOssError.hh:91
#define XRDOSS_T8023
Definition: XrdOssError.hh:88
#define XRDOSS_EBASE
Definition: XrdOssError.hh:33
#define XRDOSS_T8017
Definition: XrdOssError.hh:82
#define XRDOSS_T8012
Definition: XrdOssError.hh:77
#define XRDOSS_T8024
Definition: XrdOssError.hh:89
#define XRDOSS_T8025
Definition: XrdOssError.hh:90
#define XRDOSS_T8002
Definition: XrdOssError.hh:67
#define XRDOSS_T8016
Definition: XrdOssError.hh:81
#define XRDOSS_T8019
Definition: XrdOssError.hh:84
#define XRDOSS_T8014
Definition: XrdOssError.hh:79
#define XRDOSS_T8013
Definition: XrdOssError.hh:78
#define XRDOSS_T8022
Definition: XrdOssError.hh:87
#define XRDOSS_T8015
Definition: XrdOssError.hh:80
#define XRDOSS_T8010
Definition: XrdOssError.hh:75
#define XRDOSS_T8020
Definition: XrdOssError.hh:85
#define XRDOSS_T8011
Definition: XrdOssError.hh:76
#define XRDOSS_T8018
Definition: XrdOssError.hh:83
#define XRDOSS_T8009
Definition: XrdOssError.hh:74
#define XRDOSS_T8006
Definition: XrdOssError.hh:71
#define XRDOSS_T8008
Definition: XrdOssError.hh:73
#define XRDOSS_T8007
Definition: XrdOssError.hh:72
#define XRDOSS_T8005
Definition: XrdOssError.hh:70
#define XRDOSS_T8021
Definition: XrdOssError.hh:86
#define XRDOSS_T8004
Definition: XrdOssError.hh:69
XrdOssStatInfo_t(* XrdOssStatInfoInit_t)(XrdOss *native_oss, XrdSysLogger *Logger, const char *config_fn, const char *parms)
The typedef that describes the XRdOssStatInfoInit external.
XrdOssStatInfo2_t(* XrdOssStatInfoInit2_t)(XrdOss *native_oss, XrdSysLogger *Logger, const char *config_fn, const char *parms, XrdOucEnv *envP)
#define TRACE_Opendir
Definition: XrdOssTrace.hh:38
#define TRACE_Open
Definition: XrdOssTrace.hh:39
#define XrdOssOK
Definition: XrdOss.hh:50
#define XRDEXP_DREAD_X
Definition: XrdOucExport.hh:47
#define XRDEXP_NOTRW
Definition: XrdOucExport.hh:45
#define XRDEXP_NODREAD
Definition: XrdOucExport.hh:46
#define XRDEXP_INPLACE
Definition: XrdOucExport.hh:66
#define XRDEXP_PURGE
Definition: XrdOucExport.hh:62
#define XRDEXP_MMAP
Definition: XrdOucExport.hh:56
#define XRDEXP_MKEEP
Definition: XrdOucExport.hh:60
#define XRDEXP_PFCACHE
Definition: XrdOucExport.hh:70
#define XRDEXP_FORCERO
Definition: XrdOucExport.hh:43
#define XRDEXP_MLOK
Definition: XrdOucExport.hh:58
#define XRDEXP_STAGEMM
Definition: XrdOucExport.hh:76
#define XRDEXP_MWMODE
Definition: XrdOucExport.hh:68
#define XRDEXP_MASKSHIFT
Definition: XrdOucExport.hh:81
#define XRDEXP_CHECK_X
Definition: XrdOucExport.hh:51
#define XRDEXP_GLBLRO
Definition: XrdOucExport.hh:74
#define XRDEXP_NOCHECK
Definition: XrdOucExport.hh:50
#define XRDEXP_MEMAP
Definition: XrdOucExport.hh:84
#define XRDEXP_RCREATE
Definition: XrdOucExport.hh:48
#define XRDEXP_READONLY
Definition: XrdOucExport.hh:42
#define XRDEXP_STAGE
Definition: XrdOucExport.hh:52
#define XRDEXP_MIG
Definition: XrdOucExport.hh:54
#define XRDEXP_PFCACHE_X
Definition: XrdOucExport.hh:71
#define XRDEXP_LOCAL
Definition: XrdOucExport.hh:72
int stat(const char *path, struct stat *buf)
struct dirent * readdir(DIR *dirp)
int open(const char *path, int oflag,...)
int closedir(DIR *dirp)
XrdOucString Path
const char * XrdSysE2T(int errcode)
Definition: XrdSysE2T.cc:104
size_t strlcpy(char *dst, const char *src, size_t sz)
#define TRACE_ALL
Definition: XrdTrace.hh:35
int Init(int opX, const char *aPath, int aMode, const char *qPath=0)
Definition: XrdFrcProxy.cc:229
static const int opStg
Definition: XrdFrcProxy.hh:52
static int Add(const char *Path)
Definition: XrdOssCache.cc:250
static XrdOssCache_Group * fsgroups
Definition: XrdOssCache.hh:199
XrdOssCache_Group * next
Definition: XrdOssCache.hh:186
static int Init(const char *UDir, const char *Qfile, int isSOL, int usync=0)
Definition: XrdOssCache.cc:644
static void * Scan(int cscanint)
Definition: XrdOssCache.cc:843
static void List(const char *lname, XrdSysError &Eroute)
Definition: XrdOssCache.cc:682
static void MapDevs(bool dBug=false)
Definition: XrdOssCache.cc:709
static char isOn()
Definition: XrdOssMio.hh:51
static char isAuto()
Definition: XrdOssMio.hh:49
static void Set(int V_off, int V_preld, int V_check)
Definition: XrdOssMio.cc:320
static void Display(XrdSysError &Eroute)
Definition: XrdOssMio.cc:80
static int InitPrefix()
Definition: XrdOssPath.cc:340
static const int maxSNlen
Definition: XrdOssSpace.hh:44
void Config_Display(XrdSysError &)
int xstg(XrdOucStream &Config, XrdSysError &Eroute)
int badreqs
Definition: XrdOssApi.hh:304
int StageCreate
Definition: XrdOssApi.hh:223
XrdOucPListAnchor SPList
Definition: XrdOssApi.hh:249
char STT_DoN2N
Definition: XrdOssApi.hh:270
char STT_V2
Definition: XrdOssApi.hh:271
int ConfigXeq(char *, XrdOucStream &, XrdSysError &)
int FDLimit
Definition: XrdOssApi.hh:243
int totreqs
Definition: XrdOssApi.hh:303
int Configure(const char *, XrdSysError &, XrdOucEnv *envP)
char * LocalRoot
Definition: XrdOssApi.hh:218
OssDPath * DPList
Definition: XrdOssApi.hh:258
int STT_PreOp
Definition: XrdOssApi.hh:269
char * N2N_Parms
Definition: XrdOssApi.hh:253
int xtrace(XrdOucStream &Config, XrdSysError &Eroute)
short numCG
Definition: XrdOssApi.hh:261
long long totbytes
Definition: XrdOssApi.hh:302
long long minalloc
Definition: XrdOssApi.hh:290
char * StageEvents
Definition: XrdOssApi.hh:230
int xstl(XrdOucStream &Config, XrdSysError &Eroute)
void ConfigSpace(XrdSysError &Eroute)
int StageRealTime
Definition: XrdOssApi.hh:221
short prDepth
Definition: XrdOssApi.hh:279
int FDFence
Definition: XrdOssApi.hh:242
int ConfigStage(XrdSysError &Eroute)
int xusage(XrdOucStream &Config, XrdSysError &Eroute)
static char chkMmap
Definition: XrdOssApi.hh:204
int xfrthreads
Definition: XrdOssApi.hh:298
int OptFlags
Definition: XrdOssApi.hh:247
int xspace(XrdOucStream &Config, XrdSysError &Eroute, int *isCD=0)
int isMSSC
Definition: XrdOssApi.hh:239
void List_Path(const char *, const char *, unsigned long long, XrdSysError &)
char * QFile
Definition: XrdOssApi.hh:310
int prBytes
Definition: XrdOssApi.hh:277
int xmemf(XrdOucStream &Config, XrdSysError &Eroute)
static int AioInit()
Definition: XrdOssAio.cc:281
void * Stage_In(void *carg)
Definition: XrdOssStage.cc:303
char * ConfigFN
Definition: XrdOssApi.hh:217
int StageFormat
Definition: XrdOssApi.hh:224
int ovhalloc
Definition: XrdOssApi.hh:291
void ConfigMio(XrdSysError &Eroute)
void ConfigStats(XrdSysError &Eroute)
char * StageAction
Definition: XrdOssApi.hh:233
int xcachescan(XrdOucStream &Config, XrdSysError &Eroute)
char STT_DoARE
Definition: XrdOssApi.hh:272
char * UDir
Definition: XrdOssApi.hh:309
int StageActLen
Definition: XrdOssApi.hh:232
short USync
Definition: XrdOssApi.hh:313
int xfdlimit(XrdOucStream &Config, XrdSysError &Eroute)
int ConfigN2N(XrdSysError &Eroute, XrdOucEnv *envP)
XrdOucProg * StageProg
Definition: XrdOssApi.hh:306
XrdOucName2Name * the_N2N
Definition: XrdOssApi.hh:256
short prQSize
Definition: XrdOssApi.hh:280
long long MaxSize
Definition: XrdOssApi.hh:241
int prPSize
Definition: XrdOssApi.hh:276
int GenLocalPath(const char *, char *)
Definition: XrdOssApi.cc:232
int RSSTout
Definition: XrdOssApi.hh:240
int prActive
Definition: XrdOssApi.hh:278
int xfrspeed
Definition: XrdOssApi.hh:294
XrdOucName2Name * lcl_N2N
Definition: XrdOssApi.hh:254
long long prPMask
Definition: XrdOssApi.hh:275
long long prPBits
Definition: XrdOssApi.hh:274
int xspaceBuild(OssSpaceConfig &sInfo, XrdSysError &Eroute)
int fuzalloc
Definition: XrdOssApi.hh:292
int cscanint
Definition: XrdOssApi.hh:293
int StageAsync
Definition: XrdOssApi.hh:222
int xprerd(XrdOucStream &Config, XrdSysError &Eroute)
int ConfigStatLib(XrdSysError &Eroute, XrdOucEnv *envP)
XrdOucProg * RSSProg
Definition: XrdOssApi.hh:307
char * STT_Parms
Definition: XrdOssApi.hh:264
long long pndbytes
Definition: XrdOssApi.hh:300
int xpath(XrdOucStream &Config, XrdSysError &Eroute)
static char tryMmap
Definition: XrdOssApi.hh:203
XrdVersionInfo * myVersion
Definition: XrdOssApi.hh:282
char * N2N_Lib
Definition: XrdOssApi.hh:252
int xfrovhd
Definition: XrdOssApi.hh:295
int xcache(XrdOucStream &Config, XrdSysError &Eroute)
long long stgbytes
Definition: XrdOssApi.hh:301
void ConfigSpath(XrdSysError &Eroute, const char *Pn, unsigned long long &Fv, int noMSS)
int Stat(const char *, struct stat *, int opts=0, XrdOucEnv *Env=0)
Definition: XrdOssStat.cc:70
char * STT_Lib
Definition: XrdOssApi.hh:263
int ConfigStageC(XrdSysError &Eroute)
int xfrFdln
Definition: XrdOssApi.hh:312
XrdOucMsubs * StageSnd
Definition: XrdOssApi.hh:227
int xxfr(XrdOucStream &Config, XrdSysError &Eroute)
short numDP
Definition: XrdOssApi.hh:260
XrdFrcProxy * StageFrm
Definition: XrdOssApi.hh:228
unsigned long long DirFlags
Definition: XrdOssApi.hh:244
int StageEvSize
Definition: XrdOssApi.hh:231
XrdOucPListAnchor RPList
Definition: XrdOssApi.hh:257
int xfrhold
Definition: XrdOssApi.hh:296
int ConfigProc(XrdSysError &Eroute)
bool pfcMode
Definition: XrdOssApi.hh:314
int xfrtcount
Definition: XrdOssApi.hh:299
void ConfigCache(XrdSysError &Eroute, bool pass2=false)
char * StageCmd
Definition: XrdOssApi.hh:225
char * StageMsg
Definition: XrdOssApi.hh:226
char * RemoteRoot
Definition: XrdOssApi.hh:219
int xmaxsz(XrdOucStream &Config, XrdSysError &Eroute)
int xfrkeep
Definition: XrdOssApi.hh:297
int Solitary
Definition: XrdOssApi.hh:246
int MaxTwiddle
Definition: XrdOssApi.hh:220
char * RSSCmd
Definition: XrdOssApi.hh:238
int xdefault(XrdOucStream &Config, XrdSysError &Eroute)
int xnml(XrdOucStream &Config, XrdSysError &Eroute)
XrdOucName2Name * rmt_N2N
Definition: XrdOssApi.hh:255
int xalloc(XrdOucStream &Config, XrdSysError &Eroute)
char * xfrFdir
Definition: XrdOssApi.hh:311
char * Get(const char *varname)
Definition: XrdOucEnv.hh:69
void PutPtr(const char *varname, void *value)
Definition: XrdOucEnv.cc:316
static unsigned long long ParseDefs(XrdOucStream &Config, XrdSysError &Eroute, unsigned long long Flags)
Definition: XrdOucExport.cc:60
static XrdOucPList * ParsePath(XrdOucStream &Config, XrdSysError &Eroute, XrdOucPListAnchor &Export, unsigned long long Defopts)
int Parse(const char *oname, char *msg)
Definition: XrdOucMsubs.cc:100
XrdOucName2Name * Load(const char *libName, XrdVersionInfo &urVer, XrdOucEnv *envP=0)
void Default(unsigned long long x)
Definition: XrdOucPList.hh:101
void Insert(XrdOucPList *newitem)
Definition: XrdOucPList.hh:134
XrdOucPList * Match(const char *pathname)
Definition: XrdOucPList.hh:122
XrdOucPList * First()
Definition: XrdOucPList.hh:132
void Defstar(unsigned long long x)
Definition: XrdOucPList.hh:104
XrdOucPList * Next()
Definition: XrdOucPList.hh:44
void Set(int aval)
Definition: XrdOucPList.hh:51
char * Path()
Definition: XrdOucPList.hh:45
unsigned long long Flag()
Definition: XrdOucPList.hh:42
const char * Name()
Definition: XrdOucPList.hh:43
void * Resolve(const char *symbl, int mcnt=1)
int Start(void)
Definition: XrdOucProg.cc:349
int Setup(const char *prog, XrdSysError *errP=0, int(*Proc)(XrdOucStream *, char **, int)=0)
Definition: XrdOucProg.cc:296
const char * c_str() const
int erasefromend(int sz=0)
bool endswith(char c)
int replace(const char *s1, const char *s2, int from=0, int to=-1)
static const char * InstName(int TranOpt=0)
Definition: XrdOucUtils.cc:732
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition: XrdOuca2x.cc:45
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
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition: XrdOuca2x.cc:288
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
static void addTable(XrdSysError_Table *etp)
Definition: XrdSysError.hh:106
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
Definition: XrdSysError.cc:141
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition: XrdSysError.hh:141
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
XrdVERSIONINFODEF(myVersion, cmsclient, XrdVNUMBER, XrdVERSION)
XrdCmsConfig Config
XrdOucEnv * envP
Definition: XrdPss.cc:109
const XrdOucString & sPath
Definition: XrdOssConfig.hh:59
const XrdOucString & mName
Definition: XrdOssConfig.hh:60
const XrdOucString & sName
Definition: XrdOssConfig.hh:58