16#include "XrdVersion.hh"
69bool Cache::cfg2bytes(
const std::string &str,
long long &store,
long long totalSpace,
const char *name)
const
72 snprintf(errStr, 1024,
"ConfigParameters() Error parsing parameter %s", name);
74 if (::isalpha(*(str.rbegin())))
85 double frac = strtod(str.c_str(), &eP);
86 if (errno || eP == str.c_str())
88 m_log.Emsg(errStr, str.c_str());
92 store =
static_cast<long long>(totalSpace * frac + 0.5);
95 if (store < 0 || store > totalSpace)
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,
"");
107 long long &val,
long long min,
long long max)
const
109 if (
XrdOuca2x::a2sz(m_log,
"Error parsing block-size", str, &val, min, max))
115 m_log.Emsg(from,
"blocksize must be a multiple of 4 kB. Rounded up.");
122 int &val,
int min,
int max)
const
124 if (
XrdOuca2x::a2i(m_log,
"Error parsing prefetch block count", str, &val, min, max))
151 const char *val, *val2;
152 struct cschkopts {
const char *opname;
int opval;} csopts[] =
159 int i, numopts =
sizeof(csopts)/
sizeof(
struct cschkopts);
162 if (! (val =
Config.GetWord()))
163 {m_log.Emsg(
"Config",
"cschk parameter not specified");
return false; }
167 if ((
isNo = strncmp(val,
"no", 2) == 0))
171 for (i = 0; i < numopts; i++)
173 if (!strcmp(val2, csopts[i].opname))
176 m_configuration.m_cs_Chk &= ~csopts[i].opval;
177 else if (csopts[i].opval)
178 m_configuration.m_cs_Chk |= csopts[i].opval;
180 m_configuration.m_cs_Chk = csopts[i].opval;
186 if (strcmp(val,
"uvkeep"))
188 m_log.Emsg(
"Config",
"invalid cschk option -", val);
191 if (!(val =
Config.GetWord()))
193 m_log.Emsg(
"Config",
"cschk uvkeep value not specified");
196 if (!strcmp(val,
"lru"))
197 m_configuration.m_cs_UVKeep = -1;
203 m_configuration.m_cs_UVKeep = uvkeep;
209 m_configuration.m_cs_ChkTLS = m_configuration.m_cs_Chk &
CSChk_TLS;
210 m_configuration.m_cs_Chk &= ~CSChk_TLS;
212 m_env->Put(
"psx.CSNet", m_configuration.is_cschk_net() ? (m_configuration.m_cs_ChkTLS ?
"2" :
"1") :
"0");
228bool Cache::xdlib(XrdOucStream &Config)
233 if (! (val =
Config.GetWord()) || ! val[0])
235 TRACE(Info,
" Cache::Config() decisionlib not specified; always caching files");
245 Config.GetRest(params, 4096);
249 XrdOucPinLoader* myLib =
new XrdOucPinLoader(&m_log, 0,
"decisionlib",
252 Decision *(*ep)(XrdSysError&);
253 ep = (Decision *(*)(XrdSysError&))myLib->
Resolve(
"XrdPfcGetDecision");
254 if (! ep) {myLib->
Unload(
true);
return false; }
256 Decision * d = ep(m_log);
259 TRACE(
Error,
"Config() decisionlib was not able to create a decision object");
265 m_decisionpoints.push_back(d);
279bool Cache::xplib(XrdOucStream &Config)
284 if (! (val =
Config.GetWord()) || ! val[0])
286 TRACE(Info,
" Cache::Config() purgelib not specified; will use LRU for purging files");
296 Config.GetRest(params, 4096);
300 XrdOucPinLoader* myLib =
new XrdOucPinLoader(&m_log, 0,
"purgelib",
303 PurgePin *(*ep)(XrdSysError&);
304 ep = (PurgePin *(*)(XrdSysError&))myLib->
Resolve(
"XrdPfcGetPurgePin");
305 if (! ep) {myLib->
Unload(
true);
return false; }
307 PurgePin * dp = ep(m_log);
310 TRACE(
Error,
"Config() purgelib was not able to create a Purge Plugin object?");
327bool Cache::xtrace(XrdOucStream &Config)
330 static struct traceopts {
const char *opname;
int opval; } tropts[] =
340 int numopts =
sizeof(tropts)/
sizeof(
struct traceopts);
342 if (! (val =
Config.GetWord()))
343 {m_log.Emsg(
"Config",
"trace option not specified");
return 1; }
345 for (
int i = 0; i < numopts; i++)
347 if (! strcmp(val, tropts[i].opname))
349 m_trace->What = tropts[i].opval;
353 m_log.Emsg(
"Config",
"invalid trace option -", val);
358bool Cache::test_oss_basics_and_features()
360 static const char *epfx =
"test_oss_basics_and_features()";
362 const auto &conf = m_configuration;
363 const char *user = conf.m_username.c_str();
366 auto check_space = [&](
const char *space,
bool &has_xattr)
368 std::string fname(
"__prerun_test_pfc_");
371 env.
Put(
"oss.cgroup", space);
373 int res = m_oss->Create(user, fname.c_str(), 0600, env,
XRDOSS_mkpath);
375 m_log.Emsg(epfx,
"Can not create a file on space", space);
378 XrdOssDF *oss_file = m_oss->newFile(user);
379 res = oss_file->
Open(fname.c_str(), O_RDWR, 0600, env);
381 m_log.Emsg(epfx,
"Can not open a file on space", space);
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);
391 long long fsize = fname.length();
394 m_log.Emsg(epfx,
"Can not write xattr to a file on space", space);
402 m_oss->Lfn2Pfn(fname.c_str(), pfn, 4096);
405 if (res !=
sizeof(
long long) || fsize != (
long long) fname.length())
407 m_log.Emsg(epfx,
"Can not read xattr from a file on space", space);
412 res = m_oss->Unlink(fname.c_str());
414 m_log.Emsg(epfx,
"Can not unlink a file on space", space);
422 aOK &= check_space(conf.m_data_space.c_str(), m_dataXattr);
423 aOK &= check_space(conf.m_meta_space.c_str(), m_metaXattr);
437 const char *theINS = getenv(
"XRDINSTANCE");
438 m_isClient = (theINS != 0 && strncmp(
"*client ", theINS, 8) == 0);
444 XrdOucEnv *myEnv = env ? env : &emptyEnv;
448 if (! config_filename || ! *config_filename)
450 TRACE(
Error,
"Config() configuration file not specified.");
455 if ( (fd =
open(config_filename, O_RDONLY, 0)) < 0)
457 TRACE(
Error,
"Config() can't open configuration file " << config_filename);
462 static const char *cvec[] = {
"*** pfc plugin config:", 0 };
468 if (! ofsCfg)
return false;
477 m_configuration.m_bufferSize = 128 * 1024;
478 m_configuration.m_wqueue_blocks = 8;
479 m_configuration.m_wqueue_threads = 1;
483 if (m_configuration.is_cschk_net()) m_env->Put(
"psx.CSNet", m_configuration.m_cs_ChkTLS ?
"2" :
"1");
486 bool retval =
true, aOK =
true;
488 while ((var =
Config.GetMyFirstWord()))
490 if (! strcmp(var,
"pfc.osslib"))
494 else if (! strcmp(var,
"pfc.cschk"))
498 else if (! strcmp(var,
"pfc.decisionlib"))
502 else if (! strcmp(var,
"pfc.purgelib"))
506 else if (! strcmp(var,
"pfc.trace"))
510 else if (! strcmp(var,
"pfc.allow_xrdpfc_command"))
512 m_configuration.m_allow_xrdpfc_command =
true;
514 else if (! strncmp(var,
"pfc.", 4))
516 retval = ConfigParameters(std::string(var+4),
Config, tmpc);
529 auto orig_runmode = myEnv->
Get(
"oss.runmode");
530 myEnv->
Put(
"oss.runmode",
"pfc");
531 if (m_configuration.is_cschk_cache())
534 if (snprintf(csi_conf, 128,
"space=%s nofill", m_configuration.m_meta_space.c_str()) < 128)
538 TRACE(
Error,
"Config() buffer too small for libXrdOssCsi params.");
548 TRACE(
Error,
"Config() Unable to create an OSS object");
551 if (orig_runmode) myEnv->
Put(
"oss.runmode", orig_runmode);
552 else myEnv->
Put(
"oss.runmode",
"");
555 aOK &= test_oss_basics_and_features();
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)
563 m_log.Emsg(
"ConfigParameters()",
"error obtaining stat info for meta space ", m_configuration.m_meta_space.c_str());
566 if (m_configuration.m_meta_space != m_configuration.m_data_space && sP.
Total < 10ll << 20)
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());
572 if (m_oss->StatVS(&sP, m_configuration.m_data_space.c_str(), 1) < 0)
574 m_log.Emsg(
"ConfigParameters()",
"error obtaining stat info for data space ", m_configuration.m_data_space.c_str());
577 if (sP.
Total < 10ll << 20)
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());
584 m_configuration.m_diskTotalSpace = sP.
Total;
586 if (cfg2bytes(tmpc.
m_diskUsageLWM, m_configuration.m_diskUsageLWM, sP.
Total,
"lowWatermark") &&
589 if (m_configuration.m_diskUsageLWM >= m_configuration.m_diskUsageHWM) {
590 m_log.Emsg(
"ConfigParameters()",
"pfc.diskusage should have lowWatermark < highWatermark.");
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)
606 m_log.Emsg(
"ConfigParameters()",
"pfc.diskusage files should have baseline < nominal < max.");
611 if (aOK && m_configuration.m_fileUsageMax >= m_configuration.m_diskUsageLWM)
613 m_log.Emsg(
"ConfigParameters()",
"pfc.diskusage files values must be below lowWatermark");
627 &m_configuration.m_flushCnt,
628 100 * m_configuration.m_bufferSize , 100000 * m_configuration.m_bufferSize))
632 m_configuration.m_flushCnt /= m_configuration.m_bufferSize;
637 &m_configuration.m_flushCnt, 100, 100000))
645 if (m_configuration.m_RamAbsAvailable == 0)
647 m_configuration.m_RamAbsAvailable = m_isClient ? 256ll * 1024 * 1024 : 1024ll * 1024 * 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);
653 m_configuration.m_RamKeepStdBlocks = (m_configuration.m_RamAbsAvailable / m_configuration.m_bufferSize + 1) * 5 / 100;
656 char* cenv = getenv(
"XRDDEBUG");
657 if (cenv && ! strcmp(cenv,
"1") && m_trace->What < 4) m_trace->What = 4;
662 const char *csc[] = {
"off",
"cache nonet",
"nocache net notls",
666 "off",
"cache nonet",
"nocache net tls",
670 if (m_configuration.m_cs_UVKeep < 0)
673 sprintf(uvk,
"%lld", (
long long) m_configuration.m_cs_UVKeep);
674 float ram_gb = (m_configuration.m_RamAbsAvailable) /
float(1024*1024*1024);
676 char urlcgi_blks[64] =
"ignore", urlcgi_npref[32] =
"ignore";
678 snprintf(urlcgi_blks,
sizeof(urlcgi_blks),
"%lldk %lldk",
681 snprintf(urlcgi_npref,
sizeof(urlcgi_npref),
"%d %d",
686 loff = snprintf(buff,
sizeof(buff),
"Config effective %s pfc configuration:\n"
687 " pfc.cschk %s uvkeep %s\n"
688 " pfc.blocksize %lldk\n"
690 " pfc.urlcgi blocksize %s prefetch %s\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"
698 " pfc.acchistorysize %d\n"
699 " pfc.onlyIfCachedMinBytes %lld\n"
700 " pfc.onlyIfCachedMinFrac %.2f\n",
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,
707 m_configuration.m_wqueue_blocks, m_configuration.m_wqueue_threads,
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(),
715 m_configuration.m_flushCnt,
716 m_configuration.m_accHistorySize,
717 m_configuration.m_onlyIfCachedMinSize,
718 m_configuration.m_onlyIfCachedMinFrac);
720 if (m_configuration.is_dir_stat_reporting_on())
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());
734 if (m_configuration.m_hdfsmode)
736 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" pfc.hdfsmode hdfsbsize %lld\n", m_configuration.m_hdfsbsize);
739 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" pfc.writethrough %s\n", m_configuration.m_write_through ?
"on" :
"off");
741 if (m_configuration.m_username.empty())
745 m_configuration.m_username = unameBuff;
749 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" pfc.user %s\n", m_configuration.m_username.c_str());
752 if (m_configuration.m_httpcc)
754 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" pfc.httpcc on\n");
756 if (m_configuration.m_qfsredir)
758 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" pfc.qfsredir on\n");
763 m_env->Put(
"XRDPFC.SEGSIZE", std::to_string(m_configuration.m_bufferSize).c_str());
772 m_log.Say(
" pfc g-stream has", m_gstream ?
"" :
" NOT",
" been configured via xrootd.monitor directive\n");
778 m_res_mon->init_before_main();
781 m_log.Say(
"=====> Proxy file cache configuration parsing ", aOK ?
"completed" :
"failed");
783 if (ofsCfg)
delete ofsCfg;
787#ifdef XRDPFC_CKSUM_TEST
789 int xxx = m_configuration.m_cs_Chk;
791 for (m_configuration.m_cs_Chk =
CSChk_None; m_configuration.m_cs_Chk <=
CSChk_Both; ++m_configuration.m_cs_Chk)
793 Info::TestCksumStuff();
796 m_configuration.m_cs_Chk = xxx;
807 struct ConfWordGetter
812 ConfWordGetter(
XrdOucStream& c) : m_config(c), m_last_word((char*)1) {}
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); }
818 ConfWordGetter cwg(config);
820 Configuration &CFG = m_configuration;
822 if ( part ==
"user" )
824 m_configuration.m_username = cwg.GetWord();
825 if ( ! cwg.HasLast())
827 m_log.Emsg(
"Config",
"Error: pfc.user requires a parameter.");
831 else if ( part ==
"diskusage" )
838 m_log.Emsg(
"Config",
"Error: pfc.diskusage parameter requires at least two arguments.");
843 while ((p = cwg.GetWord()) && cwg.HasLast())
845 if (strcmp(p,
"files") == 0)
851 if ( ! cwg.HasLast())
853 m_log.Emsg(
"Config",
"Error: pfc.diskusage files directive requires three arguments.");
857 else if (strcmp(p,
"sleep") == 0 || strcmp(p,
"purgeinterval") == 0)
859 if (strcmp(p,
"sleep") == 0) m_log.Emsg(
"Config",
"warning sleep directive is deprecated in pfc.diskusage. Please use purgeinterval instead.");
861 if (
XrdOuca2x::a2tm(m_log,
"Error getting purgeinterval", cwg.GetWord(), &m_configuration.m_purgeInterval, 60, 3600))
866 else if (strcmp(p,
"purgecoldfiles") == 0)
868 if (
XrdOuca2x::a2tm(m_log,
"Error getting purgecoldfiles age", cwg.GetWord(), &m_configuration.m_purgeColdFilesAge, 3600, 3600*24*360))
872 if (
XrdOuca2x::a2i(m_log,
"Error getting purgecoldfiles period", cwg.GetWord(), &m_configuration.m_purgeAgeBasedPeriod, 1, 1000))
879 m_log.Emsg(
"Config",
"Error: diskusage stanza contains unknown directive", p);
883 else if ( part ==
"acchistorysize" )
885 if (
XrdOuca2x::a2i(m_log,
"Error getting access-history-size", cwg.GetWord(), &m_configuration.m_accHistorySize, 20, 200))
890 else if ( part ==
"dirstats" )
893 while ((p = cwg.GetWord()) && cwg.HasLast())
895 if (strcmp(p,
"interval") == 0)
897 int validIntervals[] = {60, 120, 300, 600, 900, 1200, 1800, 3600};
898 int size =
sizeof(validIntervals) /
sizeof(
int);
900 if (
XrdOuca2x::a2tm(m_log,
"Error getting dirstsat interval", cwg.GetWord(),
901 &m_configuration.m_dirStatsInterval, validIntervals[0], validIntervals[size - 1]))
905 bool match =
false, round_down =
false;
906 for (
int i = 0; i < size; i++) {
907 if (validIntervals[i] == m_configuration.m_dirStatsInterval) {
911 if (i > 0 && m_configuration.m_dirStatsInterval < validIntervals[i]) {
912 m_configuration.m_dirStatsInterval = validIntervals[i - 1];
917 if ( ! match && ! round_down) {
918 m_log.Emsg(
"Config",
"Error: dirstat interval parsing failed.");
922 m_log.Emsg(
"Config",
"Info: dirstat interval was rounded down to the nearest valid value.");
926 else if (strcmp(p,
"maxdepth") == 0)
928 if (
XrdOuca2x::a2i(m_log,
"Error getting maxdepth value", cwg.GetWord(),
929 &m_configuration.m_dirStatsStoreDepth, 0, 16))
934 else if (strcmp(p,
"dir") == 0)
937 if (p && p[0] ==
'/')
941 char d[1024]; d[0] = 0;
949 if (*(pd - 1) ==
'/')
961 if (*pd ==
'/' && pd != d) *pd = 0;
964 if (ld >= 2 && d[ld-1] ==
'*' && d[ld-2] ==
'/')
968 m_configuration.m_dirStatsDirGlobs.insert(d);
969 printf(
"Glob %s -> %s -- depth = %d\n", p, d, depth);
973 m_configuration.m_dirStatsDirs.insert(d);
974 printf(
"Dir %s -> %s -- depth = %d\n", p, d, depth);
977 m_configuration.m_dirStatsStoreDepth = std::max(m_configuration.m_dirStatsStoreDepth, depth);
981 m_log.Emsg(
"Config",
"Error: dirstats dir parameter requires a directory argument starting with a '/'.");
987 m_log.Emsg(
"Config",
"Error: dirstats stanza contains unknown directive '", p,
"'");
992 else if ( part ==
"blocksize" )
998 else if ( part ==
"prefetch" || part ==
"nramprefetch" )
1000 if (part ==
"nramprefetch")
1002 m_log.Emsg(
"Config",
"pfc.nramprefetch is deprecated, please use pfc.prefetch instead. Replacing the directive internally.");
1009 else if ( part ==
"urlcgi" )
1013 while ((p = cwg.GetWord()) && cwg.HasLast())
1015 if (strcmp(p,
"blocksize") == 0)
1017 std::string bmin = cwg.GetWord();
1018 if (bmin ==
"ignore")
1020 std::string bmax = cwg.GetWord();
1021 if ( ! cwg.HasLast()) {
1022 m_log.Emsg(
"Config",
"Error: pfc.urlcgi blocksize parameter requires two arguments.");
1032 m_log.Emsg(
"Config",
"Error: pfc.urlcgi blocksize second argument must be larger or equal to the first one.");
1037 else if (strcmp(p,
"prefetch") == 0)
1039 std::string bmin = cwg.GetWord();
1040 if (bmin ==
"ignore")
1042 std::string bmax = cwg.GetWord();
1043 if ( ! cwg.HasLast()) {
1044 m_log.Emsg(
"Config",
"Error: pfc.urlcgi blocksize parameter requires two arguments.");
1054 m_log.Emsg(
"Config",
"Error: pfc.urlcgi prefetch second argument must be larger or equal to the first one.");
1061 m_log.Emsg(
"Config",
"Error: urlcgi stanza contains unknown directive '", p,
"'");
1066 else if ( part ==
"nramread" )
1068 m_log.Emsg(
"Config",
"pfc.nramread is deprecated, please use pfc.ram instead. Ignoring this directive.");
1071 else if ( part ==
"ram" )
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))
1080 else if ( part ==
"writequeue")
1082 if (
XrdOuca2x::a2i(m_log,
"Error getting pfc.writequeue num-blocks", cwg.GetWord(), &m_configuration.m_wqueue_blocks, 1, 1024))
1086 if (
XrdOuca2x::a2i(m_log,
"Error getting pfc.writequeue num-threads", cwg.GetWord(), &m_configuration.m_wqueue_threads, 1, 64))
1091 else if ( part ==
"spaces" )
1093 m_configuration.m_data_space = cwg.GetWord();
1094 m_configuration.m_meta_space = cwg.GetWord();
1095 if ( ! cwg.HasLast())
1097 m_log.Emsg(
"Config",
"spacenames requires two parameters: <data-space> <metadata-space>.");
1101 else if ( part ==
"hdfsmode" )
1103 m_log.Emsg(
"Config",
"pfc.hdfsmode is currently unsupported.");
1106 m_configuration.m_hdfsmode =
true;
1108 const char* params = cwg.GetWord();
1111 if (! strncmp(
"hdfsbsize", params, 9))
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))
1122 m_log.Emsg(
"Config",
"Error setting the fragment size parameter name");
1127 else if ( part ==
"writethrough" )
1129 const char *val = cwg.GetWord();
1130 if (!val || !cwg.HasLast())
1132 m_log.Emsg(
"Config",
"Error: pfc.writethrough requires a parameter.");
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;
1141 m_log.Emsg(
"ConfigParameters()",
1142 "Unknown value for pfc.writethrough:", val,
"(valid values are 'on' or 'off')");
1146 else if ( part ==
"flush" )
1149 if ( ! cwg.HasLast())
1151 m_log.Emsg(
"Config",
"Error: pfc.flush requires a parameter.");
1155 else if ( part ==
"onlyifcached" )
1158 while ((p = cwg.GetWord()) && cwg.HasLast())
1160 if (strcmp(p,
"minsize") == 0)
1162 std::string minBytes = cwg.GetWord();
1163 long long minBytesTop = 1024 * 1024 * 1024;
1164 if (::isalpha(*(minBytes.rbegin())))
1166 if (
XrdOuca2x::a2sz(m_log,
"Error in parsing minsize value for onlyifcached parameter", minBytes.c_str(), &m_configuration.m_onlyIfCachedMinSize, 0, minBytesTop))
1173 if (
XrdOuca2x::a2ll(m_log,
"Error in parsing numeric minsize value for onlyifcached parameter", minBytes.c_str(),&m_configuration.m_onlyIfCachedMinSize, 0, minBytesTop))
1179 if (strcmp(p,
"minfrac") == 0)
1181 std::string minFrac = cwg.GetWord();
1184 double frac = strtod(minFrac.c_str(), &eP);
1185 if (errno || eP == minFrac.c_str())
1187 m_log.Emsg(
"Config",
"Error setting fraction for only-if-cached directive");
1190 m_configuration.m_onlyIfCachedMinFrac = frac;
1194 m_log.Emsg(
"Config",
"Error: onlyifcached stanza contains unknown directive", p);
1198 else if ( part ==
"httpcc" )
1200 const char* val = cwg.GetWord();
1201 if (!strcmp(val,
"on")) {
1202 m_configuration.m_httpcc =
true;
1204 else if (strcmp(val,
"off")) {
1205 m_log.Emsg(
"Config",
"Error: httpcc pramater can only have values [off|on]", val);
1208 else if ( part ==
"qfsredir" )
1210 const char* val = cwg.GetWord();
1211 if (!strcmp(val,
"on")) {
1212 m_configuration.m_qfsredir =
true;
1214 else if (!strcmp(val,
"off")) {
1215 m_configuration.m_qfsredir =
false;
1219 m_log.Emsg(
"Config",
"Error: qfsredir pramater can only have values [off|on]", val);
1225 m_log.Emsg(
"ConfigParameters() unmatched pfc parameter", part.c_str());
XrdVERSIONINFO(XrdOucGetCache, XrdPfc)
XrdSysXAttr * XrdSysXAttrActive
XrdOucCache * XrdOucGetCache(XrdSysLogger *logger, const char *config_filename, const char *parameters, XrdOucEnv *env)
int isNo(int dflt, const char *Msg1, const char *Msg2, const char *Msg3)
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)
virtual int Close(long long *retsz=0)=0
virtual int Open(const char *path, int Oflag, mode_t Mode, XrdOucEnv &env)
virtual ssize_t Write(const void *buffer, off_t offset, size_t size)
char * Get(const char *varname)
static int Export(const char *Var, const char *Val)
void Put(const char *varname, const char *value)
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)
static int a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
static int a2ll(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
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
virtual bool ConfigDecision(const char *params)
static size_t s_maxNumAccess
virtual bool ConfigPurgePin(const char *params)
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
const char * trace_what_strings[]
Contains parameters configurable from the xrootd config file.
long long m_hdfsbsize
used with m_hdfsmode, default 128MB
long long m_RamAbsAvailable
available from configuration
long long m_flushCnt
nuber of unsynced blcoks on disk before flush is called
long long m_cgi_max_bufferSize
max buffer size allowed in pfc.blocksize
int m_accHistorySize
max number of entries in access history part of cinfo file
int m_cgi_min_prefetch_max_blocks
min prefetch block count allowed in pfc.prefetch
bool m_httpcc
enable http cache control
bool m_cgi_prefetch_allowed
allow cgi setting of prefetch
int m_wqueue_threads
number of threads writing blocks to disk
bool m_write_through
flag indicating write-through mode is enabled
long long m_diskTotalSpace
total disk space on configured partition or oss space
long long m_fileUsageMax
cache purge - files usage maximum
long long m_fileUsageBaseline
cache purge - files usage baseline
int m_dirStatsStoreDepth
maximum depth for statistics write out
bool m_allow_xrdpfc_command
flag for enabling access to /xrdpfc-command/ functionality.
long long m_diskUsageHWM
cache purge - disk usage high water mark
static constexpr long long s_min_bufferSize
static constexpr long long s_max_bufferSize
int m_prefetch_max_blocks
default maximum number of blocks to prefetch per file
bool m_cs_ChkTLS
Allow TLS.
long long m_fileUsageNominal
cache purge - files usage nominal
int m_cs_Chk
Checksum check.
int m_purgeAgeBasedPeriod
peform cold file / uvkeep purge every this many purge cycles
bool m_qfsredir
redirect file system query to the origin
bool m_hdfsmode
flag for enabling block-level operation
int m_purgeColdFilesAge
purge files older than this age
std::string m_data_space
oss space for data files
long long m_diskUsageLWM
cache purge - disk usage low water mark
int m_RamKeepStdBlocks
number of standard-sized blocks kept after release
long long m_bufferSize
cache block size, default 128 kB
long long m_cgi_min_bufferSize
min buffer size allowed in pfc.blocksize
int m_dirStatsInterval
time between resource monitor statistics dump in seconds
std::string m_meta_space
oss space for metadata files (cinfo)
int m_wqueue_blocks
maximum number of blocks written per write-queue loop
int m_cgi_max_prefetch_max_blocks
max prefetch block count allowed in pfc.prefetch
static constexpr int s_max_prefetch_max_blocks
bool m_cgi_blocksize_allowed
allow cgi setting of blocksize
double m_onlyIfCachedMinFrac
minimum fraction of downloaded file, used by only-if-cached CGI option
time_t m_cs_UVKeep
unverified checksum cache keep
int m_purgeInterval
sleep interval between cache purges
long long m_onlyIfCachedMinSize
minumum size of downloaded file, used by only-if-cached CGI option
std::string m_diskUsageLWM
std::string m_diskUsageHWM
std::string m_fileUsageBaseline
std::string m_fileUsageNominal
std::string m_fileUsageMax