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