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