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