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