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