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