16#include "XrdVersion.hh"
78 if (size < 64) size = 64;
91 int rc = vsnprintf(
f_string.data() +
f_pos, space_left, fmt, ap);
94 throw std::runtime_error(
f_exc_prefix +
" - vsnprintf failure: " + std::to_string(rc));
96 size_t would_write = (size_t) rc;
97 if (would_write >= space_left) {
98 size_t new_size =
f_string.size() * 2;
104 f_pos += would_write;
114bool Cache::cfg2bytes(
const std::string &str,
long long &store,
long long totalSpace,
const char *name)
const
117 snprintf(errStr, 1024,
"ConfigParameters() Error parsing parameter %s", name);
119 if (::isalpha(*(str.rbegin())))
121 if (
XrdOuca2x::a2sz(m_log, errStr, str.c_str(), &store, 0, totalSpace))
130 double frac = strtod(str.c_str(), &eP);
131 if (errno || eP == str.c_str())
133 m_log.Emsg(errStr, str.c_str());
137 store =
static_cast<long long>(totalSpace * frac + 0.5);
140 if (store < 0 || store > totalSpace)
142 snprintf(errStr, 1024,
"ConfigParameters() Error: parameter %s should be between 0 and total available disk space (%lld) - it is %lld (given as %s)",
143 name, totalSpace, store, str.c_str());
144 m_log.Emsg(errStr,
"");
152 long long &val,
long long min,
long long max)
const
154 if (
XrdOuca2x::a2sz(m_log,
"Error parsing block-size", str, &val, min, max))
160 m_log.Emsg(from,
"blocksize must be a multiple of 4 kB. Rounded up.");
167 int &val,
int min,
int max)
const
169 if (
XrdOuca2x::a2i(m_log,
"Error parsing prefetch block count", str, &val, min, max))
196 const char *val, *val2;
197 struct cschkopts {
const char *opname;
int opval;} csopts[] =
204 int i, numopts =
sizeof(csopts)/
sizeof(
struct cschkopts);
207 if (! (val =
Config.GetWord()))
208 {m_log.Emsg(
"Config",
"cschk parameter not specified");
return false; }
212 if ((
isNo = strncmp(val,
"no", 2) == 0))
216 for (i = 0; i < numopts; i++)
218 if (!strcmp(val2, csopts[i].opname))
221 m_configuration.m_cs_Chk &= ~csopts[i].opval;
222 else if (csopts[i].opval)
223 m_configuration.m_cs_Chk |= csopts[i].opval;
225 m_configuration.m_cs_Chk = csopts[i].opval;
231 if (strcmp(val,
"uvkeep"))
233 m_log.Emsg(
"Config",
"invalid cschk option -", val);
236 if (!(val =
Config.GetWord()))
238 m_log.Emsg(
"Config",
"cschk uvkeep value not specified");
241 if (!strcmp(val,
"lru"))
242 m_configuration.m_cs_UVKeep = -1;
248 m_configuration.m_cs_UVKeep = uvkeep;
254 m_configuration.m_cs_ChkTLS = m_configuration.m_cs_Chk &
CSChk_TLS;
255 m_configuration.m_cs_Chk &= ~CSChk_TLS;
257 m_env->Put(
"psx.CSNet", m_configuration.is_cschk_net() ? (m_configuration.m_cs_ChkTLS ?
"2" :
"1") :
"0");
273bool Cache::xdlib(XrdOucStream &Config)
278 if (! (val =
Config.GetWord()) || ! val[0])
280 TRACE(Info,
" Cache::Config() decisionlib not specified; always caching files");
290 Config.GetRest(params, 4096);
294 XrdOucPinLoader* myLib =
new XrdOucPinLoader(&m_log, 0,
"decisionlib",
297 Decision *(*ep)(XrdSysError&);
298 ep = (Decision *(*)(XrdSysError&))myLib->
Resolve(
"XrdPfcGetDecision");
299 if (! ep) {myLib->
Unload(
true);
return false; }
301 Decision * d = ep(m_log);
304 TRACE(
Error,
"Config() decisionlib was not able to create a decision object");
308 d->ConfigDecision(params);
310 m_decisionpoints.push_back(d);
324bool Cache::xplib(XrdOucStream &Config)
329 if (! (val =
Config.GetWord()) || ! val[0])
331 TRACE(Info,
" Cache::Config() purgelib not specified; will use LRU for purging files");
341 Config.GetRest(params, 4096);
345 XrdOucPinLoader* myLib =
new XrdOucPinLoader(&m_log, 0,
"purgelib",
348 PurgePin *(*ep)(XrdSysError&);
349 ep = (PurgePin *(*)(XrdSysError&))myLib->
Resolve(
"XrdPfcGetPurgePin");
350 if (! ep) {myLib->
Unload(
true);
return false; }
352 PurgePin * dp = ep(m_log);
355 TRACE(
Error,
"Config() purgelib was not able to create a Purge Plugin object?");
361 m_purge_pin->ConfigPurgePin(params);
372bool Cache::xtrace(XrdOucStream &Config)
375 static struct traceopts {
const char *opname;
int opval; } tropts[] =
385 int numopts =
sizeof(tropts)/
sizeof(
struct traceopts);
387 if (! (val =
Config.GetWord()))
388 {m_log.Emsg(
"Config",
"trace option not specified");
return 1; }
390 for (
int i = 0; i < numopts; i++)
392 if (! strcmp(val, tropts[i].opname))
394 m_trace->What = tropts[i].opval;
398 m_log.Emsg(
"Config",
"invalid trace option -", val);
403bool Cache::test_oss_basics_and_features()
405 static const char *epfx =
"test_oss_basics_and_features()";
407 const auto &conf = m_configuration;
408 const char *user = conf.m_username.c_str();
411 auto check_space = [&](
const char *space,
bool &has_xattr)
413 std::string fname(
"__prerun_test_pfc_");
416 env.
Put(
"oss.cgroup", space);
418 int res = m_oss->Create(user, fname.c_str(), 0600, env,
XRDOSS_mkpath);
420 m_log.Emsg(epfx,
"Can not create a file on space", space);
423 XrdOssDF *oss_file = m_oss->newFile(user);
424 res = oss_file->
Open(fname.c_str(), O_RDWR, 0600, env);
426 m_log.Emsg(epfx,
"Can not open a file on space", space);
429 res = oss_file->
Write(fname.data(), 0, fname.length());
430 if (res != (
int) fname.length()) {
431 m_log.Emsg(epfx,
"Can not write into a file on space", space);
436 long long fsize = fname.length();
439 m_log.Emsg(epfx,
"Can not write xattr to a file on space", space);
447 m_oss->Lfn2Pfn(fname.c_str(), pfn, 4096);
450 if (res !=
sizeof(
long long) || fsize != (
long long) fname.length())
452 m_log.Emsg(epfx,
"Can not read xattr from a file on space", space);
457 res = m_oss->Unlink(fname.c_str());
459 m_log.Emsg(epfx,
"Can not unlink a file on space", space);
467 aOK &= check_space(conf.m_data_space.c_str(), m_dataXattr);
468 aOK &= check_space(conf.m_meta_space.c_str(), m_metaXattr);
482 const char *theINS = getenv(
"XRDINSTANCE");
483 m_isClient = (theINS != 0 && strncmp(
"*client ", theINS, 8) == 0);
489 XrdOucEnv *myEnv = env ? env : &emptyEnv;
493 if (! config_filename || ! *config_filename)
495 TRACE(
Error,
"Config() configuration file not specified.");
500 if ( (fd =
open(config_filename, O_RDONLY, 0)) < 0)
502 TRACE(
Error,
"Config() can't open configuration file " << config_filename);
507 static const char *cvec[] = {
"*** pfc plugin config:", 0 };
513 if (! ofsCfg)
return false;
522 m_configuration.m_bufferSize = 128 * 1024;
523 m_configuration.m_wqueue_blocks = 8;
524 m_configuration.m_wqueue_threads = 1;
528 if (m_configuration.is_cschk_net()) m_env->Put(
"psx.CSNet", m_configuration.m_cs_ChkTLS ?
"2" :
"1");
531 bool retval =
true, aOK =
true;
533 while ((var =
Config.GetMyFirstWord()))
535 if (! strcmp(var,
"pfc.osslib"))
539 else if (! strcmp(var,
"pfc.cschk"))
543 else if (! strcmp(var,
"pfc.decisionlib"))
547 else if (! strcmp(var,
"pfc.purgelib"))
551 else if (! strcmp(var,
"pfc.trace"))
555 else if (! strcmp(var,
"pfc.allow_xrdpfc_command"))
557 m_configuration.m_allow_xrdpfc_command =
true;
559 else if (! strncmp(var,
"pfc.", 4))
561 retval = ConfigParameters(std::string(var+4),
Config, tmpc);
574 auto orig_runmode = myEnv->
Get(
"oss.runmode");
575 myEnv->
Put(
"oss.runmode",
"pfc");
576 if (m_configuration.is_cschk_cache())
579 if (snprintf(csi_conf, 128,
"space=%s nofill", m_configuration.m_meta_space.c_str()) < 128)
583 TRACE(
Error,
"Config() buffer too small for libXrdOssCsi params.");
593 TRACE(
Error,
"Config() Unable to create an OSS object");
596 if (orig_runmode) myEnv->
Put(
"oss.runmode", orig_runmode);
597 else myEnv->
Put(
"oss.runmode",
"");
600 aOK &= test_oss_basics_and_features();
605 if (m_configuration.m_meta_space != m_configuration.m_data_space &&
606 m_oss->StatVS(&sP, m_configuration.m_meta_space.c_str(), 1) < 0)
608 m_log.Emsg(
"ConfigParameters()",
"error obtaining stat info for meta space ", m_configuration.m_meta_space.c_str());
611 if (m_configuration.m_meta_space != m_configuration.m_data_space && sP.
Total < 10ll << 20)
613 m_log.Emsg(
"ConfigParameters()",
"available data space is less than 10 MB (can be due to a mistake in oss.localroot directive) for space ",
614 m_configuration.m_meta_space.c_str());
617 if (m_oss->StatVS(&sP, m_configuration.m_data_space.c_str(), 1) < 0)
619 m_log.Emsg(
"ConfigParameters()",
"error obtaining stat info for data space ", m_configuration.m_data_space.c_str());
622 if (sP.
Total < 10ll << 20)
624 m_log.Emsg(
"ConfigParameters()",
"available data space is less than 10 MB (can be due to a mistake in oss.localroot directive) for space ",
625 m_configuration.m_data_space.c_str());
629 m_configuration.m_diskTotalSpace = sP.
Total;
631 if (cfg2bytes(tmpc.
m_diskUsageLWM, m_configuration.m_diskUsageLWM, sP.
Total,
"lowWatermark") &&
634 if (m_configuration.m_diskUsageLWM >= m_configuration.m_diskUsageHWM) {
635 m_log.Emsg(
"ConfigParameters()",
"pfc.diskusage should have lowWatermark < highWatermark.");
647 if (m_configuration.m_fileUsageBaseline >= m_configuration.m_fileUsageNominal ||
648 m_configuration.m_fileUsageBaseline >= m_configuration.m_fileUsageMax ||
649 m_configuration.m_fileUsageNominal >= m_configuration.m_fileUsageMax)
651 m_log.Emsg(
"ConfigParameters()",
"pfc.diskusage files should have baseline < nominal < max.");
656 if (aOK && m_configuration.m_fileUsageMax >= m_configuration.m_diskUsageLWM)
658 m_log.Emsg(
"ConfigParameters()",
"pfc.diskusage files values must be below lowWatermark");
672 &m_configuration.m_flushCnt,
673 100 * m_configuration.m_bufferSize , 100000 * m_configuration.m_bufferSize))
677 m_configuration.m_flushCnt /= m_configuration.m_bufferSize;
682 &m_configuration.m_flushCnt, 100, 100000))
690 if (m_configuration.m_RamAbsAvailable == 0)
692 m_configuration.m_RamAbsAvailable = m_isClient ? 256ll * 1024 * 1024 : 1024ll * 1024 * 1024;
694 snprintf(buff,
sizeof(buff),
"RAM usage pfc.ram is not specified. Default value %s is used.", m_isClient ?
"256m" :
"1g");
695 m_log.Say(
"Config info: ", buff);
698 m_configuration.m_RamKeepStdBlocks = (m_configuration.m_RamAbsAvailable / m_configuration.m_bufferSize + 1) * 5 / 100;
701 char* cenv = getenv(
"XRDDEBUG");
702 if (cenv && ! strcmp(cenv,
"1") && m_trace->What < 4) m_trace->What = 4;
707 const char *csc[] = {
"off",
"cache nonet",
"nocache net notls",
711 "off",
"cache nonet",
"nocache net tls",
715 if (m_configuration.m_cs_UVKeep < 0)
718 sprintf(uvk,
"%lld", (
long long) m_configuration.m_cs_UVKeep);
719 float ram_gb = (m_configuration.m_RamAbsAvailable) /
float(1024*1024*1024);
721 char urlcgi_blks[64] =
"ignore", urlcgi_npref[32] =
"ignore";
723 snprintf(urlcgi_blks,
sizeof(urlcgi_blks),
"%lldk %lldk",
726 snprintf(urlcgi_npref,
sizeof(urlcgi_npref),
"%d %d",
729 snprintf_wrapper cfg_printf(
"XrdPfc::Cache::Config print effective configuration", 8192);
731 cfg_printf(
"Config effective %s pfc configuration:\n"
732 " pfc.cschk %s uvkeep %s\n"
733 " pfc.blocksize %lldk\n"
735 " pfc.urlcgi blocksize %s prefetch %s\n"
737 " pfc.writequeue %d %d\n"
738 " # Total available disk: %lld\n"
739 " pfc.diskusage %lld %lld files %lld %lld %lld purgeinterval %d purgecoldfiles %d\n"
740 " pfc.spaces %s %s\n"
743 " pfc.acchistorysize %d\n"
744 " pfc.onlyIfCachedMinBytes %lld\n"
745 " pfc.onlyIfCachedMinFrac %.2f\n",
747 csc[
int(m_configuration.m_cs_Chk)], uvk,
748 m_configuration.m_bufferSize >> 10,
749 m_configuration.m_prefetch_max_blocks,
750 urlcgi_blks, urlcgi_npref,
752 m_configuration.m_wqueue_blocks, m_configuration.m_wqueue_threads,
754 m_configuration.m_diskUsageLWM, m_configuration.m_diskUsageHWM,
755 m_configuration.m_fileUsageBaseline, m_configuration.m_fileUsageNominal, m_configuration.m_fileUsageMax,
756 m_configuration.m_purgeInterval, m_configuration.m_purgeColdFilesAge,
757 m_configuration.m_data_space.c_str(),
758 m_configuration.m_meta_space.c_str(),
760 m_configuration.m_flushCnt,
761 m_configuration.m_accHistorySize,
762 m_configuration.m_onlyIfCachedMinSize,
763 m_configuration.m_onlyIfCachedMinFrac);
765 if (m_configuration.is_dir_stat_reporting_on())
767 cfg_printf(
" pfc.dirstats interval %d maxdepth %d (internal: size_of_dirlist %d, size_of_globlist %d)\n",
768 m_configuration.m_dirStatsInterval, m_configuration.m_dirStatsStoreDepth,
769 (
int) m_configuration.m_dirStatsDirs.size(), (
int) m_configuration.m_dirStatsDirGlobs.size());
770 cfg_printf(
" dirlist:\n");
771 for (std::set<std::string>::iterator i = m_configuration.m_dirStatsDirs.begin(); i != m_configuration.m_dirStatsDirs.end(); ++i)
772 cfg_printf(
" %s\n", i->c_str());
773 cfg_printf(
" globlist:\n");
774 for (std::set<std::string>::iterator i = m_configuration.m_dirStatsDirGlobs.begin(); i != m_configuration.m_dirStatsDirGlobs.end(); ++i)
775 cfg_printf(
" %s/*\n", i->c_str());
778 if (m_configuration.m_hdfsmode)
780 cfg_printf(
" pfc.hdfsmode hdfsbsize %lld\n", m_configuration.m_hdfsbsize);
783 cfg_printf(
" pfc.writethrough %s\n", m_configuration.m_write_through ?
"on" :
"off");
785 if (m_configuration.m_username.empty())
789 m_configuration.m_username = unameBuff;
793 cfg_printf(
" pfc.user %s\n", m_configuration.m_username.c_str());
796 if (m_configuration.m_httpcc)
798 cfg_printf(
" pfc.httpcc on\n");
800 if (m_configuration.m_qfsredir)
802 cfg_printf(
" pfc.qfsredir on\n");
805 m_log.Say(cfg_printf.
c_str());
807 m_env->Put(
"XRDPFC.SEGSIZE", std::to_string(m_configuration.m_bufferSize).c_str());
816 m_log.Say(
" pfc g-stream has", m_gstream ?
"" :
" NOT",
" been configured via xrootd.monitor directive\n");
822 m_res_mon->init_before_main();
825 m_log.Say(
"=====> Proxy file cache configuration parsing ", aOK ?
"completed" :
"failed");
827 if (ofsCfg)
delete ofsCfg;
831#ifdef XRDPFC_CKSUM_TEST
833 int xxx = m_configuration.m_cs_Chk;
835 for (m_configuration.m_cs_Chk =
CSChk_None; m_configuration.m_cs_Chk <=
CSChk_Both; ++m_configuration.m_cs_Chk)
837 Info::TestCksumStuff();
840 m_configuration.m_cs_Chk = xxx;
851 struct ConfWordGetter
856 ConfWordGetter(
XrdOucStream& c) : m_config(c), m_last_word((char*)1) {}
858 const char* GetWord() {
if (HasLast()) m_last_word = m_config.
GetWord();
return HasLast() ? m_last_word :
""; }
859 bool HasLast() {
return (m_last_word != 0); }
862 ConfWordGetter cwg(config);
864 Configuration &CFG = m_configuration;
866 if ( part ==
"user" )
868 m_configuration.m_username = cwg.GetWord();
869 if ( ! cwg.HasLast())
871 m_log.Emsg(
"Config",
"Error: pfc.user requires a parameter.");
875 else if ( part ==
"diskusage" )
882 m_log.Emsg(
"Config",
"Error: pfc.diskusage parameter requires at least two arguments.");
887 while ((p = cwg.GetWord()) && cwg.HasLast())
889 if (strcmp(p,
"files") == 0)
895 if ( ! cwg.HasLast())
897 m_log.Emsg(
"Config",
"Error: pfc.diskusage files directive requires three arguments.");
901 else if (strcmp(p,
"sleep") == 0 || strcmp(p,
"purgeinterval") == 0)
903 if (strcmp(p,
"sleep") == 0) m_log.Emsg(
"Config",
"warning sleep directive is deprecated in pfc.diskusage. Please use purgeinterval instead.");
905 if (
XrdOuca2x::a2tm(m_log,
"Error getting purgeinterval", cwg.GetWord(), &m_configuration.m_purgeInterval, 60, 3600))
910 else if (strcmp(p,
"purgecoldfiles") == 0)
912 if (
XrdOuca2x::a2tm(m_log,
"Error getting purgecoldfiles age", cwg.GetWord(), &m_configuration.m_purgeColdFilesAge, 3600, 3600*24*360))
916 if (
XrdOuca2x::a2i(m_log,
"Error getting purgecoldfiles period", cwg.GetWord(), &m_configuration.m_purgeAgeBasedPeriod, 1, 1000))
923 m_log.Emsg(
"Config",
"Error: diskusage stanza contains unknown directive", p);
927 else if ( part ==
"acchistorysize" )
929 if (
XrdOuca2x::a2i(m_log,
"Error getting access-history-size", cwg.GetWord(), &m_configuration.m_accHistorySize, 20, 200))
934 else if ( part ==
"dirstats" )
937 while ((p = cwg.GetWord()) && cwg.HasLast())
939 if (strcmp(p,
"interval") == 0)
941 int validIntervals[] = {60, 120, 300, 600, 900, 1200, 1800, 3600};
942 int size =
sizeof(validIntervals) /
sizeof(
int);
944 if (
XrdOuca2x::a2tm(m_log,
"Error getting dirstsat interval", cwg.GetWord(),
945 &m_configuration.m_dirStatsInterval, validIntervals[0], validIntervals[size - 1]))
949 bool match =
false, round_down =
false;
950 for (
int i = 0; i < size; i++) {
951 if (validIntervals[i] == m_configuration.m_dirStatsInterval) {
955 if (i > 0 && m_configuration.m_dirStatsInterval < validIntervals[i]) {
956 m_configuration.m_dirStatsInterval = validIntervals[i - 1];
961 if ( ! match && ! round_down) {
962 m_log.Emsg(
"Config",
"Error: dirstat interval parsing failed.");
966 m_log.Emsg(
"Config",
"Info: dirstat interval was rounded down to the nearest valid value.");
970 else if (strcmp(p,
"maxdepth") == 0)
972 if (
XrdOuca2x::a2i(m_log,
"Error getting maxdepth value", cwg.GetWord(),
973 &m_configuration.m_dirStatsStoreDepth, 0, 16))
978 else if (strcmp(p,
"dir") == 0)
981 if (p && p[0] ==
'/')
985 char d[1024]; d[0] = 0;
993 if (*(pd - 1) ==
'/')
1005 if (*pd ==
'/' && pd != d) *pd = 0;
1008 if (ld >= 2 && d[ld-1] ==
'*' && d[ld-2] ==
'/')
1012 m_configuration.m_dirStatsDirGlobs.insert(d);
1013 printf(
"Glob %s -> %s -- depth = %d\n", p, d, depth);
1017 m_configuration.m_dirStatsDirs.insert(d);
1018 printf(
"Dir %s -> %s -- depth = %d\n", p, d, depth);
1021 m_configuration.m_dirStatsStoreDepth = std::max(m_configuration.m_dirStatsStoreDepth, depth);
1025 m_log.Emsg(
"Config",
"Error: dirstats dir parameter requires a directory argument starting with a '/'.");
1031 m_log.Emsg(
"Config",
"Error: dirstats stanza contains unknown directive '", p,
"'");
1036 else if ( part ==
"blocksize" )
1039 CFG.s_min_bufferSize, CFG.s_max_bufferSize))
1042 else if ( part ==
"prefetch" || part ==
"nramprefetch" )
1044 if (part ==
"nramprefetch")
1046 m_log.Emsg(
"Config",
"pfc.nramprefetch is deprecated, please use pfc.prefetch instead. Replacing the directive internally.");
1050 0, CFG.s_max_prefetch_max_blocks))
1053 else if ( part ==
"urlcgi" )
1057 while ((p = cwg.GetWord()) && cwg.HasLast())
1059 if (strcmp(p,
"blocksize") == 0)
1061 std::string bmin = cwg.GetWord();
1062 if (bmin ==
"ignore")
1064 std::string bmax = cwg.GetWord();
1065 if ( ! cwg.HasLast()) {
1066 m_log.Emsg(
"Config",
"Error: pfc.urlcgi blocksize parameter requires two arguments.");
1070 CFG.s_min_bufferSize, CFG.s_max_bufferSize))
1073 CFG.s_min_bufferSize, CFG.s_max_bufferSize))
1075 if (CFG.m_cgi_min_bufferSize > CFG.m_cgi_max_bufferSize) {
1076 m_log.Emsg(
"Config",
"Error: pfc.urlcgi blocksize second argument must be larger or equal to the first one.");
1079 CFG.m_cgi_blocksize_allowed =
true;
1081 else if (strcmp(p,
"prefetch") == 0)
1083 std::string bmin = cwg.GetWord();
1084 if (bmin ==
"ignore")
1086 std::string bmax = cwg.GetWord();
1087 if ( ! cwg.HasLast()) {
1088 m_log.Emsg(
"Config",
"Error: pfc.urlcgi blocksize parameter requires two arguments.");
1091 if ( !
prefetch_str2value(
"Config::urlcgi", bmin.c_str(), CFG.m_cgi_min_prefetch_max_blocks,
1092 0, CFG.s_max_prefetch_max_blocks))
1094 if ( !
prefetch_str2value(
"Config::urlcgi", bmax.c_str(), CFG.m_cgi_max_prefetch_max_blocks,
1095 0, CFG.s_max_prefetch_max_blocks))
1097 if (CFG.m_cgi_min_prefetch_max_blocks > CFG.m_cgi_max_prefetch_max_blocks) {
1098 m_log.Emsg(
"Config",
"Error: pfc.urlcgi prefetch second argument must be larger or equal to the first one.");
1101 CFG.m_cgi_prefetch_allowed =
true;
1105 m_log.Emsg(
"Config",
"Error: urlcgi stanza contains unknown directive '", p,
"'");
1110 else if ( part ==
"nramread" )
1112 m_log.Emsg(
"Config",
"pfc.nramread is deprecated, please use pfc.ram instead. Ignoring this directive.");
1115 else if ( part ==
"ram" )
1117 long long minRAM = m_isClient ? 256 * 1024 * 1024 : 1024 * 1024 * 1024;
1118 long long maxRAM = 256 * minRAM;
1119 if (
XrdOuca2x::a2sz(m_log,
"get RAM available", cwg.GetWord(), &m_configuration.m_RamAbsAvailable, minRAM, maxRAM))
1124 else if ( part ==
"writequeue")
1126 if (
XrdOuca2x::a2i(m_log,
"Error getting pfc.writequeue num-blocks", cwg.GetWord(), &m_configuration.m_wqueue_blocks, 1, 1024))
1130 if (
XrdOuca2x::a2i(m_log,
"Error getting pfc.writequeue num-threads", cwg.GetWord(), &m_configuration.m_wqueue_threads, 1, 64))
1135 else if ( part ==
"spaces" )
1137 m_configuration.m_data_space = cwg.GetWord();
1138 m_configuration.m_meta_space = cwg.GetWord();
1139 if ( ! cwg.HasLast())
1141 m_log.Emsg(
"Config",
"spacenames requires two parameters: <data-space> <metadata-space>.");
1145 else if ( part ==
"hdfsmode" )
1147 m_log.Emsg(
"Config",
"pfc.hdfsmode is currently unsupported.");
1150 m_configuration.m_hdfsmode =
true;
1152 const char* params = cwg.GetWord();
1155 if (! strncmp(
"hdfsbsize", params, 9))
1157 long long minBlSize = 32 * 1024;
1158 long long maxBlSize = 128 * 1024 * 1024;
1159 if (
XrdOuca2x::a2sz(m_log,
"Error getting file fragment size", cwg.GetWord(), &m_configuration.m_hdfsbsize, minBlSize, maxBlSize))
1166 m_log.Emsg(
"Config",
"Error setting the fragment size parameter name");
1171 else if ( part ==
"writethrough" )
1173 const char *val = cwg.GetWord();
1174 if (!val || !cwg.HasLast())
1176 m_log.Emsg(
"Config",
"Error: pfc.writethrough requires a parameter.");
1180 if (strncmp(val,
"on", 2) == 0) {
1181 m_configuration.m_write_through =
true;
1182 }
else if (strncmp(val,
"off", 3) == 0) {
1183 m_configuration.m_write_through =
false;
1185 m_log.Emsg(
"ConfigParameters()",
1186 "Unknown value for pfc.writethrough:", val,
"(valid values are 'on' or 'off')");
1190 else if ( part ==
"flush" )
1193 if ( ! cwg.HasLast())
1195 m_log.Emsg(
"Config",
"Error: pfc.flush requires a parameter.");
1199 else if ( part ==
"onlyifcached" )
1202 while ((p = cwg.GetWord()) && cwg.HasLast())
1204 if (strcmp(p,
"minsize") == 0)
1206 std::string minBytes = cwg.GetWord();
1207 long long minBytesTop = 1024 * 1024 * 1024;
1208 if (::isalpha(*(minBytes.rbegin())))
1210 if (
XrdOuca2x::a2sz(m_log,
"Error in parsing minsize value for onlyifcached parameter", minBytes.c_str(), &m_configuration.m_onlyIfCachedMinSize, 0, minBytesTop))
1217 if (
XrdOuca2x::a2ll(m_log,
"Error in parsing numeric minsize value for onlyifcached parameter", minBytes.c_str(),&m_configuration.m_onlyIfCachedMinSize, 0, minBytesTop))
1223 if (strcmp(p,
"minfrac") == 0)
1225 std::string minFrac = cwg.GetWord();
1228 double frac = strtod(minFrac.c_str(), &eP);
1229 if (errno || eP == minFrac.c_str())
1231 m_log.Emsg(
"Config",
"Error setting fraction for only-if-cached directive");
1234 m_configuration.m_onlyIfCachedMinFrac = frac;
1238 m_log.Emsg(
"Config",
"Error: onlyifcached stanza contains unknown directive", p);
1242 else if ( part ==
"httpcc" )
1244 const char* val = cwg.GetWord();
1245 if (!strcmp(val,
"on")) {
1246 m_configuration.m_httpcc =
true;
1248 else if (strcmp(val,
"off")) {
1249 m_log.Emsg(
"Config",
"Error: httpcc pramater can only have values [off|on]", val);
1252 else if ( part ==
"qfsredir" )
1254 const char* val = cwg.GetWord();
1255 if (!strcmp(val,
"on")) {
1256 m_configuration.m_qfsredir =
true;
1258 else if (!strcmp(val,
"off")) {
1259 m_configuration.m_qfsredir =
false;
1263 m_log.Emsg(
"Config",
"Error: qfsredir pramater can only have values [off|on]", val);
1269 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 prefetch_str2value(const char *from, const char *str, int &val, int min, int max) const
bool Config(const char *config_filename, const char *parameters, XrdOucEnv *env)
Parse configuration file.
bool blocksize_str2value(const char *from, const char *str, long long &val, long long min, long long max) const
static size_t s_maxNumAccess
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
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
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
static const size_t s_MAX_SIZE
snprintf_wrapper(const std::string &exc_prefix, int size=1024)
const char * c_str() const
void operator()(const char *fmt,...)
std::vector< char > f_string