XRootD
Loading...
Searching...
No Matches
XrdOfsConfig.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d O f s C o n f i g . c c */
4/* */
5/* (C) 2010 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Deprtment of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31#include <unistd.h>
32#include <cctype>
33#include <cerrno>
34#include <fcntl.h>
35#include <netdb.h>
36#include <cstdlib>
37#include <string>
38#include <strings.h>
39#include <cstdio>
40#include <netinet/in.h>
41#include <vector>
42#include <sys/param.h>
43#include <sys/stat.h>
44
45#include "XrdVersion.hh"
47
48#include "XrdCks/XrdCks.hh"
49
50#include "XrdNet/XrdNetUtils.hh"
51
52#include "XrdSfs/XrdSfsFlags.hh"
53
54#include "XrdOfs/XrdOfs.hh"
58#include "XrdOfs/XrdOfsEvs.hh"
60#include "XrdOfs/XrdOfsPoscq.hh"
61#include "XrdOfs/XrdOfsStats.hh"
62#include "XrdOfs/XrdOfsTPC.hh"
64#include "XrdOfs/XrdOfsTrace.hh"
65
66#include "XrdOss/XrdOss.hh"
67
68#include "XrdOuc/XrdOuca2x.hh"
69#include "XrdOuc/XrdOucEnv.hh"
73#include "XrdOuc/XrdOucUtils.hh"
74
75#include "XrdSys/XrdSysError.hh"
77
78#include "XrdNet/XrdNetAddr.hh"
79
82#include "XrdCms/XrdCmsRole.hh"
83
85
86/******************************************************************************/
87/* G l o b a l O b j e c t s */
88/******************************************************************************/
89
91
93
94extern XrdOfs* XrdOfsFS;
95
96class XrdOss;
97extern XrdOss *XrdOfsOss;
98
99class XrdScheduler;
101
103
105{
106extern XrdOfsTPCConfig Cfg;
107}
108
109namespace
110{
111int SetMode(const char *path, mode_t mode) {return chmod(path, mode);}
112
113std::vector<std::string> csList; // Configured checksums
114}
115
116/******************************************************************************/
117/* d e f i n e s */
118/******************************************************************************/
119
120#define TS_Xeq(x,m) if (!strcmp(x,var)) return m(Config,Eroute);
121
122#define TS_XPI(x,m) if (!strcmp(x,var))\
123 return !ofsConfig->Parse(XrdOfsConfigPI:: m);
124
125#define TS_Str(x,m) if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;}
126
127#define TS_PList(x,m) if (!strcmp(x,var)) \
128 {m.Insert(new XrdOucPList(val,1)); return 0;}
129
130#define TS_Chr(x,m) if (!strcmp(x,var)) {m = val[0]; return 0;}
131
132#define TS_Bit(x,m,v) if (!strcmp(x,var)) {m |= v; Config.Echo(); return 0;}
133
134#define Max(x,y) (x > y ? x : y)
135
136/******************************************************************************/
137/* g e t V e r s i o n */
138/******************************************************************************/
139
140const char *XrdOfs::getVersion() {return XrdVERSION;}
141
142/******************************************************************************/
143/* C o n f i g u r e */
144/******************************************************************************/
145
146int XrdOfs::Configure(XrdSysError &Eroute) {return Configure(Eroute, 0);}
147
149/*
150 Function: Establish default values using a configuration file.
151
152 Input: None.
153
154 Output: 0 upon success or !0 otherwise.
155*/
156 char *var;
157 const char *tmp;
158 int cfgFD, retc, NoGo = 0;
159 XrdOucEnv myEnv;
160 XrdOucStream Config(&Eroute, getenv("XRDINSTANCE"), &myEnv, "=====> ");
161
162// Print warm-up message
163//
164 Eroute.Say("++++++ File system initialization started.");
165
166// Start off with no POSC log. Note that XrdSfsGetDefaultFileSystem nakes sure
167// that we are configured only once.
168//
169 poscLog = NULL;
170
171// Establish the network interface that the caller must provide
172//
173 if (!EnvInfo || !(myIF = (XrdNetIF *)EnvInfo->GetPtr("XrdNetIF*")))
174 {Eroute.Emsg("Finder", "Network i/f undefined; unable to self-locate.");
175 NoGo = 1;
176 }
177 ofsSchedP = (XrdScheduler *)EnvInfo->GetPtr("XrdScheduler*");
178
179// Preset all variables with common defaults
180//
181 Options = 0;
182 if (getenv("XRDDEBUG")) OfsTrace.What = TRACE_MOST | TRACE_debug;
183
184// Allocate a our plugin configurator
185//
186 ofsConfig = XrdOfsConfigPI::New(ConfigFN, &Config, &Eroute, 0, this);
187
188// If there is no config file, return with the defaults sets.
189//
190 if( !ConfigFN || !*ConfigFN)
191 Eroute.Emsg("Config", "Configuration file not specified.");
192 else {
193 // Try to open the configuration file.
194 //
195 if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
196 return Eroute.Emsg("Config", errno, "open config file",
197 ConfigFN);
198 Config.Attach(cfgFD);
199 static const char *cvec[] = {"*** ofs plugin config:",0};
200 Config.Capture(cvec);
201
202 // Now start reading records until eof.
203 //
204 while((var = Config.GetMyFirstWord()))
205 {if (!strncmp(var, "ofs.", 4)
206 || !strcmp(var, "all.role")
207 || !strcmp(var, "all.subcluster"))
208 {if (ConfigXeq(var+4,Config,Eroute)) {Config.Echo();NoGo=1;}}
209 else if (!strcmp(var, "oss.defaults")
210 || !strcmp(var, "all.export"))
211 {xexp(Config, Eroute, *var == 'a');
212 Config.noEcho();
213 }
214 }
215
216 // Now check if any errors occurred during file i/o
217 //
218 if ((retc = Config.LastError()))
219 NoGo = Eroute.Emsg("Config", -retc, "read config file",
220 ConfigFN);
221 Config.Close();
222 }
223
224// If no exports were specified, the default is that we are writable
225//
226 if (ossRW == ' ') ossRW = 'w';
227
228// Adjust the umask to correspond to the maximum mode allowed
229//
230 mode_t uMask = 0777 & (~(dMask[1] | fMask[1]));
231 umask(uMask);
232
233// Export our role if we actually have one
234//
235 if (myRole) XrdOucEnv::Export("XRDROLE", myRole);
236
237// Set the redirect option for other layers
238//
239 if (Options & isManager)
240 XrdOucEnv::Export("XRDREDIRECT", (Options & isMeta ? "M" : "R"));
241 else XrdOucEnv::Export("XRDREDIRECT", "0");
242
243// If we are a proxy, then figure out where the prosy storge system resides
244//
245 if ((Options & isProxy) && !(Options & isManager))
246 {char buff[2048], *bp, *libofs = getenv("XRDOFSLIB");
247 if (!libofs) bp = buff;
248 else {strcpy(buff, libofs); bp = buff+strlen(buff)-1;
249 while(bp != buff && *(bp-1) != '/') bp--;
250 }
251 strcpy(bp, "libXrdPss.so");
252 ofsConfig->Default(XrdOfsConfigPI::theOssLib, buff, 0);
253 ofsConfig->Default(XrdOfsConfigPI::theCksLib, buff, 0);
254 }
255
256// Configure third party copy but only if we are not a manager. Phase 1 needs
257// to be done before we load the plugins as they may need this info.
258//
259 if ((Options & ThirdPC) && !(Options & isManager))
260 NoGo |= ConfigTPC(Eroute, EnvInfo);
261
262// We need to do pre-initialization for event recording as the oss needs some
263// environmental information from that initialization to initialize the frm,
264// should it need to be used. We will do full evr initialization after the oss
265// and the finder are initialized. A bit messy in the current plug-in world.
266//
267 if (!(Options & isManager) && !evrObject.Init(&Eroute)) NoGo = 1;
268
269// Determine whether we should load authorization
270//
271 int piOpts = XrdOfsConfigPI::allXXXLib;
272 if (!(Options & Authorize)) piOpts &= ~XrdOfsConfigPI::theAutLib;
273
274// We need to export plugins to other protocols which means we need to
275// record them in the outmost environment. So get it.
276//
277 XrdOucEnv *xrdEnv = 0;
278 if (EnvInfo) xrdEnv = (XrdOucEnv*)EnvInfo->GetPtr("xrdEnv*");
279
280// Now load all of the required plugins
281//
282 if (!ofsConfig->Load(piOpts, EnvInfo)) NoGo = 1;
283 else {ofsConfig->Plugin(XrdOfsOss);
284 ossFeatures = XrdOfsOss->Features();
285 if (ossFeatures & XRDOSS_HASNOSF) FeatureSet |= XrdSfs::hasNOSF;
286 if (ossFeatures & XRDOSS_HASCACH)
288 if (xrdEnv) xrdEnv->Put("XrdCache", "T"); // Existence check
289 }
290 if (ossFeatures & XRDOSS_HASNAIO) FeatureSet |= XrdSfs::hasNAIO;
291 if (ossFeatures & XRDOSS_HASFICL) FeatureSet |= XrdSfs::hasFICL;
292 if (ossFeatures & XRDOSS_HASXERT) tryXERT = true;
293 if (xrdEnv) xrdEnv->PutPtr("XrdOss*", XrdOfsOss);
294 ofsConfig->Plugin(Cks);
295 CksPfn = !ofsConfig->OssCks();
296 CksRdr = !ofsConfig->LclCks();
297 if (ofsConfig->Plugin(prepHandler))
298 {prepAuth = ofsConfig->PrepAuth();
300 }
301 if (Options & Authorize)
302 {ofsConfig->Plugin(Authorization);
303 XrdOfsTPC::Init(Authorization);
304 if (xrdEnv) xrdEnv->PutPtr("XrdAccAuthorize*",Authorization);
306 }
307 }
308
309// If a cache has been configured then that cache may want to interact with
310// the cache-specific FSctl() operation. We check if a plugin was provided.
311//
312 if (ossFeatures & XRDOSS_HASCACH)
313 FSctl_PC = (XrdOfsFSctl_PI*)EnvInfo->GetPtr("XrdFSCtl_PC*");
314
315// Configure third party copy phase 2, but only if we are not a manager.
316//
317 if ((Options & ThirdPC) && !(Options & isManager)) NoGo |= ConfigTPC(Eroute);
318
319// Extract out the export list should it have been supplied by the oss plugin
320//
321 ossRPList = (XrdOucPListAnchor *)EnvInfo->GetPtr("XrdOssRPList*");
322
323// Initialize redirection. We type te herald here to minimize confusion
324//
325 if (Options & haveRole)
326 {Eroute.Say("++++++ Configuring ", myRole, " role. . .");
327 if (ConfigRedir(Eroute, EnvInfo))
328 {Eroute.Emsg("Config", "Unable to create cluster management client.");
329 NoGo = 1;
330 }
331 }
332
333// Initialize the FSctl plugin if we have one. Note that we needed to defer
334// until now because we needed to configure the cms plugin first (see above).
335//
336 if (ofsConfig->Plugin(FSctl_PI) && !ofsConfig->ConfigCtl(Finder, EnvInfo))
337 {Eroute.Emsg("Config", "Unable to configure FSctl plugin.");
338 NoGo = 1;
339 }
340
341// Initialize the cache FSctl handler if we have one. The same deferal applies.
342//
343 if (FSctl_PC)
344 {struct XrdOfsFSctl_PI::Plugins thePI = {Authorization, Finder,
346 XrdOucEnv pcEnv;
347 pcEnv.PutPtr("XrdOfsHandle*", dummyHandle);
348 if (!FSctl_PC->Configure(ConfigFN, 0, &pcEnv, thePI))
349 {Eroute.Emsg("Config", "Unable to configure cache FSctl handler.");
350 NoGo = 1;
351 }
352 }
353
354// Initialize th Evr object if we are an actual server
355//
356 if (!(Options & isManager) && !evrObject.Init(Balancer)) NoGo = 1;
357
358// Turn off forwarding if we are not a pure remote redirector or a peer
359//
360 if (Options & Forwarding)
361 {const char *why = 0;
362 if (!(Options & Authorize)) why = "authorization not enabled";
363 else if (!(Options & isPeer) && (Options & (isServer | isProxy)))
364 why = "not a pure manager";
365 if (why)
366 {Eroute.Say("Config warning: forwarding turned off; ", why);
367 Options &= ~(Forwarding);
368 fwdCHMOD.Reset(); fwdMKDIR.Reset(); fwdMKPATH.Reset();
369 fwdMV.Reset(); fwdRM.Reset(); fwdRMDIR.Reset();
370 fwdTRUNC.Reset();
371 }
372 }
373
374// If we need to send notifications, initialize the interface
375//
376 if (!NoGo && evsObject) NoGo = evsObject->Start(&Eroute);
377
378// If the OSS plugin is really a proxy. If it is, it will export its origin.
379// We also suppress translating lfn to pfn (usually done via osslib +cksio).
380// Note: consulting the ENVAR below is historic and remains for compatibility
381// Otherwise we can configure checkpointing if we are a data server.
382//
383 if (ossFeatures & XRDOSS_HASPRXY || getenv("XRDXROOTD_PROXY"))
384 {OssIsProxy = 1;
385 CksPfn = false;
387 } else if (!(Options & isManager) && !XrdOfsConfigCP::Init()) NoGo = 1;
388
389// Indicate wheter oss implements pgrw or it has to be simulated
390//
391 OssHasPGrw = (ossFeatures & XRDOSS_HASPGRW) != 0;
392
393// If POSC processing is enabled (as by default) do it. Warning! This must be
394// the last item in the configuration list as we need a working filesystem.
395// Note that in proxy mode we always disable posc!
396//
397 if (OssIsProxy || getenv("XRDXROOTD_NOPOSC"))
398 {if (poscAuto != -1 && !NoGo)
399 Eroute.Say("Config POSC has been disabled by the osslib plugin.");
400 } else if (poscAuto != -1 && !NoGo) NoGo |= ConfigPosc(Eroute);
401
402// Configure realtime checksums if need be
403//
404 if (CksRTCgi || CksRTName) NoGo |= ConfigCksRT(Eroute, EnvInfo);
405
406// Setup statistical monitoring
407//
408 OfsStats.setRole(myRole);
409
410// Display final configuration
411//
412 if (!NoGo) Config_Display(Eroute);
413 delete ofsConfig; ofsConfig = 0;
414
415// All done
416//
417 tmp = (NoGo ? " initialization failed." : " initialization completed.");
418 Eroute.Say("------ File system ", myRole, tmp);
419 return NoGo;
420}
421
422/******************************************************************************/
423/* C o n f i g _ D i s p l a y */
424/******************************************************************************/
425
426#define setBuff(x,y) {strcpy(bp, x); bp += y;}
427
429{
430 const char *cloc, *pval;
431 char buff[8192], fwbuff[512], *bp;
432 int i;
433
434 if (!ConfigFN || !ConfigFN[0]) cloc = "default";
435 else cloc = ConfigFN;
436 if (!poscQ) pval = "off";
437 else pval = (poscAuto ? "auto" : "manual");
438
439 snprintf(buff, sizeof(buff), "Config effective %s ofs configuration:\n"
440 " all.role %s\n"
441 "%s"
442 " ofs.maxdelay %d\n"
443 " ofs.persist %s hold %d%s%s\n"
444 " ofs.trace %x",
445 cloc, myRole,
446 (Options & Authorize ? " ofs.authorize\n" : ""),
447 MaxDelay,
448 pval, poscHold, (poscLog ? " logdir " : ""),
449 (poscLog ? poscLog : ""), OfsTrace.What);
450
451 Eroute.Say(buff);
452
453 if (CksRTCgi || CksRTName)
454 {snprintf(buff, sizeof(buff), " ofs.cksrt auto %s%s",
455 (CksRTName ? CksRTName:"none"),(CksRTCgi ? " chkcgi":""));
456 Eroute.Say(buff);
457 }
458
459 ofsConfig->Display();
460
461 if (Options & Forwarding)
462 {*fwbuff = 0;
463 if (ConfigDispFwd(buff, fwdCHMOD))
464 {Eroute.Say(buff); strcat(fwbuff, " ch");}
465 if (ConfigDispFwd(buff, fwdMKDIR))
466 {Eroute.Say(buff); strcat(fwbuff, " mk");}
467 if (ConfigDispFwd(buff, fwdMV))
468 {Eroute.Say(buff); strcat(fwbuff, " mv");}
469 if (ConfigDispFwd(buff, fwdRM))
470 {Eroute.Say(buff); strcat(fwbuff, " rm");}
471 if (ConfigDispFwd(buff, fwdRMDIR))
472 {Eroute.Say(buff); strcat(fwbuff, " rd");}
473 if (ConfigDispFwd(buff, fwdTRUNC))
474 {Eroute.Say(buff); strcat(fwbuff, " tr");}
475 if (*fwbuff) XrdOucEnv::Export("XRDOFS_FWD", fwbuff);
476 }
477
478 if (evsObject)
479 {bp = buff;
480 setBuff(" ofs.notify ", 18); // 1234567890
481 if (evsObject->Enabled(XrdOfsEvs::Chmod)) setBuff("chmod ", 6);
482 if (evsObject->Enabled(XrdOfsEvs::Closer)) setBuff("closer ", 7);
483 if (evsObject->Enabled(XrdOfsEvs::Closew)) setBuff("closew ", 7);
484 if (evsObject->Enabled(XrdOfsEvs::Create)) setBuff("create ", 7);
485 if (evsObject->Enabled(XrdOfsEvs::Mkdir)) setBuff("mkdir ", 6);
486 if (evsObject->Enabled(XrdOfsEvs::Mv)) setBuff("mv ", 3);
487 if (evsObject->Enabled(XrdOfsEvs::Openr)) setBuff("openr ", 6);
488 if (evsObject->Enabled(XrdOfsEvs::Openw)) setBuff("openw ", 6);
489 if (evsObject->Enabled(XrdOfsEvs::Rm)) setBuff("rm ", 3);
490 if (evsObject->Enabled(XrdOfsEvs::Rmdir)) setBuff("rmdir ", 6);
491 if (evsObject->Enabled(XrdOfsEvs::Trunc)) setBuff("trunc ", 6);
492 if (evsObject->Enabled(XrdOfsEvs::Fwrite)) setBuff("fwrite ", 7);
493 setBuff("msgs ", 5);
494 i=sprintf(fwbuff,"%d %d ",evsObject->maxSmsg(),evsObject->maxLmsg());
495 setBuff(fwbuff, i);
496 cloc = evsObject->Prog();
497 if (*cloc != '>') setBuff("|",1);
498 setBuff(cloc, strlen(cloc));
499 setBuff("\0", 1);
500 Eroute.Say(buff);
501 }
502}
503
504/******************************************************************************/
505/* p r i v a t e f u n c t i o n s */
506/******************************************************************************/
507/******************************************************************************/
508/* C o n f i g C k s R T */
509/******************************************************************************/
510
511int XrdOfs::ConfigCksRT(XrdSysError &Eroute, XrdOucEnv* envP)
512{
513 const char *why = 0;
514 const char *csSpec = 0;
515
516// Check if the directive is applicable to us
517//
518 if (OssIsProxy) why = "not applicable to proxies";
519 else if (Options & isManager) why = "not applicable to managers";
520 else if (!Cks || !(csSpec = envP->Get("csList")))
521 why = "checksums not configured";
522 if (why)
523 {Eroute.Say("Config warning: Ignoring cksrt directive ", why);
524 if (CksRTName) {free(CksRTName); CksRTName = 0;}
525 CksRTCgi = false;
526 return 0;
527 }
528
529// Construct the list of supported checksums
530//
531 XrdOucTUtils::splitString(csList, csSpec, " ");
532 if (csList.size() == 0)
533 {Eroute.Say("Config failure: Unable to determine configured cheksums!");
534 return 1;
535 }
536
537// Configure the automatic checksum if applicable
538//
539 if (CksRTName)
540 {if (!strcmp(CksRTName, "default"))
541 {free(CksRTName);
542 CksRTName = strdup(csList[0].c_str());
543 }
544
545 if (!(CksRTCalc = Cks->Object(CksRTName)))
546 {Eroute.Say("Config failure: cksrt auto ", CksRTName,
547 " checksum either non-native or not configured!");
548 return 1;
549 }
550 }
551
552// Success
553//
554 XrdOfsCksFile::Init(Cks, envP);
555 return 0;
556}
557
558/******************************************************************************/
559/* C o n f i g D i s p F w d */
560/******************************************************************************/
561
562int XrdOfs::ConfigDispFwd(char *buff, struct fwdOpt &Fwd)
563{
564 const char *cP;
565 char pbuff[16], *bp;
566
567// Return if this is not being forwarded
568//
569 if (!(cP = Fwd.Cmd)) return 0;
570 bp = buff;
571 setBuff(" ofs.forward ", 19);
572
573// Chck which way this is being forwarded
574//
575 if (*Fwd.Cmd == '+'){setBuff("2way ",5); cP++;}
576 else if (!Fwd.Port) {setBuff("1way ",5);}
577 else { setBuff("3way ",5);
578 if (Fwd.Port < 0) {setBuff("local ",6);}
579 else {int n = sprintf(pbuff, ":%d ", Fwd.Port);
580 setBuff(Fwd.Host, strlen(Fwd.Host));
581 setBuff(pbuff, n);
582 }
583 }
584 setBuff(cP, strlen(cP));
585 return 1;
586}
587
588/******************************************************************************/
589/* C o n f i g P o s c */
590/******************************************************************************/
591
592int XrdOfs::ConfigPosc(XrdSysError &Eroute)
593{
594 extern XrdOfs* XrdOfsFS;
595 const int AMode = S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH; // 775
596 class CloseFH : public XrdOfsHanCB
597 {public: void Retired(XrdOfsHandle *hP) {XrdOfsFS->Unpersist(hP);}};
598 static XrdOfsHanCB *hCB = static_cast<XrdOfsHanCB *>(new CloseFH);
599
600 XrdOfsPoscq::recEnt *rP, *rPP;
601 XrdOfsPoscq::Request *qP;
602 XrdOfsHandle *hP;
603 const char *iName;
604 char pBuff[MAXPATHLEN], *aPath;
605 int NoGo, rc;
606
607// Construct the proper path to the recovery file
608//
609 iName = XrdOucUtils::InstName(-1);
610 if (poscLog) aPath = XrdOucUtils::genPath(poscLog, iName, ".ofs/posc.log");
611 else {if (!(aPath = getenv("XRDADMINPATH")))
612 {XrdOucUtils::genPath(pBuff, MAXPATHLEN, "/tmp", iName);
613 aPath = pBuff;
614 }
615 aPath = XrdOucUtils::genPath(aPath, (char *)0, ".ofs/posc.log");
616 }
617 rc = strlen(aPath)-1;
618 if (aPath[rc] == '/') aPath[rc] = '\0';
619 free(poscLog); poscLog = aPath;
620
621// Make sure directory path exists
622//
623 if ((rc = XrdOucUtils::makePath(poscLog, AMode)))
624 {Eroute.Emsg("Config", rc, "create path for", poscLog);
625 return 1;
626 }
627
628// Create object then initialize it
629//
630 poscQ = new XrdOfsPoscq(&Eroute, XrdOfsOss, poscLog, int(poscSync));
631 rP = poscQ->Init(rc);
632 if (!rc) return 1;
633
634// Get file handles and put then in pending delete for all recovered records
635//
636 NoGo = 0;
637 while(rP)
638 {qP = &(rP->reqData);
639 if (qP->addT && poscHold)
641 {Eroute.Emsg("Config", "Unable to persist", qP->User, qP->LFN);
642 qP->addT = 0;
643 } else {
644 hP->PoscSet(qP->User, rP->Offset, rP->Mode);
645 hP->Retire(hCB, poscHold);
646 }
647 }
648 if (!(qP->addT) || !poscHold)
649 {if ((rc = XrdOfsOss->Unlink(qP->LFN)) && rc != -ENOENT)
650 {Eroute.Emsg("Config", rc, "unpersist", qP->LFN); NoGo = 1;}
651 else {Eroute.Emsg("Config", "Unpersisted", qP->User, qP->LFN);
652 poscQ->Del(qP->LFN, rP->Offset);
653 }
654 }
655 rPP = rP; rP = rP->Next; delete rPP;
656 }
657
658// All done
659//
660 if (!NoGo) FeatureSet |= XrdSfs::hasPOSC;
661 return NoGo;
662}
663
664/******************************************************************************/
665/* C o n f i g R e d i r */
666/******************************************************************************/
667
668int XrdOfs::ConfigRedir(XrdSysError &Eroute, XrdOucEnv *EnvInfo)
669{
670 XrdCmsClient_t CmsPI;
671 XrdSysLogger *myLogger = Eroute.logger();
672 int isRedir = Options & isManager;
673 int RMTopts = (Options & isServer ? XrdCms::IsTarget : 0)
675 | (Options & isMeta ? XrdCms::IsMeta : 0);
676 int TRGopts = (Options & isProxy ? XrdCms::IsProxy : 0)
677 | (isRedir ? XrdCms::IsRedir : 0) | XrdCms::IsTarget;
678
679// Get the cms object creator plugin
680//
681 ofsConfig->Plugin(CmsPI);
682
683// For manager roles, we simply do a standard config
684//
685 if (isRedir)
686 { if (CmsPI) Finder = CmsPI(myLogger, RMTopts, myPort, XrdOfsOss);
687 else if (XrdCmsFinderRMT::VCheck(XrdVERSIONINFOVAR(XrdOfs)))
688 Finder = (XrdCmsClient *)new XrdCmsFinderRMT(myLogger,
689 RMTopts,myPort);
690 else return 1;
691 if (!Finder) return 1;
692 if (!ofsConfig->Configure(Finder, EnvInfo))
693 {delete Finder; Finder = 0; return 1;}
694 if (EnvInfo) EnvInfo->PutPtr("XRDCMSMANLIST", Finder->Managers());
695 }
696
697// If we are a subcluster for another cluster then we can only be so if we
698// are a pure manager. If a subcluster directive was encountered and this is
699// not true we need to turn that off here. Subclusters need a target finder
700// just like supervisors eventhough we are not a supervisor.
701//
703
704// For server roles find the port number and create the object. We used to pass
705// the storage system object to the finder to allow it to process cms storage
706// requests. The cms no longer sends such requests so there is no need to do
707// so. And, in fact, we need to defer creating a storage system until after the
708// finder is created. So, it's just as well we pass a numm pointer. At some
709// point the finder should remove all storage system related code.
710//
711 if (Options & (isServer | SubCluster | (isPeer & ~isManager)))
712 {if (!myPort)
713 {Eroute.Emsg("Config", "Unable to determine server's port number.");
714 return 1;
715 }
716 if (CmsPI) Balancer = CmsPI(myLogger, TRGopts, myPort, XrdOfsOss);
717 else if (XrdCmsFinderTRG::VCheck(XrdVERSIONINFOVAR(XrdOfs)))
718 Balancer = (XrdCmsClient *)new XrdCmsFinderTRG(myLogger,
719 TRGopts,myPort);
720 else return 1;
721 if (!Balancer) return 1;
722 if (!ofsConfig->Configure(Balancer, EnvInfo))
723 {delete Balancer; Balancer = 0; return 1;}
724 if (Options & (isProxy | SubCluster))
725 Balancer = 0; // No chatting for proxies or subclusters
726 }
727
728// All done
729//
730 return 0;
731}
732
733/******************************************************************************/
734/* C o n f i g T P C */
735/******************************************************************************/
736
737
738int XrdOfs::ConfigTPC(XrdSysError &Eroute, XrdOucEnv *envP)
739{
740 XrdOfsTPCConfig &Cfg = XrdOfsTPCParms::Cfg;
741
742// Check if we need to configure rge credentials directory
743//
744 if (Cfg.fCreds)
745 {char *cpath = Cfg.cPath;
746 if (!(Cfg.cPath = ConfigTPCDir(Eroute, ".ofs/.tpccreds/", cpath)))
747 return 1;
748 free(cpath);
749 }
750
751// Construct the reproxy path. We always do this as need to solve the cart-horse
752// problem of plugin loading. If we don't need it it will be ignored later.
753//
754 if (!(Cfg.rPath = ConfigTPCDir(Eroute, ".ofs/.tpcproxy"))) return 1;
755 if (envP) envP->Put("tpc.rpdir", Cfg.rPath);
756
757// Check if TPC monitoring is wanted and set it up
758//
759 Cfg.tpcMon = (XrdXrootdTpcMon*)envP->GetPtr("TpcMonitor*");
760
761// All done
762//
763 return 0;
764}
765
766/******************************************************************************/
767
768int XrdOfs::ConfigTPC(XrdSysError &Eroute)
769{
770 XrdOfsTPCConfig &Cfg = XrdOfsTPCParms::Cfg;
771
772// If the oss plugin does not use a reproxy then remove it from the TPC config.
773// Otherwise, complete it.
774//
775 if (ossFeatures & XRDOSS_HASRPXY && Cfg.rPath)
776 {char rPBuff[1024];
777 reProxy = true;
778 snprintf(rPBuff,sizeof(rPBuff),"%s/%x-%%d.rpx",Cfg.rPath,int(time(0)));
779 free(Cfg.rPath);
780 Cfg.rPath = strdup(rPBuff);
781 } else {
782 if (Cfg.rPath) free(Cfg.rPath);
783 Cfg.rPath = 0;
784 }
785
786// Initialize the TPC object
787//
789
790// Start TPC operations
791//
792 return (XrdOfsTPC::Start() ? 0 : 1);
793}
794/******************************************************************************/
795/* C o n f i g T P C D i r */
796/******************************************************************************/
797
798char *XrdOfs::ConfigTPCDir(XrdSysError &Eroute, const char *sfx,
799 const char *xPath)
800{
801
802 const int AMode = S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH; // 775
803 const int BMode = S_IRWXU| S_IRGRP|S_IXGRP; // 750
805 const char *iName;
806 char pBuff[MAXPATHLEN], *aPath;
807 int rc;
808
809// Construct the proper path to stored credentials
810//
811 iName = XrdOucUtils::InstName(-1);
812 if (xPath) aPath = XrdOucUtils::genPath(xPath, iName, sfx);
813 else {if (!(aPath = getenv("XRDADMINPATH")))
814 {XrdOucUtils::genPath(pBuff, MAXPATHLEN, "/tmp", iName);
815 aPath = pBuff;
816 }
817 aPath = XrdOucUtils::genPath(aPath, (char *)0, sfx);
818 }
819
820// Make sure directory path exists
821//
822 if ((rc = XrdOucUtils::makePath(aPath, AMode)))
823 {Eroute.Emsg("Config", rc, "create TPC path", aPath);
824 free(aPath);
825 return 0;
826 }
827
828// Protect the last component
829//
830 if (SetMode(aPath, BMode))
831 {Eroute.Emsg("Config", errno, "protect TPC path", aPath);
832 free(aPath);
833 return 0;
834 }
835
836// list the contents of the directory
837//
838 XrdOucNSWalk nsWalk(&Eroute, aPath, 0, nswOpt);
839 XrdOucNSWalk::NSEnt *nsX, *nsP = nsWalk.Index(rc);
840 if (rc)
841 {Eroute.Emsg("Config", rc, "list TPC path", aPath);
842 free(aPath);
843 return 0;
844 }
845
846// Remove directory contents of all files
847//
848 bool isBad = false;
849 while((nsX = nsP))
850 {nsP = nsP->Next;
851 if (unlink(nsX->Path))
852 {Eroute.Emsg("Config", errno, "remove TPC creds", nsX->Path);
853 isBad = true;
854 }
855 delete nsX;
856 }
857
858// Check if all went well
859//
860 if (isBad) {free(aPath); return 0;}
861
862// All done
863//
864 return aPath;
865}
866
867/******************************************************************************/
868/* C o n f i g X e q */
869/******************************************************************************/
870
871int XrdOfs::ConfigXeq(char *var, XrdOucStream &Config,
872 XrdSysError &Eroute)
873{
874 char *val, vBuff[64];
875
876 // Now assign the appropriate global variable
877 //
878 TS_Bit("authorize", Options, Authorize);
879 TS_XPI("authlib", theAutLib);
880 TS_XPI("ckslib", theCksLib);
881 TS_Xeq("cksrt", xcksrt);
882 TS_Xeq("cksrdsz", xcrds);
883 TS_XPI("cmslib", theCmsLib);
884 TS_Xeq("crmode", xcrm);
885 TS_XPI("ctllib", theCtlLib);
886 TS_Xeq("dirlist", xdirl);
887 TS_Xeq("forward", xforward);
888 TS_Xeq("maxdelay", xmaxd);
889 TS_Xeq("notify", xnot);
890 TS_Xeq("notifymsg", xnmsg);
891 TS_XPI("osslib", theOssLib);
892 TS_Xeq("persist", xpers);
893 TS_XPI("preplib", thePrpLib);
894 TS_Xeq("role", xrole);
895 TS_Xeq("tpc", xtpc);
896 TS_Xeq("trace", xtrace);
897 TS_Xeq("xattr", xatr);
898 TS_XPI("xattrlib", theAtrLib);
899
900 // Process miscellaneous directives handled elsemwhere
901 //
902 if (!strcmp("chkpnt", var)) return (XrdOfsConfigCP::Parse(Config) ? 0 : 1);
903
904 // Screen out the subcluster directive (we need to track that)
905 //
906 TS_Bit("subcluster",Options,SubCluster);
907
908 // Get the actual value for simple directives
909 //
910 strlcpy(vBuff, var, sizeof(vBuff)); var = vBuff;
911 if (!(val = Config.GetWord()))
912 {Eroute.Emsg("Config", "value not specified for", var); return 1;}
913
914 // No match found, complain.
915 //
916 Eroute.Say("Config warning: ignoring unknown directive '",var,"'.");
917 Config.Echo();
918 return 0;
919}
920
921/******************************************************************************/
922/* V a l i d C S T */
923/******************************************************************************/
924
925bool XrdOfs::ValidCST(const char* cst)
926{
927 std::string csWant(cst);
928
929// Check if checksum type is in the list of valid ones. The list is short.
930//
931 if (csList.size())
932 {for (const auto& name : csList)
933 {if (name == csWant) return true;}
934 }
935 return false;
936}
937
938/******************************************************************************/
939/* x c k s r t */
940/******************************************************************************/
941
942/* Function: xcksrt
943
944 Purpose: To parse the directive: cksrt [auto <cipher>] [chkcgi]
945
946 auto Specifies that realtime checksums be automatically
947 computed using the specified cipher. If cgi is allowed
948 and specified, the cipher in the cgi is used. Specifying
949 'auto none' or 'auto off', disables automatic real-time
950 checksums, this is the default. Specifying 'auto default'
951 uses the default checksum speciied by the xrootd.chksum
952 directive.
953
954 chkcgi A realtime checksum can be request using the cgi element
955 "cks.type=<cipher>" on the open request URL, where <cipher>
956 is the desired checksum cipher to use. If the cipher is
957 not supported for use the open() call fails. Note that
958 it must have been allowed by the xrootd.chksum directive.
959
960 Output: 0 upon success or !0 upon failure.
961
962 Notes: Checksums must have been configured for this directive to take
963 effect.
964*/
965
966int XrdOfs::xcksrt(XrdOucStream &Config, XrdSysError &Eroute)
967{
968 char *val;
969 bool cgi = false, spec = false;
970
971// Initialize the defaults
972//
973 CksRTCgi = false;
974 if (CksRTName) {free(CksRTName); CksRTName = 0;}
975
976// Process the options
977//
978 while ((val = Config.GetWord()) && *val)
979 {spec = true;
980 if (!strcmp(val, "auto"))
981 {if (!(val = Config.GetWord()) || *val == '\0')
982 {Eroute.Emsg("Config", "cksrt auto cipher not specified.");
983 return 1;
984 }
985 if (CksRTName) {free(CksRTName); CksRTName = 0;}
986 if (strcmp(val, "none") && strcmp(val, "off"))
987 CksRTName = strdup(val);
988 continue;
989 }
990 if (!strcmp(val, "chkcgi")) {cgi = true; continue;}
991
992 Eroute.Emsg("Config", "Inavlid cksrt parameter -", val);
993 return 1;
994 }
995
996// Verify that we encountered some kind of parameter
997//
998 if (!spec)
999 {Eroute.Emsg("Config", "No cksrt parameters specified!"); return 1;}
1000
1001// Finish up
1002//
1003 if (cgi) CksRTCgi = cgi;
1004 return 0;
1005}
1006
1007/******************************************************************************/
1008/* x c r d s */
1009/******************************************************************************/
1010
1011/* Function: xcrds
1012
1013 Purpose: To parse the directive: cksrdsz <size>
1014
1015 <size> number of bytes to segment reads when calclulating a
1016 checksum. Can be suffixed by k,m,g. Maximum is 1g and
1017 is automatically set to be atleast 64k and to be a
1018 multiple of 64k.
1019
1020 Output: 0 upon success or !0 upon failure.
1021*/
1022
1023int XrdOfs::xcrds(XrdOucStream &Config, XrdSysError &Eroute)
1024{
1025 static const long long maxRds = 1024*1024*1024;
1026 char *val;
1027 long long rdsz;
1028
1029// Get the size
1030//
1031 if (!(val = Config.GetWord()) || !val[0])
1032 {Eroute.Emsg("Config", "cksrdsz size not specified"); return 1;}
1033
1034// Now convert it
1035//
1036 if (XrdOuca2x::a2sz(Eroute, "cksrdsz size", val, &rdsz, 1, maxRds)) return 1;
1037 ofsConfig->SetCksRdSz(static_cast<int>(rdsz));
1038
1039// This value is also used for real-time checksum rereads. However, while
1040// minimum is 64K the maximum is set to 2MB. Also in 64K units.
1041//
1043 return 0;
1044}
1045
1046/******************************************************************************/
1047/* x c r m */
1048/******************************************************************************/
1049
1050/* Function: xcrm
1051
1052 Purpose: To parse the directive: crmode [dirs <mspec>] [files <mspec>]
1053
1054 <mspec>: common | legacy | [raw] <modes>
1055
1056 common uses dirs 0700:0755 and files 0600:0644
1057
1058 legacy uses dirs 0000:0775 and files 0000:0775
1059
1060 raw Allows actual specification of mode bits without enforcing
1061 default requirements. The resulting modes may not be 0.
1062 Otherwise, the specified values are made consistent with
1063 the default mode settings.
1064
1065 <modes>: <minv> | :<maxv> | <minv>:<maxv>
1066
1067 <minv>: The minimum mode value required (always set), see <mval>.
1068 <maxv>: The maximum mode value to be enforced, see <mval>.
1069
1070 <mval> is either an octal mode specifiation or a standard ls type
1071 mode specification (i.e. 'rwx'). The specification is in
1072 groups of 3 letters. The first group designates user mode,
1073 the scond group mode, and the last other mode. To disallow
1074 a mode specify a dash. Note that for files, the 'x'
1075 character must be a dash unless raw mode is enabled. It is
1076 impossible to disllow any mode for user except for raw mode.
1077
1078 Output: 0 upon success or !0 upon failure.
1079*/
1080
1081int XrdOfs::xcrm(XrdOucStream &Config, XrdSysError &Eroute)
1082{
1083 static const mode_t dMin = 0700, dMax = 0775, fMin = 0600, fMax = 0664;
1084 static const mode_t xBit = 0111, wBit = 0002;
1085 const char *mtype;
1086 char *colon, *val, *minM, *maxM;
1087 mode_t mMask[2];
1088 bool isDirs, isRaw;
1089
1090// Get the size
1091//
1092 if (!(val = Config.GetWord()) || !val[0])
1093 {Eroute.Emsg("Config", "crmode argument not specified"); return 1;}
1094
1095// Process all of the specs
1096//
1097do{if (!strcmp("dirs", val)) {isDirs = true; mtype = "dirs mode";}
1098 else if (!strcmp("files", val)) {isDirs = false; mtype = "files mode";}
1099 else {Eroute.Emsg("Config", "invalid mode type - ", val);
1100 return 1;
1101 }
1102
1103 if (!(val = Config.GetWord()) || !val[0])
1104 {Eroute.Emsg("Config", mtype, "value not specified"); return 1;}
1105
1106 if (!strcmp(val, "common"))
1107 {if (isDirs) {dMask[0] = dMin; dMask[1] = dMax;}
1108 else {fMask[0] = fMin; fMask[1] = fMax;}
1109 continue;
1110 }
1111
1112 if (!strcmp(val, "legacy"))
1113 {if (isDirs) {dMask[0] = 0; dMask[1] = 0775;}
1114 else {fMask[0] = 0; fMask[1] = 0775;}
1115 continue;
1116 }
1117
1118 if ((isRaw = !strcmp(val, "raw")))
1119 {if (!(val = Config.GetWord()) || !val[0])
1120 {Eroute.Emsg("Config", mtype, "value not specified"); return 1;}
1121 }
1122
1123 colon = index(val, ':');
1124 if (!colon || colon == val || *(colon+1) == 0)
1125 {Eroute.Emsg("Config",mtype,"mode spec requires min and max values");
1126 return 1;
1127 }
1128 minM = val; *colon = 0; maxM = colon + 1;
1129
1130 if (!XrdOucUtils::mode2mask(minM, mMask[0]))
1131 {Eroute.Emsg("Config", mtype, "value is invalid -", minM);
1132 return 1;
1133 }
1134
1135 if (!XrdOucUtils::mode2mask(maxM, mMask[1]))
1136 {Eroute.Emsg("Config", mtype, "value is invalid -", maxM);
1137 return 1;
1138 }
1139
1140 if (isDirs)
1141 {if (isRaw) {dMask[0] = mMask[0]; dMask[1] = mMask[1];}
1142 else {if ((mMask[0] | mMask[1]) & wBit)
1143 {Eroute.Say("Config warning: 'other' w-mode removed from dirs mode!");
1144 mMask[0] &= ~wBit; mMask[1] &= ~wBit;
1145 }
1146 dMask[0] = (mMask[0] | dMin) & dMax;
1147 dMask[1] = (mMask[1] | dMin) & dMax;
1148 }
1149 if ((dMask[0] & dMask[1]) != dMask[0])
1150 {Eroute.Emsg("Config","dirs mode min and max values are inconsistent!");
1151 return 1;
1152 }
1153 } else { // Files
1154 if (isRaw) {fMask[0] = mMask[0]; fMask[1] = mMask[1];}
1155 else {if ((mMask[0] | mMask[1]) & wBit)
1156 {Eroute.Say("Config warning: 'other' w-mode removed from files mode!");
1157 mMask[0] &= ~wBit; mMask[1] &= ~wBit;
1158 }
1159 if ((mMask[0] | mMask[1]) & xBit)
1160 {Eroute.Say("Config warning: x-mode removed from files mode!");
1161 mMask[0] &= ~xBit; mMask[1] &= ~xBit;
1162 }
1163 fMask[0] = (mMask[0] | fMin) & fMax;
1164 fMask[1] = (mMask[1] | fMin) & fMax;
1165 }
1166 if ((fMask[0] & fMask[1]) != fMask[0])
1167 {Eroute.Emsg("Config","files mode min and max values are inconsistent!");
1168 return 1;
1169 }
1170 }
1171 } while((val = Config.GetWord()) && val[0]);
1172
1173// All done, return success
1174//
1175 return 0;
1176}
1177
1178/******************************************************************************/
1179/* x d i r l */
1180/******************************************************************************/
1181
1182/* Function: xdirl
1183
1184 Purpose: To parse the directive: dirlist {local | remote}
1185
1186 local processes directory listings locally. The oss plugin
1187 must be capable of doing this. This is the default.
1188 remote if clustering is enabled, directory listings are
1189 processed as directed by the cmsd.
1190
1191 Output: 0 upon success or !0 upon failure.
1192*/
1193
1194int XrdOfs::xdirl(XrdOucStream &Config, XrdSysError &Eroute)
1195{
1196 char *val;
1197
1198// Get the parameter
1199//
1200 if (!(val = Config.GetWord()) || !val[0])
1201 {Eroute.Emsg("Config", "dirlist parameter not specified"); return 1;}
1202
1203// Set appropriate option
1204//
1205 if (!strcmp(val, "local")) DirRdr = false;
1206 else if (!strcmp(val, "remote")) DirRdr = true;
1207 else {Eroute.Emsg("Config", "Invalid dirlist parameter -", val); return 1;}
1208
1209 return 0;
1210}
1211
1212/******************************************************************************/
1213/* x e x p */
1214/******************************************************************************/
1215
1216/* Function: xexp
1217
1218 Purpose: To prescan the all.export and oss.defaults directives to determine
1219 if we have any writable paths.
1220
1221 Output: 0 upon success or !0 upon failure.
1222*/
1223
1224int XrdOfs::xexp(XrdOucStream &Config, XrdSysError &Eroute, bool isExport)
1225{
1226 static struct rwOpts {const char *opname; int isRW;} rwtab[] =
1227 {{"r/o", 0}, {"readonly", 0},
1228 {"forcero", 0}, {"notwritable", 0},
1229 {"writable", 1}, {"r/w", 1}
1230 };
1231 static bool defRW = true;
1232 int isrw = -1, numopts = sizeof(rwtab)/sizeof(struct rwOpts);
1233 char *val;
1234
1235// If this is an export and we already know that we have a writable path, return
1236// Otherwise, scan over the path argument.
1237//
1238 if (isExport && (ossRW == 'w' || !(val = Config.GetWord()))) return 0;
1239
1240// Throw away path and scan all the options looking for something of interest
1241//
1242 while((val = Config.GetWord()))
1243 {for (int i = 0; i < numopts; i++)
1244 if (!strcmp(val, rwtab[i].opname)) isrw = rwtab[i].isRW;
1245 else if (!strcmp(val, "cache")) {isrw = 0; break;}
1246 }
1247
1248// Handle result depending if this is an export or a defaults
1249//
1250 if (isrw < 0) isrw = defRW;
1251 if (isExport) ossRW = (isrw ? 'w' : 'r');
1252 else {defRW = (isrw ? true : false);
1253 if (ossRW == ' ' && !isrw) ossRW = 'r';
1254 }
1255 return 0;
1256}
1257
1258/******************************************************************************/
1259/* x f o r w a r d */
1260/******************************************************************************/
1261
1262/* Function: xforward
1263
1264 Purpose: To parse the directive: forward [<handling>] <metaops>
1265
1266 handling: 1way | 2way | 3way {local | <host>:<port>}
1267
1268 1way forward does not respond (the default)
1269 2way forward responds; relay response back.
1270 3way forward 1way and execute locally or redirect to <host>
1271 <metaops> list of meta-file operations to forward to manager
1272
1273 Output: 0 upon success or !0 upon failure.
1274*/
1275
1276int XrdOfs::xforward(XrdOucStream &Config, XrdSysError &Eroute)
1277{
1278 enum fwdType {OfsFWDALL = 0x3f, OfsFWDCHMOD = 0x01, OfsFWDMKDIR = 0x02,
1279 OfsFWDMV = 0x04, OfsFWDRM = 0x08, OfsFWDRMDIR = 0x10,
1280 OfsFWDREM = 0x18, OfsFWDTRUNC = 0x20, OfsFWDNONE = 0};
1281
1282 static struct fwdopts {const char *opname; fwdType opval;} fwopts[] =
1283 {
1284 {"all", OfsFWDALL},
1285 {"chmod", OfsFWDCHMOD},
1286 {"mkdir", OfsFWDMKDIR},
1287 {"mv", OfsFWDMV},
1288 {"rm", OfsFWDRM},
1289 {"rmdir", OfsFWDRMDIR},
1290 {"remove", OfsFWDREM},
1291 {"trunc", OfsFWDTRUNC}
1292 };
1293 int fwval = OfsFWDNONE, fwspec = OfsFWDNONE;
1294 int numopts = sizeof(fwopts)/sizeof(struct fwdopts);
1295 int i, neg, rPort = 0, is2way = 0, is3way = 0;
1296 char *val, *pp, rHost[512];
1297
1298 *rHost = '\0';
1299 if (!(val = Config.GetWord()))
1300 {Eroute.Emsg("Config", "forward option not specified"); return 1;}
1301 if ((is2way = !strcmp("2way", val)) || !strcmp("1way", val)
1302 || (is3way = !strcmp("3way", val)))
1303 if (!(val = Config.GetWord()))
1304 {Eroute.Emsg("Config", "forward operation not specified"); return 1;}
1305
1306 if (is3way)
1307 {if (!strcmp("local", val)) rPort = -1;
1308 else
1309 {if (*val == ':')
1310 {Eroute.Emsg("Config", "redirect host not specified"); return 1;}
1311 if (!(pp = index(val, ':')))
1312 {Eroute.Emsg("Config", "redirect port not specified"); return 1;}
1313 if ((rPort = atoi(pp+1)) <= 0)
1314 {Eroute.Emsg("Config", "redirect port is invalid"); return 1;}
1315 *pp = '\0';
1316 strlcpy(rHost, val, sizeof(rHost));
1317 }
1318 if (!(val = Config.GetWord()))
1319 {Eroute.Emsg("Config", "forward operation not specified"); return 1;}
1320 }
1321
1322 while (val)
1323 {if (!strcmp(val, "off")) {fwval = OfsFWDNONE; fwspec = OfsFWDALL;}
1324 else {if ((neg = (val[0] == '-' && val[1]))) val++;
1325 for (i = 0; i < numopts; i++)
1326 {if (!strcmp(val, fwopts[i].opname))
1327 {if (neg) fwval &= ~fwopts[i].opval;
1328 else fwval |= fwopts[i].opval;
1329 fwspec |= fwopts[i].opval;
1330 break;
1331 }
1332 }
1333 if (i >= numopts)
1334 Eroute.Say("Config warning: ignoring invalid forward option '",val,"'.");
1335 }
1336 val = Config.GetWord();
1337 }
1338
1339 if (fwspec & OfsFWDCHMOD)
1340 {fwdCHMOD.Cmd = (fwval&OfsFWDCHMOD ? (is2way ? "+chmod" :"chmod") : 0);
1341 if (fwdCHMOD.Host) free(fwdCHMOD.Host);
1342 fwdCHMOD.Host = strdup(rHost); fwdCHMOD.Port = rPort;
1343 }
1344 if (fwspec&OfsFWDMKDIR)
1345 {fwdMKDIR.Cmd = (fwval&OfsFWDMKDIR ? (is2way ? "+mkdir" :"mkdir") : 0);
1346 if (fwdMKDIR.Host) free(fwdMKDIR.Host);
1347 fwdMKDIR.Host = strdup(rHost); fwdMKDIR.Port = rPort;
1348 fwdMKPATH.Cmd= (fwval&OfsFWDMKDIR ? (is2way ? "+mkpath":"mkpath") : 0);
1349 if (fwdMKPATH.Host) free(fwdMKPATH.Host);
1350 fwdMKPATH.Host = strdup(rHost); fwdMKPATH.Port = rPort;
1351 }
1352 if (fwspec&OfsFWDMV)
1353 {fwdMV .Cmd = (fwval&OfsFWDMV ? (is2way ? "+mv" :"mv") : 0);
1354 if (fwdMV.Host) free(fwdMV.Host);
1355 fwdMV.Host = strdup(rHost); fwdMV.Port = rPort;
1356 }
1357 if (fwspec&OfsFWDRM)
1358 {fwdRM .Cmd = (fwval&OfsFWDRM ? (is2way ? "+rm" :"rm") : 0);
1359 if (fwdRM.Host) free(fwdRM.Host);
1360 fwdRM.Host = strdup(rHost); fwdRM.Port = rPort;
1361 }
1362 if (fwspec&OfsFWDRMDIR)
1363 {fwdRMDIR.Cmd = (fwval&OfsFWDRMDIR ? (is2way ? "+rmdir" :"rmdir") : 0);
1364 if (fwdRMDIR.Host) free(fwdRMDIR.Host);
1365 fwdRMDIR.Host = strdup(rHost); fwdRMDIR.Port = rPort;
1366 }
1367 if (fwspec&OfsFWDTRUNC)
1368 {fwdTRUNC.Cmd = (fwval&OfsFWDTRUNC ? (is2way ? "+trunc" :"trunc") : 0);
1369 if (fwdTRUNC.Host) free(fwdTRUNC.Host);
1370 fwdTRUNC.Host = strdup(rHost); fwdTRUNC.Port = rPort;
1371 }
1372
1373// All done
1374//
1376 return 0;
1377}
1378
1379/******************************************************************************/
1380/* x m a x d */
1381/******************************************************************************/
1382
1383/* Function: xmaxd
1384
1385 Purpose: To parse the directive: maxdelay <secs>
1386
1387 <secs> maximum delay imposed for staging
1388
1389 Output: 0 upon success or !0 upon failure.
1390*/
1391
1392int XrdOfs::xmaxd(XrdOucStream &Config, XrdSysError &Eroute)
1393{
1394 char *val;
1395 int maxd;
1396
1397 if (!(val = Config.GetWord()))
1398 {Eroute.Emsg("Config","maxdelay value not specified");return 1;}
1399 if (XrdOuca2x::a2i(Eroute, "maxdelay", val, &maxd, 30)) return 1;
1400
1401 MaxDelay = maxd;
1402 return 0;
1403}
1404
1405/******************************************************************************/
1406/* x n m s g */
1407/******************************************************************************/
1408
1409/* Function: xnmsg
1410
1411 Purpose: To parse the directive: notifymsg <event> <msg>
1412
1413 Args: <events> - one or more of: all chmod closer closew close mkdir mv
1414 openr openw open rm rmdir fwrite
1415 <msg> the notification message to be sent (see notify).
1416
1417 Type: Manager only, non-dynamic.
1418
1419 Output: 0 upon success or !0 upon failure.
1420*/
1421
1422int XrdOfs::xnmsg(XrdOucStream &Config, XrdSysError &Eroute)
1423{
1424 static struct notopts {const char *opname; XrdOfsEvs::Event opval;}
1425 noopts[] = {
1426 {"chmod", XrdOfsEvs::Chmod},
1427 {"closer", XrdOfsEvs::Closer},
1428 {"closew", XrdOfsEvs::Closew},
1429 {"create", XrdOfsEvs::Create},
1430 {"mkdir", XrdOfsEvs::Mkdir},
1431 {"mv", XrdOfsEvs::Mv},
1432 {"openr", XrdOfsEvs::Openr},
1433 {"openw", XrdOfsEvs::Openw},
1434 {"rm", XrdOfsEvs::Rm},
1435 {"rmdir", XrdOfsEvs::Rmdir},
1436 {"trunc", XrdOfsEvs::Trunc},
1437 {"fwrite", XrdOfsEvs::Fwrite}
1438 };
1439 XrdOfsEvs::Event noval;
1440 int numopts = sizeof(noopts)/sizeof(struct notopts);
1441 char *val, buff[1024];
1442 XrdOucEnv *myEnv;
1443 int i;
1444
1445 // At this point, make sure we have a value
1446 //
1447 if (!(val = Config.GetWord()))
1448 {Eroute.Emsg("Config", "notifymsg event not specified");
1449 return 1;
1450 }
1451
1452 // Get the evant number
1453 //
1454 for (i = 0; i < numopts; i++) if (!strcmp(val, noopts[i].opname)) break;
1455 if (i >= numopts)
1456 {Eroute.Say("Config warning: ignoring invalid notify event '",val,"'.");
1457 return 1;
1458 }
1459 noval = noopts[i].opval;
1460
1461 // We need to suck all the tokens to the end of the line for remaining
1462 // options. Do so, until we run out of space in the buffer.
1463 //
1464 myEnv = Config.SetEnv(0);
1465 if (!Config.GetRest(buff, sizeof(buff)))
1466 {Eroute.Emsg("Config", "notifymsg arguments too long");
1467 Config.SetEnv(myEnv);
1468 return 1;
1469 }
1470
1471 // Restore substitutions and parse the message
1472 //
1473 Config.SetEnv(myEnv);
1474 return XrdOfsEvs::Parse(Eroute, noval, buff);
1475}
1476
1477/******************************************************************************/
1478/* x n o t */
1479/* Based on code developed by Derek Feichtinger, CERN. */
1480/******************************************************************************/
1481
1482/* Function: xnot
1483
1484 Purpose: Parse directive: notify <events> [msgs <min> [<max>]]
1485 {|<prog> | ><path>}
1486
1487 Args: <events> - one or more of: all chmod closer closew close mkdir mv
1488 openr openw open rm rmdir fwrite
1489 opaque and other possible information to be sent.
1490 msgs - Maximum number of messages to keep and queue. The
1491 <min> if for small messages (default 90) and <max> is
1492 for big messages (default 10).
1493 <prog> - is the program to execute and dynamically feed messages
1494 about the indicated events. Messages are piped to prog.
1495 <path> - is the udp named socket to receive the message. The
1496 server creates the path if it's not present.
1497
1498 Output: 0 upon success or !0 upon failure.
1499*/
1500int XrdOfs::xnot(XrdOucStream &Config, XrdSysError &Eroute)
1501{
1502 static struct notopts {const char *opname; XrdOfsEvs::Event opval;}
1503 noopts[] = {
1504 {"all", XrdOfsEvs::All},
1505 {"chmod", XrdOfsEvs::Chmod},
1506 {"close", XrdOfsEvs::Close},
1507 {"closer", XrdOfsEvs::Closer},
1508 {"closew", XrdOfsEvs::Closew},
1509 {"create", XrdOfsEvs::Create},
1510 {"mkdir", XrdOfsEvs::Mkdir},
1511 {"mv", XrdOfsEvs::Mv},
1512 {"open", XrdOfsEvs::Open},
1513 {"openr", XrdOfsEvs::Openr},
1514 {"openw", XrdOfsEvs::Openw},
1515 {"rm", XrdOfsEvs::Rm},
1516 {"rmdir", XrdOfsEvs::Rmdir},
1517 {"trunc", XrdOfsEvs::Trunc},
1518 {"fwrite", XrdOfsEvs::Fwrite}
1519 };
1521 int numopts = sizeof(noopts)/sizeof(struct notopts);
1522 int i, neg, msgL = 90, msgB = 10;
1523 char *val, parms[1024];
1524
1525 if (!(val = Config.GetWord()))
1526 {Eroute.Emsg("Config", "notify parameters not specified"); return 1;}
1527 while (val && *val != '|' && *val != '>')
1528 {if (!strcmp(val, "msgs"))
1529 {if (!(val = Config.GetWord()))
1530 {Eroute.Emsg("Config", "notify msgs value not specified");
1531 return 1;
1532 }
1533 if (XrdOuca2x::a2i(Eroute, "msg count", val, &msgL, 0)) return 1;
1534 if (!(val = Config.GetWord())) break;
1535 if (isdigit(*val)
1536 && XrdOuca2x::a2i(Eroute, "msg count", val, &msgB, 0)) return 1;
1537 if (!(val = Config.GetWord())) break;
1538 continue;
1539 }
1540 if ((neg = (val[0] == '-' && val[1]))) val++;
1541 i = strlen(val);
1542 for (i = 0; i < numopts; i++)
1543 {if (!strcmp(val, noopts[i].opname))
1544 {if (neg) noval = static_cast<XrdOfsEvs::Event>(~noopts[i].opval&noval);
1545 else noval = static_cast<XrdOfsEvs::Event>( noopts[i].opval|noval);
1546 break;
1547 }
1548 }
1549 if (i >= numopts)
1550 Eroute.Say("Config warning: ignoring invalid notify event '",val,"'.");
1551 val = Config.GetWord();
1552 }
1553
1554// Check if we have a program here and some events
1555//
1556 if (!val) {Eroute.Emsg("Config","notify program not specified");return 1;}
1557 if (!noval) {Eroute.Emsg("Config","notify events not specified"); return 1;}
1558
1559// Get the remaining parameters
1560//
1561 Config.RetToken();
1562 if (!Config.GetRest(parms, sizeof(parms)))
1563 {Eroute.Emsg("Config", "notify parameters too long"); return 1;}
1564 val = (*parms == '|' ? parms+1 : parms);
1565
1566// Create an notification object
1567//
1568 if (evsObject) delete evsObject;
1569 evsObject = new XrdOfsEvs(noval, val, msgL, msgB);
1570
1571// All done
1572//
1573 return 0;
1574}
1575
1576/******************************************************************************/
1577/* x p e r s */
1578/******************************************************************************/
1579
1580/* Function: xpers
1581
1582 Purpose: To parse the directive: persist [auto | manual | off]
1583 [hold <sec>] [logdir <dirp>]
1584 [sync <snum>]
1585
1586 auto POSC processing always on for creation requests
1587 manual POSC processing must be requested (default)
1588 off POSC processing is disabled
1589 <sec> Seconds inclomplete files held (default 10m)
1590 <dirp> Directory to hold POSC recovery log (default adminpath)
1591 <snum> Number of outstanding equests before syncing to disk.
1592
1593 Output: 0 upon success or !0 upon failure.
1594*/
1595
1596int XrdOfs::xpers(XrdOucStream &Config, XrdSysError &Eroute)
1597{
1598 char *val;
1599 int snum = -1, htime = -1, popt = -2;
1600
1601 if (!(val = Config.GetWord()))
1602 {Eroute.Emsg("Config","persist option not specified");return 1;}
1603
1604// Check for valid option
1605//
1606 if (!strcmp(val, "auto" )) popt = 1;
1607 else if (!strcmp(val, "off" )) popt = -1;
1608 else if (!strcmp(val, "manual" )) popt = 0;
1609
1610// Check if we should get the next token
1611//
1612 if (popt > -2) val = Config.GetWord();
1613
1614// Check for hold or log
1615//
1616 while(val)
1617 { if (!strcmp(val, "hold"))
1618 {if (!(val = Config.GetWord()))
1619 {Eroute.Emsg("Config","persist hold value not specified");
1620 return 1;
1621 }
1622 if (XrdOuca2x::a2tm(Eroute,"persist hold",val,&htime,0))
1623 return 1;
1624 }
1625 else if (!strcmp(val, "logdir"))
1626 {if (!(val = Config.GetWord()))
1627 {Eroute.Emsg("Config","persist logdir path not specified");
1628 return 1;
1629 }
1630 if (poscLog) free(poscLog);
1631 poscLog = strdup(val);
1632 }
1633 else if (!strcmp(val, "sync"))
1634 {if (!(val = Config.GetWord()))
1635 {Eroute.Emsg("Config","sync value not specified");
1636 return 1;
1637 }
1638 if (XrdOuca2x::a2i(Eroute,"sync value",val,&snum,0,32767))
1639 return 1;
1640 }
1641 else Eroute.Say("Config warning: ignoring invalid persist option '",val,"'.");
1642 val = Config.GetWord();
1643 }
1644
1645// Set values as needed
1646//
1647 if (htime >= 0) poscHold = htime;
1648 if (popt > -2) poscAuto = popt;
1649 if (snum > -1) poscSync = snum;
1650 return 0;
1651}
1652
1653/******************************************************************************/
1654/* x r o l e */
1655/******************************************************************************/
1656
1657/* Function: xrole
1658
1659 Purpose: Parse: role { {[meta] | [proxy]} manager
1660 | [proxy] server
1661 | [proxy] supervisor
1662 } [if ...]
1663
1664 manager xrootd: act as a manager (redirecting server). Prefixes:
1665 meta - connect only to manager meta's
1666 proxy - ignored
1667 cmsd: accept server subscribes and redirectors. Prefix
1668 modifiers do the following:
1669 meta - No other managers apply
1670 proxy - manage a cluster of proxy servers
1671
1672 server xrootd: act as a server (supply local data). Prefix
1673 modifications do the following:
1674 proxy - server is part of a cluster. A local
1675 cmsd is required.
1676 cmsd: subscribe to a manager, possibly as a proxy.
1677
1678 supervisor xrootd: equivalent to manager. The prefix modification
1679 is ignored.
1680 cmsd: equivalent to manager but also subscribe to a
1681 manager. When proxy is specified, then subscribe
1682 as a proxy and only accept proxies.
1683
1684 if Apply the manager directive if "if" is true. See
1685 XrdOucUtils:doIf() for "if" syntax.
1686
1687 Notes 1. The peer designation only affects how the olbd communicates.
1688
1689 Type: Server only, non-dynamic.
1690
1691 Output: 0 upon success or !0 upon failure.
1692*/
1693
1694int XrdOfs::xrole(XrdOucStream &Config, XrdSysError &Eroute)
1695{
1696 const int resetit = ~haveRole;
1697 XrdCmsRole::RoleID roleID;
1698 char *val, *Tok1, *Tok2;
1699 int rc, ropt = 0;
1700
1701// Get the first token
1702//
1703 if (!(val = Config.GetWord()) || !strcmp(val, "if"))
1704 {Eroute.Emsg("Config", "role not specified"); return 1;}
1705 Tok1 = strdup(val);
1706
1707// Get second token which might be an "if"
1708//
1709 if ((val = Config.GetWord()) && strcmp(val, "if"))
1710 {Tok2 = strdup(val);
1711 val = Config.GetWord();
1712 } else Tok2 = 0;
1713
1714// Process the if at this point
1715//
1716 if (val && !strcmp("if", val))
1717 {if ((rc = XrdOucUtils::doIf(&Eroute,Config,"role directive",
1718 getenv("XRDHOST"), XrdOucUtils::InstName(1),
1719 getenv("XRDPROG"))) <= 0)
1720 {free(Tok1); if (Tok2) free(Tok2);
1721 if (!rc) Config.noEcho();
1722 return (rc < 0);
1723 }
1724 }
1725
1726// Convert the role names to a role ID, if possible
1727//
1728 roleID = XrdCmsRole::Convert(Tok1, Tok2);
1729
1730// Set markers based on the role we have
1731//
1732 rc = 0;
1733 switch(roleID)
1734 {case XrdCmsRole::MetaManager: ropt = isManager | isMeta ; break;
1735 case XrdCmsRole::Manager: ropt = isManager ; break;
1736 case XrdCmsRole::Supervisor: ropt = isSuper ; break;
1737 case XrdCmsRole::Server: ropt = isServer ; break;
1738 case XrdCmsRole::ProxyManager: ropt = isManager | isProxy; break;
1739 case XrdCmsRole::ProxySuper: ropt = isSuper | isProxy; break;
1740 case XrdCmsRole::ProxyServer: ropt = isServer | isProxy; break;
1741 default: Eroute.Emsg("Config", "invalid role -", Tok1, Tok2); rc = 1;
1742 }
1743
1744// Release storage and return if an error occurred
1745//
1746 free(Tok1);
1747 if (Tok2) free(Tok2);
1748 if (rc) return rc;
1749
1750// Set values
1751//
1752 free(myRole);
1753 myRole = strdup(XrdCmsRole::Name(roleID));
1754 strcpy(myRType, XrdCmsRole::Type(roleID));
1755 Options &= resetit;
1756 Options |= ropt;
1757 return 0;
1758}
1759
1760/******************************************************************************/
1761/* x t p c */
1762/******************************************************************************/
1763
1764/* Function: xtpc
1765
1766 Purpose: To parse the directive: tpc [cksum <type>] [ttl <dflt> [<max>]]
1767 [logok] [xfr <n>] [allow <parms>]
1768 [require {all|client|dest} <auth>[+]]
1769 [restrict <path>]
1770 [streams <num>[,<max>]]
1771 [echo] [scan {stderr | stdout}]
1772 [autorm] [pgm <path> [parms]]
1773 [fcreds [?]<auth> =<evar>]
1774 [fcpath <path>] [oids]
1775
1776 tpc redirect [xdlg] <host>:<port> [<cgi>]
1777
1778 xdlg: delegated | undelegated
1779
1780 parms: [dn <name>] [group <grp>] [host <hn>] [vo <vo>]
1781
1782 <dflt> the default seconds a tpc authorization may be valid.
1783 <max> the maximum seconds a tpc authorization may be valid.
1784 cksum checksum incoming files using <type> checksum.
1785 logok log successful authorizations.
1786 allow only allow destinations that match the specified
1787 authentication specification.
1788 <n> maximum number of simultaneous transfers.
1789 <num> the default number of TCP streams to use for the copy.
1790 <max> The maximum number of TCP streams to use for the copy/
1791 <auth> require that the client, destination, or both (i.e. all)
1792 use the specified authentication protocol. Additional
1793 require statements may be specified to add additional
1794 valid authentication mechanisms. If the <auth> is suffixed
1795 by a plus, then the request must also be encrypted using
1796 the authentication's session key.
1797 echo echo the pgm's output to the log.
1798 autorm Remove file when copy fails.
1799 scan scan fr error messages either in stderr or stdout. The
1800 default is to scan both.
1801 pgm specifies the transfer command with optional paramaters.
1802 It must be the last parameter on the line.
1803 fcreds Forward destination credentials for protocol <auth>. The
1804 request fails if thee are no credentials for <auth>. If a
1805 question mark preceeds <auth> then if the client has not
1806 forwarded its credentials, the server's credentials are
1807 used. Otherwise, the copy fails.
1808 =<evar> the name of the envar to be set with the path to the
1809 credentials to be forwarded.
1810 fcpath where creds are stored (default <adminpath>/.ofs/.tpccreds).
1811 oids Object ID's are acceptable for the source lfn.
1812 <host> The redirection target host which may be localhost.
1813 <port> The redirection target port.
1814 <cgi> Optional cgi information.
1815
1816 Output: 0 upon success or !0 upon failure.
1817*/
1818
1819int XrdOfs::xtpc(XrdOucStream &Config, XrdSysError &Eroute)
1820{
1821 char *val, pgm[1024];
1822 XrdOfsTPCConfig &Parms = XrdOfsTPCParms::Cfg;
1823 *pgm = 0;
1824 int reqType;
1825 bool rdrok = true;
1826
1827 while((val = Config.GetWord()))
1828 {if (!strcmp(val, "redirect"))
1829 {if (rdrok) return xtpcr(Config, Eroute);
1830 Eroute.Emsg("Config", "tpc redirect must be seprately specified.");
1831 return 1;
1832 }
1833 rdrok = false;
1834 if (!strcmp(val, "allow"))
1835 {if (!xtpcal(Config, Eroute)) return 1;
1836 continue;
1837 }
1838 if (!strcmp(val, "cksum"))
1839 {if (!(val = Config.GetWord()))
1840 {Eroute.Emsg("Config","cksum type not specified"); return 1;}
1841 if (Parms.cksType) free(Parms.cksType);
1842 Parms.cksType = strdup(val);
1843 continue;
1844 }
1845 if (!strcmp(val, "scan"))
1846 {if (!(val = Config.GetWord()))
1847 {Eroute.Emsg("Config","scan type not specified"); return 1;}
1848 if (strcmp(val, "stderr")) Parms.errMon = -2;
1849 else if (strcmp(val, "stdout")) Parms.errMon = -1;
1850 else if (strcmp(val, "all" )) Parms.errMon = 0;
1851 else {Eroute.Emsg("Config","invalid scan type -",val); return 1;}
1852 continue;
1853 }
1854 if (!strcmp(val, "echo")) {Parms.doEcho = true; continue;}
1855 if (!strcmp(val, "logok")) {Parms.LogOK = true; continue;}
1856 if (!strcmp(val, "autorm")){Parms.autoRM = true; continue;}
1857 if (!strcmp(val, "oids")) {Parms.noids = false;continue;}
1858 if (!strcmp(val, "pgm"))
1859 {if (!Config.GetRest(pgm, sizeof(pgm)))
1860 {Eroute.Emsg("Config", "tpc command line too long"); return 1;}
1861 if (!*pgm)
1862 {Eroute.Emsg("Config", "tpc program not specified"); return 1;}
1863 if (Parms.XfrProg) free(Parms.XfrProg);
1864 Parms.XfrProg = strdup( pgm );
1865 break;
1866 }
1867 if (!strcmp(val, "require"))
1868 {if (!(val = Config.GetWord()))
1869 {Eroute.Emsg("Config","tpc require parameter not specified"); return 1;}
1870 if (!strcmp(val, "all")) reqType = XrdOfsTPC::reqALL;
1871 else if (!strcmp(val, "client")) reqType = XrdOfsTPC::reqORG;
1872 else if (!strcmp(val, "dest")) reqType = XrdOfsTPC::reqDST;
1873 else {Eroute.Emsg("Config", "invalid tpc require type -", val); return 1;}
1874 break;
1875 if (!(val = Config.GetWord()))
1876 {Eroute.Emsg("Config","tpc require auth not specified"); return 1;}
1877 XrdOfsTPC::Require(val, reqType);
1878 continue;
1879 }
1880 if (!strcmp(val, "restrict"))
1881 {if (!(val = Config.GetWord()))
1882 {Eroute.Emsg("Config","tpc restrict path not specified"); return 1;}
1883 if (*val != '/')
1884 {Eroute.Emsg("Config","tpc restrict path not absolute"); return 1;}
1885 if (!XrdOfsTPC::Restrict(val)) return 1;
1886 continue;
1887 }
1888 if (!strcmp(val, "ttl"))
1889 {if (!(val = Config.GetWord()))
1890 {Eroute.Emsg("Config","tpc ttl value not specified"); return 1;}
1891 if (XrdOuca2x::a2tm(Eroute,"tpc ttl default",val,&Parms.dflTTL,1))
1892 return 1;
1893 if (!(val = Config.GetWord())) break;
1894 if (!(isdigit(*val))) {Config.RetToken(); continue;}
1895 if (XrdOuca2x::a2tm(Eroute,"tpc ttl maximum",val,&Parms.maxTTL,1))
1896 return 1;
1897 continue;
1898 }
1899 if (!strcmp(val, "xfr"))
1900 {if (!(val = Config.GetWord()))
1901 {Eroute.Emsg("Config","tpc xfr value not specified"); return 1;}
1902 if (XrdOuca2x::a2i(Eroute,"tpc xfr",val,&Parms.xfrMax,1)) return 1;
1903 continue;
1904 }
1905 if (!strcmp(val, "streams"))
1906 {if (!(val = Config.GetWord()))
1907 {Eroute.Emsg("Config","tpc streams value not specified"); return 1;}
1908 char *comma = index(val,',');
1909 if (comma)
1910 {*comma++ = 0;
1911 if (!(*comma))
1912 {Eroute.Emsg("Config","tpc streams max value missing"); return 1;}
1913 if (XrdOuca2x::a2i(Eroute,"tpc max streams",comma,&Parms.tcpSMax,0,15))
1914 return 1;
1915 }
1916 if (XrdOuca2x::a2i(Eroute,"tpc streams",val,&Parms.tcpSTRM,0,15)) return 1;
1917 continue;
1918 }
1919 if (!strcmp(val, "fcreds"))
1920 {char aBuff[64];
1921 Parms.fCreds = true;
1922 if (!(val = Config.GetWord()) || (*val == '?' && *(val+1) == '\0'))
1923 {Eroute.Emsg("Config","tpc fcreds auth not specified"); return 1;}
1924 if (strlen(val) >= sizeof(aBuff))
1925 {Eroute.Emsg("Config","invalid fcreds auth -", val); return 1;}
1926 strcpy(aBuff, val);
1927 if (!(val = Config.GetWord()) || *val != '=' || *(val+1) == 0)
1928 {Eroute.Emsg("Config","tpc fcreds envar not specified"); return 1;}
1929 const char *emsg = XrdOfsTPC::AddAuth(aBuff,val+1);
1930 if (emsg) {Eroute.Emsg("Config",emsg,"-", val); return 1;}
1931 continue;
1932 }
1933 if (!strcmp(val, "fcpath"))
1934 {if (!(val = Config.GetWord()))
1935 {Eroute.Emsg("Config","tpc fcpath arg not specified"); return 1;}
1936 if (Parms.cPath) free(Parms.cPath);
1937 Parms.cPath = strdup(val);
1938 continue;
1939 }
1940 Eroute.Say("Config warning: ignoring invalid tpc option '",val,"'.");
1941 }
1942
1943 Options |= ThirdPC;
1944 return 0;
1945}
1946
1947/******************************************************************************/
1948/* x t p c a l */
1949/******************************************************************************/
1950
1951int XrdOfs::xtpcal(XrdOucStream &Config, XrdSysError &Eroute)
1952{
1953 struct tpcalopts {const char *opname; char *opval;} tpopts[] =
1954 {{"dn", 0}, {"group", 0}, {"host", 0}, {"vo", 0}};
1955 int i, spec = 0, numopts = sizeof(tpopts)/sizeof(struct tpcalopts);
1956 char *val;
1957
1958 while((val = Config.GetWord()))
1959 {for (i = 0; i < numopts && strcmp(tpopts[i].opname, val); i++) {}
1960 if (i > numopts) {Config.RetToken(); break;}
1961 {Eroute.Emsg("Config", "invalid tpc allow parameter -", val);
1962 return 0;
1963 }
1964 if (!(val = Config.GetWord()))
1965 {Eroute.Emsg("Config","tpc allow",tpopts[i].opname,"value not specified");
1966 return 0;
1967 }
1968 if (tpopts[i].opval) free(tpopts[i].opval);
1969 tpopts[i].opval = strdup(val);
1970 spec = 1;
1971 }
1972
1973 if (!spec) {Eroute.Emsg("Config","tpc allow parms not specified"); return 1;}
1974
1975 XrdOfsTPC::Allow(tpopts[0].opval, tpopts[1].opval,
1976 tpopts[2].opval, tpopts[3].opval);
1977 return 1;
1978}
1979
1980/******************************************************************************/
1981/* x t p c r */
1982/******************************************************************************/
1983
1984int XrdOfs::xtpcr(XrdOucStream &Config, XrdSysError &Eroute)
1985{
1986 char hname[256];
1987 const char *cgi, *cgisep, *hBeg, *hEnd, *pBeg, *pEnd, *eText;
1988 char *val;
1989 int n, port, dlgI;
1990
1991// Get the next token
1992//
1993 if (!(val = Config.GetWord()))
1994 {Eroute.Emsg("Config", "tpc redirect host not specified"); return 1;}
1995
1996// See if this is for delegated or undelegated (all is the default)
1997//
1998 if (!strcmp(val, "delegated")) dlgI = 0;
1999 else if (!strcmp(val, "undelegated")) dlgI = 1;
2000 else dlgI = -1;
2001
2002// Get host and port
2003//
2004 if (dlgI >= 0 && !(val = Config.GetWord()))
2005 {Eroute.Emsg("Config", "tpc redirect host not specified"); return 1;}
2006
2007// Parse this as it may be complicated.
2008//
2009 if (!XrdNetUtils::Parse(val, &hBeg, &hEnd, &pBeg, &pEnd))
2010 {Eroute.Emsg("Config", "Invalid tpc redirect target -", val); return 1;}
2011
2012// Copy out the host target (make sure it's not too long)
2013//
2014 n = hEnd - hBeg;
2015 if (*val == '[') n += 2;
2016 if (n >= (int)sizeof(hname))
2017 {Eroute.Emsg("Config", "Invalid tpc redirect target -", val); return 1;}
2018 strncpy(hname, val, n);
2019 hname[n] = 0;
2020
2021// Substitute our hostname for localhost if present
2022//
2023 if (!strcmp(hname, "localhost"))
2024 {char *myHost = XrdNetUtils::MyHostName(0, &eText);
2025 if (!myHost)
2026 {Eroute.Emsg("Config", "Unable to determine tpc localhost;",eText);
2027 return 1;
2028 }
2029 n = snprintf(hname, sizeof(hname), "%s", myHost);
2030 free(myHost);
2031 if (n >= (int)sizeof(hname))
2032 {Eroute.Emsg("Config", "Invalid tpc localhost resolution -", hname);
2033 return 1;
2034 }
2035 }
2036
2037// Make sure a port was specified
2038//
2039 if (pBeg == hEnd)
2040 {Eroute.Emsg("Config", "tpc redirect port not specified"); return 1;}
2041
2042// Get the numeric version of the port number
2043//
2044 if (!(port = XrdNetUtils::ServPort(pBeg, false, &eText)))
2045 {Eroute.Emsg("Config", "Invalid tpc redirect port;",eText); return 1;}
2046
2047// Check if there is cgi that must be included
2048//
2049 if (!(cgi = Config.GetWord())) cgisep = cgi = (char *)"";
2050 else cgisep = (*cgi != '?' ? "?" : "");
2051
2052// Copy out the hostname to be used
2053//
2054 int k = (dlgI < 0 ? 0 : dlgI);
2055do{if (tpcRdrHost[k]) {free(tpcRdrHost[k]); tpcRdrHost[k] = 0;}
2056
2057 n = strlen(hname) + strlen(cgisep) + strlen(cgi) + 1;
2058 tpcRdrHost[k] = (char *)malloc(n);
2059 snprintf(tpcRdrHost[k], n, "%s%s%s", hname, cgisep, cgi);
2060 tpcRdrPort[k] = port;
2061 k++;
2062 } while(dlgI < 0 && k < 2);
2063
2064// All done
2065//
2066 Options |= RdrTPC;
2067 return 0;
2068}
2069
2070/******************************************************************************/
2071/* x t r a c e */
2072/******************************************************************************/
2073
2074/* Function: xtrace
2075
2076 Purpose: To parse the directive: trace <events>
2077
2078 <events> the blank separated list of events to trace. Trace
2079 directives are cummalative.
2080
2081 Output: 0 upon success or !0 upon failure.
2082*/
2083
2084int XrdOfs::xtrace(XrdOucStream &Config, XrdSysError &Eroute)
2085{
2086 static struct traceopts {const char *opname; int opval;} tropts[] =
2087 {{"aio", TRACE_aio},
2088 {"all", TRACE_ALL},
2089 {"chkpnt", TRACE_chkpnt},
2090 {"chmod", TRACE_chmod},
2091 {"close", TRACE_close},
2092 {"closedir", TRACE_closedir},
2093 {"debug", TRACE_debug},
2094 {"delay", TRACE_delay},
2095 {"dir", TRACE_dir},
2096 {"exists", TRACE_exists},
2097 {"getstats", TRACE_getstats},
2098 {"fsctl", TRACE_fsctl},
2099 {"io", TRACE_IO},
2100 {"mkdir", TRACE_mkdir},
2101 {"most", TRACE_MOST},
2102 {"open", TRACE_open},
2103 {"opendir", TRACE_opendir},
2104 {"qscan", TRACE_qscan},
2105 {"read", TRACE_read},
2106 {"readdir", TRACE_readdir},
2107 {"redirect", TRACE_redirect},
2108 {"remove", TRACE_remove},
2109 {"rename", TRACE_rename},
2110 {"sync", TRACE_sync},
2111 {"truncate", TRACE_truncate},
2112 {"write", TRACE_write}
2113 };
2114 int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
2115 char *val;
2116
2117 if (!(val = Config.GetWord()))
2118 {Eroute.Emsg("Config", "trace option not specified"); return 1;}
2119 while (val)
2120 {if (!strcmp(val, "off")) trval = 0;
2121 else {if ((neg = (val[0] == '-' && val[1]))) val++;
2122 for (i = 0; i < numopts; i++)
2123 {if (!strcmp(val, tropts[i].opname))
2124 {if (neg) trval &= ~tropts[i].opval;
2125 else trval |= tropts[i].opval;
2126 break;
2127 }
2128 }
2129 if (i >= numopts)
2130 Eroute.Say("Config warning: ignoring invalid trace option '",val,"'.");
2131 }
2132 val = Config.GetWord();
2133 }
2134 OfsTrace.What = trval;
2135
2136// All done
2137//
2138 return 0;
2139}
2140
2141/******************************************************************************/
2142/* x a t r */
2143/******************************************************************************/
2144
2145/* Function: xatr
2146
2147 Purpose: To parse the directive: xattr [maxnsz <nsz>] [maxvsz <vsz>]
2148
2149 [uset {on|off}]
2150
2151 on enables user settable extended attributes.
2152
2153 off disaables user settable extended attributes.
2154
2155 <nsz> maximum length of an attribute name. The user
2156 specifiable limit will be 8 less.
2157
2158 <vsz> maximum length of an attribute value.
2159
2160 Notes: 1. This directive is not cummalative.
2161
2162 Output: 0 upon success or !0 upon failure.
2163*/
2164
2165int XrdOfs::xatr(XrdOucStream &Config, XrdSysError &Eroute)
2166{
2167 char *val;
2168 static const int xanRsv = 7;
2169 long long vtmp;
2170 int maxN = kXR_faMaxNlen, maxV = kXR_faMaxVlen;
2171 bool isOn = true;
2172
2173 while((val = Config.GetWord()))
2174 { if (!strcmp("maxnsz", val))
2175 {if (!(val = Config.GetWord()))
2176 {Eroute.Emsg("Config","xattr maxnsz value not specified");
2177 return 1;
2178 }
2179 if (XrdOuca2x::a2sz(Eroute,"maxnsz",val,&vtmp,
2180 xanRsv+1,kXR_faMaxNlen+xanRsv)) return 1;
2181 maxN = static_cast<int>(vtmp);
2182 }
2183 else if (!strcmp("maxvsz", val))
2184 {if (!(val = Config.GetWord()))
2185 {Eroute.Emsg("Config","xattr maxvsz value not specified");
2186 return 1;
2187 }
2188 if (XrdOuca2x::a2sz(Eroute,"maxvsz",val,&vtmp,0,kXR_faMaxVlen))
2189 return 1;
2190 maxV = static_cast<int>(vtmp);
2191 }
2192 else if (!strcmp("uset", val))
2193 {if (!(val = Config.GetWord()))
2194 {Eroute.Emsg("Config","xattr uset value not specified");
2195 return 1;
2196 }
2197 if (!strcmp("on", val)) isOn = true;
2198 else if (!strcmp("off", val)) isOn = false;
2199 else {Eroute.Emsg("Config", "invalid xattr uset value -", val);
2200 return 1;
2201 }
2202 }
2203 else {Eroute.Emsg("Config", "invalid xattr option -", val);
2204 return 1;
2205 }
2206 }
2207
2208 usxMaxNsz = (isOn ? maxN-xanRsv : 0);
2209 usxMaxVsz = maxV;
2210 return 0;
2211}
2212
2213/******************************************************************************/
2214/* t h e R o l e */
2215/******************************************************************************/
2216
2217const char *XrdOfs::theRole(int opts)
2218{
2219 if (opts & isPeer) return "peer";
2220 else if (opts & isManager
2221 && opts & isServer) return "supervisor";
2222 else if (opts & isManager) return "manager";
2223 else if (opts & isProxy) {return "proxy";}
2224 return "server";
2225}
@ kXR_faMaxVlen
Definition XProtocol.hh:312
@ kXR_faMaxNlen
Definition XProtocol.hh:311
#define TS_Bit(x, m, v)
XrdSysLogger myLogger
Definition XrdAccTest.cc:65
#define TRACE_delay
#define TRACE_debug
XrdCmsClient *(* XrdCmsClient_t)(XrdSysLogger *, int, int, XrdOss *)
#define TS_Xeq(x, m)
Definition XrdConfig.cc:160
#define setBuff(x, y)
XrdScheduler * ofsSchedP
XrdVERSIONINFO(XrdOfs, XrdOfs)
#define TS_XPI(x, m)
#define TRACE_dir
#define TRACE_rename
#define TRACE_read
#define TRACE_qscan
#define TRACE_getstats
#define TRACE_chkpnt
#define TRACE_exists
#define TRACE_close
#define TRACE_open
#define TRACE_sync
#define TRACE_truncate
#define TRACE_remove
#define TRACE_redirect
#define TRACE_opendir
#define TRACE_chmod
#define TRACE_closedir
#define TRACE_IO
#define TRACE_readdir
#define TRACE_mkdir
#define TRACE_MOST
#define TRACE_fsctl
#define TRACE_aio
#define TRACE_write
XrdSysTrace OfsTrace("ofs")
XrdOss * XrdOfsOss
Definition XrdOfs.cc:165
XrdOfsStats OfsStats
Definition XrdOfs.cc:115
XrdOfs * XrdOfsFS
Definition XrdOfsFS.cc:47
#define XRDOSS_HASFICL
Definition XrdOss.hh:544
#define XRDOSS_HASRPXY
Definition XrdOss.hh:542
#define XRDOSS_HASCACH
Definition XrdOss.hh:540
#define XRDOSS_HASPRXY
Definition XrdOss.hh:538
#define XRDOSS_HASXERT
Definition XrdOss.hh:543
#define XRDOSS_HASNOSF
Definition XrdOss.hh:539
#define XRDOSS_HASPGRW
Definition XrdOss.hh:536
#define XRDOSS_HASNAIO
Definition XrdOss.hh:541
#define open
Definition XrdPosix.hh:78
#define unlink(a)
Definition XrdPosix.hh:119
struct myOpts opts
int emsg(int rc, char *msg)
size_t strlcpy(char *dst, const char *src, size_t sz)
#define TRACE_ALL
Definition XrdTrace.hh:35
static bool VCheck(XrdVersionInfo &urVersion)
static bool VCheck(XrdVersionInfo &urVersion)
static const char * Name(RoleID rid)
Definition XrdCmsRole.hh:63
static const char * Type(RoleID rid)
Definition XrdCmsRole.hh:78
static RoleID Convert(const char *Tok1, const char *Tok2)
Definition XrdCmsRole.hh:47
static char * MyHostName(const char *eName="*unknown*", const char **eText=0)
static int ServPort(const char *sName, bool isUDP=false, const char **eText=0)
static bool Parse(const char *hSpec, const char **hName, const char **hNend, const char **hPort, const char **hPend)
static void Init(XrdCks *cp, XrdOucEnv *ep)
static void setRDSZ(int sz)
static bool Init()
static bool Parse(XrdOucStream &Config)
static XrdOfsConfigPI * New(const char *cfn, XrdOucStream *cfgP, XrdSysError *errP, XrdVersionInfo *verP=0, XrdSfsFileSystem *sfsP=0)
@ theOssLib
Oss plugin.
@ allXXXLib
All plugins (Load() only).
@ theCksLib
Checksum manager plugin.
static int Parse(XrdSysError &Eroute, Event eNum, char *mText)
Definition XrdOfsEvs.cc:287
The Plugins struct is used to pass plugin pointers to configure.
int Retire(int &retc, long long *retsz=0, char *buff=0, int blen=0)
int PoscSet(const char *User, int Unum, short Mode)
static const int opPC
static int Alloc(const char *thePath, int Opts, XrdOfsHandle **Handle)
static int Restrict(const char *Path)
Definition XrdOfsTPC.cc:465
static const int reqDST
Definition XrdOfsTPC.hh:86
static const char * AddAuth(const char *auth, const char *avar)
Definition XrdOfsTPC.cc:164
static void Init()
Definition XrdOfsTPC.cc:414
static int Start()
Definition XrdOfsTPC.cc:520
static const int reqORG
Definition XrdOfsTPC.hh:87
static void Require(const char *Auth, int RType)
Definition XrdOfsTPC.cc:445
static void Allow(char *vDN, char *vGN, char *vHN, char *vVO)
Definition XrdOfsTPC.cc:209
static const int reqALL
Definition XrdOfsTPC.hh:85
struct fwdOpt fwdTRUNC
Definition XrdOfs.hh:425
mode_t dMask[2]
Definition XrdOfs.hh:394
int myPort
Definition XrdOfs.hh:390
XrdCmsClient * Finder
Definition XrdOfs.hh:439
mode_t fMask[2]
Definition XrdOfs.hh:395
struct fwdOpt fwdRMDIR
Definition XrdOfs.hh:424
XrdOfsEvr evrObject
Definition XrdOfs.hh:438
char * ConfigFN
Definition XrdOfs.hh:430
int tpcRdrPort[2]
Definition XrdOfs.hh:400
virtual int Configure(XrdSysError &)
struct fwdOpt fwdMKPATH
Definition XrdOfs.hh:421
void Config_Display(XrdSysError &)
XrdOfs()
Definition XrdOfs.cc:171
char * tpcRdrHost[2]
Definition XrdOfs.hh:399
int Options
Definition XrdOfs.hh:389
struct fwdOpt fwdMKDIR
Definition XrdOfs.hh:420
static int MaxDelay
Definition XrdOfs.hh:427
struct fwdOpt fwdMV
Definition XrdOfs.hh:422
XrdNetIF * myIF
Definition XrdOfs.hh:404
const char * getVersion()
struct fwdOpt fwdRM
Definition XrdOfs.hh:423
virtual int ConfigXeq(char *var, XrdOucStream &, XrdSysError &)
bool ValidCST(const char *cst)
struct fwdOpt fwdCHMOD
Definition XrdOfs.hh:419
@ isProxy
Definition XrdOfs.hh:377
@ haveRole
Definition XrdOfs.hh:382
@ RdrTPC
Definition XrdOfs.hh:386
@ ThirdPC
Definition XrdOfs.hh:384
@ isMeta
Definition XrdOfs.hh:381
@ SubCluster
Definition XrdOfs.hh:385
@ isManager
Definition XrdOfs.hh:378
@ isPeer
Definition XrdOfs.hh:376
@ isSuper
Definition XrdOfs.hh:380
@ isServer
Definition XrdOfs.hh:379
@ Authorize
Definition XrdOfs.hh:374
@ Forwarding
Definition XrdOfs.hh:383
void Unpersist(XrdOfsHandle *hP, int xcev=1)
Definition XrdOfs.cc:2933
virtual int Unlink(const char *path, int Opts=0, XrdOucEnv *envP=0)=0
char * Get(const char *varname)
Definition XrdOucEnv.hh:69
static int Export(const char *Var, const char *Val)
Definition XrdOucEnv.cc:170
void * GetPtr(const char *varname)
Definition XrdOucEnv.cc:263
void PutPtr(const char *varname, void *value)
Definition XrdOucEnv.cc:298
void Put(const char *varname, const char *value)
Definition XrdOucEnv.hh:85
static const int retFile
static const int retLink
static void splitString(Container &result, const std::string &input, const std::string &delimiter)
Split a string.
static char * genPath(const char *path, const char *inst, const char *psfx=0)
static const char * InstName(int TranOpt=0)
static bool mode2mask(const char *mode, mode_t &mask)
static int doIf(XrdSysError *eDest, XrdOucStream &Config, const char *what, const char *hname, const char *nname, const char *pname)
static int makePath(char *path, mode_t mode, bool reset=false)
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 a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition XrdOuca2x.cc:288
virtual void EnvInfo(XrdOucEnv *envP)
uint64_t FeatureSet
Adjust features at initialization.
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)
XrdSysLogger * logger(XrdSysLogger *lp=0)
XrdCmsConfig Config
@ IsTarget
The role is server and will be a redirection target.
@ IsProxy
The role is proxy {plus one or more of the below}.
@ IsRedir
The role is manager and will redirect users.
@ IsMeta
The role is meta {plus one or more of the above}.
XrdOfsTPCConfig Cfg
Definition XrdOfsTPC.cc:85
XrdOucEnv * envP
Definition XrdPss.cc:110
static const uint64_t hasAUTZ
Feature: Authorization.
static const uint64_t hasPRP2
Feature: Prepare Handler Version 2 (different calling conventions).
static const uint64_t hasCACH
Feature: Implements a data cache.
static const uint64_t hasNOSF
Feature: Supports no sendfile.
static const uint64_t hasPOSC
Feature: Persist On Successful Close.
static const uint64_t hasFICL
Feature: Supports file cloning and samefs.
static const uint64_t hasNAIO
Feature: Supports no async I/O.
static const uint64_t hasPRXY
Feature: Proxy Server.
struct Request reqData
struct NSEnt * Next