XRootD
XrdPfcConfiguration.cc
Go to the documentation of this file.
1 #include "XrdPfc.hh"
2 #include "XrdPfcTrace.hh"
3 #include "XrdPfcInfo.hh"
4 
6 #include "XrdPfcPurgePin.hh"
7 
8 #include "XrdOss/XrdOss.hh"
9 
10 #include "XrdOuc/XrdOucEnv.hh"
11 #include "XrdOuc/XrdOucUtils.hh"
12 #include "XrdOuc/XrdOucStream.hh"
14 #include "XrdOuc/XrdOuca2x.hh"
15 
16 #include "XrdVersion.hh"
17 #include "XrdOfs/XrdOfsConfigPI.hh"
18 #include "XrdSys/XrdSysXAttr.hh"
19 
20 #include <fcntl.h>
21 
23 
24 namespace XrdPfc
25 {
26  const char *trace_what_strings[] = {"","error ","warning ","info ","debug ","dump "};
27 }
28 
29 using namespace XrdPfc;
30 
32 
34  m_write_through(false),
35  m_hdfsmode(false),
36  m_allow_xrdpfc_command(false),
37  m_data_space("public"),
38  m_meta_space("public"),
39  m_diskTotalSpace(-1),
40  m_diskUsageLWM(-1),
41  m_diskUsageHWM(-1),
42  m_fileUsageBaseline(-1),
43  m_fileUsageNominal(-1),
44  m_fileUsageMax(-1),
45  m_purgeInterval(300),
46  m_purgeColdFilesAge(-1),
47  m_purgeAgeBasedPeriod(10),
48  m_accHistorySize(20),
49  m_dirStatsInterval(900),
50  m_dirStatsStoreDepth(1),
51  m_bufferSize(128*1024),
52  m_RamAbsAvailable(0),
53  m_RamKeepStdBlocks(0),
54  m_wqueue_blocks(16),
55  m_wqueue_threads(4),
56  m_prefetch_max_blocks(10),
57  m_hdfsbsize(128*1024*1024),
58  m_flushCnt(2000),
59  m_cs_UVKeep(-1),
60  m_cs_Chk(CSChk_Net),
61  m_cs_ChkTLS(false),
62  m_onlyIfCachedMinSize(1024*1024),
63  m_onlyIfCachedMinFrac(1.0),
64  m_httpcc(false),
65  m_qfsredir(true)
66 {}
67 
68 
69 bool Cache::cfg2bytes(const std::string &str, long long &store, long long totalSpace, const char *name) const
70 {
71  char errStr[1024];
72  snprintf(errStr, 1024, "ConfigParameters() Error parsing parameter %s", name);
73 
74  if (::isalpha(*(str.rbegin())))
75  {
76  if (XrdOuca2x::a2sz(m_log, errStr, str.c_str(), &store, 0, totalSpace))
77  {
78  return false;
79  }
80  }
81  else
82  {
83  char *eP;
84  errno = 0;
85  double frac = strtod(str.c_str(), &eP);
86  if (errno || eP == str.c_str())
87  {
88  m_log.Emsg(errStr, str.c_str());
89  return false;
90  }
91 
92  store = static_cast<long long>(totalSpace * frac + 0.5);
93  }
94 
95  if (store < 0 || store > totalSpace)
96  {
97  snprintf(errStr, 1024, "ConfigParameters() Error: parameter %s should be between 0 and total available disk space (%lld) - it is %lld (given as %s)",
98  name, totalSpace, store, str.c_str());
99  m_log.Emsg(errStr, "");
100  return false;
101  }
102 
103  return true;
104 }
105 
106 bool Cache::blocksize_str2value(const char *from, const char *str,
107  long long &val, long long min, long long max) const
108 {
109  if (XrdOuca2x::a2sz(m_log, "Error parsing block-size", str, &val, min, max))
110  return false;
111 
112  if (val & 0xFFF) {
113  val &= ~0x0FFF;
114  val += 0x1000;
115  m_log.Emsg(from, "blocksize must be a multiple of 4 kB. Rounded up.");
116  }
117 
118  return true;
119 }
120 
121 bool Cache::prefetch_str2value(const char *from, const char *str,
122  int &val, int min, int max) const
123 {
124  if (XrdOuca2x::a2i(m_log, "Error parsing prefetch block count", str, &val, min, max))
125  return false;
126 
127  return true;
128 }
129 
130 /* Function: xcschk
131 
132  Purpose: To parse the directive: cschk <parms>
133 
134  parms: [[no]net] [[no]tls] [[no]cache] [uvkeep <arg>]
135 
136  all Checksum check on cache & net transfers.
137  cache Checksum check on cache only, 'no' turns it off.
138  net Checksum check on net transfers 'no' turns it off.
139  tls use TLS if server doesn't support checksums 'no' turns it off.
140  uvkeep Maximum amount of time a cached file make be kept if it
141  contains unverified checksums as n[d|h|m|s], where 'n'
142  is a non-negative integer. A value of 0 prohibits disk
143  caching unless the checksum can be verified. You can
144  also specify "lru" which means the standard purge policy
145  is to be used.
146 
147  Output: true upon success or false upon failure.
148  */
149 bool Cache::xcschk(XrdOucStream &Config)
150 {
151  const char *val, *val2;
152  struct cschkopts {const char *opname; int opval;} csopts[] =
153  {
154  {"off", CSChk_None},
155  {"cache", CSChk_Cache},
156  {"net", CSChk_Net},
157  {"tls", CSChk_TLS}
158  };
159  int i, numopts = sizeof(csopts)/sizeof(struct cschkopts);
160  bool isNo;
161 
162  if (! (val = Config.GetWord()))
163  {m_log.Emsg("Config", "cschk parameter not specified"); return false; }
164 
165  while(val)
166  {
167  if ((isNo = strncmp(val, "no", 2) == 0))
168  val2 = val + 2;
169  else
170  val2 = val;
171  for (i = 0; i < numopts; i++)
172  {
173  if (!strcmp(val2, csopts[i].opname))
174  {
175  if (isNo)
176  m_configuration.m_cs_Chk &= ~csopts[i].opval;
177  else if (csopts[i].opval)
178  m_configuration.m_cs_Chk |= csopts[i].opval;
179  else
180  m_configuration.m_cs_Chk = csopts[i].opval;
181  break;
182  }
183  }
184  if (i >= numopts)
185  {
186  if (strcmp(val, "uvkeep"))
187  {
188  m_log.Emsg("Config", "invalid cschk option -", val);
189  return false;
190  }
191  if (!(val = Config.GetWord()))
192  {
193  m_log.Emsg("Config", "cschk uvkeep value not specified");
194  return false;
195  }
196  if (!strcmp(val, "lru"))
197  m_configuration.m_cs_UVKeep = -1;
198  else
199  {
200  int uvkeep;
201  if (XrdOuca2x::a2tm(m_log, "uvkeep time", val, &uvkeep, 0))
202  return false;
203  m_configuration.m_cs_UVKeep = uvkeep;
204  }
205  }
206  val = Config.GetWord();
207  }
208  // Decompose into separate TLS state, it is only passed on to psx
209  m_configuration.m_cs_ChkTLS = m_configuration.m_cs_Chk & CSChk_TLS;
210  m_configuration.m_cs_Chk &= ~CSChk_TLS;
211 
212  m_env->Put("psx.CSNet", m_configuration.is_cschk_net() ? (m_configuration.m_cs_ChkTLS ? "2" : "1") : "0");
213 
214  return true;
215 }
216 
217 
218 /* Function: xdlib
219 
220  Purpose: To parse the directive: decisionlib <path> [<parms>]
221 
222  <path> the path of the decision library to be used.
223  <parms> optional parameters to be passed.
224 
225 
226  Output: true upon success or false upon failure.
227  */
228 bool Cache::xdlib(XrdOucStream &Config)
229 {
230  const char* val;
231 
232  std::string libp;
233  if (! (val = Config.GetWord()) || ! val[0])
234  {
235  TRACE(Info," Cache::Config() decisionlib not specified; always caching files");
236  return true;
237  }
238  else
239  {
240  libp = val;
241  }
242 
243  char params[4096];
244  if (val[0])
245  Config.GetRest(params, 4096);
246  else
247  params[0] = 0;
248 
249  XrdOucPinLoader* myLib = new XrdOucPinLoader(&m_log, 0, "decisionlib",
250  libp.c_str());
251 
252  Decision *(*ep)(XrdSysError&);
253  ep = (Decision *(*)(XrdSysError&))myLib->Resolve("XrdPfcGetDecision");
254  if (! ep) {myLib->Unload(true); return false; }
255 
256  Decision * d = ep(m_log);
257  if (! d)
258  {
259  TRACE(Error, "Config() decisionlib was not able to create a decision object");
260  return false;
261  }
262  if (params[0])
263  d->ConfigDecision(params);
264 
265  m_decisionpoints.push_back(d);
266  return true;
267 }
268 
269 /* Function: xplib
270 
271  Purpose: To parse the directive: purgelib <path> [<parms>]
272 
273  <path> the path of the decision library to be used.
274  <parms> optional parameters to be passed.
275 
276 
277  Output: true upon success or false upon failure.
278  */
279 bool Cache::xplib(XrdOucStream &Config)
280 {
281  const char* val;
282 
283  std::string libp;
284  if (! (val = Config.GetWord()) || ! val[0])
285  {
286  TRACE(Info," Cache::Config() purgelib not specified; will use LRU for purging files");
287  return true;
288  }
289  else
290  {
291  libp = val;
292  }
293 
294  char params[4096];
295  if (val[0])
296  Config.GetRest(params, 4096);
297  else
298  params[0] = 0;
299 
300  XrdOucPinLoader* myLib = new XrdOucPinLoader(&m_log, 0, "purgelib",
301  libp.c_str());
302 
303  PurgePin *(*ep)(XrdSysError&);
304  ep = (PurgePin *(*)(XrdSysError&))myLib->Resolve("XrdPfcGetPurgePin");
305  if (! ep) {myLib->Unload(true); return false; }
306 
307  PurgePin * dp = ep(m_log);
308  if (! dp)
309  {
310  TRACE(Error, "Config() purgelib was not able to create a Purge Plugin object?");
311  return false;
312  }
313  m_purge_pin = dp;
314 
315  if (params[0])
316  m_purge_pin->ConfigPurgePin(params);
317 
318 
319  return true;
320 }
321 
322 /* Function: xtrace
323 
324  Purpose: To parse the directive: trace <level>
325  Output: true upon success or false upon failure.
326  */
327 bool Cache::xtrace(XrdOucStream &Config)
328 {
329  char *val;
330  static struct traceopts {const char *opname; int opval; } tropts[] =
331  {
332  {"none", 0},
333  {"error", 1},
334  {"warning", 2},
335  {"info", 3},
336  {"debug", 4},
337  {"dump", 5},
338  {"dumpxl", 6}
339  };
340  int numopts = sizeof(tropts)/sizeof(struct traceopts);
341 
342  if (! (val = Config.GetWord()))
343  {m_log.Emsg("Config", "trace option not specified"); return 1; }
344 
345  for (int i = 0; i < numopts; i++)
346  {
347  if (! strcmp(val, tropts[i].opname))
348  {
349  m_trace->What = tropts[i].opval;
350  return true;
351  }
352  }
353  m_log.Emsg("Config", "invalid trace option -", val);
354  return false;
355 }
356 
357 // Determine if oss spaces are operational and if they support xattrs.
358 bool Cache::test_oss_basics_and_features()
359 {
360  static const char *epfx = "test_oss_basics_and_features()";
361 
362  const auto &conf = m_configuration;
363  const char *user = conf.m_username.c_str();
364  XrdOucEnv env;
365 
366  auto check_space = [&](const char *space, bool &has_xattr)
367  {
368  std::string fname("__prerun_test_pfc_");
369  fname += space;
370  fname += "_space__";
371  env.Put("oss.cgroup", space);
372 
373  int res = m_oss->Create(user, fname.c_str(), 0600, env, XRDOSS_mkpath);
374  if (res != XrdOssOK) {
375  m_log.Emsg(epfx, "Can not create a file on space", space);
376  return false;
377  }
378  XrdOssDF *oss_file = m_oss->newFile(user);
379  res = oss_file->Open(fname.c_str(), O_RDWR, 0600, env);
380  if (res != XrdOssOK) {
381  m_log.Emsg(epfx, "Can not open a file on space", space);
382  return false;
383  }
384  res = oss_file->Write(fname.data(), 0, fname.length());
385  if (res != (int) fname.length()) {
386  m_log.Emsg(epfx, "Can not write into a file on space", space);
387  return false;
388  }
389 
390  has_xattr = true;
391  long long fsize = fname.length();
392  res = XrdSysXAttrActive->Set("pfc.fsize", &fsize, sizeof(long long), 0, oss_file->getFD(), 0);
393  if (res != 0) {
394  m_log.Emsg(epfx, "Can not write xattr to a file on space", space);
395  has_xattr = false;
396  }
397 
398  oss_file->Close();
399 
400  if (has_xattr) {
401  char pfn[4096];
402  m_oss->Lfn2Pfn(fname.c_str(), pfn, 4096);
403  fsize = -1ll;
404  res = XrdSysXAttrActive->Get("pfc.fsize", &fsize, sizeof(long long), pfn);
405  if (res != sizeof(long long) || fsize != (long long) fname.length())
406  {
407  m_log.Emsg(epfx, "Can not read xattr from a file on space", space);
408  has_xattr = false;
409  }
410  }
411 
412  res = m_oss->Unlink(fname.c_str());
413  if (res != XrdOssOK) {
414  m_log.Emsg(epfx, "Can not unlink a file on space", space);
415  return false;
416  }
417 
418  return true;
419  };
420 
421  bool aOK = true;
422  aOK &= check_space(conf.m_data_space.c_str(), m_dataXattr);
423  aOK &= check_space(conf.m_meta_space.c_str(), m_metaXattr);
424 
425  return aOK;
426 }
427 
428 //______________________________________________________________________________
429 /* Function: Config
430 
431  Purpose: To parse configuration file and configure Cache instance.
432  Output: true upon success or false upon failure.
433  */
434 bool Cache::Config(const char *config_filename, const char *parameters, XrdOucEnv *env)
435 {
436  // Indicate whether or not we are a client instance
437  const char *theINS = getenv("XRDINSTANCE");
438  m_isClient = (theINS != 0 && strncmp("*client ", theINS, 8) == 0);
439 
440  // Tell everyone else we are a caching proxy
441  XrdOucEnv::Export("XRDPFC", 1);
442 
443  XrdOucEnv emptyEnv;
444  XrdOucEnv *myEnv = env ? env : &emptyEnv;
445 
446  XrdOucStream Config(&m_log, theINS, myEnv, "=====> ");
447 
448  if (! config_filename || ! *config_filename)
449  {
450  TRACE(Error, "Config() configuration file not specified.");
451  return false;
452  }
453 
454  int fd;
455  if ( (fd = open(config_filename, O_RDONLY, 0)) < 0)
456  {
457  TRACE( Error, "Config() can't open configuration file " << config_filename);
458  return false;
459  }
460 
461  Config.Attach(fd);
462  static const char *cvec[] = { "*** pfc plugin config:", 0 };
463  Config.Capture(cvec);
464 
465  // Obtain OFS configurator for OSS plugin.
466  XrdOfsConfigPI *ofsCfg = XrdOfsConfigPI::New(config_filename,&Config,&m_log,
467  &XrdVERSIONINFOVAR(XrdOucGetCache));
468  if (! ofsCfg) return false;
469 
470  TmpConfiguration tmpc;
471 
472  Configuration &CFG = m_configuration;
473 
474  // Adjust default parameters for client/serverless caching
475  if (m_isClient)
476  {
477  m_configuration.m_bufferSize = 128 * 1024; // same as normal.
478  m_configuration.m_wqueue_blocks = 8;
479  m_configuration.m_wqueue_threads = 1;
480  }
481 
482  // If network checksum processing is the default, indicate so.
483  if (m_configuration.is_cschk_net()) m_env->Put("psx.CSNet", m_configuration.m_cs_ChkTLS ? "2" : "1");
484 
485  // Actual parsing of the config file.
486  bool retval = true, aOK = true;
487  char *var;
488  while ((var = Config.GetMyFirstWord()))
489  {
490  if (! strcmp(var,"pfc.osslib"))
491  {
492  retval = ofsCfg->Parse(XrdOfsConfigPI::theOssLib);
493  }
494  else if (! strcmp(var,"pfc.cschk"))
495  {
496  retval = xcschk(Config);
497  }
498  else if (! strcmp(var,"pfc.decisionlib"))
499  {
500  retval = xdlib(Config);
501  }
502  else if (! strcmp(var,"pfc.purgelib"))
503  {
504  retval = xplib(Config);
505  }
506  else if (! strcmp(var,"pfc.trace"))
507  {
508  retval = xtrace(Config);
509  }
510  else if (! strcmp(var,"pfc.allow_xrdpfc_command"))
511  {
512  m_configuration.m_allow_xrdpfc_command = true;
513  }
514  else if (! strncmp(var,"pfc.", 4))
515  {
516  retval = ConfigParameters(std::string(var+4), Config, tmpc);
517  }
518 
519  if ( ! retval)
520  {
521  TRACE(Error, "Config() error in parsing");
522  aOK = false;
523  }
524  }
525 
526  Config.Close();
527 
528  // Load OSS plugin.
529  auto orig_runmode = myEnv->Get("oss.runmode");
530  myEnv->Put("oss.runmode", "pfc");
531  if (m_configuration.is_cschk_cache())
532  {
533  char csi_conf[128];
534  if (snprintf(csi_conf, 128, "space=%s nofill", m_configuration.m_meta_space.c_str()) < 128)
535  {
536  ofsCfg->Push(XrdOfsConfigPI::theOssLib, "libXrdOssCsi.so", csi_conf);
537  } else {
538  TRACE(Error, "Config() buffer too small for libXrdOssCsi params.");
539  return false;
540  }
541  }
542  if (ofsCfg->Load(XrdOfsConfigPI::theOssLib, myEnv))
543  {
544  ofsCfg->Plugin(m_oss);
545  }
546  else
547  {
548  TRACE(Error, "Config() Unable to create an OSS object");
549  return false;
550  }
551  if (orig_runmode) myEnv->Put("oss.runmode", orig_runmode);
552  else myEnv->Put("oss.runmode", "");
553 
554  // Test if OSS is operational, determine optional features.
555  aOK &= test_oss_basics_and_features();
556 
557  // sets default value for disk usage
558  XrdOssVSInfo sP;
559  {
560  if (m_configuration.m_meta_space != m_configuration.m_data_space &&
561  m_oss->StatVS(&sP, m_configuration.m_meta_space.c_str(), 1) < 0)
562  {
563  m_log.Emsg("ConfigParameters()", "error obtaining stat info for meta space ", m_configuration.m_meta_space.c_str());
564  return false;
565  }
566  if (m_configuration.m_meta_space != m_configuration.m_data_space && sP.Total < 10ll << 20)
567  {
568  m_log.Emsg("ConfigParameters()", "available data space is less than 10 MB (can be due to a mistake in oss.localroot directive) for space ",
569  m_configuration.m_meta_space.c_str());
570  return false;
571  }
572  if (m_oss->StatVS(&sP, m_configuration.m_data_space.c_str(), 1) < 0)
573  {
574  m_log.Emsg("ConfigParameters()", "error obtaining stat info for data space ", m_configuration.m_data_space.c_str());
575  return false;
576  }
577  if (sP.Total < 10ll << 20)
578  {
579  m_log.Emsg("ConfigParameters()", "available data space is less than 10 MB (can be due to a mistake in oss.localroot directive) for space ",
580  m_configuration.m_data_space.c_str());
581  return false;
582  }
583 
584  m_configuration.m_diskTotalSpace = sP.Total;
585 
586  if (cfg2bytes(tmpc.m_diskUsageLWM, m_configuration.m_diskUsageLWM, sP.Total, "lowWatermark") &&
587  cfg2bytes(tmpc.m_diskUsageHWM, m_configuration.m_diskUsageHWM, sP.Total, "highWatermark"))
588  {
589  if (m_configuration.m_diskUsageLWM >= m_configuration.m_diskUsageHWM) {
590  m_log.Emsg("ConfigParameters()", "pfc.diskusage should have lowWatermark < highWatermark.");
591  aOK = false;
592  }
593  }
594  else aOK = false;
595 
596  if ( ! tmpc.m_fileUsageMax.empty())
597  {
598  if (cfg2bytes(tmpc.m_fileUsageBaseline, m_configuration.m_fileUsageBaseline, sP.Total, "files baseline") &&
599  cfg2bytes(tmpc.m_fileUsageNominal, m_configuration.m_fileUsageNominal, sP.Total, "files nominal") &&
600  cfg2bytes(tmpc.m_fileUsageMax, m_configuration.m_fileUsageMax, sP.Total, "files max"))
601  {
602  if (m_configuration.m_fileUsageBaseline >= m_configuration.m_fileUsageNominal ||
603  m_configuration.m_fileUsageBaseline >= m_configuration.m_fileUsageMax ||
604  m_configuration.m_fileUsageNominal >= m_configuration.m_fileUsageMax)
605  {
606  m_log.Emsg("ConfigParameters()", "pfc.diskusage files should have baseline < nominal < max.");
607  aOK = false;
608  }
609 
610 
611  if (aOK && m_configuration.m_fileUsageMax >= m_configuration.m_diskUsageLWM)
612  {
613  m_log.Emsg("ConfigParameters()", "pfc.diskusage files values must be below lowWatermark");
614  aOK = false;
615  }
616  }
617  else aOK = false;
618  }
619  }
620 
621  // sets flush frequency
622  if ( ! tmpc.m_flushRaw.empty())
623  {
624  if (::isalpha(*(tmpc.m_flushRaw.rbegin())))
625  {
626  if (XrdOuca2x::a2sz(m_log, "Error getting number of bytes written before flush", tmpc.m_flushRaw.c_str(),
627  &m_configuration.m_flushCnt,
628  100 * m_configuration.m_bufferSize , 100000 * m_configuration.m_bufferSize))
629  {
630  return false;
631  }
632  m_configuration.m_flushCnt /= m_configuration.m_bufferSize;
633  }
634  else
635  {
636  if (XrdOuca2x::a2ll(m_log, "Error getting number of blocks written before flush", tmpc.m_flushRaw.c_str(),
637  &m_configuration.m_flushCnt, 100, 100000))
638  {
639  return false;
640  }
641  }
642  }
643 
644  // get number of available RAM blocks after process configuration
645  if (m_configuration.m_RamAbsAvailable == 0)
646  {
647  m_configuration.m_RamAbsAvailable = m_isClient ? 256ll * 1024 * 1024 : 1024ll * 1024 * 1024;
648  char buff[1024];
649  snprintf(buff, sizeof(buff), "RAM usage pfc.ram is not specified. Default value %s is used.", m_isClient ? "256m" : "1g");
650  m_log.Say("Config info: ", buff);
651  }
652  // Setup number of standard-size blocks not released back to the system to 5% of total RAM.
653  m_configuration.m_RamKeepStdBlocks = (m_configuration.m_RamAbsAvailable / m_configuration.m_bufferSize + 1) * 5 / 100;
654 
655  // Set tracing to debug if this is set in environment
656  char* cenv = getenv("XRDDEBUG");
657  if (cenv && ! strcmp(cenv,"1") && m_trace->What < 4) m_trace->What = 4;
658 
659  if (aOK)
660  {
661 // 000 001 010
662  const char *csc[] = {"off", "cache nonet", "nocache net notls",
663 // 011
664  "cache net notls",
665 // 100 101 110
666  "off", "cache nonet", "nocache net tls",
667 // 111
668  "cache net tls"};
669  char uvk[32];
670  if (m_configuration.m_cs_UVKeep < 0)
671  strcpy(uvk, "lru");
672  else
673  sprintf(uvk, "%lld", (long long) m_configuration.m_cs_UVKeep);
674  float ram_gb = (m_configuration.m_RamAbsAvailable) / float(1024*1024*1024);
675 
676  char urlcgi_blks[64] = "ignore", urlcgi_npref[32] = "ignore";
677  if (CFG.m_cgi_blocksize_allowed)
678  snprintf(urlcgi_blks, sizeof(urlcgi_blks), "%lldk %lldk",
679  CFG.m_cgi_min_bufferSize >> 10, CFG.m_cgi_max_bufferSize >> 10);
680  if (CFG.m_cgi_prefetch_allowed)
681  snprintf(urlcgi_npref, sizeof(urlcgi_npref), "%d %d",
683 
684  char buff[8192];
685  int loff = 0;
686  loff = snprintf(buff, sizeof(buff), "Config effective %s pfc configuration:\n"
687  " pfc.cschk %s uvkeep %s\n"
688  " pfc.blocksize %lldk\n"
689  " pfc.prefetch %d\n"
690  " pfc.urlcgi blocksize %s prefetch %s\n"
691  " pfc.ram %.fg\n"
692  " pfc.writequeue %d %d\n"
693  " # Total available disk: %lld\n"
694  " pfc.diskusage %lld %lld files %lld %lld %lld purgeinterval %d purgecoldfiles %d\n"
695  " pfc.spaces %s %s\n"
696  " pfc.trace %d\n"
697  " pfc.flush %lld\n"
698  " pfc.acchistorysize %d\n"
699  " pfc.onlyIfCachedMinBytes %lld\n"
700  " pfc.onlyIfCachedMinFrac %.2f\n",
701  config_filename,
702  csc[int(m_configuration.m_cs_Chk)], uvk,
703  m_configuration.m_bufferSize >> 10,
704  m_configuration.m_prefetch_max_blocks,
705  urlcgi_blks, urlcgi_npref,
706  ram_gb,
707  m_configuration.m_wqueue_blocks, m_configuration.m_wqueue_threads,
708  sP.Total,
709  m_configuration.m_diskUsageLWM, m_configuration.m_diskUsageHWM,
710  m_configuration.m_fileUsageBaseline, m_configuration.m_fileUsageNominal, m_configuration.m_fileUsageMax,
711  m_configuration.m_purgeInterval, m_configuration.m_purgeColdFilesAge,
712  m_configuration.m_data_space.c_str(),
713  m_configuration.m_meta_space.c_str(),
714  m_trace->What,
715  m_configuration.m_flushCnt,
716  m_configuration.m_accHistorySize,
717  m_configuration.m_onlyIfCachedMinSize,
718  m_configuration.m_onlyIfCachedMinFrac);
719 
720  if (m_configuration.is_dir_stat_reporting_on())
721  {
722  loff += snprintf(buff + loff, sizeof(buff) - loff,
723  " pfc.dirstats interval %d maxdepth %d (internal: size_of_dirlist %d, size_of_globlist %d)\n",
724  m_configuration.m_dirStatsInterval, m_configuration.m_dirStatsStoreDepth,
725  (int) m_configuration.m_dirStatsDirs.size(), (int) m_configuration.m_dirStatsDirGlobs.size());
726  loff += snprintf(buff + loff, sizeof(buff) - loff, " dirlist:\n");
727  for (std::set<std::string>::iterator i = m_configuration.m_dirStatsDirs.begin(); i != m_configuration.m_dirStatsDirs.end(); ++i)
728  loff += snprintf(buff + loff, sizeof(buff) - loff, " %s\n", i->c_str());
729  loff += snprintf(buff + loff, sizeof(buff) - loff, " globlist:\n");
730  for (std::set<std::string>::iterator i = m_configuration.m_dirStatsDirGlobs.begin(); i != m_configuration.m_dirStatsDirGlobs.end(); ++i)
731  loff += snprintf(buff + loff, sizeof(buff) - loff, " %s/*\n", i->c_str());
732  }
733 
734  if (m_configuration.m_hdfsmode)
735  {
736  loff += snprintf(buff + loff, sizeof(buff) - loff, " pfc.hdfsmode hdfsbsize %lld\n", m_configuration.m_hdfsbsize);
737  }
738 
739  loff += snprintf(buff + loff, sizeof(buff) - loff, " pfc.writethrough %s\n", m_configuration.m_write_through ? "on" : "off");
740 
741  if (m_configuration.m_username.empty())
742  {
743  char unameBuff[256];
744  XrdOucUtils::UserName(getuid(), unameBuff, sizeof(unameBuff));
745  m_configuration.m_username = unameBuff;
746  }
747  else
748  {
749  loff += snprintf(buff + loff, sizeof(buff) - loff, " pfc.user %s\n", m_configuration.m_username.c_str());
750  }
751 
752  if (m_configuration.m_httpcc)
753  {
754  loff += snprintf(buff + loff, sizeof(buff) - loff, " pfc.httpcc on\n");
755  }
756  if (m_configuration.m_qfsredir)
757  {
758  loff += snprintf(buff + loff, sizeof(buff) - loff, " pfc.qfsredir on\n");
759  }
760 
761  m_log.Say(buff);
762 
763  m_env->Put("XRDPFC.SEGSIZE", std::to_string(m_configuration.m_bufferSize).c_str());
764  }
765 
766  // Derived settings
767  m_prefetch_enabled = CFG.m_prefetch_max_blocks > 0 || CFG.m_cgi_max_prefetch_max_blocks > 0;
769 
770  m_gstream = (XrdXrootdGStream*) m_env->GetPtr("pfc.gStream*");
771 
772  m_log.Say(" pfc g-stream has", m_gstream ? "" : " NOT", " been configured via xrootd.monitor directive\n");
773 
774  // Create the ResourceMonitor and get it ready for starting the main thread function.
775  if (aOK)
776  {
777  m_res_mon = new ResourceMonitor(*m_oss);
778  m_res_mon->init_before_main();
779  }
780 
781  m_log.Say("=====> Proxy file cache configuration parsing ", aOK ? "completed" : "failed");
782 
783  if (ofsCfg) delete ofsCfg;
784 
785  // XXXX-CKSUM Testing. To be removed after OssPgi is also merged and valildated.
786  // Building of xrdpfc_print fails when this is enabled.
787 #ifdef XRDPFC_CKSUM_TEST
788  {
789  int xxx = m_configuration.m_cs_Chk;
790 
791  for (m_configuration.m_cs_Chk = CSChk_None; m_configuration.m_cs_Chk <= CSChk_Both; ++m_configuration.m_cs_Chk)
792  {
793  Info::TestCksumStuff();
794  }
795 
796  m_configuration.m_cs_Chk = xxx;
797  }
798 #endif
799 
800  return aOK;
801 }
802 
803 //------------------------------------------------------------------------------
804 
805 bool Cache::ConfigParameters(std::string part, XrdOucStream& config, TmpConfiguration &tmpc)
806 {
807  struct ConfWordGetter
808  {
809  XrdOucStream &m_config;
810  char *m_last_word;
811 
812  ConfWordGetter(XrdOucStream& c) : m_config(c), m_last_word((char*)1) {}
813 
814  const char* GetWord() { if (HasLast()) m_last_word = m_config.GetWord(); return HasLast() ? m_last_word : ""; }
815  bool HasLast() { return (m_last_word != 0); }
816  };
817 
818  ConfWordGetter cwg(config);
819 
820  Configuration &CFG = m_configuration;
821 
822  if ( part == "user" )
823  {
824  m_configuration.m_username = cwg.GetWord();
825  if ( ! cwg.HasLast())
826  {
827  m_log.Emsg("Config", "Error: pfc.user requires a parameter.");
828  return false;
829  }
830  }
831  else if ( part == "diskusage" )
832  {
833  tmpc.m_diskUsageLWM = cwg.GetWord();
834  tmpc.m_diskUsageHWM = cwg.GetWord();
835 
836  if (tmpc.m_diskUsageHWM.empty())
837  {
838  m_log.Emsg("Config", "Error: pfc.diskusage parameter requires at least two arguments.");
839  return false;
840  }
841 
842  const char *p = 0;
843  while ((p = cwg.GetWord()) && cwg.HasLast())
844  {
845  if (strcmp(p, "files") == 0)
846  {
847  tmpc.m_fileUsageBaseline = cwg.GetWord();
848  tmpc.m_fileUsageNominal = cwg.GetWord();
849  tmpc.m_fileUsageMax = cwg.GetWord();
850 
851  if ( ! cwg.HasLast())
852  {
853  m_log.Emsg("Config", "Error: pfc.diskusage files directive requires three arguments.");
854  return false;
855  }
856  }
857  else if (strcmp(p, "sleep") == 0 || strcmp(p, "purgeinterval") == 0)
858  {
859  if (strcmp(p, "sleep") == 0) m_log.Emsg("Config", "warning sleep directive is deprecated in pfc.diskusage. Please use purgeinterval instead.");
860 
861  if (XrdOuca2x::a2tm(m_log, "Error getting purgeinterval", cwg.GetWord(), &m_configuration.m_purgeInterval, 60, 3600))
862  {
863  return false;
864  }
865  }
866  else if (strcmp(p, "purgecoldfiles") == 0)
867  {
868  if (XrdOuca2x::a2tm(m_log, "Error getting purgecoldfiles age", cwg.GetWord(), &m_configuration.m_purgeColdFilesAge, 3600, 3600*24*360))
869  {
870  return false;
871  }
872  if (XrdOuca2x::a2i(m_log, "Error getting purgecoldfiles period", cwg.GetWord(), &m_configuration.m_purgeAgeBasedPeriod, 1, 1000))
873  {
874  return false;
875  }
876  }
877  else
878  {
879  m_log.Emsg("Config", "Error: diskusage stanza contains unknown directive", p);
880  }
881  }
882  }
883  else if ( part == "acchistorysize" )
884  {
885  if ( XrdOuca2x::a2i(m_log, "Error getting access-history-size", cwg.GetWord(), &m_configuration.m_accHistorySize, 20, 200))
886  {
887  return false;
888  }
889  }
890  else if ( part == "dirstats" )
891  {
892  const char *p = 0;
893  while ((p = cwg.GetWord()) && cwg.HasLast())
894  {
895  if (strcmp(p, "interval") == 0)
896  {
897  int validIntervals[] = {60, 120, 300, 600, 900, 1200, 1800, 3600};
898  int size = sizeof(validIntervals) / sizeof(int);
899 
900  if (XrdOuca2x::a2tm(m_log, "Error getting dirstsat interval", cwg.GetWord(),
901  &m_configuration.m_dirStatsInterval, validIntervals[0], validIntervals[size - 1]))
902  {
903  return false;
904  }
905  bool match = false, round_down = false;
906  for (int i = 0; i < size; i++) {
907  if (validIntervals[i] == m_configuration.m_dirStatsInterval) {
908  match = true;
909  break;
910  }
911  if (i > 0 && m_configuration.m_dirStatsInterval < validIntervals[i]) {
912  m_configuration.m_dirStatsInterval = validIntervals[i - 1];
913  round_down = true;
914  break;
915  }
916  }
917  if ( ! match && ! round_down) {
918  m_log.Emsg("Config", "Error: dirstat interval parsing failed.");
919  return false;
920  }
921  if (round_down) {
922  m_log.Emsg("Config", "Info: dirstat interval was rounded down to the nearest valid value.");
923  }
924 
925  }
926  else if (strcmp(p, "maxdepth") == 0)
927  {
928  if (XrdOuca2x::a2i(m_log, "Error getting maxdepth value", cwg.GetWord(),
929  &m_configuration.m_dirStatsStoreDepth, 0, 16))
930  {
931  return false;
932  }
933  }
934  else if (strcmp(p, "dir") == 0)
935  {
936  p = cwg.GetWord();
937  if (p && p[0] == '/')
938  {
939  // XXX -- should we just store them as sets of PathTokenizer objects, not strings?
940 
941  char d[1024]; d[0] = 0;
942  int depth = 0;
943  { // Compress multiple slashes and "measure" depth
944  const char *pp = p;
945  char *pd = d;
946  *(pd++) = *(pp++);
947  while (*pp != 0)
948  {
949  if (*(pd - 1) == '/')
950  {
951  if (*pp == '/')
952  {
953  ++pp; continue;
954  }
955  ++depth;
956  }
957  *(pd++) = *(pp++);
958  }
959  *(pd--) = 0;
960  // remove trailing but but not leading /
961  if (*pd == '/' && pd != d) *pd = 0;
962  }
963  int ld = strlen(d);
964  if (ld >= 2 && d[ld-1] == '*' && d[ld-2] == '/')
965  {
966  d[ld-2] = 0;
967  ld -= 2;
968  m_configuration.m_dirStatsDirGlobs.insert(d);
969  printf("Glob %s -> %s -- depth = %d\n", p, d, depth);
970  }
971  else
972  {
973  m_configuration.m_dirStatsDirs.insert(d);
974  printf("Dir %s -> %s -- depth = %d\n", p, d, depth);
975  }
976 
977  m_configuration.m_dirStatsStoreDepth = std::max(m_configuration.m_dirStatsStoreDepth, depth);
978  }
979  else
980  {
981  m_log.Emsg("Config", "Error: dirstats dir parameter requires a directory argument starting with a '/'.");
982  return false;
983  }
984  }
985  else
986  {
987  m_log.Emsg("Config", "Error: dirstats stanza contains unknown directive '", p, "'");
988  return false;
989  }
990  }
991  }
992  else if ( part == "blocksize" )
993  {
994  if ( ! blocksize_str2value("Config", cwg.GetWord(), CFG.m_bufferSize,
996  return false;
997  }
998  else if ( part == "prefetch" || part == "nramprefetch" )
999  {
1000  if (part == "nramprefetch")
1001  {
1002  m_log.Emsg("Config", "pfc.nramprefetch is deprecated, please use pfc.prefetch instead. Replacing the directive internally.");
1003  }
1004 
1005  if ( ! prefetch_str2value("Config", cwg.GetWord(), CFG.m_prefetch_max_blocks,
1006  0, CFG.s_max_prefetch_max_blocks))
1007  return false;
1008  }
1009  else if ( part == "urlcgi" )
1010  {
1011  // pfc.urlcgi [blocksize {ignore | min max}] [prefetch {ignore | min max}]
1012  const char *p = 0;
1013  while ((p = cwg.GetWord()) && cwg.HasLast())
1014  {
1015  if (strcmp(p, "blocksize") == 0)
1016  {
1017  std::string bmin = cwg.GetWord();
1018  if (bmin == "ignore")
1019  continue;
1020  std::string bmax = cwg.GetWord();
1021  if ( ! cwg.HasLast()) {
1022  m_log.Emsg("Config", "Error: pfc.urlcgi blocksize parameter requires two arguments.");
1023  return false;
1024  }
1025  if ( ! blocksize_str2value("Config::urlcgi", bmin.c_str(), CFG.m_cgi_min_bufferSize,
1027  return false;
1028  if ( ! blocksize_str2value("Config::urlcgi", bmax.c_str(), CFG.m_cgi_max_bufferSize,
1030  return false;
1032  m_log.Emsg("Config", "Error: pfc.urlcgi blocksize second argument must be larger or equal to the first one.");
1033  return false;
1034  }
1035  CFG.m_cgi_blocksize_allowed = true;
1036  }
1037  else if (strcmp(p, "prefetch") == 0)
1038  {
1039  std::string bmin = cwg.GetWord();
1040  if (bmin == "ignore")
1041  continue;
1042  std::string bmax = cwg.GetWord();
1043  if ( ! cwg.HasLast()) {
1044  m_log.Emsg("Config", "Error: pfc.urlcgi blocksize parameter requires two arguments.");
1045  return false;
1046  }
1047  if ( ! prefetch_str2value("Config::urlcgi", bmin.c_str(), CFG.m_cgi_min_prefetch_max_blocks,
1048  0, CFG.s_max_prefetch_max_blocks))
1049  return false;
1050  if ( ! prefetch_str2value("Config::urlcgi", bmax.c_str(), CFG.m_cgi_max_prefetch_max_blocks,
1051  0, CFG.s_max_prefetch_max_blocks))
1052  return false;
1054  m_log.Emsg("Config", "Error: pfc.urlcgi prefetch second argument must be larger or equal to the first one.");
1055  return false;
1056  }
1057  CFG.m_cgi_prefetch_allowed = true;
1058  }
1059  else
1060  {
1061  m_log.Emsg("Config", "Error: urlcgi stanza contains unknown directive '", p, "'");
1062  return false;
1063  }
1064  } // while get next pfc.urlcgi word
1065  }
1066  else if ( part == "nramread" )
1067  {
1068  m_log.Emsg("Config", "pfc.nramread is deprecated, please use pfc.ram instead. Ignoring this directive.");
1069  cwg.GetWord(); // Ignoring argument.
1070  }
1071  else if ( part == "ram" )
1072  {
1073  long long minRAM = m_isClient ? 256 * 1024 * 1024 : 1024 * 1024 * 1024;
1074  long long maxRAM = 256 * minRAM;
1075  if ( XrdOuca2x::a2sz(m_log, "get RAM available", cwg.GetWord(), &m_configuration.m_RamAbsAvailable, minRAM, maxRAM))
1076  {
1077  return false;
1078  }
1079  }
1080  else if ( part == "writequeue")
1081  {
1082  if (XrdOuca2x::a2i(m_log, "Error getting pfc.writequeue num-blocks", cwg.GetWord(), &m_configuration.m_wqueue_blocks, 1, 1024))
1083  {
1084  return false;
1085  }
1086  if (XrdOuca2x::a2i(m_log, "Error getting pfc.writequeue num-threads", cwg.GetWord(), &m_configuration.m_wqueue_threads, 1, 64))
1087  {
1088  return false;
1089  }
1090  }
1091  else if ( part == "spaces" )
1092  {
1093  m_configuration.m_data_space = cwg.GetWord();
1094  m_configuration.m_meta_space = cwg.GetWord();
1095  if ( ! cwg.HasLast())
1096  {
1097  m_log.Emsg("Config", "spacenames requires two parameters: <data-space> <metadata-space>.");
1098  return false;
1099  }
1100  }
1101  else if ( part == "hdfsmode" )
1102  {
1103  m_log.Emsg("Config", "pfc.hdfsmode is currently unsupported.");
1104  return false;
1105 
1106  m_configuration.m_hdfsmode = true;
1107 
1108  const char* params = cwg.GetWord();
1109  if (params)
1110  {
1111  if (! strncmp("hdfsbsize", params, 9))
1112  {
1113  long long minBlSize = 32 * 1024;
1114  long long maxBlSize = 128 * 1024 * 1024;
1115  if ( XrdOuca2x::a2sz(m_log, "Error getting file fragment size", cwg.GetWord(), &m_configuration.m_hdfsbsize, minBlSize, maxBlSize))
1116  {
1117  return false;
1118  }
1119  }
1120  else
1121  {
1122  m_log.Emsg("Config", "Error setting the fragment size parameter name");
1123  return false;
1124  }
1125  }
1126  }
1127  else if ( part == "writethrough" )
1128  {
1129  const char *val = cwg.GetWord();
1130  if (!val || !cwg.HasLast())
1131  {
1132  m_log.Emsg("Config", "Error: pfc.writethrough requires a parameter.");
1133  return false;
1134  }
1135 
1136  if (strncmp(val, "on", 2) == 0) {
1137  m_configuration.m_write_through = true;
1138  } else if (strncmp(val, "off", 3) == 0) {
1139  m_configuration.m_write_through = false;
1140  } else {
1141  m_log.Emsg("ConfigParameters()",
1142  "Unknown value for pfc.writethrough:", val, "(valid values are 'on' or 'off')");
1143  return false;
1144  }
1145  }
1146  else if ( part == "flush" )
1147  {
1148  tmpc.m_flushRaw = cwg.GetWord();
1149  if ( ! cwg.HasLast())
1150  {
1151  m_log.Emsg("Config", "Error: pfc.flush requires a parameter.");
1152  return false;
1153  }
1154  }
1155  else if ( part == "onlyifcached" )
1156  {
1157  const char *p = 0;
1158  while ((p = cwg.GetWord()) && cwg.HasLast())
1159  {
1160  if (strcmp(p, "minsize") == 0)
1161  {
1162  std::string minBytes = cwg.GetWord();
1163  long long minBytesTop = 1024 * 1024 * 1024;
1164  if (::isalpha(*(minBytes.rbegin())))
1165  {
1166  if (XrdOuca2x::a2sz(m_log, "Error in parsing minsize value for onlyifcached parameter", minBytes.c_str(), &m_configuration.m_onlyIfCachedMinSize, 0, minBytesTop))
1167  {
1168  return false;
1169  }
1170  }
1171  else
1172  {
1173  if (XrdOuca2x::a2ll(m_log, "Error in parsing numeric minsize value for onlyifcached parameter", minBytes.c_str(),&m_configuration.m_onlyIfCachedMinSize, 0, minBytesTop))
1174  {
1175  return false;
1176  }
1177  }
1178  }
1179  if (strcmp(p, "minfrac") == 0)
1180  {
1181  std::string minFrac = cwg.GetWord();
1182  char *eP;
1183  errno = 0;
1184  double frac = strtod(minFrac.c_str(), &eP);
1185  if (errno || eP == minFrac.c_str())
1186  {
1187  m_log.Emsg("Config", "Error setting fraction for only-if-cached directive");
1188  return false;
1189  }
1190  m_configuration.m_onlyIfCachedMinFrac = frac;
1191  }
1192  else
1193  {
1194  m_log.Emsg("Config", "Error: onlyifcached stanza contains unknown directive", p);
1195  }
1196  }
1197  }
1198  else if ( part == "httpcc" )
1199  {
1200  const char* val = cwg.GetWord();
1201  if (!strcmp(val, "on")) {
1202  m_configuration.m_httpcc = true;
1203  }
1204  else if (strcmp(val, "off")) {
1205  m_log.Emsg("Config", "Error: httpcc pramater can only have values [off|on]", val);
1206  }
1207  }
1208  else if ( part == "qfsredir" )
1209  {
1210  const char* val = cwg.GetWord();
1211  if (!strcmp(val, "on")) {
1212  m_configuration.m_qfsredir = true;
1213  }
1214  else if (!strcmp(val, "off")) {
1215  m_configuration.m_qfsredir = false;
1216  }
1217  else
1218  {
1219  m_log.Emsg("Config", "Error: qfsredir pramater can only have values [off|on]", val);
1220  return false;
1221  }
1222  }
1223  else
1224  {
1225  m_log.Emsg("ConfigParameters() unmatched pfc parameter", part.c_str());
1226  return false;
1227  }
1228 
1229  return true;
1230 }
#define XrdOssOK
Definition: XrdOss.hh:54
#define XRDOSS_mkpath
Definition: XrdOss.hh:526
XrdSysXAttr * XrdSysXAttrActive
Definition: XrdSysFAttr.cc:61
XrdVERSIONINFO(XrdOucGetCache, XrdPfc)
XrdOucCache * XrdOucGetCache(XrdSysLogger *logger, const char *config_filename, const char *parameters, XrdOucEnv *env)
Definition: XrdPfc.cc:80
#define open
Definition: XrdPosix.hh:78
int isNo(int dflt, const char *Msg1, const char *Msg2, const char *Msg3)
if(Avsz)
@ Error
#define TRACE(act, x)
Definition: XrdTrace.hh:63
bool Parse(TheLib what)
bool Plugin(XrdAccAuthorize *&piP)
Get Authorization plugin.
static XrdOfsConfigPI * New(const char *cfn, XrdOucStream *cfgP, XrdSysError *errP, XrdVersionInfo *verP=0, XrdSfsFileSystem *sfsP=0)
bool Load(int what, XrdOucEnv *envP=0)
bool Push(TheLib what, const char *plugP, const char *parmP=0)
@ theOssLib
Oss plugin.
virtual int Close(long long *retsz=0)=0
virtual int getFD()
Definition: XrdOss.hh:486
virtual int Open(const char *path, int Oflag, mode_t Mode, XrdOucEnv &env)
Definition: XrdOss.hh:228
virtual ssize_t Write(const void *buffer, off_t offset, size_t size)
Definition: XrdOss.hh:385
long long Total
Definition: XrdOssVS.hh:90
virtual int Create(const char *tid, const char *path, mode_t mode, XrdOucEnv &env, int opts=0)=0
virtual int Lfn2Pfn(const char *Path, char *buff, int blen)
Definition: XrdOss.hh:954
virtual int StatVS(XrdOssVSInfo *vsP, const char *sname=0, int updt=0)
Definition: XrdOss.cc:117
virtual XrdOssDF * newFile(const char *tident)=0
virtual int Unlink(const char *path, int Opts=0, XrdOucEnv *envP=0)=0
static int Export(const char *Var, const char *Val)
Definition: XrdOucEnv.cc:188
void * GetPtr(const char *varname)
Definition: XrdOucEnv.cc:281
char * Get(const char *varname)
Definition: XrdOucEnv.hh:69
void Put(const char *varname, const char *value)
Definition: XrdOucEnv.hh:85
void * Resolve(const char *symbl, int mcnt=1)
void Unload(bool dodel=false)
char * GetWord(int lowcase=0)
static int UserName(uid_t uID, char *uName, int uNsz)
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 a2ll(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
Definition: XrdOuca2x.cc:70
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition: XrdOuca2x.cc:288
bool blocksize_str2value(const char *from, const char *str, long long &val, long long min, long long max) const
bool Config(const char *config_filename, const char *parameters, XrdOucEnv *env)
Parse configuration file.
bool prefetch_str2value(const char *from, const char *str, int &val, int min, int max) const
Base class for selecting which files should be cached.
virtual bool ConfigDecision(const char *params)
Status of cached file. Can be read from and written into a binary file.
Definition: XrdPfcInfo.hh:41
static size_t s_maxNumAccess
Definition: XrdPfcInfo.hh:311
Base class for reguesting directory space to obtain.
virtual bool ConfigPurgePin(const char *params)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:116
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
virtual int Get(const char *Aname, void *Aval, int Avsz, const char *Path, int fd=-1)=0
virtual int Set(const char *Aname, const void *Aval, int Avsz, const char *Path, int fd=-1, int isNew=0)=0
XrdCmsConfig Config
Definition: XrdPfc.hh:43
const char * trace_what_strings[]
@ CSChk_Both
Definition: XrdPfcTypes.hh:27
@ CSChk_Net
Definition: XrdPfcTypes.hh:27
@ CSChk_TLS
Definition: XrdPfcTypes.hh:28
@ CSChk_Cache
Definition: XrdPfcTypes.hh:27
@ CSChk_None
Definition: XrdPfcTypes.hh:27
Contains parameters configurable from the xrootd config file.
Definition: XrdPfc.hh:66
long long m_hdfsbsize
used with m_hdfsmode, default 128MB
Definition: XrdPfc.hh:124
long long m_RamAbsAvailable
available from configuration
Definition: XrdPfc.hh:111
long long m_flushCnt
nuber of unsynced blcoks on disk before flush is called
Definition: XrdPfc.hh:125
long long m_cgi_max_bufferSize
max buffer size allowed in pfc.blocksize
Definition: XrdPfc.hh:118
int m_accHistorySize
max number of entries in access history part of cinfo file
Definition: XrdPfc.hh:103
int m_cgi_min_prefetch_max_blocks
min prefetch block count allowed in pfc.prefetch
Definition: XrdPfc.hh:119
bool m_httpcc
enable http cache control
Definition: XrdPfc.hh:139
bool m_cgi_prefetch_allowed
allow cgi setting of prefetch
Definition: XrdPfc.hh:122
int m_wqueue_threads
number of threads writing blocks to disk
Definition: XrdPfc.hh:114
bool m_write_through
flag indicating write-through mode is enabled
Definition: XrdPfc.hh:86
long long m_diskTotalSpace
total disk space on configured partition or oss space
Definition: XrdPfc.hh:94
long long m_fileUsageMax
cache purge - files usage maximum
Definition: XrdPfc.hh:99
long long m_fileUsageBaseline
cache purge - files usage baseline
Definition: XrdPfc.hh:97
int m_dirStatsStoreDepth
maximum depth for statistics write out
Definition: XrdPfc.hh:108
bool m_allow_xrdpfc_command
flag for enabling access to /xrdpfc-command/ functionality.
Definition: XrdPfc.hh:88
long long m_diskUsageHWM
cache purge - disk usage high water mark
Definition: XrdPfc.hh:96
bool is_cschk_cache() const
Definition: XrdPfc.hh:77
std::set< std::string > m_dirStatsDirGlobs
directory globs for which stat reporting was requested
Definition: XrdPfc.hh:106
static constexpr long long s_min_bufferSize
Definition: XrdPfc.hh:134
static constexpr long long s_max_bufferSize
Definition: XrdPfc.hh:135
int m_prefetch_max_blocks
default maximum number of blocks to prefetch per file
Definition: XrdPfc.hh:115
bool m_cs_ChkTLS
Allow TLS.
Definition: XrdPfc.hh:129
long long m_fileUsageNominal
cache purge - files usage nominal
Definition: XrdPfc.hh:98
int m_cs_Chk
Checksum check.
Definition: XrdPfc.hh:128
int m_purgeAgeBasedPeriod
peform cold file / uvkeep purge every this many purge cycles
Definition: XrdPfc.hh:102
bool m_qfsredir
redirect file system query to the origin
Definition: XrdPfc.hh:140
bool m_hdfsmode
flag for enabling block-level operation
Definition: XrdPfc.hh:87
int m_purgeColdFilesAge
purge files older than this age
Definition: XrdPfc.hh:101
std::string m_data_space
oss space for data files
Definition: XrdPfc.hh:91
std::set< std::string > m_dirStatsDirs
directories for which stat reporting was requested
Definition: XrdPfc.hh:105
long long m_diskUsageLWM
cache purge - disk usage low water mark
Definition: XrdPfc.hh:95
int m_RamKeepStdBlocks
number of standard-sized blocks kept after release
Definition: XrdPfc.hh:112
long long m_bufferSize
cache block size, default 128 kB
Definition: XrdPfc.hh:110
long long m_cgi_min_bufferSize
min buffer size allowed in pfc.blocksize
Definition: XrdPfc.hh:117
int m_dirStatsInterval
time between resource monitor statistics dump in seconds
Definition: XrdPfc.hh:107
std::string m_meta_space
oss space for metadata files (cinfo)
Definition: XrdPfc.hh:92
int m_wqueue_blocks
maximum number of blocks written per write-queue loop
Definition: XrdPfc.hh:113
int m_cgi_max_prefetch_max_blocks
max prefetch block count allowed in pfc.prefetch
Definition: XrdPfc.hh:120
std::string m_username
username passed to oss plugin
Definition: XrdPfc.hh:90
static constexpr int s_max_prefetch_max_blocks
Definition: XrdPfc.hh:137
bool m_cgi_blocksize_allowed
allow cgi setting of blocksize
Definition: XrdPfc.hh:121
bool is_cschk_net() const
Definition: XrdPfc.hh:78
double m_onlyIfCachedMinFrac
minimum fraction of downloaded file, used by only-if-cached CGI option
Definition: XrdPfc.hh:132
time_t m_cs_UVKeep
unverified checksum cache keep
Definition: XrdPfc.hh:127
int m_purgeInterval
sleep interval between cache purges
Definition: XrdPfc.hh:100
long long m_onlyIfCachedMinSize
minumum size of downloaded file, used by only-if-cached CGI option
Definition: XrdPfc.hh:131
bool is_dir_stat_reporting_on() const
Definition: XrdPfc.hh:72
std::string m_diskUsageLWM
Definition: XrdPfc.hh:147
std::string m_diskUsageHWM
Definition: XrdPfc.hh:148
std::string m_fileUsageBaseline
Definition: XrdPfc.hh:149
std::string m_fileUsageNominal
Definition: XrdPfc.hh:150
std::string m_flushRaw
Definition: XrdPfc.hh:152
std::string m_fileUsageMax
Definition: XrdPfc.hh:151