17 #include "XrdVersion.hh"
27 m_allow_xrdpfc_command(false),
28 m_data_space(
"public"),
29 m_meta_space(
"public"),
33 m_fileUsageBaseline(-1),
34 m_fileUsageNominal(-1),
37 m_purgeColdFilesAge(-1),
38 m_purgeAgeBasedPeriod(10),
40 m_dirStatsMaxDepth(-1),
41 m_dirStatsStoreDepth(0),
42 m_bufferSize(128*1024),
44 m_RamKeepStdBlocks(0),
47 m_prefetch_max_blocks(10),
48 m_hdfsbsize(128*1024*1024),
53 m_onlyIfCachedMinSize(1024*1024),
54 m_onlyIfCachedMinFrac(1.0)
58 bool Cache::cfg2bytes(
const std::string &str,
long long &store,
long long totalSpace,
const char *name)
61 snprintf(errStr, 1024,
"ConfigParameters() Error parsing parameter %s", name);
63 if (::isalpha(*(str.rbegin())))
74 double frac = strtod(str.c_str(), &eP);
75 if (errno || eP == str.c_str())
77 m_log.
Emsg(errStr, str.c_str());
81 store =
static_cast<long long>(totalSpace * frac + 0.5);
84 if (store < 0 || store > totalSpace)
86 snprintf(errStr, 1024,
"ConfigParameters() Error: parameter %s should be between 0 and total available disk space (%lld) - it is %lld (given as %s)",
87 name, totalSpace, store, str.c_str());
88 m_log.
Emsg(errStr,
"");
116 const char *val, *val2;
117 struct cschkopts {
const char *opname;
int opval;} csopts[] =
124 int i, numopts =
sizeof(csopts)/
sizeof(
struct cschkopts);
127 if (! (val =
Config.GetWord()))
128 {m_log.
Emsg(
"Config",
"cschk parameter not specified");
return false; }
132 if ((
isNo = strncmp(val,
"no", 2) == 0))
136 for (i = 0; i < numopts; i++)
138 if (!strcmp(val2, csopts[i].opname))
141 m_configuration.
m_cs_Chk &= ~csopts[i].opval;
142 else if (csopts[i].opval)
143 m_configuration.
m_cs_Chk |= csopts[i].opval;
145 m_configuration.
m_cs_Chk = csopts[i].opval;
151 if (strcmp(val,
"uvkeep"))
153 m_log.
Emsg(
"Config",
"invalid cschk option -", val);
156 if (!(val =
Config.GetWord()))
158 m_log.
Emsg(
"Config",
"cschk uvkeep value not specified");
161 if (!strcmp(val,
"lru"))
174 m_configuration.m_cs_ChkTLS = m_configuration.m_cs_Chk &
CSChk_TLS;
177 m_env->Put(
"psx.CSNet", m_configuration.is_cschk_net() ? (m_configuration.m_cs_ChkTLS ?
"2" :
"1") :
"0");
198 if (! (val =
Config.GetWord()) || ! val[0])
200 TRACE(
Info,
" Cache::Config() decisionlib not specified; always caching files");
210 Config.GetRest(params, 4096);
219 if (! ep) {myLib->
Unload(
true);
return false; }
224 TRACE(
Error,
"Config() decisionlib was not able to create a decision object");
230 m_decisionpoints.push_back(d);
249 if (! (val =
Config.GetWord()) || ! val[0])
251 TRACE(
Info,
" Cache::Config() purgelib not specified; will use LRU for purging files");
261 Config.GetRest(params, 4096);
270 if (! ep) {myLib->
Unload(
true);
return false; }
275 TRACE(
Error,
"Config() purgelib was not able to create a Purge Plugin object?");
295 static struct traceopts {
const char *opname;
int opval; } tropts[] =
305 int numopts =
sizeof(tropts)/
sizeof(
struct traceopts);
307 if (! (val =
Config.GetWord()))
308 {m_log.
Emsg(
"Config",
"trace option not specified");
return 1; }
310 for (
int i = 0; i < numopts; i++)
312 if (! strcmp(val, tropts[i].opname))
314 m_trace->
What = tropts[i].opval;
318 m_log.
Emsg(
"Config",
"invalid trace option -", val);
332 const char *theINS = getenv(
"XRDINSTANCE");
333 m_isClient = (theINS != 0 && strncmp(
"*client ", theINS, 8) == 0);
341 if (! config_filename || ! *config_filename)
343 TRACE(
Error,
"Config() configuration file not specified.");
348 if ( (fd =
open(config_filename, O_RDONLY, 0)) < 0)
350 TRACE(
Error,
"Config() can't open configuration file " << config_filename);
355 static const char *cvec[] = {
"*** pfc plugin config:", 0 };
361 if (! ofsCfg)
return false;
377 bool retval =
true, aOK =
true;
379 while ((var =
Config.GetMyFirstWord()))
381 if (! strcmp(var,
"pfc.osslib"))
385 else if (! strcmp(var,
"pfc.cschk"))
389 else if (! strcmp(var,
"pfc.decisionlib"))
393 else if (! strcmp(var,
"pfc.purgelib"))
397 else if (! strcmp(var,
"pfc.trace"))
401 else if (! strcmp(var,
"pfc.allow_xrdpfc_command"))
405 else if (! strncmp(var,
"pfc.", 4))
407 retval = ConfigParameters(std::string(var+4),
Config, tmpc);
420 myEnv.
Put(
"oss.runmode",
"pfc");
424 if (snprintf(csi_conf, 128,
"space=%s nofill", m_configuration.
m_meta_space.c_str()) < 128)
428 TRACE(
Error,
"Config() buffer too small for libXrdOssCsi params.");
438 TRACE(
Error,
"Config() Unable to create an OSS object");
448 m_log.
Emsg(
"ConfigParameters()",
"error obtaining stat info for meta space ", m_configuration.
m_meta_space.c_str());
453 m_log.
Emsg(
"ConfigParameters()",
"available data space is less than 10 MB (can be due to a mistake in oss.localroot directive) for space ",
459 m_log.
Emsg(
"ConfigParameters()",
"error obtaining stat info for data space ", m_configuration.
m_data_space.c_str());
462 if (sP.
Total < 10ll << 20)
464 m_log.
Emsg(
"ConfigParameters()",
"available data space is less than 10 MB (can be due to a mistake in oss.localroot directive) for space ",
475 m_log.
Emsg(
"ConfigParameters()",
"pfc.diskusage should have lowWatermark < highWatermark.");
491 m_log.
Emsg(
"ConfigParameters()",
"pfc.diskusage files should have baseline < nominal < max.");
498 m_log.
Emsg(
"ConfigParameters()",
"pfc.diskusage files values must be below lowWatermark");
531 m_configuration.
m_RamAbsAvailable = m_isClient ? 256ll * 1024 * 1024 : 1024ll * 1024 * 1024;
533 snprintf(buff,
sizeof(buff),
"RAM usage pfc.ram is not specified. Default value %s is used.", m_isClient ?
"256m" :
"1g");
534 m_log.
Say(
"Config info: ", buff);
541 char* cenv = getenv(
"XRDDEBUG");
542 if (cenv && ! strcmp(cenv,
"1") && m_trace->
What < 4) m_trace->
What = 4;
548 const char *csc[] = {
"off",
"cache nonet",
"nocache net notls",
552 "off",
"cache nonet",
"nocache net tls",
555 char buff[8192], uvk[32];
559 sprintf(uvk,
"%lld", (
long long) m_configuration.
m_cs_UVKeep);
561 loff = snprintf(buff,
sizeof(buff),
"Config effective %s pfc configuration:\n"
562 " pfc.cschk %s uvkeep %s\n"
563 " pfc.blocksize %lld\n"
566 " pfc.writequeue %d %d\n"
567 " # Total available disk: %lld\n"
568 " pfc.diskusage %lld %lld files %lld %lld %lld purgeinterval %d purgecoldfiles %d\n"
569 " pfc.spaces %s %s\n"
572 " pfc.acchistorysize %d\n"
573 " pfc.onlyIfCachedMinBytes %lld\n"
574 " pfc.onlyIfCachedMinFrac %.2f\n",
576 csc[
int(m_configuration.
m_cs_Chk)], uvk,
595 loff += snprintf(buff + loff,
sizeof(buff) - loff,
596 " pfc.dirstats maxdepth %d ((internal: store_depth %d, size_of_dirlist %d, size_of_globlist %d))\n",
599 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" dirlist:\n");
601 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" %s\n", i->c_str());
602 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" globlist:\n");
604 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" %s/*\n", i->c_str());
609 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" pfc.hdfsmode hdfsbsize %lld\n", m_configuration.
m_hdfsbsize);
620 loff += snprintf(buff + loff,
sizeof(buff) - loff,
" pfc.user %s\n", m_configuration.
m_username.c_str());
625 m_env->
Put(
"XRDPFC.SEGSIZE", std::to_string(m_configuration.
m_bufferSize).c_str());
634 m_log.
Say(
" pfc g-stream has", m_gstream ?
"" :
" NOT",
" been configured via xrootd.monitor directive\n");
643 m_log.
Say(
"=====> Proxy file cache configuration parsing ", aOK ?
"completed" :
"failed");
645 if (ofsCfg)
delete ofsCfg;
649 #ifdef XRDPFC_CKSUM_TEST
655 Info::TestCksumStuff();
669 struct ConfWordGetter
674 ConfWordGetter(
XrdOucStream& c) : m_config(c), m_last_word((char*)1) {}
676 const char* GetWord() {
if (HasLast()) m_last_word = m_config.
GetWord();
return HasLast() ? m_last_word :
""; }
677 bool HasLast() {
return (m_last_word != 0); }
680 ConfWordGetter cwg(config);
683 if ( part ==
"user" )
686 if ( ! cwg.HasLast())
688 m_log.
Emsg(
"Config",
"Error: pfc.user requires a parameter.");
692 else if ( part ==
"diskusage" )
699 m_log.
Emsg(
"Config",
"Error: pfc.diskusage parameter requires at least two arguments.");
704 while ((p = cwg.GetWord()) && cwg.HasLast())
706 if (strcmp(p,
"files") == 0)
712 if ( ! cwg.HasLast())
714 m_log.
Emsg(
"Config",
"Error: pfc.diskusage files directive requires three arguments.");
718 else if (strcmp(p,
"sleep") == 0 || strcmp(p,
"purgeinterval") == 0)
720 if (strcmp(p,
"sleep") == 0) m_log.
Emsg(
"Config",
"warning sleep directive is deprecated in pfc.diskusage. Please use purgeinterval instead.");
727 else if (strcmp(p,
"purgecoldfiles") == 0)
740 m_log.
Emsg(
"Config",
"Error: diskusage stanza contains unknown directive", p);
744 else if ( part ==
"acchistorysize" )
751 else if ( part ==
"dirstats" )
754 while ((p = cwg.GetWord()) && cwg.HasLast())
756 if (strcmp(p,
"maxdepth") == 0)
764 else if (strcmp(p,
"dir") == 0)
767 if (p && p[0] ==
'/')
771 char d[1024]; d[0] = 0;
779 if (*(pd - 1) ==
'/')
791 if (*pd ==
'/' && pd != d) *pd = 0;
794 if (ld >= 2 && d[ld-1] ==
'*' && d[ld-2] ==
'/')
799 printf(
"Glob %s -> %s -- depth = %d\n", p, d, depth);
804 printf(
"Dir %s -> %s -- depth = %d\n", p, d, depth);
811 m_log.
Emsg(
"Config",
"Error: dirstats dir parameter requires a directory argument starting with a '/'.");
817 m_log.
Emsg(
"Config",
"Error: dirstats stanza contains unknown directive '", p,
"'");
822 else if ( part ==
"blocksize" )
824 long long minBSize = 4 * 1024;
825 long long maxBSize = 512 * 1024 * 1024;
834 m_log.
Emsg(
"Config",
"pfc.blocksize must be a multiple of 4 kB. Rounded up.");
837 else if ( part ==
"prefetch" || part ==
"nramprefetch" )
839 if (part ==
"nramprefetch")
841 m_log.
Emsg(
"Config",
"pfc.nramprefetch is deprecated, please use pfc.prefetch instead. Replacing the directive internally.");
850 else if ( part ==
"nramread" )
852 m_log.
Emsg(
"Config",
"pfc.nramread is deprecated, please use pfc.ram instead. Ignoring this directive.");
855 else if ( part ==
"ram" )
857 long long minRAM = m_isClient ? 256 * 1024 * 1024 : 1024 * 1024 * 1024;
858 long long maxRAM = 256 * minRAM;
864 else if ( part ==
"writequeue")
875 else if ( part ==
"spaces" )
879 if ( ! cwg.HasLast())
881 m_log.
Emsg(
"Config",
"spacenames requires two parameters: <data-space> <metadata-space>.");
885 else if ( part ==
"hdfsmode" )
887 m_log.
Emsg(
"Config",
"pfc.hdfsmode is currently unsupported.");
892 const char* params = cwg.GetWord();
895 if (! strncmp(
"hdfsbsize", params, 9))
897 long long minBlSize = 32 * 1024;
898 long long maxBlSize = 128 * 1024 * 1024;
899 if (
XrdOuca2x::a2sz(m_log,
"Error getting file fragment size", cwg.GetWord(), &m_configuration.
m_hdfsbsize, minBlSize, maxBlSize))
906 m_log.
Emsg(
"Config",
"Error setting the fragment size parameter name");
911 else if ( part ==
"flush" )
914 if ( ! cwg.HasLast())
916 m_log.
Emsg(
"Config",
"Error: pfc.flush requires a parameter.");
920 else if ( part ==
"onlyifcached" )
923 while ((p = cwg.GetWord()) && cwg.HasLast())
925 if (strcmp(p,
"minsize") == 0)
927 std::string minBytes = cwg.GetWord();
928 long long minBytesTop = 1024 * 1024 * 1024;
929 if (::isalpha(*(minBytes.rbegin())))
944 if (strcmp(p,
"minfrac") == 0)
946 std::string minFrac = cwg.GetWord();
949 double frac = strtod(minFrac.c_str(), &eP);
950 if (errno || eP == minFrac.c_str())
952 m_log.
Emsg(
"Config",
"Error setting fraction for only-if-cached directive");
959 m_log.
Emsg(
"Config",
"Error: onlyifcached stanza contains unknown directive", p);
965 m_log.
Emsg(
"ConfigParameters() unmatched pfc parameter", part.c_str());
XrdVERSIONINFO(XrdOucGetCache, XrdPfc)
XrdOucCache * XrdOucGetCache(XrdSysLogger *logger, const char *config_filename, const char *parameters, XrdOucEnv *env)
int open(const char *path, int oflag,...)
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 StatVS(XrdOssVSInfo *vsP, const char *sname=0, int updt=0)
static int Export(const char *Var, const char *Val)
void * GetPtr(const char *varname)
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 Config(const char *config_filename, const char *parameters)
Parse configuration file.
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.
static size_t s_maxNumAccess
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)
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)
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
int m_accHistorySize
max number of entries in access history part of cinfo file
int m_wqueue_threads
number of threads writing blocks to disk
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
depth to which statistics should be collected
bool m_allow_xrdpfc_command
flag for enabling access to /xrdpfc-command/ functionality.
long long m_diskUsageHWM
cache purge - disk usage high water mark
bool is_cschk_cache() const
std::set< std::string > m_dirStatsDirGlobs
directory globs for which stat reporting was requested
int m_prefetch_max_blocks
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_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
std::set< std::string > m_dirStatsDirs
directories for which stat reporting was requested
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
prefetch buffer size, default 1MB
std::string m_meta_space
oss space for metadata files (cinfo)
int m_wqueue_blocks
maximum number of blocks written per write-queue loop
std::string m_username
username passed to oss plugin
bool is_cschk_net() const
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_dirStatsMaxDepth
maximum depth for statistics write out
int m_purgeInterval
sleep interval between cache purges
long long m_onlyIfCachedMinSize
minumum size of downloaded file, used by only-if-cached CGI option
bool is_dir_stat_reporting_on() const
std::string m_diskUsageLWM
std::string m_diskUsageHWM
std::string m_fileUsageBaseline
std::string m_fileUsageNominal
std::string m_fileUsageMax