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