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