XRootD
XrdCmsConfig.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C m s C o n f i g . c c */
4 /* */
5 /* (c) 2011 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 Department 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 /*
32  The methods in this file handle cmsd() initialization.
33 */
34 
35 #include <string>
36 #include <unistd.h>
37 #include <cctype>
38 #include <fcntl.h>
39 #include <strings.h>
40 #include <cstdio>
41 #include <sys/param.h>
42 #include <sys/resource.h>
43 #include <sys/stat.h>
44 #include <sys/types.h>
45 #include <dirent.h>
46 
47 #include "XrdVersion.hh"
48 #include "Xrd/XrdProtocol.hh"
49 #include "Xrd/XrdScheduler.hh"
50 #include "Xrd/XrdSendQ.hh"
51 
52 #include "XrdCms/XrdCmsAdmin.hh"
53 #include "XrdCms/XrdCmsBaseFS.hh"
55 #include "XrdCms/XrdCmsCache.hh"
56 #include "XrdCms/XrdCmsCluster.hh"
57 #include "XrdCms/XrdCmsConfig.hh"
58 #include "XrdCms/XrdCmsManager.hh"
59 #include "XrdCms/XrdCmsMeter.hh"
60 #include "XrdCms/XrdCmsNode.hh"
61 #include "XrdCms/XrdCmsPrepare.hh"
62 #include "XrdCms/XrdCmsPrepArgs.hh"
63 #include "XrdCms/XrdCmsProtocol.hh"
64 #include "XrdCms/XrdCmsRole.hh"
65 #include "XrdCms/XrdCmsRRQ.hh"
66 #include "XrdCms/XrdCmsSecurity.hh"
67 #include "XrdCms/XrdCmsSelect.hh"
68 #include "XrdCms/XrdCmsState.hh"
70 #include "XrdCms/XrdCmsTrace.hh"
71 #include "XrdCms/XrdCmsUtils.hh"
72 
73 #include "XrdNet/XrdNetOpts.hh"
74 #include "XrdNet/XrdNetUtils.hh"
75 #include "XrdNet/XrdNetSecurity.hh"
76 #include "XrdNet/XrdNetSocket.hh"
77 
78 #include "XrdOss/XrdOss.hh"
79 
80 #include "XrdOuc/XrdOuca2x.hh"
81 #include "XrdOuc/XrdOucEnv.hh"
82 #include "XrdOuc/XrdOucExport.hh"
84 #include "XrdOuc/XrdOucProg.hh"
85 #include "XrdOuc/XrdOucStream.hh"
86 #include "XrdOuc/XrdOucUtils.hh"
87 
88 #include "XrdSys/XrdSysError.hh"
89 #include "XrdSys/XrdSysHeaders.hh"
90 #include "XrdSys/XrdSysPlatform.hh"
91 #include "XrdSys/XrdSysPthread.hh"
92 #include "XrdSys/XrdSysTimer.hh"
93 
94 using namespace XrdCms;
95 
96 /******************************************************************************/
97 /* G l o b a l O b j e c t s */
98 /******************************************************************************/
99 
100 namespace XrdCms
101 {
103 
105 
107 
109 
110  XrdSysError Say(0, "");
111 
112  XrdSysTrace Trace("cms");
113 
115 };
116 
117 /******************************************************************************/
118 /* S e c u r i t y S y m b o l T i e - I n */
119 /******************************************************************************/
120 
121 // The following is a bit of a kludge. The client side will use the xrootd
122 // security infrastructure if it exists. This is tipped off by the presence
123 // of the following symbol being non-zero. On the server side, we have no
124 // such symbol and need to provide one initialized to zero.
125 //
126  XrdSecProtocol *(*XrdXrootdSecGetProtocol)
127  (const char *hostname,
128  const struct sockaddr &netaddr,
129  const XrdSecParameters &parms,
130  XrdOucErrInfo *einfo)=0;
131 
132 /******************************************************************************/
133 /* E x t e r n a l T h r e a d I n t e r f a c e s */
134 /******************************************************************************/
135 
136 void *XrdCmsStartMonPerf(void *carg) { return Cluster.MonPerf(); }
137 
138 void *XrdCmsStartMonRefs(void *carg) { return Cluster.MonRefs(); }
139 
140 void *XrdCmsStartMonStat(void *carg) { return CmsState.Monitor(); }
141 
142 void *XrdCmsStartAdmin(void *carg)
143  {return XrdCms::Admin.Start((XrdNetSocket *)carg);
144  }
145 
146 void *XrdCmsStartAnote(void *carg)
147  {XrdCmsAdmin Anote;
148  return Anote.Notes((XrdNetSocket *)carg);
149  }
150 
151 void *XrdCmsStartPreparing(void *carg)
153  return (void *)0;
154  }
155 
156 void *XrdCmsStartSupervising(void *carg)
158  return (void *)0;
159  }
160 
161 /******************************************************************************/
162 /* P i n g C l o c k H a n d l e r */
163 /******************************************************************************/
164 
165 namespace XrdCms
166 {
167 
169 {
170 public:
171 
172  void DoIt() {Config.PingTick++;
173  Sched->Schedule((XrdJob *)this,time(0)+Config.AskPing);
174  }
175 
176 static void Start() {static PingClock selfie;}
177 
178  PingClock() : XrdJob(".ping clock") {DoIt();}
180 private:
181 };
182 };
183 
184 /******************************************************************************/
185 /* d e f i n e s */
186 /******************************************************************************/
187 
188 #define TS_Lib(x, y, z) if (!strcmp(x, var)) \
189  return (XrdOucUtils::parseLib(*eDest, CFile, x, y, z) ? 0 : 1);
190 
191 #define TS_String(x,m) if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;}
192 
193 #define TS_Xeq(x,m) if (!strcmp(x,var)) return m(eDest, CFile);
194 #define TS_Xer(x,m,v) if (!strcmp(x,var)) return m(eDest, CFile, v);
195 
196 #define TS_Set(x,v) if (!strcmp(x,var)) {v=1; CFile.Echo(true); return 0;}
197 
198 #define TS_unSet(x,v) if (!strcmp(x,var)) {v=0; CFile.Echo(true); return 0;}
199 
200 /******************************************************************************/
201 /* C o n f i g u r e 0 */
202 /******************************************************************************/
203 
205 {
206 
207 // Initialize the error message handler and get starting values
208 //
209  Say.logger(pi->eDest->logger(0));
210  Trace.SetLogger(pi->eDest->logger(0));
211  myName = strdup(pi->myName);
212  PortTCP = (pi->Port < 0 ? 0 : pi->Port);
213  myInsName = strdup(pi->myInst);
214  myProg = strdup(pi->myProg);
215  Sched = pi->Sched;
216  if (pi->AdmPath) AdminPath = strdup(pi->AdmPath);
217  else AdminPath = XrdOucUtils::genPath("/tmp/",
218  XrdOucUtils::InstName(myInsName,0));
219  AdminMode = pi->AdmMode;
220  if (pi->DebugON) Trace.What = TRACE_ALL;
221  xrdEnv = pi->theEnv;
222 
223 // Create an xrootd compatabile environment
224 //
225  theEnv.PutPtr("XrdScheduler*", Sched);
226  if (pi->theEnv) theEnv.PutPtr("xrdEnv*", pi->theEnv);
227 
228 // All done
229 //
230  return 0;
231 }
232 
233 /******************************************************************************/
234 /* C o n f i g u r e 1 */
235 /******************************************************************************/
236 
237 int XrdCmsConfig::Configure1(int argc, char **argv, char *cfn)
238 {
239 /*
240  Function: Establish phase 1 configuration at start up time.
241 
242  Input: argc - argument count
243  argv - argument vector
244  cfn - optional configuration file name
245 
246  Output: 0 upon success or !0 otherwise.
247 */
248  int NoGo = 0, immed = 0;
249  char c, buff[512];
250  extern int opterr, optopt;
251 
252 // Process the options
253 //
254  opterr = 0; optind = 1;
255  if (argc > 1 && '-' == *argv[1])
256  while ((c=getopt(argc,argv,"iw")) && ((unsigned char)c != 0xff))
257  { switch(c)
258  {
259  case 'i': immed = 1;
260  break;
261  case 'w': immed = -1; // Backward compatibility only
262  break;
263  default: buff[0] = '-'; buff[1] = optopt; buff[2] = '\0';
264  Say.Say("Config warning: unrecognized option, ",buff,", ignored.");
265  }
266  }
267 
268 // Accept a single parameter defining the overiding major role
269 //
270  if (optind < argc)
271  { if (!strcmp(argv[optind], "manager")) isManager = 1;
272  else if (!strcmp(argv[optind], "server" )) isServer = 1;
273  else if (!strcmp(argv[optind], "super" )) isServer = isManager = 1;
274  else Say.Say("Config warning: unrecognized parameter, ",
275  argv[optind],", ignored.");
276  }
277 
278 // Bail if no configuration file specified
279 //
280  inArgv = argv; inArgc = argc;
281  if ((!(ConfigFN = cfn) && !(ConfigFN = getenv("XrdCmsCONFIGFN")))
282  || !*ConfigFN)
283  {Say.Emsg("Config", "Required config file not specified.");
284  Usage(1);
285  }
286 
287 // Establish my instance name
288 //
289  sprintf(buff, "%s@%s", XrdOucUtils::InstName(myInsName), myName);
290  myInstance = strdup(buff);
291 
292 // This is somewhat poor but we need to establish the default non-blocking
293 // message queue limit for the cms (this being 30) which can be overriden.
294 //
295  XrdSendQ::SetQM(30);
296 
297 // Print herald
298 //
299  Say.Say("++++++ ", myInstance, " phase 1 initialization started.");
300 
301 // If we don't know our role yet then we must find out before processing the
302 // config file. This means a double scan, sigh.
303 //
304  if (!(isManager || isServer))
305  if (!(NoGo |= ConfigProc(1)) && !(isManager || isServer))
306  {Say.Say("Config warning: role not specified; manager role assumed.");
307  isManager = -1;
308  }
309 
310 // Process the configuration file
311 //
312  if (!NoGo) NoGo |= ConfigProc();
313 
314 // Override the trace option
315 //
316  if (getenv("XRDDEBUG")) Trace.What = TRACE_ALL;
317 
318 // Override the wait/nowait from the command line
319 //
320  if (immed) doWait = (immed > 0 ? 0 : 1);
321 
322 // Determine the role
323 //
324  if (isManager < 0) isManager = 1;
325  if (isPeer < 0) isPeer = 1;
326  if (isProxy < 0) isProxy = 1;
327  if (isServer < 0) isServer = 1;
328 
329 // Create a text description of our role for use in messages
330 //
331  if (!myRole)
333  if (isMeta) rid = XrdCmsRole::MetaManager;
334  else if (isPeer) rid = XrdCmsRole::Peer;
335  else if (isProxy)
336  {if (isManager) rid = (isServer ? XrdCmsRole::ProxySuper
338  else rid = XrdCmsRole::ProxyServer;
339  }
340  else if (isManager)
341  {if (isManager) rid = (isServer ? XrdCmsRole::Supervisor
343  }
344  else rid = XrdCmsRole::Server;
345  strcpy(myRType, XrdCmsRole::Type(rid));
346  myRole = strdup(XrdCmsRole::Name(rid));
347  myRoleID = static_cast<int>(rid);
348  }
349 
350 // Export the role IN basic form and expanded form
351 //
352  XrdOucEnv::Export("XRDROLE", myRole);
353  XrdOucEnv::Export("XRDROLETYPE", myRType);
354 
355 // For managers, make sure that we have a well designated port.
356 // For servers or supervisors, force an ephemeral port to be used.
357 //
358  if (!NoGo)
359  {if ((isManager && !isServer) || isPeer)
360  {if (PortTCP <= 0)
361  {Say.Emsg("Config","port for this", myRole, "not specified.");
362  NoGo = 1;
363  }
364  }
365  else if ((isManager && isServer)) PortTCP = PortSUP;
366  else PortTCP = 0;
367  }
368 
369 // If we are configured in proxy mode then we are running a shared filesystem
370 //
372  (baseFS.Local() ? XrdCmsBaseFS::Cntrl : 0), 0, 0);
373 
374 // If we are a server and some scheduling parameters were specified but
375 // nothing to feed them, give a warning.
376 //
377  if (isServer)
378  {if (P_cpu|P_io|P_load|P_mem|P_pag)
379  {if (!prfLib && !perfpgm)
380  Say.Say("Config warning: metric scheduling requested without a "
381  "metrics supplier!");
382  } else {
383  if ( prfLib || perfpgm)
384  Say.Say("Config warning: metrics supplier specified without "
385  "any scheduling metrics!");
386  }
387  }
388 
389 // Determine how we ended and return status
390 //
391  sprintf(buff, " phase 1 %s initialization %s.", myRole,
392  (NoGo ? "failed" : "completed"));
393  Say.Say("------ ", myInstance, buff);
394  return NoGo;
395 }
396 
397 /******************************************************************************/
398 /* C o n f i g u r e 2 */
399 /******************************************************************************/
400 
402 {
403 /*
404  Function: Establish phase 2 configuration at start up time.
405 
406  Input: None.
407 
408  Output: 0 upon success or !0 otherwise.
409 */
410  int Who, NoGo = 0;
411  char *p, buff[512];
412  std::string envData;
413 
414 // Add our host name to the env
415 //
416  envData += "myHN=";
417  envData += myName;
418  const char *override_hn = getenv("OVERRIDEXRDHOST");
419  if (override_hn)
420  {envData += "&ovHN=";
421  envData += override_hn;
422  }
423 
424 // Print herald
425 //
426  sprintf(buff, " phase 2 %s initialization started.", myRole);
427  Say.Say("++++++ ", myInstance, buff);
428 
429 // Fix up the QryMinum (we hard code 64 as the max) and P_gshr values.
430 // The QryMinum only applies to a metamanager and is set as 1 minus the min.
431 //
432  if (!isMeta) QryMinum = 0;
433  else if (QryMinum < 2) QryMinum = 0;
434  else if (QryMinum > 64) QryMinum = 64;
435  if (P_gshr < 0) P_gshr = 0;
436  else if (P_gshr > 100) P_gshr = 100;
437 
438 // Determine who we are. If we are a manager or supervisor start the file
439 // location cache scrubber.
440 //
441  if (QryDelay < 0) QryDelay = LUPDelay;
442  if (isManager)
443  NoGo = !Cache.Init(cachelife,LUPDelay,QryDelay,baseFS.isDFS(),emptylife);
444 
445 // Issue warning if the adminpath resides in /tmp
446 //
447  if (!strncmp(AdminPath, "/tmp/", 5))
448  Say.Say("Config warning: adminpath resides in /tmp and may be unstable!");
449 
450 
451 // Establish the path to be used for admin functions. It has already been
452 // qualified by the instance name.
453 //
454  p = XrdOucUtils::genPath(AdminPath, (const char *)0, ".olb");
455  free(AdminPath);
456  AdminPath = p;
457 
458 // Setup the admin path (used in all roles)
459 //
460  if (!NoGo) NoGo = !(AdminSock = XrdNetSocket::Create(&Say, AdminPath,
461  (isManager|isPeer ? "olbd.nimda":"olbd.admin"),AdminMode));
462 
463 // Develop a stable unique identifier for this cmsd independent of the port
464 //
465  if (!NoGo)
466  {if (!(mySID = setupSid())) NoGo = 1;
467  else {if (QTRACE(Debug))
468  Say.Say("Config ", "Global System Identification: ", mySID);
469  if (Config.mySite)
470  {envData += "&site=";
471  envData += mySite;
472  }
473  }
474  }
475 
476 // Create envCGI string for logins
477 //
478  envCGI = (envData.length() > 0 ? strdup(envData.c_str()) : 0);
479 
480 // If we need a name library, load it now
481 //
482  if ((LocalRoot || RemotRoot || N2N_Lib) && ConfigN2N()) NoGo = 1;
483 
484 // Configure the OSS, the base filesystem, and initialize the prep queue
485 //
486  if (!NoGo) NoGo = ConfigOSS();
487  if (!NoGo) baseFS.Start();
488  if (!NoGo) PrepQ.Init();
489 
490 // Setup manager or server, as needed
491 //
492  if (!NoGo && isManager) NoGo = setupManager();
493  if (!NoGo && (isServer || ManList)) NoGo = setupServer();
494 
495 // If we are a solo peer then we have no servers and a lot of space and
496 // connections don't matter. Only one connection matters for a meta-manager.
497 // Servers, supervisors, and managers who have a meta manager must wait for
498 // for the local data server to connect so port mapping occurs. Otherwise,
499 // we indicate that it doesn't matter as the local server won't connect.
500 //
501  if (isPeer && isSolo)
502  {SUPCount = SUPLevel = 0; Meter.setVirtual(XrdCmsMeter::peerFS);}
503  else if (isManager)
505  if (isMeta) {SUPCount = 1; SUPLevel = 0;}
506  if (!ManList) CmsState.Update(XrdCmsState::FrontEnd, 1);
507  }
508  if (isManager) Who = (isServer ? -1 : 1);
509  else Who = 0;
510  CmsState.Set(SUPCount, Who, AdminPath);
511 
512 // At this point we will add to the existing manifest file
513 //
514  if (!NoGo) NoGo |= Manifest();
515 
516 // All done, check for success or failure
517 //
518  sprintf(buff, " phase 2 %s initialization %s.", myRole,
519  (NoGo ? "failed" : "completed"));
520  Say.Say("------ ", myInstance, buff);
521 
522 // The remainder of the configuration needs to be run in a separate thread
523 //
524  if (!NoGo) Sched->Schedule((XrdJob *)this);
525 
526 // All done
527 //
528  return NoGo;
529 }
530 
531 /******************************************************************************/
532 /* C o n f i g X e q */
533 /******************************************************************************/
534 
536 {
537  int dynamic;
538 
539  // Determine whether is is dynamic or not
540  //
541  if (eDest) dynamic = 1;
542  else {dynamic = 0; eDest = &Say;}
543 
544  // Process items
545  //
546  TS_Xeq("delay", xdelay); // Manager, dynamic
547  TS_Xeq("fxhold", xfxhld); // Manager, dynamic
548  TS_Xeq("ping", xping); // Manager, dynamic
549  TS_Xeq("sched", xsched); // Any, dynamic
550  TS_Xeq("space", xspace); // Any, dynamic
551  TS_Xeq("trace", xtrace); // Any, dynamic
552 
553  if (!dynamic)
554  {
555  TS_Xeq("adminpath", xapath); // Any, non-dynamic
556  TS_Xeq("allow", xallow); // Manager, non-dynamic
557  TS_Xeq("altds", xaltds); // Server, non-dynamic
558  TS_Xeq("blacklist", xblk); // Manager, non-dynamic
559  TS_Xeq("cidtag", xcid); // Any, non-dynamic
560  TS_Xeq("defaults", xdefs); // Server, non-dynamic
561  TS_Xeq("dfs", xdfs); // Any, non-dynamic
562  TS_Xeq("export", xexpo); // Any, non-dynamic
563  TS_Xeq("fsxeq", xfsxq); // Server, non-dynamic
564  TS_Xeq("localroot", xlclrt); // Any, non-dynamic
565  TS_Xeq("manager", xmang); // Server, non-dynamic
566  TS_Lib("namelib", N2N_Lib, &N2N_Parms);
567  TS_Xeq("nbsendq", xnbsq); // Any non-dynamic
568  TS_Lib("osslib", ossLib, &ossParms);
569  TS_Xeq("perf", xperf); // Server, non-dynamic
570  TS_Xeq("prep", xprep); // Any, non-dynamic
571  TS_Xeq("prepmsg", xprepm); // Any, non-dynamic
572  TS_Xeq("remoteroot", xrmtrt); // Any, non-dynamic
573  TS_Xeq("repstats", xreps); // Any, non-dynamic
574  TS_Xeq("role", xrole); // Server, non-dynamic
575  TS_Xeq("seclib", xsecl); // Server, non-dynamic
576  TS_Xeq("subcluster", xsubc); // Manager, non-dynamic
577  TS_Xeq("superport", xsupp); // Super, non-dynamic
578  TS_Xeq("vnid", xvnid); // Server, non-dynamic
579  TS_Set("wait", doWait); // Server, non-dynamic (backward compat)
580  TS_unSet("nowait", doWait); // Server, non-dynamic
581  TS_Xer("whitelist", xblk,true);//Manager, non-dynamic
582  }
583 
584  // The following are client directives that we will ignore
585  //
586  if (!strcmp(var, "conwait")
587  || !strcmp(var, "request")) return 0;
588 
589  // No match found, complain.
590  //
591  if (!strcmp(var, "pidpath"))
592  {Say.Say("Config warning: 'cms.pidpath' no longer "
593  "supported; use 'all.pidpath'.");
594  } else {
595  Say.Say("Config warning: ignoring unknown directive '", var, "'.");
596  }
597  CFile.Echo(false);
598  return 0;
599 }
600 
601 /******************************************************************************/
602 /* D o I t */
603 /******************************************************************************/
604 
606 {
607  XrdSysSemaphore SyncUp(0);
608  pthread_t tid;
609  time_t eTime = time(0);
610  int wTime;
611 
612 // Set doWait correctly. We only wait if we have to provide a data path. This
613 // include server, supervisors, and managers who have a meta-manager, only.
614 // Why? Because we never get a primary login if we are a mere manager.
615 //
616  if (isManager && !isServer && !ManList) doWait = 0;
617  else if (isServer && adsMon) doWait = 1;
618 
619 // Start the notification thread if we need to
620 //
621  if (AnoteSock)
622  if (XrdSysThread::Run(&tid, XrdCmsStartAnote, (void *)AnoteSock,
623  0, "Notification handler"))
624  Say.Emsg("cmsd", errno, "start notification handler");
625 
626 // Start the prepare handler
627 //
629  (void *)0, 0, "Prep handler"))
630  Say.Emsg("cmsd", errno, "start prep handler");
631 
632 // Start the supervisor subsystem
633 //
636  (void *)0, 0, "supervisor"))
637  {Say.Emsg("cmsd", errno, "start", myRole);
638  return;
639  }
640  }
641 
642 // Start the ping clock if we are a manager of any kind
643 //
644  if (isManager) PingClock::Start();
645 
646 // Start the admin thread if we need to, we will not continue until told
647 // to do so by the admin interface.
648 //
649  if (AdminSock)
650  {XrdCmsAdmin::setSync(&SyncUp);
651  if (XrdSysThread::Run(&tid, XrdCmsStartAdmin, (void *)AdminSock,
652  0, "Admin traffic"))
653  Say.Emsg("cmsd", errno, "start admin handler");
654  SyncUp.Wait();
655  }
656 
657 // Start the manager subsystem.
658 //
659  if (isManager || isServer || isPeer) XrdCmsManager::Start(ManList);
660 
661 // Start state monitoring thread
662 //
663  if (XrdSysThread::Run(&tid, XrdCmsStartMonStat, (void *)0,
664  0, "State monitor"))
665  {Say.Emsg("Config", errno, "create state monitor thread");
666  return;
667  }
668 
669 // If we are a manager then we must do a service enable after a service delay
670 //
671  if ((isManager || isPeer) && SRVDelay)
672  {wTime = SRVDelay - static_cast<int>((time(0) - eTime));
673  if (wTime > 0) XrdSysTimer::Wait(wTime*1000);
674  }
675 
676 // All done
677 //
678  if (!SUPCount) CmsState.Update(XrdCmsState::Counts, 0, 0);
679  CmsState.Enable();
680  Say.Emsg("Config", myRole, "service enabled.");
681 }
682 
683 /******************************************************************************/
684 /* G e n L o c a l P a t h */
685 /******************************************************************************/
686 
687 /* GenLocalPath() generates the path that a file will have in the local file
688  system. The decision is made based on the user-given path (typically what
689  the user thinks is the local file system path). The output buffer where the
690  new path is placed must be at least XrdCmsMAX_PATH_LEN bytes long.
691 */
692 int XrdCmsConfig::GenLocalPath(const char *oldp, char *newp)
693 {
694  if (lcl_N2N) return -(lcl_N2N->lfn2pfn(oldp, newp, XrdCmsMAX_PATH_LEN));
695  if (strlen(oldp) >= XrdCmsMAX_PATH_LEN) return -ENAMETOOLONG;
696  strcpy(newp, oldp);
697  return 0;
698 }
699 
700 /******************************************************************************/
701 /* P r i v a t e F u n c t i o n s */
702 /******************************************************************************/
703 /******************************************************************************/
704 /* C o n f i g D e f a u l t s */
705 /******************************************************************************/
706 
707 void XrdCmsConfig::ConfigDefaults(void)
708 {
709  static XrdVERSIONINFODEF(myVer, cmsd, XrdVNUMBER, XrdVERSION);
710  int myTZ, isEast = 0;
711 
712 // Preset all variables with common defaults
713 //
714  myName = (char *)"localhost"; // Correctly set in Configure()
715  myDomain = 0;
716  LUPDelay = 5;
717  QryDelay =-1;
718  QryMinum = 0;
719  LUPHold = 178;
720  DELDelay = 960; // 15 minutes
721  DRPDelay = 10*60;
722  PSDelay = 0;
723  RWDelay = 2;
724  SRVDelay = 90;
725  SUPCount = 1;
726  SUPLevel = 80;
727  SUPDelay = 15;
728  SUSDelay = 30;
729  MaxLoad = 0x7fffffff;
730  MaxRetries= 0x7fffffff;
731  MsgTTL = 7;
732  MultiSrc = 1;
733  PortTCP = 0;
734  PortSUP = 0;
735  P_cpu = 0;
736  P_fuzz = 20;
737  P_gsdf = 0;
738  P_gshr = 0;
739  P_io = 0;
740  P_load = 0;
741  P_mem = 0;
742  P_pag = 0;
743  AskPerf = 10; // Every 10 pings
744  AskPing = 60; // Every 1 minute
745  PingTick = 0;
746  DoMWChk = 1;
747  DoHnTry = 1;
748  MaxDelay = -1;
749  LogPerf = 10; // Every 10 usage requests
750  DiskMin = 10240; // 10GB*1024 (Min partition space) in MB
751  DiskHWM = 11264; // 11GB*1024 (High Water Mark SUO) in MB
752  DiskMinP = 2;
753  DiskHWMP = 5;
754  DiskAsk = 12; // 15 Seconds between space calibrations.
755  DiskWT = 0; // Do not defer when out of space
756  DiskSS = false; // Not a staging server
757  DiskOK = false; // Does not have any disk
758  myPaths = (char *)""; // Default is 'r /'
759  ConfigFN = 0;
760  sched_RR = sched_Pack = sched_AffPC = sched_Level = sched_LoadR = 0; sched_Force = 1;
761  isManager= 0;
762  isMeta = 0;
763  isPeer = 0;
764  isSolo = 0;
765  isProxy = 0;
766  isServer = 0;
767  VNID_Lib = 0;
768  VNID_Parms=0;
769  N2N_Lib = 0;
770  N2N_Parms= 0;
771  lcl_N2N = 0;
772  xeq_N2N = 0;
773  LocalRoot= 0;
774  RemotRoot= 0;
775  myInsName= 0;
776  RepStats = 0;
777  myRole =0;
778  myRType[0]=0;
779  myRoleID = XrdCmsRole::noRole;
780  ManList =0;
781  NanList =0;
782  SanList =0;
783  myVNID = 0;
784  mySID = 0;
785  mySite = 0;
786  envCGI = 0;
787  cidTag = 0;
788  ifList =0;
789  perfint = 3*60;
790  perfpgm = 0;
791  xrdEnv = 0;
792  AdminPath= 0;
793  AdminMode= 0700;
794  AdminSock= 0;
795  AnoteSock= 0;
796  RedirSock= 0;
797  Police = 0;
798  cachelife= 8*60*60;
799  emptylife= 0;
800  pendplife= 60*60*24*7;
801  DiskLinger=0;
802  ProgCH = 0;
803  ProgMD = 0;
804  ProgMV = 0;
805  ProgRD = 0;
806  ProgRM = 0;
807  doWait = 1;
808  RefReset = 60*60;
809  RefTurn = 3*STMax*(DiskLinger+1);
810  DirFlags = 0;
811  blkList = 0;
812  blkChk = 0;
813  SecLib = 0;
814  ossLib = 0;
815  ossParms = 0;
816  prfLib = 0;
817  prfParms = 0;
818  ossFS = 0;
819  myVInfo = &myVer;
820  adsPort = 0;
821  adsMon = 0;
822  adsProt = 0;
823  nbSQ = 1;
824 
825  mrRdrHost = 0;
826  mrRdrHLen = 0;
827  mrRdrPort = 0;
828  msRdrHost = 0;
829  msRdrHLen = 0;
830  msRdrPort = 0;
831 
832 // Compute the time zone we are in
833 //
834  myTZ = XrdSysTimer::TimeZone();
835  if (myTZ <= 0) {isEast = 0x10; myTZ = -myTZ;}
836  if (myTZ > 12) myTZ = 12;
837  TimeZone = (myTZ | isEast);
838 }
839 
840 /******************************************************************************/
841 /* C o n f i g N 2 N */
842 /******************************************************************************/
843 
844 int XrdCmsConfig::ConfigN2N()
845 {
846  XrdOucN2NLoader n2nLoader(&Say, ConfigFN, N2N_Parms, LocalRoot, RemotRoot);
847 
848 // Get the plugin
849 //
850  if (!(xeq_N2N = n2nLoader.Load(N2N_Lib, *myVInfo, &theEnv))) return 1;
851 
852 // Optimize the local case
853 //
854  if (N2N_Lib || LocalRoot) lcl_N2N = xeq_N2N;
855 
856 // All done
857 //
858  PrepQ.setParms(lcl_N2N);
859  return 0;
860 }
861 
862 /******************************************************************************/
863 /* C o n f i g O S S */
864 /******************************************************************************/
865 
866 int XrdCmsConfig::ConfigOSS()
867 {
868  extern XrdOss *XrdOssGetSS(XrdSysLogger *, const char *, const char *,
869  const char *, XrdOucEnv *, XrdVersionInfo &);
870  void *arFunc;
871 
872 // Set up environment for the OSS to keep it relevant for cmsd
873 //
874  XrdOucEnv::Export("XRDREDIRECT", "Q");
875  XrdOucEnv::Export("XRDOSSTYPE", "cms");
876  XrdOucEnv::Export("XRDOSSCSCAN", "off");
877 
878 // If no osslib was specified but we are a proxy, then we must load the
879 // the proxy osslib.
880 //
881  if (!ossLib && isProxy) ossLib = strdup("libXrdPss.so");
882 
883 // Load and return result
884 //
885  ossFS=XrdOssGetSS(Say.logger(),ConfigFN,ossLib,ossParms,&theEnv,*myVInfo);
886  if (!ossFS) return 1;
887 
888 // Check if we should elay add/remove events to the statinfo function
889 //
890  if (!isManager && isServer && (arFunc = theEnv.GetPtr("XrdOssStatInfo2*")))
891  return (XrdCmsAdmin::InitAREvents(arFunc) ? 0 : 1);
892  return 0;
893 }
894 
895 /******************************************************************************/
896 /* C o n f i g P r o c */
897 /******************************************************************************/
898 
899 int XrdCmsConfig::ConfigProc(int getrole)
900 {
901  char *var;
902  int cfgFD, retc, NoGo = 0;
903  XrdOucEnv myEnv;
904  XrdOucStream CFile(&Say, getenv("XRDINSTANCE"), &myEnv, "=====> ");
905 
906 // Try to open the configuration file.
907 //
908  if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
909  {Say.Emsg("Config", errno, "open config file", ConfigFN);
910  return 1;
911  }
912  CFile.Attach(cfgFD);
913 
914 // Turn off echoing if we are doing a pre-scan
915 //
916  if (getrole) CFile.SetEroute(0);
917 
918 // Now start reading records until eof.
919 //
920  while((var = CFile.GetMyFirstWord()))
921  if (getrole)
922  {if (!strcmp("all.role", var) || !strcmp("olb.role", var))
923  if (xrole(&Say, CFile))
924  {CFile.SetEroute(&Say); CFile.Echo(); NoGo = 1;
925  CFile.SetEroute(0);
926  }
927  }
928  else if (!strncmp(var, "cms.", 4)
929  || !strncmp(var, "olb.", 4) // Backward compatibility
930  || !strcmp(var, "ofs.osslib")
931  || !strcmp(var, "oss.defaults")
932  || !strcmp(var, "oss.localroot")
933  || !strcmp(var, "oss.remoteroot")
934  || !strcmp(var, "oss.namelib")
935  || !strcmp(var, "all.export")
936  || !strcmp(var, "all.manager")
937  || !strcmp(var, "all.role")
938  || !strcmp(var, "all.seclib")
939  || !strcmp(var, "all.subcluster"))
940  {if (ConfigXeq(var+4, CFile, 0)) {CFile.Echo(); NoGo = 1;}}
941  else if (!strcmp(var, "oss.stagecmd")) DiskSS = true;
942 
943 // Now check if any errors occurred during file i/o
944 //
945  if ((retc = CFile.LastError()))
946  NoGo = Say.Emsg("Config", retc, "read config file", ConfigFN);
947  CFile.Close();
948 
949 // Merge Paths as needed
950 //
951  if (!getrole && (ManList || SanList)) NoGo |= MergeP();
952 
953 // Return final return code
954 //
955  return NoGo;
956 }
957 
958 /******************************************************************************/
959 /* i s E x e c */
960 /******************************************************************************/
961 
962 int XrdCmsConfig::isExec(XrdSysError *eDest, const char *ptype, char *prog)
963 {
964  char buff[512], pp, *mp = prog;
965 
966 // Isolate the program name
967 //
968  while(*mp && *mp != ' ') mp++;
969  pp = *mp; *mp ='\0';
970 
971 // Make sure the program is executable by us
972 //
973  if (access(prog, X_OK))
974  {sprintf(buff, "find %s executable", ptype);
975  eDest->Emsg("Config", errno, buff, prog);
976  *mp = pp;
977  return 0;
978  }
979 
980 // All is well
981 //
982  *mp = pp;
983  return 1;
984 }
985 
986 /******************************************************************************/
987 /* M a n i f e s t */
988 /******************************************************************************/
989 
990 int XrdCmsConfig::Manifest()
991 {
992  int xfd;
993  const char *clID, *xop = 0;
994  char *envFN;
995 
996 // Get the exiting manifest file from he environment. If none, return.
997 //
998  if (!xrdEnv || !(envFN = xrdEnv->Get("envFile"))) return 0;
999 
1000  if ((clID = index(mySID, ' '))) clID++;
1001  else clID = mySID;
1002 
1003  if ((xfd = open(envFN, O_WRONLY|O_APPEND)) < 0) xop = "open";
1004  else {bool bad = false;
1005  if (LocalRoot)
1006  bad = write(xfd,(void *)"&pfx=",5) < 0
1007  || write(xfd,(void *)LocalRoot,strlen(LocalRoot)) < 0;
1008  if (!bad && AdminPath)
1009  bad = write(xfd,(void *)"&ap=", 4) < 0
1010  || write(xfd,(void *)AdminPath,strlen(AdminPath)) < 0;
1011  if (!bad) bad = write(xfd,(void *)"&cn=", 4) < 0
1012  || write(xfd,(void *)clID, strlen(clID)) < 0;
1013  if (bad) xop = "append to";
1014  close(xfd);
1015  }
1016 
1017  if (xop) Say.Emsg("Config", errno, xop, envFN);
1018 
1019  return xop != 0;
1020 }
1021 
1022 /******************************************************************************/
1023 /* M e r g e P */
1024 /******************************************************************************/
1025 
1026 int XrdCmsConfig::MergeP()
1027 {
1028  static const unsigned long long stage4MM = XRDEXP_STAGEMM & ~XRDEXP_STAGE;
1029  static const unsigned long long stageAny = XRDEXP_PFCACHE | XRDEXP_STAGE;
1030  static const unsigned long long readOnly = XRDEXP_PFCACHE | XRDEXP_NOTRW;
1031 
1032  XrdOucPList *plp = PexpList.First();
1033  XrdCmsPList *pp;
1034  XrdCmsPInfo opinfo, npinfo;
1035  const char *ptype;
1036  char *pbP;
1037  unsigned long long Opts;
1038  int pbLen = 0, NoGo = 0, export2MM = isManager && !isServer;
1039  npinfo.rovec = 1;
1040 
1041 // For each path in the export list merge it into the path list
1042 //
1043  while(plp)
1044  {Opts = plp->Flag();
1045  if (!(Opts & XRDEXP_LOCAL))
1046  {npinfo.rwvec = (Opts & (XRDEXP_GLBLRO | readOnly) ? 0 : 1);
1047  if (export2MM) npinfo.ssvec = (Opts & stage4MM ? 1 : 0);
1048  else npinfo.ssvec = (Opts & stageAny ? 1 : 0);
1049  if (!PathList.Add(plp->Path(), &npinfo))
1050  Say.Emsg("Config","Ignoring duplicate export path",plp->Path());
1051  else if (npinfo.ssvec) DiskSS = true;
1052  }
1053  plp = plp->Next();
1054  }
1055 
1056 // Document what we will be declaring as available
1057 //
1058  if (!NoGo)
1059  {const char *Who;
1060  if (isManager)
1061  {if (SanList) Who = "subcluster manager:";
1062  else Who = (isServer ? "manager:" : "meta-manager:");
1063  } else Who = "redirector:";
1064  Say.Say("The following paths are available to the ", Who);
1065  if (!(pp = PathList.First())) Say.Say("r /");
1066  else while(pp)
1067  {ptype = pp->PType();
1068  Say.Say(ptype, (strlen(ptype) > 1 ? " " : " "), pp->Path());
1069  pbLen += strlen(pp->Path())+8; pp = pp->Next();
1070  }
1071  Say.Say(" ");
1072  }
1073 
1074 // Now allocate a buffer and place all of the paths into that buffer to be
1075 // sent during the login phase.
1076 //
1077  if (pbLen != 0 && (pp = PathList.First()))
1078  {pbP = myPaths = (char *)malloc(pbLen);
1079  while(pp)
1080  {pbP += sprintf(pbP, "\n%s %s", pp->PType(), pp->Path());
1081  pp = pp->Next();
1082  }
1083  myPaths++;
1084  }
1085 
1086 // All done update the staging status (it's nostage by default)
1087 //
1088  if (DiskSS) CmsState.Update(XrdCmsState::Counts, 0, 1);
1089  return NoGo;
1090 }
1091 
1092 /******************************************************************************/
1093 /* s e t u p M a n a g e r */
1094 /******************************************************************************/
1095 
1096 int XrdCmsConfig::setupManager()
1097 {
1098  pthread_t tid;
1099  int rc;
1100 
1101 // If we are a subcluster then we need to replace the manager list with the
1102 // one specified on the subcluster directive.
1103 //
1104  if (SanList)
1105  {XrdOucTList *nP, *tP = ManList;
1106  const char *urDom, *myDom = index(myName, '.');
1107  bool isBad = false;
1108  while(tP) {nP = tP; tP = tP->next; delete nP;}
1109  ManList = tP = SanList;
1110  if (myDom) while(tP)
1111  {if ((urDom = index(tP->text, '.')) && strcmp(urDom, myDom))
1112  {Say.Emsg("Config", "Subcluster's manager", tP->text,
1113  "is in a different domain.");
1114  isBad = true;
1115  }
1116  tP = tP->next;
1117  }
1118  if (isBad) {Say.Emsg("Config","Cross domain subclusters disallowed!");
1119  return 1;
1120  }
1121  }
1122 
1123 // Setup supervisor mode if we are also a server
1124 //
1125  if (isServer && !XrdCmsSupervisor::Init(AdminPath, AdminMode)) return 1;
1126 
1127 // Compute the scheduling policy
1128 //
1129  sched_RR = (100 == P_fuzz) || !AskPerf
1130  || !(P_cpu || P_io || P_load || P_mem || P_pag);
1131  if (sched_RR)
1132  {Say.Say("Config round robin scheduling in effect.");
1133  sched_Level = 0;
1134  }
1135 
1136 // Create statistical monitoring thread
1137 //
1138  if ((rc = XrdSysThread::Run(&tid, XrdCmsStartMonPerf, (void *)0,
1139  0, "Performance monitor")))
1140  {Say.Emsg("Config", rc, "create perf monitor thread");
1141  return 1;
1142  }
1143 
1144 // Create reference monitoring thread
1145 //
1146  RefTurn = 3*STMax*(DiskLinger+1);
1147  if (RefReset)
1148  {if ((rc = XrdSysThread::Run(&tid, XrdCmsStartMonRefs, (void *)0,
1149  0, "Refcount monitor")))
1150  {Say.Emsg("Config", rc, "create refcount monitor thread");
1151  return 1;
1152  }
1153  }
1154 
1155 // Initialize the fast redirect queue
1156 //
1157  RRQ.Init(LUPHold, LUPDelay);
1158 
1159 // Initialize the security interface
1160 //
1161  if (SecLib && !XrdCmsSecurity::Configure(SecLib, ConfigFN)) return 1;
1162 
1163 // Initialize the black list
1164 //
1165  if (!isServer && blkChk)
1166  XrdCmsBlackList::Init(Sched, &Cluster, blkList, blkChk);
1167 
1168 // All done
1169 //
1170  return 0;
1171 }
1172 
1173 /******************************************************************************/
1174 /* s e t u p S e r v e r */
1175 /******************************************************************************/
1176 
1177 int XrdCmsConfig::setupServer()
1178 {
1179  XrdOucTList *tp;
1180  int n = 0;
1181 
1182 // Make sure we have enough info to be a server
1183 //
1184  if (!ManList)
1185  {Say.Emsg("Config", "Manager node not specified for", myRole, "role");
1186  return 1;
1187  }
1188 
1189 // Count the number of managers. Make sure there are not too many.
1190 //
1191  tp = ManList;
1192  while(tp) {n++; tp = tp->next;}
1193  if (n > XrdCmsManager::MTMax)
1194  {Say.Emsg("Config", "Too many managers have been specified"); return 1;}
1195 
1196 // Calculate overload delay time
1197 //
1198  if (MaxDelay < 0) MaxDelay = AskPerf*AskPing+30;
1199  if (DiskWT < 0) DiskWT = AskPerf*AskPing+30;
1200 
1201 // Setup notification path
1202 //
1203  if (!(AnoteSock = XrdNetSocket::Create(&Say, AdminPath,
1204  (isManager|isPeer ? "olbd.seton":"olbd.notes"),
1205  AdminMode, XRDNET_UDPSOCKET))) return 1;
1206 
1207 // We have data only if we are a pure data server (the default is noData)
1208 // If we have no data, then we are done (the rest is for pure servers)
1209 //
1210  if (isManager || isPeer) return 0;
1211  SUPCount = 0; SUPLevel = 0;
1212  if (isProxy) return 0;
1213  DiskOK = true;
1214 
1215 // If this is a staging server then set up the Prepq object
1216 //
1217  if (DiskSS) PrepQ.Reset(myInsName, AdminPath, AdminMode);
1218 
1219 // Setup file system metering (skip it for peers)
1220 //
1221  Meter.Init();
1222  if (perfpgm && Meter.Monitor(perfpgm, perfint))
1223  Say.Say("Config warning: load based scheduling disabled.");
1224 
1225 // All done
1226 //
1227  return 0;
1228 }
1229 
1230 /******************************************************************************/
1231 /* s e t u p S i d */
1232 /******************************************************************************/
1233 
1234 char *XrdCmsConfig::setupSid()
1235 {
1236  XrdOucTList *tp = (NanList ? NanList : ManList);
1237  char *sidVal, sfx;
1238 
1239 // Grab the interfaces. This is normally set as an envar. If present then
1240 // we will copy it because we must use it permanently.
1241 //
1242  if (getenv("XRDIFADDRS")) ifList = strdup(getenv("XRDIFADDRS"));
1243 
1244 // Grab the site name
1245 //
1246  if ((mySite = getenv("XRDSITE")) && *mySite) mySite = strdup(mySite);
1247  else mySite = 0;
1248 
1249 // Determine what type of role we are playing
1250 //
1251  if (isManager && isServer) sfx = 'u';
1252  else sfx = (isManager ? 'm' : 's');
1253  if (isProxy) sfx = toupper(sfx);
1254 
1255 // Get the node ID if we need to
1256 //
1257  if (VNID_Lib)
1258  {myVNID = XrdCmsSecurity::getVnId(Say,ConfigFN,VNID_Lib,VNID_Parms,sfx);
1259  if (!myVNID) return 0;
1260  }
1261 
1262 // Generate the system ID and set the cluster ID
1263 //
1264  sidVal = XrdCmsSecurity::setSystemID(tp, myVNID, cidTag, sfx);
1265  if (!sidVal || *sidVal == '!')
1266  {const char *msg;
1267  if (!sidVal) msg = "too many managers.";
1268  else msg = sidVal+1;
1269  Say.Emsg("cmsd","Unable to generate system ID; ", msg);
1270  return 0;
1271  }
1272  return sidVal;
1273 }
1274 
1275 /******************************************************************************/
1276 /* U s a g e */
1277 /******************************************************************************/
1278 
1279 void XrdCmsConfig::Usage(int rc)
1280 {
1281 std::cerr <<"\nUsage: cmsd [xrdopts] [-i] [-m] [-s] -c <cfile>" <<std::endl;
1282 exit(rc);
1283 }
1284 
1285 /******************************************************************************/
1286 /* x a l l o w */
1287 /******************************************************************************/
1288 
1289 /* Function: xallow
1290 
1291  Purpose: To parse the directive: allow {host | netgroup} <name>
1292 
1293  <name> The dns name of the host that is allowed to connect or the
1294  netgroup name the host must be a member of. For DNS names,
1295  a single asterisk may be specified anywhere in the name.
1296 
1297  Type: Manager only, non-dynamic.
1298 
1299  Output: 0 upon success or !0 upon failure.
1300 */
1301 
1302 int XrdCmsConfig::xallow(XrdSysError *eDest, XrdOucStream &CFile)
1303 {
1304  char *val;
1305  int ishost;
1306 
1307  if (!isManager) return CFile.noEcho();
1308 
1309  if (!(val = CFile.GetWord()))
1310  {eDest->Emsg("Config", "allow type not specified"); return 1;}
1311 
1312  if (!strcmp(val, "host")) ishost = 1;
1313  else if (!strcmp(val, "netgroup")) ishost = 0;
1314  else {eDest->Emsg("Config", "invalid allow type -", val);
1315  return 1;
1316  }
1317 
1318  if (!(val = CFile.GetWord()))
1319  {eDest->Emsg("Config", "allow target name not specified"); return 1;}
1320 
1321  if (!Police) Police = new XrdNetSecurity();
1322  if (ishost) Police->AddHost(val);
1323  else Police->AddNetGroup(val);
1324 
1325  return 0;
1326 }
1327 
1328 /******************************************************************************/
1329 /* x a l t d s */
1330 /******************************************************************************/
1331 
1332 /* Function: xaltds
1333 
1334  Purpose: To parse the directive: altds xroot <port> [[no]monitor]
1335 
1336  xroot The protocol used by the alternate data server.
1337  <port> The port being used by the alternate data server.
1338  mon Actively monitor alternate data server by connecting to it.
1339  This is the default.
1340  nomon Do not monitor the alternate data server.
1341  it and if <sec> is greater than zero, send "ping" requests
1342  every <sec> seconds. Zero merely connects.
1343 
1344  Type: Manager only, non-dynamic.
1345 
1346  Output: 0 upon success or !0 upon failure.
1347 */
1348 
1349 int XrdCmsConfig::xaltds(XrdSysError *eDest, XrdOucStream &CFile)
1350 {
1351  char *val;
1352 
1353  if (isManager) return CFile.noEcho();
1354 
1355  if (!(val = CFile.GetWord()))
1356  {eDest->Emsg("Config", "protocol not specified"); return 1;}
1357 
1358  if (strcmp(val, "xroot"))
1359  {eDest->Emsg("Config", "unsupported protocol, '", val, "'."); return 1;}
1360  if (adsProt) free(adsProt);
1361  adsProt = strdup(val);
1362 
1363  if (!(val = CFile.GetWord()))
1364  {eDest->Emsg("Config", "data server port not specified"); return 1;}
1365 
1366  if (isdigit(*val))
1367  {if (XrdOuca2x::a2i(*eDest,"data server port",val,&adsPort,1,65535))
1368  return 1;
1369  }
1370  else if (!(adsPort = XrdNetUtils::ServPort(val, "tcp")))
1371  {eDest->Emsg("Config", "Unable to find tcp service '",val,"'.");
1372  return 1;
1373  }
1374 
1375  if (!(val = CFile.GetWord()) || !strcmp(val, "monitor")) adsMon = 1;
1376  else if (!strcmp(val, "nomonitor")) adsMon = 0;
1377  else {eDest->Emsg("Config", "invalid option, '", val, "'.");
1378  return 1;
1379  }
1380 
1381  return 0;
1382 }
1383 
1384 /******************************************************************************/
1385 /* x a p a t h */
1386 /******************************************************************************/
1387 
1388 /* Function: xapath
1389 
1390  Purpose: To parse the directive: adminpath <path>
1391 
1392  <path> the path of the named socket to use for admin requests.
1393 
1394  Type: Manager and Server, non-dynamic.
1395 
1396  Output: 0 upon success or !0 upon failure.
1397 */
1398 
1399 int XrdCmsConfig::xapath(XrdSysError *eDest, XrdOucStream &CFile)
1400 {
1401  char *pval, *val;
1402  mode_t mode = S_IRWXU;
1403 
1404 // Get the path
1405 //
1406  pval = CFile.GetWord();
1407  if (!pval || !pval[0])
1408  {eDest->Emsg("Config", "adminpath not specified"); return 1;}
1409 
1410 // Make sure it's an absolute path
1411 //
1412  if (*pval != '/')
1413  {eDest->Emsg("Config", "adminpath not absolute"); return 1;}
1414  pval = strdup(pval);
1415 
1416 // Get the optional access rights
1417 //
1418  if ((val = CFile.GetWord()) && val[0])
1419  {if (!strcmp("group", val)) mode |= S_IRWXG;
1420  else {eDest->Emsg("Config", "invalid admin path modifier -", val);
1421  free(pval); return 1;
1422  }
1423  }
1424 
1425 // Record the path
1426 //
1427  if (AdminPath) free(AdminPath);
1428  AdminPath = XrdOucUtils::genPath(pval,XrdOucUtils::InstName(myInsName,0));
1429  free(pval);
1430  AdminMode = mode;
1431  return 0;
1432 }
1433 
1434 /******************************************************************************/
1435 /* x b l k */
1436 /******************************************************************************/
1437 
1438 /* Function: xblk
1439 
1440  Purpose: To parse the directive: blacklist [check <time>] [<path>]
1441 
1442  <time> how often to check for black list changes.
1443  <path> the path to the blacklist file
1444 
1445  Output: 0 upon success or !0 upon failure.
1446 */
1447 
1448 int XrdCmsConfig::xblk(XrdSysError *eDest, XrdOucStream &CFile, bool iswl)
1449 {
1450  const char *fType = (iswl ? "whitelist" : "blacklist");
1451  char *val = CFile.GetWord();
1452 
1453 // We only support this for managers
1454 //
1455  if (!isManager || isServer) return CFile.noEcho();
1456 
1457 // Indicate blacklisting is active and free up any current blacklist path
1458 //
1459  blkChk = 600;
1460  if (blkList) {free(blkList); blkList = 0;}
1461 
1462 // Avoid echoing limitation in the stream object
1463 //
1464  if (!val || !val[0])
1465  {eDest->Say("=====> cms.", fType);
1466  return 0;
1467  }
1468 
1469 // Process any options
1470 //
1471  do { if (!strcmp(val, "check"))
1472  {if (!(val = CFile.GetWord()) || !val[0])
1473  {eDest->Emsg("Config",fType,"check interval not specified");
1474  return 1;
1475  }
1476  if (XrdOuca2x::a2tm(*eDest, "check value", val, &blkChk, 60)) return 1;
1477  }
1478  else break;
1479  } while((val = CFile.GetWord()));
1480 
1481 // Handle the invert option
1482 //
1483  if (iswl) blkChk = -blkChk;
1484 
1485 // Verify the path, if any. is absolute
1486 //
1487  if (!val || !val[0]) return 0;
1488  if (*val != '/')
1489  {eDest->Emsg("Config", "blacklist path not absolute"); return 1;}
1490 
1491 // Record the path
1492 //
1493  blkList = strdup(val);
1494  return 0;
1495 }
1496 
1497 /******************************************************************************/
1498 /* x c i d */
1499 /******************************************************************************/
1500 
1501 /* Function: xcid
1502 
1503  Purpose: To parse the directive: cidtag <tag>
1504 
1505  <tag> a 1- to 16-character cluster ID tag.
1506 
1507  Output: 0 upon success or !0 upon failure.
1508 */
1509 
1510 int XrdCmsConfig::xcid(XrdSysError *eDest, XrdOucStream &CFile)
1511 {
1512  char *val;
1513 
1514 // Get the path
1515 //
1516  if (!(val = CFile.GetWord()) || !val[0])
1517  {eDest->Emsg("Config", "tag not specified"); return 1;}
1518 
1519 // Make sure it is not too long
1520 //
1521  if ((int)strlen(val) > 16)
1522  {eDest->Emsg("Config", "tag is > 16 characters"); return 1;}
1523 
1524 // Record the tag
1525 //
1526  if (cidTag) free(cidTag);
1527  cidTag = strdup(val);
1528  return 0;
1529 }
1530 
1531 /******************************************************************************/
1532 /* x d e l a y */
1533 /******************************************************************************/
1534 
1535 /* Function: xdelay
1536 
1537  Purpose: To parse the directive: delay [lookup <sec>] [overload <sec>]
1538  [startup <sec>] [servers <cnt>[%]]
1539  [full <sec>] [discard <cnt>]
1540  [suspend <sec>] [drop <sec>]
1541  [service <sec>] [hold <msec>]
1542  [peer <sec>] [rw <lvl>] [qdl <sec>]
1543  [qdn <cnt>] [delnode <sec>]
1544  [nostage <cnt>]
1545 
1546  delnode <sec> maximum seconds to wait to be able to delete a node.
1547  discard <cnt> maximum number a message may be forwarded.
1548  drop <sec> seconds to delay a drop of an offline server.
1549  full <sec> seconds to delay client when no servers have space.
1550  hold <msec> millseconds to optimistically hold requests.
1551  lookup <sec> seconds to delay client when finding a file.
1552  nostage <cnt> Maximum number of staging reselections allowed.
1553  overload <sec> seconds to delay client when all servers overloaded.
1554  peer <sec> maximum seconds client may be delayed before peer
1555  selection is triggered.
1556  qdl <sec> the query response deadline.
1557  qdn <cnt> Min number of servers that must respond to satisfy qdl.
1558  rw <lvl> how to delay r/w lookups (one of three levels):
1559  0 - always use fast redirect when possible
1560  1 - delay update requests only
1561  2 - delay all rw requests (the default)
1562  servers <cnt> minimum number of servers we need.
1563  service <sec> seconds to delay client when waiting for servers.
1564  startup <sec> seconds to delay enabling our service
1565  suspend <sec> seconds to delay client when all servers suspended.
1566 
1567  Type: Manager only, dynamic.
1568 
1569  Output: 0 upon success or !0 upon failure.
1570 */
1571 int XrdCmsConfig::xdelay(XrdSysError *eDest, XrdOucStream &CFile)
1572 { char *val;
1573  const char *etxt = "invalid delay option";
1574  int i, ppp, minV = 1, ispercent = 0, noStage = 0;
1575  static struct delayopts {const char *opname; int *oploc; int istime;}
1576  dyopts[] =
1577  {
1578  {"delnode", &DELDelay, 1},
1579  {"discard", &MsgTTL, 0},
1580  {"drop", &DRPDelay, 1},
1581  {"full", &DiskWT, -1},
1582  {"hold", &LUPHold, 0},
1583  {"lookup", &LUPDelay, 1},
1584  {"nostage", &noStage, 01},
1585  {"overload", &MaxDelay,-1},
1586  {"peer", &PSDelay, 1},
1587  {"qdl", &QryDelay, 1},
1588  {"qdn", &QryMinum, 0},
1589  {"rw", &RWDelay, 0},
1590  {"servers", &SUPCount, 0},
1591  {"service", &SUPDelay, 1},
1592  {"startup", &SRVDelay, 1},
1593  {"suspend", &SUSDelay, 1}
1594  };
1595  int numopts = sizeof(dyopts)/sizeof(struct delayopts);
1596 
1597  if (!isManager && !isPeer) return CFile.noEcho();
1598 
1599  if (!(val = CFile.GetWord()))
1600  {eDest->Emsg("Config", "delay arguments not specified"); return 1;}
1601 
1602  while (val)
1603  {for (i = 0; i < numopts; i++)
1604  if (!strcmp(val, dyopts[i].opname))
1605  {if (!(val = CFile.GetWord()))
1606  {eDest->Emsg("Config", "delay ", dyopts[i].opname,
1607  " argument not specified.");
1608  return 1;
1609  }
1610  if (dyopts[i].istime < 0 && !strcmp(val, "*")) ppp = -1;
1611  else if (dyopts[i].istime)
1612  {if (XrdOuca2x::a2tm(*eDest,etxt,val,&ppp,1))
1613  return 1;
1614  } else
1615  if (*dyopts[i].opname == 'r')
1616  {if (XrdOuca2x::a2i( *eDest,etxt,val,&ppp,0,2))
1617  return 1;
1618  } else {
1619  if (*dyopts[i].opname == 's')
1620  {ppp = strlen(val); SUPLevel = 0; minV = 0;
1621  if (val[ppp-1] == '%')
1622  {ispercent = 1; val[ppp-1] = '\0';}
1623  } else minV = 1;
1624  if (XrdOuca2x::a2i( *eDest,etxt,val,&ppp,minV))
1625  return 1;
1626  }
1627  if (!ispercent) *dyopts[i].oploc = ppp;
1628  else {ispercent = 0; SUPCount = 1; SUPLevel = ppp;}
1629  break;
1630  }
1631  if (i >= numopts)
1632  eDest->Say("Config warning: ignoring invalid delay option '",val,"'.");
1633  val = CFile.GetWord();
1634  }
1635 
1636 // Set the nostage option here
1637 //
1638  if (noStage) baseFS.SetTries(false, noStage);
1639  return 0;
1640 }
1641 
1642 /******************************************************************************/
1643 /* x d e f s */
1644 /******************************************************************************/
1645 
1646 /* Function: xdefs
1647 
1648  Purpose: Parse: oss.defaults <default options>
1649 
1650  Notes: See the oss configuration manual for the meaning of each option.
1651  The actual implementation is defined in XrdOucExport.
1652 
1653  Output: 0 upon success or !0 upon failure.
1654 */
1655 
1656 int XrdCmsConfig::xdefs(XrdSysError *eDest, XrdOucStream &CFile)
1657 {
1658  DirFlags = XrdOucExport::ParseDefs(CFile, *eDest, DirFlags);
1659  return 0;
1660 }
1661 
1662 /******************************************************************************/
1663 /* x d f s */
1664 /******************************************************************************/
1665 
1666 /* Function: xdfs
1667 
1668  Purpose: To parse the directive: dfs <opts>
1669 
1670  <opts>: limit [central] [=]<n>
1671  central - apply limit on manager node. Otherwise, limit
1672  is applied where lookups occur.
1673  [=]<n> - the limit value as transactions per second. If
1674  an equals is given before the limit, then
1675  requests are paced at the specified rate.
1676  Otherwise, a predictive algorithm is used.
1677  Zero (default) turns limit off.
1678 
1679  lookup {central | distrib}
1680  central - perform file lookups on the manager.
1681  distrib - distribute file lookups to servers (default).
1682 
1683  mdhold <n> - remember missing directories for n seconds
1684  Zero (default) turns this off.
1685 
1686  qmax <n> - maximum number of requests that may be queued.
1687  One is the minimum. The default qmax is 2.5
1688  the limit value.
1689 
1690  redirect {immed | verify}
1691  immed - do not verify file existence prior to
1692  redirecting a client. This is the
1693  default for proxy configurations.
1694  verify - verify file existence prior to
1695  redirecting a client. This is the
1696  default for non-proxy configurations. top
1697 
1698  retries <n> Maximum number of select retries.
1699 
1700  Type: Any, non-dynamic.
1701 
1702  Output: 0 upon success or !0 upon failure.
1703 */
1704 
1705 int XrdCmsConfig::xdfs(XrdSysError *eDest, XrdOucStream &CFile)
1706 {
1707  int Opts = XrdCmsBaseFS::DFSys | (isProxy ? XrdCmsBaseFS::Immed : 0)
1708  | (!isManager && isServer ? XrdCmsBaseFS::Servr: 0);
1709  int Hold = 0, limCent = 0, limFix = 0, limV = 0, qMax = 0, rTry = -1;
1710  char *val;
1711 
1712 // If we are a meta-manager or a peer, ignore this option
1713 //
1714  if (isMeta || isPeer) return CFile.noEcho();
1715 
1716 // Get first option. We need one but they can come in any order
1717 //
1718  if (!(val = CFile.GetWord()))
1719  {eDest->Emsg("Config", "dfs option not specified"); return 1;}
1720 
1721 // Now parse each option
1722 //
1723 do{ if (!strcmp("mdhold", val))
1724  {if (!(val = CFile.GetWord()))
1725  {eDest->Emsg("Config","mdhold value not specified."); return 1;}
1726  if (XrdOuca2x::a2tm(*eDest, "hold value", val, &Hold, 0)) return 1;
1727  }
1728  else if (!strcmp("limit", val))
1729  {if (!(val = CFile.GetWord()))
1730  {eDest->Emsg("Config","limit value not specified."); return 1;}
1731  if ((limCent = !strcmp("central",val)) && !(val = CFile.GetWord()))
1732  {eDest->Emsg("Config","limit value not specified."); return 1;}
1733  if ((limFix = (*val == '=')) && *(val+1)) val++;
1734  if (XrdOuca2x::a2i(*eDest, "limit value", val, &limV, 0)) return 1;
1735  }
1736  else if (!strcmp("lookup", val))
1737  {if (!(val = CFile.GetWord()))
1738  {eDest->Emsg("Config","lookup value not specified."); return 1;}
1739  if (!strcmp("central", val)) Opts |= XrdCmsBaseFS::Cntrl;
1740  else if (!strcmp("distrib", val)) Opts &= ~XrdCmsBaseFS::Cntrl;
1741  else {eDest->Emsg("Config","invalid lookup value '", val, "'.");
1742  return 1;
1743  }
1744  }
1745  else if (!strcmp("qmax", val))
1746  {if (!(val = CFile.GetWord()))
1747  {eDest->Emsg("Config","qmax value not specified."); return 1;}
1748  if (XrdOuca2x::a2i(*eDest, "qmax value", val, &qMax, 1)) return 1;
1749  }
1750  else if (!strcmp("redirect",val))
1751  {if (!(val = CFile.GetWord()))
1752  {eDest->Emsg("Config","redirect value not specified.");return 1;}
1753  if (!strcmp("immed", val)) Opts |= XrdCmsBaseFS::Immed;
1754  else if (!strcmp("verify", val)) Opts &= ~XrdCmsBaseFS::Immed;
1755  else {eDest->Emsg("Config","invalid redirect value -", val);
1756  return 1;
1757  }
1758  }
1759  else if (!strcmp("retries", val))
1760  {if (!(val = CFile.GetWord()))
1761  {eDest->Emsg("Config","retries value not specified."); return 1;}
1762  if (XrdOuca2x::a2i(*eDest, "retries value", val, &rTry, 0)) return 1;
1763  }
1764  else {eDest->Emsg("Config", "invalid dfs option '",val,"'."); return 1;}
1765  } while((val = CFile.GetWord()));
1766 
1767 // Supervisors are special beasts so we need to make transparent. One of these
1768 // days we'll allow lookups to go down to the supervisor level.
1769 //
1770  if (isManager && isServer)
1771  {limV = 0;
1772  Opts &= ~XrdCmsBaseFS::Cntrl;
1773  }
1774 
1775 // Adjust the limit value and option as needed
1776 //
1777  if (limV)
1778  {if (limFix) limV = -limV;
1779  if (limCent || Opts & XrdCmsBaseFS::Cntrl) {if (isServer) limV = 0;}
1780  else if (isManager) limV = 0;
1781  }
1782 
1783 // If we are a manager but not doing local lookups, then hold does not apply
1784 //
1785  if (isManager && !(Opts & XrdCmsBaseFS::Cntrl)) Hold = 0;
1786 
1787 // All done, simply set the values
1788 //
1789  baseFS.SetTries(true, rTry);
1790  baseFS.Limit(limV, qMax);
1791  baseFS.Init(Opts, Hold, Hold*10);
1792  return 0;
1793 }
1794 
1795 /******************************************************************************/
1796 /* x e x p o */
1797 /******************************************************************************/
1798 
1799 /* Function: xexpo
1800 
1801  Purpose: To parse the directive: all.export <path> [<options>]
1802 
1803  <path> the full path that resides in a remote system.
1804  <options> a blank separated list of options (see XrdOucExport)
1805 
1806  Output: 0 upon success or !0 upon failure.
1807 */
1808 
1809 int XrdCmsConfig::xexpo(XrdSysError *eDest, XrdOucStream &CFile)
1810 {
1811 
1812 // Parse the arguments
1813 //
1814  return (XrdOucExport::ParsePath(CFile, *eDest, PexpList, DirFlags) ? 0 : 1);
1815 }
1816 
1817 /******************************************************************************/
1818 /* x f s x q */
1819 /******************************************************************************/
1820 
1821 /* Function: xfsxq
1822 
1823  Purpose: To parse the directive: fsxeq <types> <prog>
1824 
1825  <types> what operations the program performs (one or more of):
1826  chmod mkdir mkpath mv rm rmdir
1827  <prog> the program to execute when doing a forwarded fs op.
1828 
1829  Type: Server only, non-dynamic.
1830 
1831  Output: 0 upon success or !0 upon failure.
1832 */
1833 
1834 int XrdCmsConfig::xfsxq(XrdSysError *eDest, XrdOucStream &CFile)
1835 {
1836  struct xeqopts {const char *opname; int doset; XrdOucProg **pgm;} xqopts[] =
1837  {
1838  {"chmod", 0, &ProgCH},
1839  {"mkdir", 0, &ProgMD},
1840  {"mkpath", 0, &ProgMP},
1841  {"mv", 0, &ProgMV},
1842  {"rm", 0, &ProgRM},
1843  {"rmdir", 0, &ProgRD},
1844  {"trunc", 0, &ProgTR}
1845  };
1846  int i, xtval = 0, numopts = sizeof(xqopts)/sizeof(struct xeqopts);
1847  char *val;
1848 
1849 // If we are a manager, ignore this option
1850 //
1851  if (!isServer) return CFile.noEcho();
1852 
1853 // Get the operation types
1854 //
1855  val = CFile.GetWord();
1856  while (val && *val != '/')
1857  {for (i = 0; i < numopts; i++)
1858  if (!strcmp(val, xqopts[i].opname))
1859  {xqopts[i].doset = 1;
1860  xtval = 1;
1861  break;
1862  }
1863  if (i >= numopts)
1864  eDest->Say("Config warning: ignoring invalid fsxeq type option '",val,"'.");
1865  val = CFile.GetWord();
1866  }
1867 
1868 // Make sure some type was specified
1869 //
1870  if (!xtval)
1871  {eDest->Emsg("Config", "fsxeq type option not specified"); return 1;}
1872 
1873 // Make sure a program was specified
1874 //
1875  if (!val)
1876  {eDest->Emsg("Config", "fsxeq program not specified"); return 1;}
1877 
1878 // Get the program
1879 //
1880  CFile.RetToken();
1881 
1882 // Set the program for each type
1883 //
1884  for (i = 0; i < numopts; i++)
1885  if (xqopts[i].doset)
1886  {if (!*xqopts[i].pgm) *(xqopts[i].pgm) = new XrdOucProg(0);
1887  if ((*(xqopts[i].pgm))->Setup(val, eDest)) return 1;
1888  }
1889 
1890 // All done
1891 //
1892  return 0;
1893 }
1894 
1895 /******************************************************************************/
1896 /* x f x h l d */
1897 /******************************************************************************/
1898 
1899 /* Function: xfxhld
1900 
1901  Purpose: To parse the directive: fxhold [noloc <nls>] <sec>
1902 
1903  <nls> number of seconds (or M, H, etc) to cache file non-existence
1904  <sec> number of seconds (or M, H, etc) to cache file existence
1905 
1906  Type: Manager only, dynamic.
1907 
1908  Output: 0 upon success or !0 upon failure.
1909 */
1910 
1911 int XrdCmsConfig::xfxhld(XrdSysError *eDest, XrdOucStream &CFile)
1912 {
1913  char *val;
1914  int ct;
1915 
1916  if (!isManager) return CFile.noEcho();
1917 
1918  if (!(val = CFile.GetWord()))
1919  {eDest->Emsg("Config", "fxhold value not specified."); return 1;}
1920 
1921  if (!strcmp(val, "noloc"))
1922  {if (!(val = CFile.GetWord()))
1923  {eDest->Emsg("Config","fxhold noloc value not specified."); return 1;}
1924  if (XrdOuca2x::a2tm(*eDest, "fxhold noloc value", val, &ct,
1925  XrdCmsCache:: min_nxTime)) return 1;
1926  emptylife = ct;
1927  if (!(val = CFile.GetWord())) return 0;
1928  }
1929 
1930  if (XrdOuca2x::a2tm(*eDest, "fxhold value", val, &ct, 60)) return 1;
1931 
1932  cachelife = ct;
1933  return 0;
1934 }
1935 
1936 /******************************************************************************/
1937 /* x l c l r t */
1938 /******************************************************************************/
1939 
1940 /* Function: xlclrt
1941 
1942  Purpose: To parse the directive: localroot <path>
1943 
1944  <path> the path that the server will prefix to all local paths.
1945 
1946  Type: Server only, non-dynamic.
1947 
1948  Output: 0 upon success or !0 upon failure.
1949 */
1950 
1951 int XrdCmsConfig::xlclrt(XrdSysError *eDest, XrdOucStream &CFile)
1952 {
1953  char *val;
1954  int i;
1955 
1956 // If we are a manager, ignore this option
1957 //
1958  if (!isServer) return CFile.noEcho();
1959 
1960 // Get path type
1961 //
1962  val = CFile.GetWord();
1963  if (!val || !val[0])
1964  {eDest->Emsg("Config", "localroot path not specified"); return 1;}
1965  if (*val != '/')
1966  {eDest->Emsg("Config", "localroot path not absolute"); return 1;}
1967 
1968 // Cleanup the path
1969 //
1970  i = strlen(val)-1;
1971  while (i && val[i] == '/') val[i--] = '\0';
1972 
1973 // Assign new path prefix
1974 //
1975  if (i)
1976  {if (LocalRoot) free(LocalRoot);
1977  LocalRoot = strdup(val);
1978  }
1979  return 0;
1980 }
1981 
1982 /******************************************************************************/
1983 /* x m a n g */
1984 /******************************************************************************/
1985 
1986 /* Function: xmang
1987 
1988  Purpose: Parse: manager [meta | peer | proxy] [all|any]
1989  <host>[+][:<port>|<port>] [if ...]
1990 
1991  meta For cmsd: Specified the manager when running as a manager
1992  For xrootd: The directive is ignored.
1993  peer For cmsd: Specified the manager when running as a peer
1994  For xrootd: The directive is ignored.
1995  proxy For cmsd: This directive is ignored.
1996  For xrootd: Specifies the cmsd-proxy service manager
1997  all Ignored (useful only to the cmsd client)
1998  any Ignored (useful only to the cmsd client)
1999  <host> The dns name of the host that is the cache manager.
2000  If the host name ends with a plus, all addresses that are
2001  associated with the host are treated as managers.
2002  <port> The port number to use for this host.
2003  if Apply the manager directive if "if" is true. See
2004  XrdOucUtils:doIf() for "if" syntax.
2005 
2006  Notes: Any number of manager directives can be given.
2007 
2008  Type: Remote server only, non-dynamic.
2009 
2010  Output: 0 upon success or !0 upon failure.
2011 */
2012 
2013 int XrdCmsConfig::xmang(XrdSysError *eDest, XrdOucStream &CFile)
2014 {
2015  class StorageHelper
2016  {public:
2017  StorageHelper(char **v1, char **v2) : val1(v1), val2(v2) {}
2018  ~StorageHelper() {if (*val1) free(*val1);
2019  if (*val2) free(*val2);
2020  }
2021  char **val1, **val2;
2022  };
2023 
2024  XrdOucTList **theList = &ManList;
2025  char *val, *hSpec = 0, *hPort = 0;
2026  StorageHelper SHelp(&hSpec, &hPort);
2027  int rc, xMeta = 0, xPeer = 0, xProxy = 0, *myPort = 0;
2028 
2029 // Process the optional "meta", "peer" or "proxy"
2030 //
2031  if ((val = CFile.GetWord()))
2032  {if ((xMeta = !strcmp("meta", val))
2033  || (xPeer = !strcmp("peer", val))
2034  || (xProxy = !strcmp("proxy", val)))
2035  {if ((xMeta && (isServer || isPeer))
2036  || (xPeer && !isPeer)
2037  || (xProxy && !isProxy)) return CFile.noEcho();
2038  val = CFile.GetWord();
2039  } else if (isPeer) return CFile.noEcho();
2040  }
2041 
2042 // We can accept this manager. Skip the optional "all" or "any"
2043 //
2044  if (val)
2045  if (!strcmp("any", val) || !strcmp("all", val)) val = CFile.GetWord();
2046 
2047 // Get the actual host name and copy it
2048 //
2049  if (!val)
2050  {eDest->Emsg("Config","manager host name not specified"); return 1;}
2051  hSpec = strdup(val);
2052 
2053 // Grab the port number (either in hostname or following token)
2054 //
2055  if (!(hPort = XrdCmsUtils::ParseManPort(eDest, CFile, hSpec))) return 1;
2056 
2057 // Check if this statement is gaurded by and "if" and process it
2058 //
2059  if ((val = CFile.GetWord()))
2060  {if (strcmp(val, "if"))
2061  {eDest->Emsg("Config","expecting manager 'if' but",val,"found");
2062  return 1;
2063  }
2064  if ((rc = XrdOucUtils::doIf(eDest,CFile,"manager directive",
2065  myName,myInsName,myProg))<=0)
2066  {if (!rc) CFile.noEcho(); return rc < 0;}
2067  }
2068 
2069 // Calculate the correct queue and port number to update
2070 //
2071  if (isManager && !isServer)
2072 // {if (((xMeta && isMeta) || (!xMeta && !isMeta)) && PortTCP < 1)
2073  {if (((xMeta && isMeta) || (!xMeta && !isMeta)))
2074  myPort = &PortTCP;
2075  if (isMeta) theList = 0;
2076  else theList = (xMeta ? &ManList : &NanList);
2077  }
2078 
2079 // Parse the specification and return
2080 //
2081  return (XrdCmsUtils::ParseMan(eDest, theList, hSpec, hPort, myPort) ? 0 : 1);
2082 }
2083 
2084 /******************************************************************************/
2085 /* x n b s q */
2086 /******************************************************************************/
2087 
2088 /* Function: xnbsq
2089 
2090  Purpose: To parse the directive: nbsendq [<opt>] [warn <nw>] [maxq <mq>]
2091 
2092  <opt> One of: all | off | remote
2093  <nw> Warning will be issued at a <nw> backlog.
2094  <mq> Message will be discarded at a <mq> backlog (<mq> may
2095  also be the word "none").
2096 
2097  Defaults: remote warn 3 maxq 30
2098 
2099  Output: 0 upon success or !0 upon failure.
2100 */
2101 
2102 int XrdCmsConfig::xnbsq(XrdSysError *eDest, XrdOucStream &CFile)
2103 {
2104  char *val, xopt[16];
2105  int ival;
2106  bool xAll = false, xOff = false, xRmt = false;
2107 
2108 // Process the optional "all", "off" or "remote"
2109 //
2110  if ((val = CFile.GetWord()))
2111  {if ((xAll = !strcmp("all", val))
2112  || (xOff = !strcmp("off", val))
2113  || (xRmt = !strcmp("remote", val)))
2114  { if (xAll) nbSQ = 2;
2115  else if (xRmt) nbSQ = 1;
2116  else nbSQ = 0;
2117  val = CFile.GetWord();
2118  }
2119  } else {eDest->Emsg("Config","nbsendq option not specified"); return 1;}
2120 
2121 // Now scan for the other options
2122 //
2123  while(val && *val)
2124  {size_t size = sizeof(xopt)-1;
2125  strncpy(xopt, val, size);
2126  xopt[size] = '\0';
2127  if (!(val= CFile.GetWord()) || *val == 0)
2128  {eDest->Emsg("Config","nbsendq ", xopt, " argument not specified");
2129  return 1;
2130  }
2131  if (!strcmp(xopt, "maxq"))
2132  {if (!strcmp("val", "none")) ival = -1;
2133  else if (XrdOuca2x::a2i(*eDest,"nbsendq maxq",val,&ival,0))
2134  return 1;
2135  XrdSendQ::SetQM(ival);
2136  }
2137  else if (!strcmp(xopt, "warn"))
2138  {if (XrdOuca2x::a2i(*eDest,"nbsendq warn",val,&ival,0)) return 1;
2139  XrdSendQ::SetQW(ival);
2140  }
2141  else eDest->Say("Config warning: ignoring invalid nbsendq option '",xopt,"'.");
2142  val = CFile.GetWord();
2143  }
2144  return 0;
2145 }
2146 
2147 /******************************************************************************/
2148 /* x p e r f */
2149 /******************************************************************************/
2150 
2151 /* Function: xperf
2152 
2153  Purpose: To parse the directive: perf [xrootd] [int <sec>]
2154  [lib <lib> [<parms>] | pgm <pgm>]
2155 
2156  int <time> estimated time (seconds, M, H) between reports by <pgm>
2157  lib <lib> the shared library holding the XrdCmsPerf object that
2158  reports perf values. It must be the last option.
2159  pgm <pgm> program to start that will write perf values to standard
2160  out. It must be the last option.
2161  xrootd This directive only applies to the cms xrootd plugin.
2162 
2163  Type: Server only, non-dynamic.
2164 
2165  Output: 0 upon success or !0 upon failure. Ignored by manager.
2166 */
2167 int XrdCmsConfig::xperf(XrdSysError *eDest, XrdOucStream &CFile)
2168 { char *pgm=0, *val, rest[2048];
2169 
2170  if (!isServer) return CFile.noEcho();
2171 
2172  if (!(val = CFile.GetWord()))
2173  {eDest->Emsg("Config", "perf options not specified"); return 1;}
2174 
2175  if (!strcmp("xrootd", val)) return CFile.noEcho();
2176  perfint = 3*60;
2177 
2178  do { if (!strcmp("int", val))
2179  {if (!(val = CFile.GetWord()))
2180  {eDest->Emsg("Config", "perf int value not specified");
2181  return 1;
2182  }
2183  if (XrdOuca2x::a2tm(*eDest,"perf int",val,&perfint,0)) return 1;
2184  }
2185  else if (!strcmp("lib", val))
2186  {if (perfpgm) {free(perfpgm); perfpgm = 0;}
2187  return (XrdOucUtils::parseLib(*eDest,CFile,"perf lib",
2188  prfLib, &prfParms) ? 0 : 1);
2189  break;
2190  }
2191  else if (!strcmp("pgm", val))
2192  {if (!CFile.GetRest(rest, sizeof(rest)))
2193  {eDest->Emsg("Config", "perf pgm parameters too long");
2194  return 1;
2195  }
2196  if (!*rest)
2197  {eDest->Emsg("Config", "perf pgm value not specified");
2198  return 1;
2199  }
2200  pgm = rest;
2201  break;
2202  }
2203  else eDest->Say("Config warning: ignoring invalid perf option '",val,"'.");
2204  } while((val = CFile.GetWord()));
2205 
2206 // Make sure that the perf program is here
2207 //
2208  if (perfpgm) {free(perfpgm); perfpgm = 0;}
2209  if (prfLib) {free(prfLib); prfLib = 0;}
2210  if (prfParms){free(prfParms);prfParms = 0;}
2211  if (pgm) {if (!isExec(eDest, "perf", pgm)) return 1;
2212  else perfpgm = strdup(pgm);
2213  }
2214 
2215 // All done.
2216 //
2217  return 0;
2218 }
2219 
2220 /******************************************************************************/
2221 /* x p i n g */
2222 /******************************************************************************/
2223 
2224 /* Function: xping
2225 
2226  Purpose: To parse the directive: ping <ptm> [log <num>] [usage <cnt>]
2227 
2228  <ptm> Time (seconds, M, H. etc) between keepalive pings.
2229  The default is 60 seconds.
2230  log values are logged to the log every <num> usage
2231  requests (default 10). Zero, suppresses logging.
2232  usage The number of pings between resource usage requests.
2233  The default is 10. Zero suppresses usage requests.
2234 
2235  Note: The defaults will log usage 100 minutes (little less than 2 hours).
2236 
2237  Type: Server for ping value and Manager for all values, dynamic.
2238 
2239  Output: 0 upon success or !0 upon failure.
2240 */
2241 int XrdCmsConfig::xping(XrdSysError *eDest, XrdOucStream &CFile)
2242 { int pnum = AskPerf, lnum = LogPerf, ping;
2243  char *val;
2244 
2245  if (!(val = CFile.GetWord()))
2246  {eDest->Emsg("Config", "ping value not specified"); return 1;}
2247  if (XrdOuca2x::a2tm(*eDest, "ping interval",val,&ping,0)) return 1;
2248  if (ping < 3) ping = 3;
2249 
2250  while((val = CFile.GetWord()))
2251  { if (!strcmp("log", val))
2252  {if (!(val = CFile.GetWord()))
2253  {eDest->Emsg("Config", "ping log value not specified");
2254  return 1;
2255  }
2256  if (XrdOuca2x::a2i(*eDest,"ping log",val,&lnum,0)) return 1;
2257  }
2258  else if (!strcmp("usage", val))
2259  {if (!(val = CFile.GetWord()))
2260  {eDest->Emsg("Config", "ping usage value not specified");
2261  return 1;
2262  }
2263  if (XrdOuca2x::a2i(*eDest,"ping usage",val,&pnum,1)) return 1;
2264  }
2265  }
2266  AskPerf = pnum;
2267  AskPing = ping;
2268  LogPerf = lnum;
2269  return 0;
2270 }
2271 
2272 /******************************************************************************/
2273 /* x p r e p */
2274 /******************************************************************************/
2275 
2276 /* Function: xprep
2277 
2278  Purpose: To parse the directive: prep [echo]
2279  [reset <cnt>] [scrub <sec>]
2280  [ifpgm <pgm>]
2281 
2282  echo display list of pending prepares during resets.
2283  reset <cnt> number of scrubs after which a full reset is done.
2284  scrub <sec> time (seconds, M, H) between pendq scrubs.
2285  ifpgm <pgm> program that adds, deletes, and lists prepare queue
2286  entries. If specified, t must be specified as the last
2287  option on the line. If not specified, then the built-in
2288  frm_xfragent program is used.
2289 
2290  Type: Any, non-dynamic. Note that the Manager only need the "batch" option
2291  while slacves need the remaining options.
2292 
2293  Output: 0 upon success or !0 upon failure. Ignored by manager.
2294 */
2295 int XrdCmsConfig::xprep(XrdSysError *eDest, XrdOucStream &CFile)
2296 { int reset=0, scrub=0, echo = 0, doset = 0;
2297  char *prepif=0, *val, rest[2048];
2298 
2299  if (!isServer) return CFile.noEcho();
2300 
2301  if (!(val = CFile.GetWord())) {PrepQ.setParms(""); return 0;}
2302 
2303  do { if (!strcmp("echo", val)) doset = echo = 1;
2304  else if (!strcmp("reset", val))
2305  {if (!(val = CFile.GetWord()))
2306  {eDest->Emsg("Config", "prep reset value not specified");
2307  return 1;
2308  }
2309  if (XrdOuca2x::a2i(*eDest,"prep reset int",val,&reset,1)) return 1;
2310  doset = 1;
2311  }
2312  else if (!strcmp("scrub", val))
2313  {if (!(val = CFile.GetWord()))
2314  {eDest->Emsg("Config", "prep scrub value not specified");
2315  return 1;
2316  }
2317  if (XrdOuca2x::a2tm(*eDest,"prep scrub",val,&scrub,0)) return 1;
2318  doset = 1;
2319  }
2320  else if (!strcmp("ifpgm", val))
2321  {if (!CFile.GetRest(rest, sizeof(rest)))
2322  {eDest->Emsg("Config", "prep ifpgm parameters too long"); return 1;}
2323  if (!*rest)
2324  {eDest->Emsg("Config", "prep ifpgm value not specified");
2325  return 1;
2326  }
2327  prepif = rest;
2328  break;
2329  }
2330  else eDest->Say("Config warning: ignoring invalid prep option '",val,"'.");
2331  } while((val = CFile.GetWord()));
2332 
2333 
2334 
2335 // Set the values
2336 //
2337  if (scrub) pendplife = scrub;
2338  if (doset) PrepQ.setParms(reset, scrub, echo);
2339  if (prepif) {if (!isExec(eDest, "prep", prepif)) return 1;
2340  else return PrepQ.setParms(prepif);
2341  } else PrepQ.setParms("");
2342  return 0;
2343 }
2344 
2345 /******************************************************************************/
2346 /* x p r e p m */
2347 /******************************************************************************/
2348 
2349 /* Function: xprepm
2350 
2351  Purpose: To parse the directive: prepmsg <msg>
2352 
2353  <msg> the message to be sent to the prep ifpgm (see prep).
2354 
2355  Type: Manager only, non-dynamic.
2356 
2357  Output: 0 upon success or !0 upon failure.
2358 */
2359 
2360 int XrdCmsConfig::xprepm(XrdSysError *eDest, XrdOucStream &CFile)
2361 {
2362  char *val, buff[2048];
2363  XrdOucEnv *myEnv = CFile.SetEnv(0);
2364 
2365  // At this point, make sure we have a value
2366  //
2367  if (!(val = CFile.GetWord()))
2368  {eDest->Emsg("Config", "no value for prepmsg directive");
2369  CFile.SetEnv(myEnv);
2370  return 1;
2371  }
2372 
2373  // We need to suck all the tokens to the end of the line for remaining
2374  // options. Do so, until we run out of space in the buffer.
2375  //
2376  CFile.RetToken();
2377  if (!CFile.GetRest(buff, sizeof(buff)))
2378  {eDest->Emsg("Config", "prepmsg arguments too long");
2379  CFile.SetEnv(myEnv);
2380  return 1;
2381  }
2382 
2383  // Restore substitutions and parse the message
2384  //
2385  CFile.SetEnv(myEnv);
2386  return PrepQ.setParms(0, buff);
2387 }
2388 
2389 /******************************************************************************/
2390 /* x r e p s */
2391 /******************************************************************************/
2392 
2393 /* Function: xreps
2394 
2395  Purpose: To parse the directive: repstats <options>
2396 
2397  Type: Manager or Server, dynamic.
2398 
2399  Output: 0 upon success or !0 upon failure.
2400 */
2401 
2402 int XrdCmsConfig::xreps(XrdSysError *eDest, XrdOucStream &CFile)
2403 {
2404  char *val;
2405  static struct repsopts {const char *opname; int opval;} rsopts[] =
2406  {
2407  {"all", RepStat_All},
2408  {"frq", RepStat_frq},
2409  {"shr", RepStat_shr}
2410  };
2411  int i, neg, rsval = 0, numopts = sizeof(rsopts)/sizeof(struct repsopts);
2412 
2413  if (!(val = CFile.GetWord()))
2414  {eDest->Emsg("config", "repstats option not specified"); return 1;}
2415  while (val)
2416  {if (!strcmp(val, "off")) rsval = 0;
2417  else {if ((neg = (val[0] == '-' && val[1]))) val++;
2418  for (i = 0; i < numopts; i++)
2419  {if (!strcmp(val, rsopts[i].opname))
2420  {if (neg) rsval &= ~rsopts[i].opval;
2421  else rsval |= rsopts[i].opval;
2422  break;
2423  }
2424  }
2425  if (i >= numopts)
2426  eDest->Say("Config warning: ignoring invalid repstats option '",val,"'.");
2427  }
2428  val = CFile.GetWord();
2429  }
2430 
2431  RepStats = rsval;
2432  return 0;
2433 }
2434 
2435 /******************************************************************************/
2436 /* x r m t r t */
2437 /******************************************************************************/
2438 
2439 /* Function: xrmtrt
2440 
2441  Purpose: To parse the directive: remoteroot <path>
2442 
2443  <path> the path that the server will prefix to all remote paths.
2444 
2445  Type: Manager only, non-dynamic.
2446 
2447  Output: 0 upon success or !0 upon failure.
2448 */
2449 
2450 int XrdCmsConfig::xrmtrt(XrdSysError *eDest, XrdOucStream &CFile)
2451 {
2452  char *val, *colon, *slash;
2453  int i;
2454 
2455 // If we are a manager, ignore this option
2456 //
2457  if (isManager) return CFile.noEcho();
2458 
2459 // Get path type
2460 //
2461  val = CFile.GetWord();
2462  if (!val || !val[0])
2463  {eDest->Emsg("Config", "remoteroot path not specified"); return 1;}
2464 
2465 // For remote roots we allow a url-type specification o/w path must be absolute
2466 //
2467  if (*val != '/')
2468  {colon = index(val, ':'); slash = index(val, '/');
2469  if ((colon+1) != slash)
2470  {eDest->Emsg("Config", "remoteroot path not absolute"); return 1;}
2471  }
2472 
2473 // Cleanup the path
2474 //
2475  i = strlen(val)-1;
2476  while (i && val[i] == '/') val[i--] = '\0';
2477 
2478 // Assign new path prefix
2479 //
2480  if (i)
2481  {if (RemotRoot) free(RemotRoot);
2482  RemotRoot = strdup(val);
2483  }
2484  return 0;
2485 }
2486 
2487 /******************************************************************************/
2488 /* x r o l e */
2489 /******************************************************************************/
2490 
2491 /* Function: xrole
2492  Purpose: Parse: role { {[meta] | [peer] [proxy]} manager
2493  | peer | proxy | [proxy] server
2494  | [proxy] supervisor
2495  } [if ...]
2496 
2497  manager xrootd: act as a manager (redirecting server). Prefixes:
2498  meta - connect only to manager meta's
2499  peer - ignored
2500  proxy - ignored
2501  cmsd: accept server subscribes and redirectors. Prefix
2502  modifiers do the following:
2503  meta - No other managers apply
2504  peer - subscribe to other managers as a peer
2505  proxy - manage a cluster of proxy servers
2506 
2507  peer xrootd: same as "peer manager"
2508  cmsd: same as "peer manager" but no server subscribers
2509  are required to function (i.e., run stand-alone).
2510 
2511  proxy xrootd: act as a server but supply data from another
2512  server. No local cmsd is present or required.
2513  cmsd: Generates an error as this makes no sense.
2514 
2515  server xrootd: act as a server (supply local data). Prefix
2516  modifications do the following:
2517  proxy - server is part of a cluster. A local
2518  cmsd is required.
2519  cmsd: subscribe to a manager, possibly as a proxy.
2520 
2521  supervisor xrootd: equivalent to manager.
2522  cmsd: equivalent to manager but also subscribe to a
2523  manager. When proxy is specified, subscribe as
2524  a proxy and only accept proxy servers.
2525 
2526 
2527  if Apply the manager directive if "if" is true. See
2528  XrdOucUtils:doIf() for "if" syntax.
2529 
2530 
2531  Type: Server only, non-dynamic.
2532 
2533  Output: 0 upon success or !0 upon failure.
2534 */
2535 
2536 int XrdCmsConfig::xrole(XrdSysError *eDest, XrdOucStream &CFile)
2537 {
2538  XrdCmsRole::RoleID roleID;
2539  char *val, *Tok1, *Tok2;
2540  int rc, xMeta=0, xPeer=0, xProxy=0, xServ=0, xMan=0, xSolo=0;
2541 
2542 // Get the first token
2543 //
2544  if (!(val = CFile.GetWord()) || !strcmp(val, "if"))
2545  {eDest->Emsg("Config", "role not specified"); return 1;}
2546  Tok1 = strdup(val);
2547 
2548 // Get second token which might be an "if"
2549 //
2550  if ((val = CFile.GetWord()) && strcmp(val, "if"))
2551  {Tok2 = strdup(val);
2552  val = CFile.GetWord();
2553  } else Tok2 = 0;
2554 
2555 // Process the if at this point
2556 //
2557  if (val && !strcmp("if", val))
2558  if ((rc = XrdOucUtils::doIf(eDest,CFile,"role directive",
2559  myName,myInsName,myProg)) <= 0)
2560  {free(Tok1); if (Tok2) free(Tok2);
2561  if (!rc) CFile.noEcho();
2562  return (rc < 0);
2563  }
2564 
2565 // Convert the role names to a role ID, if possible
2566 //
2567  roleID = XrdCmsRole::Convert(Tok1, Tok2);
2568 
2569 // Set markers based on the role we have
2570 //
2571  rc = 0;
2572  switch(roleID)
2573  {case XrdCmsRole::MetaManager: xMeta = xMan = -1; break;
2574  case XrdCmsRole::Manager: xMan = -1; break;
2575  case XrdCmsRole::Supervisor: xMan = xServ = -1; break;
2576  case XrdCmsRole::Server: xServ = -1; break;
2577  case XrdCmsRole::ProxyManager: xProxy = xMan = -1; break;
2578  case XrdCmsRole::ProxySuper: xProxy = xMan = xServ = -1; break;
2579  case XrdCmsRole::ProxyServer: xProxy = xServ = -1; break;
2580  case XrdCmsRole::PeerManager: xPeer = xMan = -1; break;
2581  case XrdCmsRole::Peer: xPeer = xSolo = xServ -1; break;
2582  default: eDest->Emsg("Config", "invalid role -", Tok1, Tok2); rc = 1;
2583  }
2584 
2585 // Release storage and return if an error occurred
2586 //
2587  free(Tok1);
2588  if (Tok2) free(Tok2);
2589  if (rc) return rc;
2590 
2591 // If the role was specified on the command line, issue warning and ignore this
2592 //
2593  if (isServer > 0 || isManager > 0 || isProxy > 0 || isPeer > 0)
2594  {eDest->Say("Config warning: role directive over-ridden by command line.");
2595  return 0;
2596  }
2597 
2598 // Fill out information
2599 //
2600  isServer = xServ; isManager = xMan; isProxy = xProxy;
2601  isPeer = xPeer; isSolo = xSolo; isMeta = xMeta;
2602  if (myRole) free(myRole);
2603  myRole = strdup(XrdCmsRole::Name(roleID));
2604  myRoleID = static_cast<int>(roleID);
2605  strcpy(myRType, XrdCmsRole::Type(roleID));
2606  return 0;
2607 }
2608 
2609 /******************************************************************************/
2610 /* x s c h e d */
2611 /******************************************************************************/
2612 
2613 /* Function: xsched
2614 
2615  Purpose: To parse directive: sched [cpu <p>] [gsdflt <p>] [gshr <p>]
2616  [io <p>] [runq <p>]
2617  [mem <p>] [pag <p>] [space <p>]
2618  [fuzz <p>] [maxload <p>] [refreset <sec>]
2619  [maxretries <n>[@<host>:<port>]]
2620  [nomultisrc[@<host>:<port>]]
2621  [affinity [default] {none | weak | strong | strict}]
2622  [affpath {all | first m | last n}]
2623 
2624  <p> is the percentage to include in the load as a value
2625  between 0 and 100. For fuzz this is the largest
2626  difference two load values may have to be treated equal.
2627  maxload is the largest load allowed before server is
2628  not selected. refreset is the minimum number of seconds
2629  between reference counter resets. gshr is the percentage
2630  share of requests that should be redirected here via the
2631  metamanager (i.e. global share). The gsdflt is the
2632  default to be used by the metamanager.
2633 
2634  Type: Any, dynamic.
2635 
2636  Output: retc upon success or -EINVAL upon failure.
2637 */
2638 
2639 int XrdCmsConfig::xsched(XrdSysError *eDest, XrdOucStream &CFile)
2640 {
2641  char *val;
2642  int i, ppp, V_hntry = -1;
2643  static struct schedopts {const char *opname; int maxv; int *oploc;}
2644  scopts[] =
2645  {
2646  {"cpu", 100, &P_cpu},
2647  {"fuzz", 100, &P_fuzz},
2648  {"gsdflt", 100, &P_gsdf},
2649  {"gshr", 100, &P_gshr},
2650  {"io", 100, &P_io},
2651  {"runq", 100, &P_load}, // Actually load, runq to avoid confusion
2652  {"mem", 100, &P_mem},
2653  {"pag", 100, &P_pag},
2654  {"space", 100, &P_dsk},
2655  {"maxload", 100, &MaxLoad},
2656  {"refreset", -1, &RefReset},
2657  {"affinity", -2, 0},
2658  {"affpath", -3, 0},
2659  {"tryhname", 1, &V_hntry}
2660  };
2661  int numopts = sizeof(scopts)/sizeof(struct schedopts);
2662 
2663  if (!(val = CFile.GetWord()))
2664  {eDest->Emsg("Config", "sched option not specified"); return 1;}
2665 
2666  while (val)
2667  {for (i = 0; i < numopts; i++)
2668  if (!strcmp(val, scopts[i].opname))
2669  {if (!(val = CFile.GetWord()))
2670  {eDest->Emsg("Config", "sched ", scopts[i].opname,
2671  "argument not specified.");
2672  return 1;
2673  }
2674  if (scopts[i].maxv == -2)
2675  {if (!xschedm(val, eDest, CFile)) return 1;
2676  break;
2677  }
2678  if (scopts[i].maxv == -3)
2679  {if (!xschedp(val, eDest, CFile)) return 1;
2680  break;
2681  }
2682  if (scopts[i].maxv < 0)
2683  {if (XrdOuca2x::a2tm(*eDest,"sched value", val, &ppp, 0))
2684  return 1;
2685  }
2686  else if (XrdOuca2x::a2i(*eDest,"sched value", val, &ppp,
2687  0, scopts[i].maxv)) return 1;
2688  *scopts[i].oploc = ppp;
2689  break;
2690  }
2691  if (i >= numopts)
2692  {int rc = xschedx(val, eDest, CFile);
2693  if (rc < 0) return 1;
2694  if (rc > 0) eDest->Say("Config warning: "
2695  "ignoring invalid sched option '",val,"'.");
2696  }
2697  val = CFile.GetWord();
2698  }
2699 
2700 // Handle non-int settings
2701 //
2702  if (V_hntry >= 0) DoHnTry = static_cast<char>(V_hntry);
2703 
2704  return 0;
2705 }
2706 
2707 /******************************************************************************/
2708 
2709 int XrdCmsConfig::xschedm(char *val, XrdSysError *eDest, XrdOucStream &CFile)
2710 {
2711 
2712  if (!strcmp(val, "default"))
2713  {sched_Force = 0;
2714  if (!(val = CFile.GetWord()))
2715  {eDest->Emsg("Config", "sched affinity not specified"); return 0;}
2716  } else sched_Force = 1;
2717 
2718  if (!strcmp(val, "none"))
2719  {sched_Pack = sched_Level = 0;
2720  return 1;
2721  }
2722 
2723  sched_Pack = sched_Level = 1;
2724 
2725  if (!strcmp(val, "weak")) return 1;
2726 
2727  sched_Pack = 2;
2728 
2729  if (!strcmp(val, "strong")) return 1;
2730 
2731  if (!strcmp(val, "strict"))
2732  {sched_Level = 0;
2733  return 1;
2734  }
2735 
2736  if (!strcmp(val, "randomized"))
2737  {sched_LoadR = 1;
2738  return 1;
2739  }
2740 
2741  eDest->Emsg("Config", "Invalid sched affinity -", val);
2742  return 0;
2743 }
2744 
2745 /******************************************************************************/
2746 
2747 int XrdCmsConfig::xschedp(char *val, XrdSysError *eDest, XrdOucStream &CFile)
2748 {
2749  int afpsign, afpval;
2750 
2751  if (!strcmp(val, "all"))
2752  {sched_AffPC = 0;
2753  return 1;
2754  }
2755 
2756  if (!strcmp(val, "first")) afpsign = 1;
2757  else if (!strcmp(val, "last")) afpsign = -1;
2758  else {eDest->Emsg("Config", "sched affpath option invalid -", val);
2759  return 0;
2760  }
2761 
2762  if (!(val = CFile.GetWord()))
2763  {eDest->Emsg("Config", "sched affpath argument not specified"); return 0;}
2764 
2765  if (XrdOuca2x::a2i(*eDest,"sched affpath value", val, &afpval, 1, 255))
2766  return 0;
2767 
2768  sched_AffPC = static_cast<char>(afpval*afpsign);
2769  return 1;
2770 }
2771 
2772 /******************************************************************************/
2773 
2774 int XrdCmsConfig::xschedx(char *val, XrdSysError *eDest, XrdOucStream &CFile)
2775 {
2776 
2777 // Check for maxretries
2778 //
2779  if (!strcmp(val, "maxretries"))
2780  {if (!(val = CFile.GetWord()))
2781  {eDest->Emsg("Config","sched ","maxretries argument not specified.");
2782  return -1;
2783  }
2784  if (!xschedy(val, eDest, mrRdrHost, mrRdrHLen, mrRdrPort)) return -1;
2785  if (XrdOuca2x::a2i(*eDest,"sched value",val,&MaxRetries,0)) return -1;
2786  return 0;
2787  }
2788 
2789 // Check for unqualified nomultisrc
2790 //
2791  if (!strcmp(val, "nomultisrc"))
2792  {MultiSrc = 0;
2793  if (msRdrHost)
2794  {free(msRdrHost);
2795  msRdrHost = 0;
2796  msRdrHLen = 0;
2797  }
2798  return 0;
2799  }
2800 
2801 // Check for qualified nomultisrc
2802 // 12345678901
2803  if (!strncmp(val, "nomultisrc@", 11))
2804  {if (!xschedy(val, eDest, msRdrHost, msRdrHLen, msRdrPort)) return -1;
2805  MultiSrc = 0;
2806  return 0;
2807  }
2808 
2809  return 1;
2810 }
2811 
2812 /******************************************************************************/
2813 
2814 bool XrdCmsConfig::xschedy(char *val, XrdSysError *eDest, char *&host,
2815  int &hlen, int &port)
2816 {
2817  const char *badTarget = "Invalid sched redirect target '%s'%s";
2818  XrdNetAddr netAddr;
2819  char *at, hName[XrdCmsSelect::SelDSZ];
2820  const char *eText = "not a redirect target";
2821 
2822 // Free the host name if present
2823 //
2824  if (host) {free(host); host = 0; hlen = port = 0;}
2825 
2826 // Check if we have an at sign
2827 //
2828  if (!(at = index(val, '@'))) return true;
2829  if (!*(at+1))
2830  {snprintf(hName, sizeof(hName),
2831  "Missing sched redirect target after '%s'.", val);
2832  eDest->Emsg("Config", hName);
2833  return false;
2834  }
2835  *at = 0; val = at + 1;
2836 
2837 // Make sure this is not a named pipe
2838 //
2839  if (*val == '/')
2840  {snprintf(hName, sizeof(hName), badTarget, val, ".");
2841  eDest->Emsg("Config", hName);
2842  return false;
2843  }
2844 
2845 // Parse the host and port
2846 //
2847  if ((eText = netAddr.Set(val)))
2848  {snprintf(hName, sizeof(hName), badTarget, val, ";");
2849  eDest->Emsg("Config", hName, eText);
2850  return false;
2851  }
2852 
2853 // Now get the host name and port
2854 //
2855  if (!netAddr.Format(hName, sizeof(hName), XrdNetAddrInfo::fmtAuto,
2857  {snprintf(hName, sizeof(hName), badTarget, val, ".");
2858  eDest->Emsg("Config", hName);
2859  return false;
2860  }
2861 
2862 // Set values and return
2863 //
2864  host = strdup(hName);
2865  hlen = strlen(hName)+1;
2866  port = netAddr.Port();
2867  return true;
2868 }
2869 
2870 /******************************************************************************/
2871 /* x s e c l */
2872 /******************************************************************************/
2873 
2874 /* Function: xsecl
2875 
2876  Purpose: To parse the directive: seclib <path>
2877 
2878  <path> the location of the security library.
2879 
2880  Type: Server only, non-dynamic.
2881 
2882  Output: 0 upon success or !0 upon failure.
2883 */
2884 
2885 int XrdCmsConfig::xsecl(XrdSysError *eDest, XrdOucStream &CFile)
2886 {
2887 
2888 // If we are a server, ignore this option
2889 //
2890  if (!isManager) return CFile.noEcho();
2891 
2892 // Return parse result
2893 //
2894  return (XrdOucUtils::parseLib(*eDest,CFile,"seclib",SecLib,0) ? 0 : 1);
2895 }
2896 
2897 /******************************************************************************/
2898 /* x s p a c e */
2899 /******************************************************************************/
2900 
2901 /* Function: xspace
2902 
2903  Purpose: To parse the directive: space [linger <num>] [recalc <sec>]
2904 
2905  [[min] {<mnp> [<min>] | <min>} [[<hwp>] <hwm>]]
2906 
2907  [mwfiles]
2908 
2909  <num> Maximum number of times a server may be reselected without
2910  a break. The default is 0.
2911 
2912  <mnp> Min free space needed as percentage of the largest partition.
2913 
2914  <min> Min free space needed in bytes (or K, M, G) in a partition.
2915  The default is 10G.
2916 
2917  <hwp> Percentage of free space needed to requalify.
2918 
2919  <hwm> Bytes (or K, M,G) of free space needed when bytes falls below
2920  <min> to requalify a server for selection.
2921  The default is 11G.
2922 
2923  <sec> Number of seconds that must elapse before a disk free space
2924  calculation will occur.
2925 
2926  mwfiles
2927  space supports multiple writable file copies. This suppresses
2928  multiple file check when open a file in write mode.
2929 
2930  Notes: This is used by the manager and the server.
2931 
2932  Type: All, dynamic.
2933 
2934  Output: 0 upon success or !0 upon failure.
2935 */
2936 
2937 int XrdCmsConfig::xspace(XrdSysError *eDest, XrdOucStream &CFile)
2938 {
2939  char *val;
2940  int i, alinger = -1, arecalc = -1, minfP = -1, hwmP = -1;
2941  long long minf = -1, hwm = -1;
2942  bool haveopt = false;
2943 
2944  while((val = CFile.GetWord()))
2945  { if (!strcmp("linger", val))
2946  {if (!(val = CFile.GetWord()))
2947  {eDest->Emsg("Config", "linger value not specified"); return 1;}
2948  if (XrdOuca2x::a2i(*eDest,"linger",val,&alinger,0)) return 1;
2949  }
2950  else if (!strcmp("recalc", val))
2951  {if (!(val = CFile.GetWord()))
2952  {eDest->Emsg("Config", "recalc value not specified"); return 1;}
2953  if (XrdOuca2x::a2i(*eDest,"recalc",val,&arecalc,1)) return 1;
2954  }
2955  else if (!strcmp("min", val))
2956  {if (!(val = CFile.GetWord()) || !isdigit(*val))
2957  {eDest->Emsg("Config", "space min value not specified"); return 1;}
2958  break;
2959  }
2960  else if (!strcmp("mwfiles", val)) {DoMWChk = 0; haveopt = true;}
2961  else if (isdigit(*val)) break;
2962  else {eDest->Emsg("Config", "invalid space parameters"); return 1;}
2963  }
2964 
2965  if (val && isdigit(*val))
2966  {i = strlen(val);
2967  if (val[i-1] == '%')
2968  {val[i-1] = '\0';
2969  if (XrdOuca2x::a2i(*eDest,"space % minfree",val,&minfP,1,99)) return 1;
2970  val = CFile.GetWord();
2971  }
2972  }
2973 
2974  if (val && isdigit(*val))
2975  {i = strlen(val);
2976  if (val[i-1] != '%')
2977  {if (XrdOuca2x::a2sz(*eDest,"space minfree",val,&minf,0)) return 1;
2978  val = CFile.GetWord();
2979  }
2980  }
2981 
2982  if (minfP >= 0 && minf < 0)
2983  {eDest->Emsg("Config", "absolute min value not specified"); return 1;}
2984 
2985  if (val && isdigit(*val))
2986  {i = strlen(val);
2987  if (val[i-1] == '%')
2988  {val[i-1] = '\0';
2989  if (XrdOuca2x::a2i(*eDest,"space % high watermark",val,&hwmP,1,99)) return 1;
2990  val = CFile.GetWord();
2991  }
2992  }
2993 
2994  if (val && isdigit(*val))
2995  {i = strlen(val);
2996  if (val[i-1] != '%')
2997  {if (XrdOuca2x::a2sz(*eDest,"space high watermark",val,&hwm,0)) return 1;
2998  val = CFile.GetWord();
2999  }
3000  }
3001 
3002  if (hwmP >= 0 && hwm < 0)
3003  {eDest->Emsg("Config", "absolute high watermark value not specified"); return 1;}
3004 
3005  if (val) {eDest->Emsg("Config", "invalid space parameter -", val); return 1;}
3006 
3007  if (!haveopt && alinger < 0 && arecalc < 0 && minf < 0)
3008  {eDest->Emsg("Config", "no space values specified"); return 1;}
3009 
3010  if (alinger >= 0) DiskLinger = alinger;
3011  if (arecalc >= 0) DiskAsk = arecalc;
3012 
3013  if (minfP > 0)
3014  {if (hwmP < minfP) hwmP = minfP + 1;
3015  DiskMinP = minfP; DiskHWMP = hwmP;
3016  } else DiskMinP = DiskHWMP = 0;
3017 
3018  if (minf >= 0)
3019  {if (hwm < minf) hwm = minf+1073741824; // Minimum + 1GB
3020  minf = minf >> 20LL; hwm = hwm >> 20LL; // Now Megabytes
3021  if (minf >> 31LL) {minf = 0x7fefffff; hwm = 0x7fffffff;}
3022  else if (hwm >> 31LL) minf = 0x7fffffff;
3023  DiskMin = static_cast<int>(minf);
3024  DiskHWM = static_cast<int>(hwm);
3025  }
3026  return 0;
3027 }
3028 
3029 /******************************************************************************/
3030 /* x s u b c */
3031 /******************************************************************************/
3032 
3033 /* Function: subc
3034 
3035  Purpose: To parse the directive: subcluster of <host>[+][:<port>|<port>]
3036 
3037  Type: Manager only, non-dynamic.
3038 
3039  Output: 0 upon success or !0 upon failure.
3040 */
3041 
3042 int XrdCmsConfig::xsubc(XrdSysError *eDest, XrdOucStream &CFile)
3043 {
3044  class StorageHelper
3045  {public:
3046  StorageHelper(char **v1, char **v2) : val1(v1), val2(v2) {}
3047  ~StorageHelper() {if (*val1) free(*val1);
3048  if (*val2) free(*val2);
3049  }
3050  char **val1, **val2;
3051  };
3052 
3053  char *val, *hSpec = 0, *hPort = 0;
3054  StorageHelper SHelp(&hSpec, &hPort);
3055 
3056 // Ignore this call if we are not a simple manager
3057 //
3058  if (isMeta || isServer || isPeer || isProxy) return CFile.noEcho();
3059 
3060 // Skip the optional "of" keyword
3061 //
3062  val = CFile.GetWord();
3063  if (val && !strcmp("of", val)) val = CFile.GetWord();
3064 
3065 // Get the actual host name and copy it
3066 //
3067  if (!val)
3068  {eDest->Emsg("Config","cluster manager host name not specified");
3069  return 1;
3070  }
3071  hSpec = strdup(val);
3072 
3073 // Grab the port number (either in hostname or following token)
3074 //
3075  if (!(hPort = XrdCmsUtils::ParseManPort(eDest, CFile, hSpec))) return 1;
3076 
3077 // Parse the specification and return
3078 //
3079  return (XrdCmsUtils::ParseMan(eDest, &SanList, hSpec, hPort) ? 0 : 1);
3080 }
3081 
3082 /******************************************************************************/
3083 /* x s u p p */
3084 /******************************************************************************/
3085 
3086 /* Function: xsupp
3087 
3088  Purpose: To parse the directive: superport <tcpnum>
3089  [if [<hlst>] [named <nlst>]]
3090 
3091  <tcpnum> number of the tcp port for incoming requests
3092  <hlst> list of applicable host patterns
3093  <nlst> list of applicable instance names.
3094 
3095  Output: 0 upon success or !0 upon failure.
3096 */
3097 int XrdCmsConfig::xsupp(XrdSysError *eDest, XrdOucStream &CFile)
3098 { const char *invp = "superport port";
3099  char *val, cport[32];
3100  int rc, pnum;
3101 
3102  if (!(val = CFile.GetWord()))
3103  {eDest->Emsg("Config", "tcp port not specified"); return 1;}
3104 
3105  strncpy(cport, val, sizeof(cport)-1); cport[sizeof(cport)-1] = '\0';
3106 
3107  if ((val = CFile.GetWord()) && !strcmp("if", val))
3108  if ((rc = XrdOucUtils::doIf(eDest,CFile,"superport directive",
3109  myName,myInsName,myProg))<=0)
3110  {if (!rc) CFile.noEcho(); return rc < 0;}
3111 
3112  if (!strcmp(cport, "any")) pnum = 0;
3113  else if (!strcmp(cport, "-p")) pnum = PortTCP;
3114  else if (isdigit(*cport))
3115  {if (XrdOuca2x::a2i(*eDest,invp,cport,&pnum,1,65535)) return 0;}
3116  else if (!(pnum = XrdNetUtils::ServPort(cport)))
3117  {eDest->Emsg("Config", "Unable to find superport", cport);
3118  return 1;
3119  }
3120 
3121  PortSUP = pnum;
3122 
3123  return 0;
3124 }
3125 
3126 /******************************************************************************/
3127 /* x t r a c e */
3128 /******************************************************************************/
3129 
3130 /* Function: xtrace
3131 
3132  Purpose: To parse the directive: trace <options>
3133 
3134  Type: Manager or Server, dynamic.
3135 
3136  Output: 0 upon success or !0 upon failure.
3137 */
3138 
3139 int XrdCmsConfig::xtrace(XrdSysError *eDest, XrdOucStream &CFile)
3140 {
3141  char *val;
3142  static struct traceopts {const char *opname; int opval;} tropts[] =
3143  {
3144  {"all", TRACE_ALL},
3145  {"debug", TRACE_Debug},
3146  {"defer", TRACE_Defer},
3147  {"files", TRACE_Files},
3148  {"forward", TRACE_Forward},
3149  {"redirect", TRACE_Redirect},
3150  {"space", TRACE_Space},
3151  {"stage", TRACE_Stage}
3152  };
3153  int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
3154 
3155  if (!(val = CFile.GetWord()))
3156  {eDest->Emsg("config", "trace option not specified"); return 1;}
3157  while (val)
3158  {if (!strcmp(val, "off")) trval = 0;
3159  else {if ((neg = (val[0] == '-' && val[1]))) val++;
3160  for (i = 0; i < numopts; i++)
3161  {if (!strcmp(val, tropts[i].opname))
3162  {if (neg) trval &= ~tropts[i].opval;
3163  else trval |= tropts[i].opval;
3164  break;
3165  }
3166  }
3167  if (i >= numopts)
3168  eDest->Say("Config warning: ignoring invalid trace option '",val,"'.");
3169  }
3170  val = CFile.GetWord();
3171  }
3172 
3173  Trace.What = trval;
3174  return 0;
3175 }
3176 
3177 /******************************************************************************/
3178 /* x v n i d */
3179 /******************************************************************************/
3180 
3181 /* Function: xvnid
3182 
3183  Purpose: To parse the directive: vnid {=|<|@}<vnarg> [<parms>]
3184 
3185  <vnarg> = - the actual vnid value
3186  < - the path of the file to be read for the vnid.
3187  @ - the path of the plugin library to be used.
3188  <parms> optional parms to be passed
3189 
3190  Output: 0 upon success or !0 upon failure.
3191 */
3192 
3193 int XrdCmsConfig::xvnid(XrdSysError *eDest, XrdOucStream &CFile)
3194 {
3195  char *val, parms[1024];
3196 
3197 // Get the argument
3198 //
3199  if (!(val = CFile.GetWord()) || !val[0])
3200  {eDest->Emsg("Config", "vnid not specified"); return 1;}
3201 
3202 // Record the path
3203 //
3204  if (VNID_Lib) free(VNID_Lib);
3205  VNID_Lib = strdup(val);
3206 
3207 // Record any parms (only if it starts with an @)
3208 //
3209  if (VNID_Parms) {free(VNID_Parms); VNID_Parms = 0;}
3210  if (*VNID_Lib == '@')
3211  {if (!CFile.GetRest(parms, sizeof(parms)))
3212  {eDest->Emsg("Config", "vnid plug-in parameters too long"); return 1;}
3213  if (*parms) VNID_Parms = strdup(parms);
3214  }
3215  return 0;
3216 }
void Usage(const char *msg)
Definition: XrdAccTest.cc:105
#define TS_Set(x, v)
void * XrdCmsStartAdmin(void *carg)
void * XrdCmsStartMonPerf(void *carg)
void * XrdCmsStartMonStat(void *carg)
void * XrdCmsStartAnote(void *carg)
void * XrdCmsStartMonRefs(void *carg)
#define TS_Xeq(x, m)
void * XrdCmsStartSupervising(void *carg)
#define TS_Lib(x, y, z)
void * XrdCmsStartPreparing(void *carg)
#define TS_Xer(x, m, v)
#define TS_unSet(x, v)
#define TRACE_Stage
Definition: XrdCmsTrace.hh:38
#define TRACE_Space
Definition: XrdCmsTrace.hh:43
#define TRACE_Debug
Definition: XrdCmsTrace.hh:37
#define TRACE_Files
Definition: XrdCmsTrace.hh:42
#define TRACE_Redirect
Definition: XrdCmsTrace.hh:41
#define QTRACE(act)
Definition: XrdCmsTrace.hh:49
#define TRACE_Forward
Definition: XrdCmsTrace.hh:40
#define TRACE_Defer
Definition: XrdCmsTrace.hh:39
#define STMax
Definition: XrdCmsTypes.hh:39
#define XrdCmsMAX_PATH_LEN
Definition: XrdCmsTypes.hh:46
static XrdSysError eDest(0,"crypto_")
int optopt
int optind
#define XRDNET_UDPSOCKET
Definition: XrdNetOpts.hh:79
XrdOss * XrdOssGetSS(XrdSysLogger *Logger, const char *config_fn, const char *OssLib, const char *OssParms, XrdOucEnv *envP, XrdVersionInfo &urVer)
Definition: XrdOssApi.cc:98
#define XRDEXP_NOTRW
Definition: XrdOucExport.hh:45
#define XRDEXP_PFCACHE
Definition: XrdOucExport.hh:70
#define XRDEXP_STAGEMM
Definition: XrdOucExport.hh:76
#define XRDEXP_GLBLRO
Definition: XrdOucExport.hh:74
#define XRDEXP_STAGE
Definition: XrdOucExport.hh:52
#define XRDEXP_LOCAL
Definition: XrdOucExport.hh:72
int open(const char *path, int oflag,...)
ssize_t write(int fildes, const void *buf, size_t nbyte)
int access(const char *path, int amode)
#define close(a)
Definition: XrdPosix.hh:43
bool Debug
#define TRACE_ALL
Definition: XrdTrace.hh:35
static bool InitAREvents(void *arFunc)
Definition: XrdCmsAdmin.cc:176
void * Start(XrdNetSocket *AdminSock)
Definition: XrdCmsAdmin.cc:451
static void setSync(XrdSysSemaphore *sync)
Definition: XrdCmsAdmin.hh:55
void * Notes(XrdNetSocket *AdminSock)
Definition: XrdCmsAdmin.cc:301
void SetTries(bool xdfs, int tcnt)
static const int Immed
static const int Servr
void Init(int Opts, int DMlife, int DPLife)
static const int Cntrl
static const int DFSys
static void Init(XrdScheduler *sP, XrdCmsCluster *cP, const char *blfn, int chkt=600)
int Init(int fxHold, int fxDelay, int fxQuery, int seFS, int nxHold)
Definition: XrdCmsCache.cc:380
static const int min_nxTime
Definition: XrdCmsCache.hh:81
void * MonPerf()
void * MonRefs()
int GenLocalPath(const char *oldp, char *newp)
const char * mySite
int Configure1(int argc, char **argv, char *cfn)
int ConfigXeq(char *var, XrdOucStream &CFile, XrdSysError *eDest)
int Configure0(XrdProtocol_Config *pi)
static bool Start(const XrdOucTList *mL)
static const int MTMax
int Monitor(char *pgm, int itv)
Definition: XrdCmsMeter.cc:258
void setVirtual(vType vVal)
Definition: XrdCmsMeter.hh:76
static void do_StateDFS(XrdCmsBaseFR *rP, int rc)
SMask_t ssvec
Definition: XrdCmsPList.hh:49
SMask_t rovec
Definition: XrdCmsPList.hh:47
SMask_t rwvec
Definition: XrdCmsPList.hh:48
char * Path()
Definition: XrdCmsPList.hh:76
XrdCmsPList * Next()
Definition: XrdCmsPList.hh:75
const char * PType()
Definition: XrdCmsPList.cc:212
static void Process()
int setParms(int rcnt, int stime, int deco=0)
void Reset(const char *iName, const char *aPath, int aMode)
int Init(int Tint=0, int Tdly=0)
Definition: XrdCmsRRQ.cc:125
static const char * Name(RoleID rid)
Definition: XrdCmsRole.hh:63
static RoleID Convert(const char *Tok1, const char *Tok2)
Definition: XrdCmsRole.hh:47
static const char * Type(RoleID rid)
Definition: XrdCmsRole.hh:78
static char * getVnId(XrdSysError &eDest, const char *cfgFN, const char *nidlib, const char *nidparm, char nidType)
static char * setSystemID(XrdOucTList *tp, const char *iVNID, const char *iTag, char iType)
static int Configure(const char *Lib, const char *Cfn=0)
static const int SelDSZ
Definition: XrdCmsSelect.hh:87
void * Monitor()
Definition: XrdCmsState.cc:111
void Update(StateType StateT, int ActivVal, int StageVal=0)
Definition: XrdCmsState.cc:258
void Set(int ncount)
Definition: XrdCmsState.cc:182
void Enable()
Definition: XrdCmsState.cc:85
static void Start()
static int Init(const char *AdminPath, int AdminMode)
static char * ParseManPort(XrdSysError *eDest, XrdOucStream &CFile, char *hSpec)
Definition: XrdCmsUtils.cc:249
static bool ParseMan(XrdSysError *eDest, XrdOucTList **oldMans, char *hSpec, char *hPort, int *sPort=0, bool hush=false)
Definition: XrdCmsUtils.cc:123
static void Start()
Definition: XrdJob.hh:43
static const int noPort
Do not add port number.
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
@ fmtAuto
Hostname if already resolved o/w use fmtAddr.
int Port(int pNum=-1)
Definition: XrdNetAddr.cc:148
const char * Set(const char *hSpec, int pNum=PortInSpec)
Definition: XrdNetAddr.cc:208
static XrdNetSocket * Create(XrdSysError *Say, const char *path, const char *fn, mode_t mode, int isudp=0)
static int ServPort(const char *sName, bool isUDP=false, const char **eText=0)
Definition: XrdNetUtils.cc:837
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
static unsigned long long ParseDefs(XrdOucStream &Config, XrdSysError &Eroute, unsigned long long Flags)
Definition: XrdOucExport.cc:60
static XrdOucPList * ParsePath(XrdOucStream &Config, XrdSysError &Eroute, XrdOucPListAnchor &Export, unsigned long long Defopts)
XrdOucPList * Next()
Definition: XrdOucPList.hh:44
char * Path()
Definition: XrdOucPList.hh:45
unsigned long long Flag()
Definition: XrdOucPList.hh:42
char * GetWord(int lowcase=0)
XrdOucEnv * SetEnv(XrdOucEnv *newEnv)
int GetRest(char *theBuf, int Blen, int lowcase=0)
XrdOucTList * next
Definition: XrdOucTList.hh:45
char * text
Definition: XrdOucTList.hh:46
static char * genPath(const char *path, const char *inst, const char *psfx=0)
Definition: XrdOucUtils.cc:414
static bool parseLib(XrdSysError &eDest, XrdOucStream &Config, const char *libName, char *&path, char **libparm)
Definition: XrdOucUtils.cc:986
static const char * InstName(int TranOpt=0)
Definition: XrdOucUtils.cc:729
static int doIf(XrdSysError *eDest, XrdOucStream &Config, const char *what, const char *hname, const char *nname, const char *pname)
Definition: XrdOucUtils.cc:228
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
const char * myName
Definition: XrdProtocol.hh:82
XrdScheduler * Sched
Definition: XrdProtocol.hh:64
const char * AdmPath
Definition: XrdProtocol.hh:76
XrdSysError * eDest
Definition: XrdProtocol.hh:61
XrdOucEnv * theEnv
Definition: XrdProtocol.hh:66
const char * myProg
Definition: XrdProtocol.hh:83
const char * myInst
Definition: XrdProtocol.hh:81
void Schedule(XrdJob *jp)
static void SetQW(unsigned int qwVal)
Definition: XrdSendQ.hh:58
static void SetQM(unsigned int qmVal)
Definition: XrdSendQ.hh:56
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
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)
Definition: XrdSysError.cc:141
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition: XrdSysError.hh:141
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
static int TimeZone()
Definition: XrdSysTimer.cc:210
static void Wait(int milliseconds)
Definition: XrdSysTimer.cc:227
void SetLogger(XrdSysLogger *logp)
Definition: XrdSysTrace.cc:65
XrdCmsMeter Meter
Definition: XrdCmsMeter.hh:131
XrdCmsRRQ RRQ
Definition: XrdCmsRRQ.cc:55
XrdCmsCache Cache
Definition: XrdCmsCache.cc:54
XrdCmsAdmin Admin
XrdVERSIONINFODEF(myVersion, cmsclient, XrdVNUMBER, XrdVERSION)
XrdScheduler * Sched
XrdCmsCluster Cluster
XrdCmsBaseFS baseFS
XrdSysError Say
XrdSysTrace Trace("cms")
XrdCmsState CmsState
Definition: XrdCmsState.cc:55
XrdCmsPrepare PrepQ
XrdCmsConfig Config
XrdOucEnv theEnv
int Opts
Definition: XrdMpxStats.cc:58
const char * myDomain
Generic structure to pass security information back and forth.