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);
360 fwdCHMOD.Reset(); fwdMKDIR.Reset(); fwdMKPATH.Reset();
361 fwdMV.Reset(); fwdRM.Reset(); fwdRMDIR.Reset();
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;
531 XrdOfsPoscq::Request *qP;
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)))
618 Finder = (XrdCmsClient *)new XrdCmsFinderRMT(myLogger,
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//
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{
670 XrdOfsTPCConfig &Cfg = XrdOfsTPCParms::Cfg;
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{
700 XrdOfsTPCConfig &Cfg = XrdOfsTPCParms::Cfg;
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 [preclose {data | none}]
1422 [hold <sec>] [logdir <dirp>]
1423 [sync <snum>]
1424
1425 auto POSC processing always on for creation requests
1426 manual POSC processing must be requested (default)
1427 off POSC processing is disabled
1428 <sec> Seconds inclomplete files held (default 10m)
1429 <dirp> Directory to hold POSC recovery log (default adminpath)
1430 <snum> Number of outstanding equests before syncing to disk.
1431 preclose When data is specified fsync( is called before close().
1432 When none is specified, the default, this is skipped.
1433
1434 Output: 0 upon success or !0 upon failure.
1435*/
1436
1437int XrdOfs::xpers(XrdOucStream &Config, XrdSysError &Eroute)
1438{
1439 char *val;
1440 int snum = -1, htime = -1, popt = -2, fopt = -12;
1441
1442 if (!(val = Config.GetWord()))
1443 {Eroute.Emsg("Config","persist option not specified");return 1;}
1444
1445// Check for valid option
1446//
1447 if (!strcmp(val, "auto" )) popt = 1;
1448 else if (!strcmp(val, "off" )) popt = -1;
1449 else if (!strcmp(val, "manual" )) popt = 0;
1450
1451// Check if we should get the next token
1452//
1453 if (popt > -2) val = Config.GetWord();
1454
1455// Check for hold or log
1456//
1457 while(val)
1458 { if (!strcmp(val, "hold"))
1459 {if (!(val = Config.GetWord()))
1460 {Eroute.Emsg("Config","persist hold value not specified");
1461 return 1;
1462 }
1463 if (XrdOuca2x::a2tm(Eroute,"persist hold",val,&htime,0))
1464 return 1;
1465 }
1466 else if (!strcmp(val, "logdir"))
1467 {if (!(val = Config.GetWord()))
1468 {Eroute.Emsg("Config","persist logdir path not specified");
1469 return 1;
1470 }
1471 if (poscLog) free(poscLog);
1472
1473 poscLog = strdup(val);
1474 }
1475 else if (!strcmp(val, "preclose"))
1476 {if (!(val = Config.GetWord()))
1477 {Eroute.Emsg("Config","persist preclose parm not specified");
1478 return 1;
1479 }
1480 if (!strcmp(val, "data")) fopt = 1;
1481 else if (!strcmp(val, "none")) fopt = 0;
1482 else {Eroute.Emsg("Config","Invalid persist preclose parm -",
1483 val);
1484 return 1;
1485 }
1486 }
1487 else if (!strcmp(val, "sync"))
1488 {if (!(val = Config.GetWord()))
1489 {Eroute.Emsg("Config","sync value not specified");
1490 return 1;
1491 }
1492 if (XrdOuca2x::a2i(Eroute,"sync value",val,&snum,0,32767))
1493 return 1;
1494 }
1495 else Eroute.Say("Config warning: ignoring invalid persist option '",val,"'.");
1496 val = Config.GetWord();
1497 }
1498
1499// Set values as needed
1500//
1501 if (htime >= 0) poscHold = htime;
1502 if (fopt > -1) XrdOfsFile::ocFsync = fopt;
1503 if (popt > -2) poscAuto = popt;
1504 if (snum > -1) poscSync = snum;
1505 return 0;
1506}
1507
1508/******************************************************************************/
1509/* x r o l e */
1510/******************************************************************************/
1511
1512/* Function: xrole
1513
1514 Purpose: Parse: role { {[meta] | [proxy]} manager
1515 | [proxy] server
1516 | [proxy] supervisor
1517 } [if ...]
1518
1519 manager xrootd: act as a manager (redirecting server). Prefixes:
1520 meta - connect only to manager meta's
1521 proxy - ignored
1522 cmsd: accept server subscribes and redirectors. Prefix
1523 modifiers do the following:
1524 meta - No other managers apply
1525 proxy - manage a cluster of proxy servers
1526
1527 server xrootd: act as a server (supply local data). Prefix
1528 modifications do the following:
1529 proxy - server is part of a cluster. A local
1530 cmsd is required.
1531 cmsd: subscribe to a manager, possibly as a proxy.
1532
1533 supervisor xrootd: equivalent to manager. The prefix modification
1534 is ignored.
1535 cmsd: equivalent to manager but also subscribe to a
1536 manager. When proxy is specified, then subscribe
1537 as a proxy and only accept proxies.
1538
1539 if Apply the manager directive if "if" is true. See
1540 XrdOucUtils:doIf() for "if" syntax.
1541
1542 Notes 1. The peer designation only affects how the olbd communicates.
1543
1544 Type: Server only, non-dynamic.
1545
1546 Output: 0 upon success or !0 upon failure.
1547*/
1548
1549int XrdOfs::xrole(XrdOucStream &Config, XrdSysError &Eroute)
1550{
1551 const int resetit = ~haveRole;
1552 XrdCmsRole::RoleID roleID;
1553 char *val, *Tok1, *Tok2;
1554 int rc, ropt = 0;
1555
1556// Get the first token
1557//
1558 if (!(val = Config.GetWord()) || !strcmp(val, "if"))
1559 {Eroute.Emsg("Config", "role not specified"); return 1;}
1560 Tok1 = strdup(val);
1561
1562// Get second token which might be an "if"
1563//
1564 if ((val = Config.GetWord()) && strcmp(val, "if"))
1565 {Tok2 = strdup(val);
1566 val = Config.GetWord();
1567 } else Tok2 = 0;
1568
1569// Process the if at this point
1570//
1571 if (val && !strcmp("if", val))
1572 {if ((rc = XrdOucUtils::doIf(&Eroute,Config,"role directive",
1573 getenv("XRDHOST"), XrdOucUtils::InstName(1),
1574 getenv("XRDPROG"))) <= 0)
1575 {free(Tok1); if (Tok2) free(Tok2);
1576 if (!rc) Config.noEcho();
1577 return (rc < 0);
1578 }
1579 }
1580
1581// Convert the role names to a role ID, if possible
1582//
1583 roleID = XrdCmsRole::Convert(Tok1, Tok2);
1584
1585// Set markers based on the role we have
1586//
1587 rc = 0;
1588 switch(roleID)
1589 {case XrdCmsRole::MetaManager: ropt = isManager | isMeta ; break;
1590 case XrdCmsRole::Manager: ropt = isManager ; break;
1591 case XrdCmsRole::Supervisor: ropt = isSuper ; break;
1592 case XrdCmsRole::Server: ropt = isServer ; break;
1593 case XrdCmsRole::ProxyManager: ropt = isManager | isProxy; break;
1594 case XrdCmsRole::ProxySuper: ropt = isSuper | isProxy; break;
1595 case XrdCmsRole::ProxyServer: ropt = isServer | isProxy; break;
1596 default: Eroute.Emsg("Config", "invalid role -", Tok1, Tok2); rc = 1;
1597 }
1598
1599// Release storage and return if an error occurred
1600//
1601 free(Tok1);
1602 if (Tok2) free(Tok2);
1603 if (rc) return rc;
1604
1605// Set values
1606//
1607 free(myRole);
1608 myRole = strdup(XrdCmsRole::Name(roleID));
1609 strcpy(myRType, XrdCmsRole::Type(roleID));
1610 Options &= resetit;
1611 Options |= ropt;
1612 return 0;
1613}
1614
1615/******************************************************************************/
1616/* x t p c */
1617/******************************************************************************/
1618
1619/* Function: xtpc
1620
1621 Purpose: To parse the directive: tpc [cksum <type>] [ttl <dflt> [<max>]]
1622 [logok] [xfr <n>] [allow <parms>]
1623 [require {all|client|dest} <auth>[+]]
1624 [restrict <path>]
1625 [streams <num>[,<max>]]
1626 [echo] [scan {stderr | stdout}]
1627 [autorm] [pgm <path> [parms]]
1628 [fcreds [?]<auth> =<evar>]
1629 [fcpath <path>] [oids]
1630
1631 tpc redirect [xdlg] <host>:<port> [<cgi>]
1632
1633 xdlg: delegated | undelegated
1634
1635 parms: [dn <name>] [group <grp>] [host <hn>] [vo <vo>]
1636
1637 <dflt> the default seconds a tpc authorization may be valid.
1638 <max> the maximum seconds a tpc authorization may be valid.
1639 cksum checksum incoming files using <type> checksum.
1640 logok log successful authorizations.
1641 allow only allow destinations that match the specified
1642 authentication specification.
1643 <n> maximum number of simultaneous transfers.
1644 <num> the default number of TCP streams to use for the copy.
1645 <max> The maximum number of TCP streams to use for the copy/
1646 <auth> require that the client, destination, or both (i.e. all)
1647 use the specified authentication protocol. Additional
1648 require statements may be specified to add additional
1649 valid authentication mechanisms. If the <auth> is suffixed
1650 by a plus, then the request must also be encrypted using
1651 the authentication's session key.
1652 echo echo the pgm's output to the log.
1653 autorm Remove file when copy fails.
1654 scan scan fr error messages either in stderr or stdout. The
1655 default is to scan both.
1656 pgm specifies the transfer command with optional paramaters.
1657 It must be the last parameter on the line.
1658 fcreds Forward destination credentials for protocol <auth>. The
1659 request fails if thee are no credentials for <auth>. If a
1660 question mark preceeds <auth> then if the client has not
1661 forwarded its credentials, the server's credentials are
1662 used. Otherwise, the copy fails.
1663 =<evar> the name of the envar to be set with the path to the
1664 credentials to be forwarded.
1665 fcpath where creds are stored (default <adminpath>/.ofs/.tpccreds).
1666 oids Object ID's are acceptable for the source lfn.
1667 <host> The redirection target host which may be localhost.
1668 <port> The redirection target port.
1669 <cgi> Optional cgi information.
1670
1671 Output: 0 upon success or !0 upon failure.
1672*/
1673
1674int XrdOfs::xtpc(XrdOucStream &Config, XrdSysError &Eroute)
1675{
1676 char *val, pgm[1024];
1677 XrdOfsTPCConfig &Parms = XrdOfsTPCParms::Cfg;
1678 *pgm = 0;
1679 int reqType;
1680 bool rdrok = true;
1681
1682 while((val = Config.GetWord()))
1683 {if (!strcmp(val, "redirect"))
1684 {if (rdrok) return xtpcr(Config, Eroute);
1685 Eroute.Emsg("Config", "tpc redirect must be seprately specified.");
1686 return 1;
1687 }
1688 rdrok = false;
1689 if (!strcmp(val, "allow"))
1690 {if (!xtpcal(Config, Eroute)) return 1;
1691 continue;
1692 }
1693 if (!strcmp(val, "cksum"))
1694 {if (!(val = Config.GetWord()))
1695 {Eroute.Emsg("Config","cksum type not specified"); return 1;}
1696 if (Parms.cksType) free(Parms.cksType);
1697 Parms.cksType = strdup(val);
1698 continue;
1699 }
1700 if (!strcmp(val, "scan"))
1701 {if (!(val = Config.GetWord()))
1702 {Eroute.Emsg("Config","scan type not specified"); return 1;}
1703 if (strcmp(val, "stderr")) Parms.errMon = -2;
1704 else if (strcmp(val, "stdout")) Parms.errMon = -1;
1705 else if (strcmp(val, "all" )) Parms.errMon = 0;
1706 else {Eroute.Emsg("Config","invalid scan type -",val); return 1;}
1707 continue;
1708 }
1709 if (!strcmp(val, "echo")) {Parms.doEcho = true; continue;}
1710 if (!strcmp(val, "logok")) {Parms.LogOK = true; continue;}
1711 if (!strcmp(val, "autorm")){Parms.autoRM = true; continue;}
1712 if (!strcmp(val, "oids")) {Parms.noids = false;continue;}
1713 if (!strcmp(val, "pgm"))
1714 {if (!Config.GetRest(pgm, sizeof(pgm)))
1715 {Eroute.Emsg("Config", "tpc command line too long"); return 1;}
1716 if (!*pgm)
1717 {Eroute.Emsg("Config", "tpc program not specified"); return 1;}
1718 if (Parms.XfrProg) free(Parms.XfrProg);
1719 Parms.XfrProg = strdup( pgm );
1720 break;
1721 }
1722 if (!strcmp(val, "require"))
1723 {if (!(val = Config.GetWord()))
1724 {Eroute.Emsg("Config","tpc require parameter not specified"); return 1;}
1725 if (!strcmp(val, "all")) reqType = XrdOfsTPC::reqALL;
1726 else if (!strcmp(val, "client")) reqType = XrdOfsTPC::reqORG;
1727 else if (!strcmp(val, "dest")) reqType = XrdOfsTPC::reqDST;
1728 else {Eroute.Emsg("Config", "invalid tpc require type -", val); return 1;}
1729 break;
1730 if (!(val = Config.GetWord()))
1731 {Eroute.Emsg("Config","tpc require auth not specified"); return 1;}
1732 XrdOfsTPC::Require(val, reqType);
1733 continue;
1734 }
1735 if (!strcmp(val, "restrict"))
1736 {if (!(val = Config.GetWord()))
1737 {Eroute.Emsg("Config","tpc restrict path not specified"); return 1;}
1738 if (*val != '/')
1739 {Eroute.Emsg("Config","tpc restrict path not absolute"); return 1;}
1740 if (!XrdOfsTPC::Restrict(val)) return 1;
1741 continue;
1742 }
1743 if (!strcmp(val, "ttl"))
1744 {if (!(val = Config.GetWord()))
1745 {Eroute.Emsg("Config","tpc ttl value not specified"); return 1;}
1746 if (XrdOuca2x::a2tm(Eroute,"tpc ttl default",val,&Parms.dflTTL,1))
1747 return 1;
1748 if (!(val = Config.GetWord())) break;
1749 if (!(isdigit(*val))) {Config.RetToken(); continue;}
1750 if (XrdOuca2x::a2tm(Eroute,"tpc ttl maximum",val,&Parms.maxTTL,1))
1751 return 1;
1752 continue;
1753 }
1754 if (!strcmp(val, "xfr"))
1755 {if (!(val = Config.GetWord()))
1756 {Eroute.Emsg("Config","tpc xfr value not specified"); return 1;}
1757 if (XrdOuca2x::a2i(Eroute,"tpc xfr",val,&Parms.xfrMax,1)) return 1;
1758 continue;
1759 }
1760 if (!strcmp(val, "streams"))
1761 {if (!(val = Config.GetWord()))
1762 {Eroute.Emsg("Config","tpc streams value not specified"); return 1;}
1763 char *comma = index(val,',');
1764 if (comma)
1765 {*comma++ = 0;
1766 if (!(*comma))
1767 {Eroute.Emsg("Config","tpc streams max value missing"); return 1;}
1768 if (XrdOuca2x::a2i(Eroute,"tpc max streams",comma,&Parms.tcpSMax,0,15))
1769 return 1;
1770 }
1771 if (XrdOuca2x::a2i(Eroute,"tpc streams",val,&Parms.tcpSTRM,0,15)) return 1;
1772 continue;
1773 }
1774 if (!strcmp(val, "fcreds"))
1775 {char aBuff[64];
1776 Parms.fCreds = true;
1777 if (!(val = Config.GetWord()) || (*val == '?' && *(val+1) == '\0'))
1778 {Eroute.Emsg("Config","tpc fcreds auth not specified"); return 1;}
1779 if (strlen(val) >= sizeof(aBuff))
1780 {Eroute.Emsg("Config","invalid fcreds auth -", val); return 1;}
1781 strcpy(aBuff, val);
1782 if (!(val = Config.GetWord()) || *val != '=' || *(val+1) == 0)
1783 {Eroute.Emsg("Config","tpc fcreds envar not specified"); return 1;}
1784 const char *emsg = XrdOfsTPC::AddAuth(aBuff,val+1);
1785 if (emsg) {Eroute.Emsg("Config",emsg,"-", val); return 1;}
1786 continue;
1787 }
1788 if (!strcmp(val, "fcpath"))
1789 {if (!(val = Config.GetWord()))
1790 {Eroute.Emsg("Config","tpc fcpath arg not specified"); return 1;}
1791 if (Parms.cPath) free(Parms.cPath);
1792 Parms.cPath = strdup(val);
1793 continue;
1794 }
1795 Eroute.Say("Config warning: ignoring invalid tpc option '",val,"'.");
1796 }
1797
1798 Options |= ThirdPC;
1799 return 0;
1800}
1801
1802/******************************************************************************/
1803/* x t p c a l */
1804/******************************************************************************/
1805
1806int XrdOfs::xtpcal(XrdOucStream &Config, XrdSysError &Eroute)
1807{
1808 struct tpcalopts {const char *opname; char *opval;} tpopts[] =
1809 {{"dn", 0}, {"group", 0}, {"host", 0}, {"vo", 0}};
1810 int i, spec = 0, numopts = sizeof(tpopts)/sizeof(struct tpcalopts);
1811 char *val;
1812
1813 while((val = Config.GetWord()))
1814 {for (i = 0; i < numopts && strcmp(tpopts[i].opname, val); i++) {}
1815 if (i > numopts) {Config.RetToken(); break;}
1816 {Eroute.Emsg("Config", "invalid tpc allow parameter -", val);
1817 return 0;
1818 }
1819 if (!(val = Config.GetWord()))
1820 {Eroute.Emsg("Config","tpc allow",tpopts[i].opname,"value not specified");
1821 return 0;
1822 }
1823 if (tpopts[i].opval) free(tpopts[i].opval);
1824 tpopts[i].opval = strdup(val);
1825 spec = 1;
1826 }
1827
1828 if (!spec) {Eroute.Emsg("Config","tpc allow parms not specified"); return 1;}
1829
1830 XrdOfsTPC::Allow(tpopts[0].opval, tpopts[1].opval,
1831 tpopts[2].opval, tpopts[3].opval);
1832 return 1;
1833}
1834
1835/******************************************************************************/
1836/* x t p c r */
1837/******************************************************************************/
1838
1839int XrdOfs::xtpcr(XrdOucStream &Config, XrdSysError &Eroute)
1840{
1841 char hname[256];
1842 const char *cgi, *cgisep, *hBeg, *hEnd, *pBeg, *pEnd, *eText;
1843 char *val;
1844 int n, port, dlgI;
1845
1846// Get the next token
1847//
1848 if (!(val = Config.GetWord()))
1849 {Eroute.Emsg("Config", "tpc redirect host not specified"); return 1;}
1850
1851// See if this is for delegated or undelegated (all is the default)
1852//
1853 if (!strcmp(val, "delegated")) dlgI = 0;
1854 else if (!strcmp(val, "undelegated")) dlgI = 1;
1855 else dlgI = -1;
1856
1857// Get host and port
1858//
1859 if (dlgI >= 0 && !(val = Config.GetWord()))
1860 {Eroute.Emsg("Config", "tpc redirect host not specified"); return 1;}
1861
1862// Parse this as it may be complicated.
1863//
1864 if (!XrdNetUtils::Parse(val, &hBeg, &hEnd, &pBeg, &pEnd))
1865 {Eroute.Emsg("Config", "Invalid tpc redirect target -", val); return 1;}
1866
1867// Copy out the host target (make sure it's not too long)
1868//
1869 n = hEnd - hBeg;
1870 if (*val == '[') n += 2;
1871 if (n >= (int)sizeof(hname))
1872 {Eroute.Emsg("Config", "Invalid tpc redirect target -", val); return 1;}
1873 strncpy(hname, val, n);
1874 hname[n] = 0;
1875
1876// Substitute our hostname for localhost if present
1877//
1878 if (!strcmp(hname, "localhost"))
1879 {char *myHost = XrdNetUtils::MyHostName(0, &eText);
1880 if (!myHost)
1881 {Eroute.Emsg("Config", "Unable to determine tpc localhost;",eText);
1882 return 1;
1883 }
1884 n = snprintf(hname, sizeof(hname), "%s", myHost);
1885 free(myHost);
1886 if (n >= (int)sizeof(hname))
1887 {Eroute.Emsg("Config", "Invalid tpc localhost resolution -", hname);
1888 return 1;
1889 }
1890 }
1891
1892// Make sure a port was specified
1893//
1894 if (pBeg == hEnd)
1895 {Eroute.Emsg("Config", "tpc redirect port not specified"); return 1;}
1896
1897// Get the numeric version of the port number
1898//
1899 if (!(port = XrdNetUtils::ServPort(pBeg, false, &eText)))
1900 {Eroute.Emsg("Config", "Invalid tpc redirect port;",eText); return 1;}
1901
1902// Check if there is cgi that must be included
1903//
1904 if (!(cgi = Config.GetWord())) cgisep = cgi = (char *)"";
1905 else cgisep = (*cgi != '?' ? "?" : "");
1906
1907// Copy out the hostname to be used
1908//
1909 int k = (dlgI < 0 ? 0 : dlgI);
1910do{if (tpcRdrHost[k]) {free(tpcRdrHost[k]); tpcRdrHost[k] = 0;}
1911
1912 n = strlen(hname) + strlen(cgisep) + strlen(cgi) + 1;
1913 tpcRdrHost[k] = (char *)malloc(n);
1914 snprintf(tpcRdrHost[k], n, "%s%s%s", hname, cgisep, cgi);
1915 tpcRdrPort[k] = port;
1916 k++;
1917 } while(dlgI < 0 && k < 2);
1918
1919// All done
1920//
1921 Options |= RdrTPC;
1922 return 0;
1923}
1924
1925/******************************************************************************/
1926/* x t r a c e */
1927/******************************************************************************/
1928
1929/* Function: xtrace
1930
1931 Purpose: To parse the directive: trace <events>
1932
1933 <events> the blank separated list of events to trace. Trace
1934 directives are cummalative.
1935
1936 Output: 0 upon success or !0 upon failure.
1937*/
1938
1939int XrdOfs::xtrace(XrdOucStream &Config, XrdSysError &Eroute)
1940{
1941 static struct traceopts {const char *opname; int opval;} tropts[] =
1942 {{"aio", TRACE_aio},
1943 {"all", TRACE_ALL},
1944 {"chkpnt", TRACE_chkpnt},
1945 {"chmod", TRACE_chmod},
1946 {"close", TRACE_close},
1947 {"closedir", TRACE_closedir},
1948 {"debug", TRACE_debug},
1949 {"delay", TRACE_delay},
1950 {"dir", TRACE_dir},
1951 {"exists", TRACE_exists},
1952 {"getstats", TRACE_getstats},
1953 {"fsctl", TRACE_fsctl},
1954 {"io", TRACE_IO},
1955 {"mkdir", TRACE_mkdir},
1956 {"most", TRACE_MOST},
1957 {"open", TRACE_open},
1958 {"opendir", TRACE_opendir},
1959 {"qscan", TRACE_qscan},
1960 {"read", TRACE_read},
1961 {"readdir", TRACE_readdir},
1962 {"redirect", TRACE_redirect},
1963 {"remove", TRACE_remove},
1964 {"rename", TRACE_rename},
1965 {"sync", TRACE_sync},
1966 {"truncate", TRACE_truncate},
1967 {"write", TRACE_write}
1968 };
1969 int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
1970 char *val;
1971
1972 if (!(val = Config.GetWord()))
1973 {Eroute.Emsg("Config", "trace option not specified"); return 1;}
1974 while (val)
1975 {if (!strcmp(val, "off")) trval = 0;
1976 else {if ((neg = (val[0] == '-' && val[1]))) val++;
1977 for (i = 0; i < numopts; i++)
1978 {if (!strcmp(val, tropts[i].opname))
1979 {if (neg) trval &= ~tropts[i].opval;
1980 else trval |= tropts[i].opval;
1981 break;
1982 }
1983 }
1984 if (i >= numopts)
1985 Eroute.Say("Config warning: ignoring invalid trace option '",val,"'.");
1986 }
1987 val = Config.GetWord();
1988 }
1989 OfsTrace.What = trval;
1990
1991// All done
1992//
1993 return 0;
1994}
1995
1996/******************************************************************************/
1997/* x a t r */
1998/******************************************************************************/
1999
2000/* Function: xatr
2001
2002 Purpose: To parse the directive: xattr [maxnsz <nsz>] [maxvsz <vsz>]
2003
2004 [uset {on|off}]
2005
2006 on enables user settable extended attributes.
2007
2008 off disaables user settable extended attributes.
2009
2010 <nsz> maximum length of an attribute name. The user
2011 specifiable limit will be 8 less.
2012
2013 <vsz> maximum length of an attribute value.
2014
2015 Notes: 1. This directive is not cummalative.
2016
2017 Output: 0 upon success or !0 upon failure.
2018*/
2019
2020int XrdOfs::xatr(XrdOucStream &Config, XrdSysError &Eroute)
2021{
2022 char *val;
2023 static const int xanRsv = 7;
2024 long long vtmp;
2025 int maxN = kXR_faMaxNlen, maxV = kXR_faMaxVlen;
2026 bool isOn = true;
2027
2028 while((val = Config.GetWord()))
2029 { if (!strcmp("maxnsz", val))
2030 {if (!(val = Config.GetWord()))
2031 {Eroute.Emsg("Config","xattr maxnsz value not specified");
2032 return 1;
2033 }
2034 if (XrdOuca2x::a2sz(Eroute,"maxnsz",val,&vtmp,
2035 xanRsv+1,kXR_faMaxNlen+xanRsv)) return 1;
2036 maxN = static_cast<int>(vtmp);
2037 }
2038 else if (!strcmp("maxvsz", val))
2039 {if (!(val = Config.GetWord()))
2040 {Eroute.Emsg("Config","xattr maxvsz value not specified");
2041 return 1;
2042 }
2043 if (XrdOuca2x::a2sz(Eroute,"maxvsz",val,&vtmp,0,kXR_faMaxVlen))
2044 return 1;
2045 maxV = static_cast<int>(vtmp);
2046 }
2047 else if (!strcmp("uset", val))
2048 {if (!(val = Config.GetWord()))
2049 {Eroute.Emsg("Config","xattr uset value not specified");
2050 return 1;
2051 }
2052 if (!strcmp("on", val)) isOn = true;
2053 else if (!strcmp("off", val)) isOn = false;
2054 else {Eroute.Emsg("Config", "invalid xattr uset value -", val);
2055 return 1;
2056 }
2057 }
2058 else {Eroute.Emsg("Config", "invalid xattr option -", val);
2059 return 1;
2060 }
2061 }
2062
2063 usxMaxNsz = (isOn ? maxN-xanRsv : 0);
2064 usxMaxVsz = maxV;
2065 return 0;
2066}
2067
2068/******************************************************************************/
2069/* t h e R o l e */
2070/******************************************************************************/
2071
2072const char *XrdOfs::theRole(int opts)
2073{
2074 if (opts & isPeer) return "peer";
2075 else if (opts & isManager
2076 && opts & isServer) return "supervisor";
2077 else if (opts & isManager) return "manager";
2078 else if (opts & isProxy) {return "proxy";}
2079 return "server";
2080}
@ 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:160
#define setBuff(x, y)
XrdScheduler * ofsSchedP
XrdVERSIONINFO(XrdOfs, XrdOfs)
#define TS_XPI(x, m)
#define TRACE_dir
#define TRACE_rename
#define TRACE_read
#define TRACE_qscan
#define TRACE_getstats
#define TRACE_chkpnt
#define TRACE_exists
#define TRACE_close
#define TRACE_open
#define TRACE_sync
#define TRACE_truncate
#define TRACE_remove
#define TRACE_redirect
#define TRACE_opendir
#define TRACE_chmod
#define TRACE_closedir
#define TRACE_IO
#define TRACE_readdir
#define TRACE_mkdir
#define TRACE_MOST
#define TRACE_fsctl
#define TRACE_aio
#define TRACE_write
XrdSysTrace OfsTrace("ofs")
XrdOss * XrdOfsOss
Definition XrdOfs.cc: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
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)
static XrdOfsConfigPI * New(const char *cfn, XrdOucStream *cfgP, XrdSysError *errP, XrdVersionInfo *verP=0, XrdSfsFileSystem *sfsP=0)
@ theOssLib
Oss plugin.
@ allXXXLib
All plugins (Load() only)
@ theCksLib
Checksum manager plugin.
static int Parse(XrdSysError &Eroute, Event eNum, char *mText)
Definition XrdOfsEvs.cc:287
The Plugins struct is used to pass plugin pointers to configure.
static bool ocFsync
Definition XrdOfs.hh:194
int Retire(int &retc, long long *retsz=0, char *buff=0, int blen=0)
int PoscSet(const char *User, int Unum, short Mode)
static const int opPC
static int Alloc(const char *thePath, int Opts, XrdOfsHandle **Handle)
static int Restrict(const char *Path)
Definition XrdOfsTPC.cc:465
static const int reqDST
Definition XrdOfsTPC.hh:86
static const char * AddAuth(const char *auth, const char *avar)
Definition XrdOfsTPC.cc:164
static void Init()
Definition XrdOfsTPC.cc:414
static int Start()
Definition XrdOfsTPC.cc:520
static const int reqORG
Definition XrdOfsTPC.hh:87
static void Require(const char *Auth, int RType)
Definition XrdOfsTPC.cc:445
static void Allow(char *vDN, char *vGN, char *vHN, char *vVO)
Definition XrdOfsTPC.cc:209
static const int reqALL
Definition XrdOfsTPC.hh:85
struct fwdOpt fwdTRUNC
Definition XrdOfs.hh:417
mode_t dMask[2]
Definition XrdOfs.hh:386
int myPort
Definition XrdOfs.hh:382
XrdCmsClient * Finder
Definition XrdOfs.hh:431
mode_t fMask[2]
Definition XrdOfs.hh:387
struct fwdOpt fwdRMDIR
Definition XrdOfs.hh:416
XrdOfsEvr evrObject
Definition XrdOfs.hh:430
char * ConfigFN
Definition XrdOfs.hh:422
int tpcRdrPort[2]
Definition XrdOfs.hh:392
virtual int Configure(XrdSysError &)
struct fwdOpt fwdMKPATH
Definition XrdOfs.hh:413
void Config_Display(XrdSysError &)
XrdOfs()
Definition XrdOfs.cc:169
char * tpcRdrHost[2]
Definition XrdOfs.hh:391
int Options
Definition XrdOfs.hh:381
struct fwdOpt fwdMKDIR
Definition XrdOfs.hh:412
static int MaxDelay
Definition XrdOfs.hh:419
struct fwdOpt fwdMV
Definition XrdOfs.hh:414
XrdNetIF * myIF
Definition XrdOfs.hh:396
const char * getVersion()
struct fwdOpt fwdRM
Definition XrdOfs.hh:415
virtual int ConfigXeq(char *var, XrdOucStream &, XrdSysError &)
struct fwdOpt fwdCHMOD
Definition XrdOfs.hh:411
@ isProxy
Definition XrdOfs.hh:369
@ haveRole
Definition XrdOfs.hh:374
@ RdrTPC
Definition XrdOfs.hh:378
@ ThirdPC
Definition XrdOfs.hh:376
@ isMeta
Definition XrdOfs.hh:373
@ SubCluster
Definition XrdOfs.hh:377
@ isManager
Definition XrdOfs.hh:370
@ isPeer
Definition XrdOfs.hh:368
@ isSuper
Definition XrdOfs.hh:372
@ isServer
Definition XrdOfs.hh:371
@ Authorize
Definition XrdOfs.hh:366
@ Forwarding
Definition XrdOfs.hh:375
void Unpersist(XrdOfsHandle *hP, int xcev=1)
Definition XrdOfs.cc:2743
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)
XrdCmsConfig Config
@ IsTarget
The role is server and will be a redirection target.
@ IsProxy
The role is proxy {plus one or more of the below}.
@ IsRedir
The role is manager and will redirect users.
@ IsMeta
The role is meta {plus one or more of the above}.
XrdOfsTPCConfig Cfg
Definition XrdOfsTPC.cc:85
XrdOucEnv * envP
Definition XrdPss.cc: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
struct NSEnt * Next