41 #include <sys/param.h>
42 #include <sys/resource.h>
44 #include <sys/types.h>
47 #include "XrdVersion.hh"
127 (
const char *hostname,
128 const struct sockaddr &netaddr,
188 #define TS_Lib(x, y, z) if (!strcmp(x, var)) \
189 return (XrdOucUtils::parseLib(*eDest, CFile, x, y, z) ? 0 : 1);
191 #define TS_String(x,m) if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;}
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);
196 #define TS_Set(x,v) if (!strcmp(x,var)) {v=1; CFile.Echo(true); return 0;}
198 #define TS_unSet(x,v) if (!strcmp(x,var)) {v=0; CFile.Echo(true); return 0;}
211 myName = strdup(pi->
myName);
212 PortTCP = (pi->
Port < 0 ? 0 : pi->
Port);
213 myInsName = strdup(pi->
myInst);
214 myProg = strdup(pi->
myProg);
248 int NoGo = 0, immed = 0;
250 extern int opterr,
optopt;
255 if (argc > 1 &&
'-' == *argv[1])
256 while ((c=getopt(argc,argv,
"iw")) && ((
unsigned char)c != 0xff))
261 case 'w': immed = -1;
263 default: buff[0] =
'-'; buff[1] =
optopt; buff[2] =
'\0';
264 Say.
Say(
"Config warning: unrecognized option, ",buff,
", ignored.");
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.");
280 inArgv = argv; inArgc = argc;
281 if ((!(ConfigFN = cfn) && !(ConfigFN = getenv(
"XrdCmsCONFIGFN")))
283 {
Say.
Emsg(
"Config",
"Required config file not specified.");
290 myInstance = strdup(buff);
299 Say.
Say(
"++++++ ", myInstance,
" phase 1 initialization started.");
304 if (!(isManager || isServer))
305 if (!(NoGo |= ConfigProc(1)) && !(isManager || isServer))
306 {
Say.
Say(
"Config warning: role not specified; manager role assumed.");
312 if (!NoGo) NoGo |= ConfigProc();
320 if (immed) doWait = (immed > 0 ? 0 : 1);
324 if (isManager < 0) isManager = 1;
325 if (isPeer < 0) isPeer = 1;
326 if (isProxy < 0) isProxy = 1;
327 if (isServer < 0) isServer = 1;
347 myRoleID =
static_cast<int>(rid);
359 {
if ((isManager && !isServer) || isPeer)
361 {
Say.
Emsg(
"Config",
"port for this", myRole,
"not specified.");
365 else if ((isManager && isServer)) PortTCP = PortSUP;
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!");
383 if ( prfLib || perfpgm)
384 Say.
Say(
"Config warning: metrics supplier specified without "
385 "any scheduling metrics!");
391 sprintf(buff,
" phase 1 %s initialization %s.", myRole,
392 (NoGo ?
"failed" :
"completed"));
393 Say.
Say(
"------ ", myInstance, buff);
421 sprintf(buff,
" phase 2 %s initialization started.", myRole);
422 Say.
Say(
"++++++ ", myInstance, buff);
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;
436 if (QryDelay < 0) QryDelay = LUPDelay;
442 if (!strncmp(AdminPath,
"/tmp/", 5))
443 Say.
Say(
"Config warning: adminpath resides in /tmp and may be unstable!");
456 (isManager|isPeer ?
"olbd.nimda":
"olbd.admin"),AdminMode));
461 {
if (!(
mySID = setupSid())) NoGo = 1;
463 Say.
Say(
"Config ",
"Global System Identification: ",
mySID);
465 {envData +=
"&site=";
473 envCGI = (envData.length() > 0 ? strdup(envData.c_str()) : 0);
477 if ((LocalRoot || RemotRoot || N2N_Lib) && ConfigN2N()) NoGo = 1;
481 if (!NoGo) NoGo = ConfigOSS();
487 if (!NoGo && isManager) NoGo = setupManager();
488 if (!NoGo && (isServer || ManList)) NoGo = setupServer();
496 if (isPeer && isSolo)
500 if (isMeta) {SUPCount = 1; SUPLevel = 0;}
503 if (isManager) Who = (isServer ? -1 : 1);
509 if (!NoGo) NoGo |= Manifest();
513 sprintf(buff,
" phase 2 %s initialization %s.", myRole,
514 (NoGo ?
"failed" :
"completed"));
515 Say.
Say(
"------ ", myInstance, buff);
536 if (
eDest) dynamic = 1;
550 TS_Xeq(
"adminpath", xapath);
553 TS_Xeq(
"blacklist", xblk);
555 TS_Xeq(
"defaults", xdefs);
559 TS_Xeq(
"localroot", xlclrt);
562 TS_Lib(
"namelib", N2N_Lib, &N2N_Parms);
564 TS_Lib(
"osslib", ossLib, &ossParms);
567 TS_Xeq(
"prepmsg", xprepm);
568 TS_Xeq(
"remoteroot", xrmtrt);
569 TS_Xeq(
"repstats", xreps);
572 TS_Xeq(
"subcluster", xsubc);
573 TS_Xeq(
"superport", xsupp);
577 TS_Xer(
"whitelist", xblk,
true);
582 if (!strcmp(var,
"conwait")
583 || !strcmp(var,
"request"))
return 0;
587 if (!strcmp(var,
"pidpath"))
588 {
Say.
Say(
"Config warning: 'cms.pidpath' no longer "
589 "supported; use 'all.pidpath'.");
591 Say.
Say(
"Config warning: ignoring unknown directive '", var,
"'.");
605 time_t eTime = time(0);
612 if (isManager && !isServer && !ManList) doWait = 0;
613 else if (isServer && adsMon) doWait = 1;
619 0,
"Notification handler"))
620 Say.
Emsg(
"cmsd", errno,
"start notification handler");
625 (
void *)0, 0,
"Prep handler"))
626 Say.
Emsg(
"cmsd", errno,
"start prep handler");
632 (
void *)0, 0,
"supervisor"))
633 {
Say.
Emsg(
"cmsd", errno,
"start", myRole);
649 Say.
Emsg(
"cmsd", errno,
"start admin handler");
661 {
Say.
Emsg(
"Config", errno,
"create state monitor thread");
667 if ((isManager || isPeer) && SRVDelay)
668 {wTime = SRVDelay -
static_cast<int>((time(0) - eTime));
676 Say.
Emsg(
"Config", myRole,
"service enabled.");
703 void XrdCmsConfig::ConfigDefaults(
void)
706 int myTZ, isEast = 0;
710 myName = (
char *)
"localhost";
725 MaxLoad = 0x7fffffff;
726 MaxRetries= 0x7fffffff;
755 myPaths = (
char *)
"";
757 sched_RR = sched_Pack = sched_AffPC = sched_Level = sched_LoadR = 0; sched_Force = 1;
797 pendplife= 60*60*24*7;
806 RefTurn = 3*
STMax*(DiskLinger+1);
832 if (myTZ <= 0) {isEast = 0x10; myTZ = -myTZ;}
833 if (myTZ > 12) myTZ = 12;
834 TimeZone = (myTZ | isEast);
841 int XrdCmsConfig::ConfigN2N()
847 if (!(xeq_N2N = n2nLoader.Load(N2N_Lib, *myVInfo, &
theEnv)))
return 1;
851 if (N2N_Lib || LocalRoot) lcl_N2N = xeq_N2N;
863 int XrdCmsConfig::ConfigOSS()
866 const char *,
XrdOucEnv *, XrdVersionInfo &);
878 if (!ossLib && isProxy) ossLib = strdup(
"libXrdPss.so");
883 if (!ossFS)
return 1;
887 if (!isManager && isServer && (arFunc =
theEnv.
GetPtr(
"XrdOssStatInfo2*")))
896 int XrdCmsConfig::ConfigProc(
int getrole)
899 int cfgFD, retc, NoGo = 0;
905 if ( (cfgFD =
open(ConfigFN, O_RDONLY, 0)) < 0)
906 {
Say.
Emsg(
"Config", errno,
"open config file", ConfigFN);
913 if (getrole) CFile.SetEroute(0);
917 while((var = CFile.GetMyFirstWord()))
919 {
if (!strcmp(
"all.role", var) || !strcmp(
"olb.role", var))
920 if (xrole(&
Say, CFile))
921 {CFile.SetEroute(&
Say); CFile.Echo(); NoGo = 1;
925 else if (!strncmp(var,
"cms.", 4)
926 || !strncmp(var,
"olb.", 4)
927 || !strcmp(var,
"ofs.osslib")
928 || !strcmp(var,
"oss.defaults")
929 || !strcmp(var,
"oss.localroot")
930 || !strcmp(var,
"oss.remoteroot")
931 || !strcmp(var,
"oss.namelib")
932 || !strcmp(var,
"all.export")
933 || !strcmp(var,
"all.manager")
934 || !strcmp(var,
"all.role")
935 || !strcmp(var,
"all.seclib")
936 || !strcmp(var,
"all.subcluster"))
937 {
if (ConfigXeq(var+4, CFile, 0)) {CFile.Echo(); NoGo = 1;}}
938 else if (!strcmp(var,
"oss.stagecmd")) DiskSS =
true;
942 if ((retc = CFile.LastError()))
943 NoGo =
Say.
Emsg(
"Config", retc,
"read config file", ConfigFN);
948 if (!getrole && (ManList || SanList)) NoGo |= MergeP();
961 char buff[512], pp, *mp = prog;
965 while(*mp && *mp !=
' ') mp++;
971 {sprintf(buff,
"find %s executable", ptype);
972 eDest->
Emsg(
"Config", errno, buff, prog);
987 int XrdCmsConfig::Manifest()
990 const char *clID, *xop = 0;
995 if (!xrdEnv || !(envFN = xrdEnv->Get(
"envFile")))
return 0;
997 if ((clID = index(
mySID,
' '))) clID++;
1000 if ((xfd =
open(envFN, O_WRONLY|O_APPEND)) < 0) xop =
"open";
1001 else {
bool bad =
false;
1003 bad =
write(xfd,(
void *)
"&pfx=",5) < 0
1004 ||
write(xfd,(
void *)LocalRoot,strlen(LocalRoot)) < 0;
1005 if (!bad && AdminPath)
1006 bad =
write(xfd,(
void *)
"&ap=", 4) < 0
1007 ||
write(xfd,(
void *)AdminPath,strlen(AdminPath)) < 0;
1008 if (!bad) bad =
write(xfd,(
void *)
"&cn=", 4) < 0
1009 ||
write(xfd,(
void *)clID, strlen(clID)) < 0;
1010 if (bad) xop =
"append to";
1014 if (xop)
Say.
Emsg(
"Config", errno, xop, envFN);
1023 int XrdCmsConfig::MergeP()
1034 unsigned long long Opts;
1035 int pbLen = 0, NoGo = 0, export2MM = isManager && !isServer;
1044 if (export2MM) npinfo.
ssvec = (
Opts & stage4MM ? 1 : 0);
1045 else npinfo.
ssvec = (
Opts & stageAny ? 1 : 0);
1046 if (!PathList.Add(plp->
Path(), &npinfo))
1047 Say.
Emsg(
"Config",
"Ignoring duplicate export path",plp->
Path());
1048 else if (npinfo.
ssvec) DiskSS =
true;
1058 {
if (SanList) Who =
"subcluster manager:";
1059 else Who = (isServer ?
"manager:" :
"meta-manager:");
1060 }
else Who =
"redirector:";
1061 Say.
Say(
"The following paths are available to the ", Who);
1062 if (!(pp = PathList.First()))
Say.
Say(
"r /");
1064 {ptype = pp->
PType();
1065 Say.
Say(ptype, (strlen(ptype) > 1 ?
" " :
" "), pp->
Path());
1066 pbLen += strlen(pp->
Path())+8; pp = pp->
Next();
1074 if (pbLen != 0 && (pp = PathList.First()))
1075 {pbP = myPaths = (
char *)malloc(pbLen);
1077 {pbP += sprintf(pbP,
"\n%s %s", pp->
PType(), pp->
Path());
1093 int XrdCmsConfig::setupManager()
1103 const char *urDom, *myDom = index(myName,
'.');
1105 while(tP) {nP = tP; tP = tP->
next;
delete nP;}
1106 ManList = tP = SanList;
1107 if (myDom)
while(tP)
1108 {
if ((urDom = index(tP->
text,
'.')) && strcmp(urDom, myDom))
1109 {
Say.
Emsg(
"Config",
"Subcluster's manager", tP->
text,
1110 "is in a different domain.");
1115 if (isBad) {
Say.
Emsg(
"Config",
"Cross domain subclusters disallowed!");
1126 sched_RR = (100 == P_fuzz) || !AskPerf
1127 || !(P_cpu || P_io || P_load || P_mem || P_pag);
1129 {
Say.
Say(
"Config round robin scheduling in effect.");
1136 0,
"Performance monitor")))
1137 {
Say.
Emsg(
"Config", rc,
"create perf monitor thread");
1143 RefTurn = 3*
STMax*(DiskLinger+1);
1146 0,
"Refcount monitor")))
1147 {
Say.
Emsg(
"Config", rc,
"create refcount monitor thread");
1162 if (!isServer && blkChk)
1174 int XrdCmsConfig::setupServer()
1182 {
Say.
Emsg(
"Config",
"Manager node not specified for", myRole,
"role");
1189 while(tp) {n++; tp = tp->
next;}
1191 {
Say.
Emsg(
"Config",
"Too many managers have been specified");
return 1;}
1195 if (MaxDelay < 0) MaxDelay = AskPerf*AskPing+30;
1196 if (DiskWT < 0) DiskWT = AskPerf*AskPing+30;
1201 (isManager|isPeer ?
"olbd.seton":
"olbd.notes"),
1207 if (isManager || isPeer)
return 0;
1208 SUPCount = 0; SUPLevel = 0;
1209 if (isProxy)
return 0;
1214 if (DiskSS)
PrepQ.
Reset(myInsName, AdminPath, AdminMode);
1220 Say.
Say(
"Config warning: load based scheduling disabled.");
1231 char *XrdCmsConfig::setupSid()
1239 if (getenv(
"XRDIFADDRS")) ifList = strdup(getenv(
"XRDIFADDRS"));
1243 if ((mySite = getenv(
"XRDSITE")) && *mySite) mySite = strdup(mySite);
1248 if (isManager && isServer) sfx =
'u';
1249 else sfx = (isManager ?
'm' :
's');
1250 if (isProxy) sfx = toupper(sfx);
1256 if (!myVNID)
return 0;
1262 if (!sidVal || *sidVal ==
'!')
1264 if (!sidVal) msg =
"too many managers.";
1265 else msg = sidVal+1;
1266 Say.
Emsg(
"cmsd",
"Unable to generate system ID; ", msg);
1276 void XrdCmsConfig::Usage(
int rc)
1278 std::cerr <<
"\nUsage: cmsd [xrdopts] [-i] [-m] [-s] -c <cfile>" <<std::endl;
1304 if (!isManager)
return CFile.
noEcho();
1307 {
eDest->
Emsg(
"Config",
"allow type not specified");
return 1;}
1309 if (!strcmp(val,
"host")) ishost = 1;
1310 else if (!strcmp(val,
"netgroup")) ishost = 0;
1311 else {
eDest->
Emsg(
"Config",
"invalid allow type -", val);
1316 {
eDest->
Emsg(
"Config",
"allow target name not specified");
return 1;}
1319 if (ishost) Police->AddHost(val);
1320 else Police->AddNetGroup(val);
1350 if (isManager)
return CFile.
noEcho();
1353 {
eDest->
Emsg(
"Config",
"protocol not specified");
return 1;}
1355 if (strcmp(val,
"xroot"))
1356 {
eDest->
Emsg(
"Config",
"unsupported protocol, '", val,
"'.");
return 1;}
1357 if (adsProt) free(adsProt);
1358 adsProt = strdup(val);
1361 {
eDest->
Emsg(
"Config",
"data server port not specified");
return 1;}
1368 {
eDest->
Emsg(
"Config",
"Unable to find tcp service '",val,
"'.");
1372 if (!(val = CFile.
GetWord()) || !strcmp(val,
"monitor")) adsMon = 1;
1373 else if (!strcmp(val,
"nomonitor")) adsMon = 0;
1374 else {
eDest->
Emsg(
"Config",
"invalid option, '", val,
"'.");
1399 mode_t mode = S_IRWXU;
1404 if (!pval || !pval[0])
1405 {
eDest->
Emsg(
"Config",
"adminpath not specified");
return 1;}
1410 {
eDest->
Emsg(
"Config",
"adminpath not absolute");
return 1;}
1411 pval = strdup(pval);
1415 if ((val = CFile.
GetWord()) && val[0])
1416 {
if (!strcmp(
"group", val)) mode |= S_IRWXG;
1417 else {
eDest->
Emsg(
"Config",
"invalid admin path modifier -", val);
1418 free(pval);
return 1;
1424 if (AdminPath) free(AdminPath);
1447 const char *fType = (iswl ?
"whitelist" :
"blacklist");
1452 if (!isManager || isServer)
return CFile.
noEcho();
1457 if (blkList) {free(blkList); blkList = 0;}
1461 if (!val || !val[0])
1468 do {
if (!strcmp(val,
"check"))
1469 {
if (!(val = CFile.
GetWord()) || !val[0])
1470 {
eDest->
Emsg(
"Config",fType,
"check interval not specified");
1476 }
while((val = CFile.
GetWord()));
1480 if (iswl) blkChk = -blkChk;
1484 if (!val || !val[0])
return 0;
1486 {
eDest->
Emsg(
"Config",
"blacklist path not absolute");
return 1;}
1490 blkList = strdup(val);
1513 if (!(val = CFile.
GetWord()) || !val[0])
1514 {
eDest->
Emsg(
"Config",
"tag not specified");
return 1;}
1518 if ((
int)strlen(val) > 16)
1519 {
eDest->
Emsg(
"Config",
"tag is > 16 characters");
return 1;}
1523 if (cidTag) free(cidTag);
1524 cidTag = strdup(val);
1570 const char *etxt =
"invalid delay option";
1571 int i, ppp, minV = 1, ispercent = 0, noStage = 0;
1572 static struct delayopts {
const char *opname;
int *oploc;
int istime;}
1575 {
"delnode", &DELDelay, 1},
1576 {
"discard", &MsgTTL, 0},
1577 {
"drop", &DRPDelay, 1},
1578 {
"full", &DiskWT, -1},
1579 {
"hold", &LUPHold, 0},
1580 {
"lookup", &LUPDelay, 1},
1581 {
"nostage", &noStage, 01},
1582 {
"overload", &MaxDelay,-1},
1583 {
"peer", &PSDelay, 1},
1584 {
"qdl", &QryDelay, 1},
1585 {
"qdn", &QryMinum, 0},
1586 {
"rw", &RWDelay, 0},
1587 {
"servers", &SUPCount, 0},
1588 {
"service", &SUPDelay, 1},
1589 {
"startup", &SRVDelay, 1},
1590 {
"suspend", &SUSDelay, 1}
1592 int numopts =
sizeof(dyopts)/
sizeof(
struct delayopts);
1594 if (!isManager && !isPeer)
return CFile.
noEcho();
1597 {
eDest->
Emsg(
"Config",
"delay arguments not specified");
return 1;}
1600 {
for (i = 0; i < numopts; i++)
1601 if (!strcmp(val, dyopts[i].opname))
1602 {
if (!(val = CFile.
GetWord()))
1603 {
eDest->
Emsg(
"Config",
"delay ", dyopts[i].opname,
1604 " argument not specified.");
1607 if (dyopts[i].istime < 0 && !strcmp(val,
"*")) ppp = -1;
1608 else if (dyopts[i].istime)
1612 if (*dyopts[i].opname ==
'r')
1616 if (*dyopts[i].opname ==
's')
1617 {ppp = strlen(val); SUPLevel = 0; minV = 0;
1618 if (val[ppp-1] ==
'%')
1619 {ispercent = 1; val[ppp-1] =
'\0';}
1624 if (!ispercent) *dyopts[i].oploc = ppp;
1625 else {ispercent = 0; SUPCount = 1; SUPLevel = ppp;}
1629 eDest->
Say(
"Config warning: ignoring invalid delay option '",val,
"'.");
1706 int Hold = 0, limCent = 0, limFix = 0, limV = 0, qMax = 0, rTry = -1;
1711 if (isMeta || isPeer)
return CFile.
noEcho();
1716 {
eDest->
Emsg(
"Config",
"dfs option not specified");
return 1;}
1720 do{
if (!strcmp(
"mdhold", val))
1721 {
if (!(val = CFile.
GetWord()))
1722 {
eDest->
Emsg(
"Config",
"mdhold value not specified.");
return 1;}
1725 else if (!strcmp(
"limit", val))
1726 {
if (!(val = CFile.
GetWord()))
1727 {
eDest->
Emsg(
"Config",
"limit value not specified.");
return 1;}
1728 if ((limCent = !strcmp(
"central",val)) && !(val = CFile.
GetWord()))
1729 {
eDest->
Emsg(
"Config",
"limit value not specified.");
return 1;}
1730 if ((limFix = (*val ==
'=')) && *(val+1)) val++;
1733 else if (!strcmp(
"lookup", val))
1734 {
if (!(val = CFile.
GetWord()))
1735 {
eDest->
Emsg(
"Config",
"lookup value not specified.");
return 1;}
1738 else {
eDest->
Emsg(
"Config",
"invalid lookup value '", val,
"'.");
1742 else if (!strcmp(
"qmax", val))
1743 {
if (!(val = CFile.
GetWord()))
1744 {
eDest->
Emsg(
"Config",
"qmax value not specified.");
return 1;}
1747 else if (!strcmp(
"redirect",val))
1748 {
if (!(val = CFile.
GetWord()))
1749 {
eDest->
Emsg(
"Config",
"redirect value not specified.");
return 1;}
1752 else {
eDest->
Emsg(
"Config",
"invalid redirect value -", val);
1756 else if (!strcmp(
"retries", val))
1757 {
if (!(val = CFile.
GetWord()))
1758 {
eDest->
Emsg(
"Config",
"retries value not specified.");
return 1;}
1761 else {
eDest->
Emsg(
"Config",
"invalid dfs option '",val,
"'.");
return 1;}
1762 }
while((val = CFile.
GetWord()));
1767 if (isManager && isServer)
1775 {
if (limFix) limV = -limV;
1777 else if (isManager) limV = 0;
1833 struct xeqopts {
const char *opname;
int doset;
XrdOucProg **pgm;} xqopts[] =
1835 {
"chmod", 0, &ProgCH},
1836 {
"mkdir", 0, &ProgMD},
1837 {
"mkpath", 0, &ProgMP},
1840 {
"rmdir", 0, &ProgRD},
1841 {
"trunc", 0, &ProgTR}
1843 int i, xtval = 0, numopts =
sizeof(xqopts)/
sizeof(
struct xeqopts);
1848 if (!isServer)
return CFile.
noEcho();
1853 while (val && *val !=
'/')
1854 {
for (i = 0; i < numopts; i++)
1855 if (!strcmp(val, xqopts[i].opname))
1856 {xqopts[i].doset = 1;
1861 eDest->
Say(
"Config warning: ignoring invalid fsxeq type option '",val,
"'.");
1868 {
eDest->
Emsg(
"Config",
"fsxeq type option not specified");
return 1;}
1873 {
eDest->
Emsg(
"Config",
"fsxeq program not specified");
return 1;}
1881 for (i = 0; i < numopts; i++)
1882 if (xqopts[i].doset)
1883 {
if (!*xqopts[i].pgm) *(xqopts[i].pgm) =
new XrdOucProg(0);
1884 if ((*(xqopts[i].pgm))->Setup(val,
eDest))
return 1;
1913 if (!isManager)
return CFile.
noEcho();
1916 {
eDest->
Emsg(
"Config",
"fxhold value not specified.");
return 1;}
1918 if (!strcmp(val,
"noloc"))
1919 {
if (!(val = CFile.
GetWord()))
1920 {
eDest->
Emsg(
"Config",
"fxhold noloc value not specified.");
return 1;}
1924 if (!(val = CFile.
GetWord()))
return 0;
1955 if (!isServer)
return CFile.
noEcho();
1960 if (!val || !val[0])
1961 {
eDest->
Emsg(
"Config",
"localroot path not specified");
return 1;}
1963 {
eDest->
Emsg(
"Config",
"localroot path not absolute");
return 1;}
1968 while (i && val[i] ==
'/') val[i--] =
'\0';
1973 {
if (LocalRoot) free(LocalRoot);
1974 LocalRoot = strdup(val);
2014 StorageHelper(
char **v1,
char **v2) : val1(v1), val2(v2) {}
2015 ~StorageHelper() {
if (*val1) free(*val1);
2016 if (*val2) free(*val2);
2018 char **val1, **val2;
2022 char *val, *hSpec = 0, *hPort = 0;
2023 StorageHelper SHelp(&hSpec, &hPort);
2024 int rc, xMeta = 0, xPeer = 0, xProxy = 0, *myPort = 0;
2029 {
if ((xMeta = !strcmp(
"meta", val))
2030 || (xPeer = !strcmp(
"peer", val))
2031 || (xProxy = !strcmp(
"proxy", val)))
2032 {
if ((xMeta && (isServer || isPeer))
2033 || (xPeer && !isPeer)
2034 || (xProxy && !isProxy))
return CFile.
noEcho();
2036 }
else if (isPeer)
return CFile.
noEcho();
2042 if (!strcmp(
"any", val) || !strcmp(
"all", val)) val = CFile.
GetWord();
2047 {
eDest->
Emsg(
"Config",
"manager host name not specified");
return 1;}
2048 hSpec = strdup(val);
2057 {
if (strcmp(val,
"if"))
2058 {
eDest->
Emsg(
"Config",
"expecting manager 'if' but",val,
"found");
2062 myName,myInsName,myProg))<=0)
2063 {
if (!rc) CFile.
noEcho();
return rc < 0;}
2068 if (isManager && !isServer)
2070 {
if (((xMeta && isMeta) || (!xMeta && !isMeta)))
2072 if (isMeta) theList = 0;
2073 else theList = (xMeta ? &ManList : &NanList);
2102 if (!isManager)
return CFile.
noEcho();
2105 {
eDest->
Emsg(
"Config",
"mode type not specified");
return 1;}
2107 if (!strcmp(val,
"r/o") || !strcmp(val,
"readonly")) forceRO =
true;
2108 else if (!strcmp(val,
"r/w") || !strcmp(val,
"readwrite")) forceRO =
false;
2109 else {
eDest->
Emsg(
"Config",
"invalid mode type -", val);
2136 char *val, xopt[16];
2138 bool xAll =
false, xOff =
false, xRmt =
false;
2143 {
if ((xAll = !strcmp(
"all", val))
2144 || (xOff = !strcmp(
"off", val))
2145 || (xRmt = !strcmp(
"remote", val)))
2146 {
if (xAll) nbSQ = 2;
2147 else if (xRmt) nbSQ = 1;
2151 }
else {
eDest->
Emsg(
"Config",
"nbsendq option not specified");
return 1;}
2156 {
size_t size =
sizeof(xopt)-1;
2157 strncpy(xopt, val, size);
2159 if (!(val= CFile.
GetWord()) || *val == 0)
2160 {
eDest->
Emsg(
"Config",
"nbsendq ", xopt,
" argument not specified");
2163 if (!strcmp(xopt,
"maxq"))
2164 {
if (!strcmp(
"val",
"none")) ival = -1;
2169 else if (!strcmp(xopt,
"warn"))
2173 else eDest->
Say(
"Config warning: ignoring invalid nbsendq option '",xopt,
"'.");
2200 {
char *pgm=0, *val, rest[2048];
2202 if (!isServer)
return CFile.
noEcho();
2205 {
eDest->
Emsg(
"Config",
"perf options not specified");
return 1;}
2207 if (!strcmp(
"xrootd", val))
return CFile.
noEcho();
2210 do {
if (!strcmp(
"int", val))
2211 {
if (!(val = CFile.
GetWord()))
2212 {
eDest->
Emsg(
"Config",
"perf int value not specified");
2217 else if (!strcmp(
"lib", val))
2218 {
if (perfpgm) {free(perfpgm); perfpgm = 0;}
2220 prfLib, &prfParms) ? 0 : 1);
2223 else if (!strcmp(
"pgm", val))
2224 {
if (!CFile.
GetRest(rest,
sizeof(rest)))
2225 {
eDest->
Emsg(
"Config",
"perf pgm parameters too long");
2229 {
eDest->
Emsg(
"Config",
"perf pgm value not specified");
2235 else eDest->
Say(
"Config warning: ignoring invalid perf option '",val,
"'.");
2236 }
while((val = CFile.
GetWord()));
2240 if (perfpgm) {free(perfpgm); perfpgm = 0;}
2241 if (prfLib) {free(prfLib); prfLib = 0;}
2242 if (prfParms){free(prfParms);prfParms = 0;}
2243 if (pgm) {
if (!isExec(
eDest,
"perf", pgm))
return 1;
2244 else perfpgm = strdup(pgm);
2274 {
int pnum = AskPerf, lnum = LogPerf, ping;
2278 {
eDest->
Emsg(
"Config",
"ping value not specified");
return 1;}
2280 if (ping < 3) ping = 3;
2282 while((val = CFile.
GetWord()))
2283 {
if (!strcmp(
"log", val))
2284 {
if (!(val = CFile.
GetWord()))
2285 {
eDest->
Emsg(
"Config",
"ping log value not specified");
2290 else if (!strcmp(
"usage", val))
2291 {
if (!(val = CFile.
GetWord()))
2292 {
eDest->
Emsg(
"Config",
"ping usage value not specified");
2328 {
int reset=0, scrub=0, echo = 0, doset = 0;
2329 char *prepif=0, *val, rest[2048];
2331 if (!isServer)
return CFile.
noEcho();
2335 do {
if (!strcmp(
"echo", val)) doset = echo = 1;
2336 else if (!strcmp(
"reset", val))
2337 {
if (!(val = CFile.
GetWord()))
2338 {
eDest->
Emsg(
"Config",
"prep reset value not specified");
2344 else if (!strcmp(
"scrub", val))
2345 {
if (!(val = CFile.
GetWord()))
2346 {
eDest->
Emsg(
"Config",
"prep scrub value not specified");
2352 else if (!strcmp(
"ifpgm", val))
2353 {
if (!CFile.
GetRest(rest,
sizeof(rest)))
2354 {
eDest->
Emsg(
"Config",
"prep ifpgm parameters too long");
return 1;}
2356 {
eDest->
Emsg(
"Config",
"prep ifpgm value not specified");
2362 else eDest->
Say(
"Config warning: ignoring invalid prep option '",val,
"'.");
2363 }
while((val = CFile.
GetWord()));
2369 if (scrub) pendplife = scrub;
2371 if (prepif) {
if (!isExec(
eDest,
"prep", prepif))
return 1;
2394 char *val, buff[2048];
2400 {
eDest->
Emsg(
"Config",
"no value for prepmsg directive");
2409 if (!CFile.
GetRest(buff,
sizeof(buff)))
2410 {
eDest->
Emsg(
"Config",
"prepmsg arguments too long");
2437 static struct repsopts {
const char *opname;
int opval;} rsopts[] =
2439 {
"all", RepStat_All},
2440 {
"frq", RepStat_frq},
2441 {
"shr", RepStat_shr}
2443 int i, neg, rsval = 0, numopts =
sizeof(rsopts)/
sizeof(
struct repsopts);
2446 {
eDest->
Emsg(
"config",
"repstats option not specified");
return 1;}
2448 {
if (!strcmp(val,
"off")) rsval = 0;
2449 else {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
2450 for (i = 0; i < numopts; i++)
2451 {
if (!strcmp(val, rsopts[i].opname))
2452 {
if (neg) rsval &= ~rsopts[i].opval;
2453 else rsval |= rsopts[i].opval;
2458 eDest->
Say(
"Config warning: ignoring invalid repstats option '",val,
"'.");
2484 char *val, *colon, *slash;
2489 if (isManager)
return CFile.
noEcho();
2494 if (!val || !val[0])
2495 {
eDest->
Emsg(
"Config",
"remoteroot path not specified");
return 1;}
2500 {colon = index(val,
':'); slash = index(val,
'/');
2501 if ((colon+1) != slash)
2502 {
eDest->
Emsg(
"Config",
"remoteroot path not absolute");
return 1;}
2508 while (i && val[i] ==
'/') val[i--] =
'\0';
2513 {
if (RemotRoot) free(RemotRoot);
2514 RemotRoot = strdup(val);
2571 char *val, *Tok1, *Tok2;
2572 int rc, xMeta=0, xPeer=0, xProxy=0, xServ=0, xMan=0, xSolo=0;
2576 if (!(val = CFile.
GetWord()) || !strcmp(val,
"if"))
2577 {
eDest->
Emsg(
"Config",
"role not specified");
return 1;}
2582 if ((val = CFile.
GetWord()) && strcmp(val,
"if"))
2583 {Tok2 = strdup(val);
2589 if (val && !strcmp(
"if", val))
2591 myName,myInsName,myProg)) <= 0)
2592 {free(Tok1);
if (Tok2) free(Tok2);
2614 default:
eDest->
Emsg(
"Config",
"invalid role -", Tok1, Tok2); rc = 1;
2620 if (Tok2) free(Tok2);
2625 if (isServer > 0 || isManager > 0 || isProxy > 0 || isPeer > 0)
2626 {
eDest->
Say(
"Config warning: role directive over-ridden by command line.");
2632 isServer = xServ; isManager = xMan; isProxy = xProxy;
2633 isPeer = xPeer; isSolo = xSolo; isMeta = xMeta;
2634 if (myRole) free(myRole);
2636 myRoleID =
static_cast<int>(roleID);
2674 int i, ppp, V_hntry = -1;
2675 static struct schedopts {
const char *opname;
int maxv;
int *oploc;}
2678 {
"cpu", 100, &P_cpu},
2679 {
"fuzz", 100, &P_fuzz},
2680 {
"gsdflt", 100, &P_gsdf},
2681 {
"gshr", 100, &P_gshr},
2683 {
"runq", 100, &P_load},
2684 {
"mem", 100, &P_mem},
2685 {
"pag", 100, &P_pag},
2686 {
"space", 100, &P_dsk},
2687 {
"maxload", 100, &MaxLoad},
2688 {
"refreset", -1, &RefReset},
2689 {
"affinity", -2, 0},
2691 {
"tryhname", 1, &V_hntry}
2693 int numopts =
sizeof(scopts)/
sizeof(
struct schedopts);
2696 {
eDest->
Emsg(
"Config",
"sched option not specified");
return 1;}
2699 {
for (i = 0; i < numopts; i++)
2700 if (!strcmp(val, scopts[i].opname))
2701 {
if (!(val = CFile.
GetWord()))
2702 {
eDest->
Emsg(
"Config",
"sched ", scopts[i].opname,
2703 "argument not specified.");
2706 if (scopts[i].maxv == -2)
2707 {
if (!xschedm(val,
eDest, CFile))
return 1;
2710 if (scopts[i].maxv == -3)
2711 {
if (!xschedp(val,
eDest, CFile))
return 1;
2714 if (scopts[i].maxv < 0)
2719 0, scopts[i].maxv))
return 1;
2720 *scopts[i].oploc = ppp;
2724 {
int rc = xschedx(val,
eDest, CFile);
2725 if (rc < 0)
return 1;
2726 if (rc > 0)
eDest->
Say(
"Config warning: "
2727 "ignoring invalid sched option '",val,
"'.");
2734 if (V_hntry >= 0) DoHnTry =
static_cast<char>(V_hntry);
2744 if (!strcmp(val,
"default"))
2747 {
eDest->
Emsg(
"Config",
"sched affinity not specified");
return 0;}
2748 }
else sched_Force = 1;
2750 if (!strcmp(val,
"none"))
2751 {sched_Pack = sched_Level = 0;
2755 sched_Pack = sched_Level = 1;
2757 if (!strcmp(val,
"weak"))
return 1;
2761 if (!strcmp(val,
"strong"))
return 1;
2763 if (!strcmp(val,
"strict"))
2768 if (!strcmp(val,
"randomized"))
2773 eDest->
Emsg(
"Config",
"Invalid sched affinity -", val);
2781 int afpsign, afpval;
2783 if (!strcmp(val,
"all"))
2788 if (!strcmp(val,
"first")) afpsign = 1;
2789 else if (!strcmp(val,
"last")) afpsign = -1;
2790 else {
eDest->
Emsg(
"Config",
"sched affpath option invalid -", val);
2795 {
eDest->
Emsg(
"Config",
"sched affpath argument not specified");
return 0;}
2800 sched_AffPC =
static_cast<char>(afpval*afpsign);
2811 if (!strcmp(val,
"maxretries"))
2812 {
if (!(val = CFile.
GetWord()))
2813 {
eDest->
Emsg(
"Config",
"sched ",
"maxretries argument not specified.");
2816 if (!xschedy(val,
eDest, mrRdrHost, mrRdrHLen, mrRdrPort))
return -1;
2823 if (!strcmp(val,
"nomultisrc"))
2835 if (!strncmp(val,
"nomultisrc@", 11))
2836 {
if (!xschedy(val,
eDest, msRdrHost, msRdrHLen, msRdrPort))
return -1;
2847 int &hlen,
int &port)
2849 const char *badTarget =
"Invalid sched redirect target '%s'%s";
2852 const char *eText =
"not a redirect target";
2856 if (host) {free(host); host = 0; hlen = port = 0;}
2860 if (!(at = index(val,
'@')))
return true;
2862 {snprintf(hName,
sizeof(hName),
2863 "Missing sched redirect target after '%s'.", val);
2867 *at = 0; val = at + 1;
2872 {snprintf(hName,
sizeof(hName), badTarget, val,
".");
2879 if ((eText = netAddr.
Set(val)))
2880 {snprintf(hName,
sizeof(hName), badTarget, val,
";");
2889 {snprintf(hName,
sizeof(hName), badTarget, val,
".");
2896 host = strdup(hName);
2897 hlen = strlen(hName)+1;
2898 port = netAddr.
Port();
2922 if (!isManager)
return CFile.
noEcho();
2972 int i, alinger = -1, arecalc = -1, minfP = -1, hwmP = -1;
2973 long long minf = -1, hwm = -1;
2974 bool haveopt =
false;
2976 while((val = CFile.
GetWord()))
2977 {
if (!strcmp(
"linger", val))
2978 {
if (!(val = CFile.
GetWord()))
2979 {
eDest->
Emsg(
"Config",
"linger value not specified");
return 1;}
2982 else if (!strcmp(
"recalc", val))
2983 {
if (!(val = CFile.
GetWord()))
2984 {
eDest->
Emsg(
"Config",
"recalc value not specified");
return 1;}
2987 else if (!strcmp(
"min", val))
2988 {
if (!(val = CFile.
GetWord()) || !isdigit(*val))
2989 {
eDest->
Emsg(
"Config",
"space min value not specified");
return 1;}
2992 else if (!strcmp(
"mwfiles", val)) {DoMWChk = 0; haveopt =
true;}
2993 else if (isdigit(*val))
break;
2994 else {
eDest->
Emsg(
"Config",
"invalid space parameters");
return 1;}
2997 if (val && isdigit(*val))
2999 if (val[i-1] ==
'%')
3006 if (val && isdigit(*val))
3008 if (val[i-1] !=
'%')
3014 if (minfP >= 0 && minf < 0)
3015 {
eDest->
Emsg(
"Config",
"absolute min value not specified");
return 1;}
3017 if (val && isdigit(*val))
3019 if (val[i-1] ==
'%')
3026 if (val && isdigit(*val))
3028 if (val[i-1] !=
'%')
3034 if (hwmP >= 0 && hwm < 0)
3035 {
eDest->
Emsg(
"Config",
"absolute high watermark value not specified");
return 1;}
3037 if (val) {
eDest->
Emsg(
"Config",
"invalid space parameter -", val);
return 1;}
3039 if (!haveopt && alinger < 0 && arecalc < 0 && minf < 0)
3040 {
eDest->
Emsg(
"Config",
"no space values specified");
return 1;}
3042 if (alinger >= 0) DiskLinger = alinger;
3043 if (arecalc >= 0) DiskAsk = arecalc;
3046 {
if (hwmP < minfP) hwmP = minfP + 1;
3047 DiskMinP = minfP; DiskHWMP = hwmP;
3048 }
else DiskMinP = DiskHWMP = 0;
3051 {
if (hwm < minf) hwm = minf+1073741824;
3052 minf = minf >> 20LL; hwm = hwm >> 20LL;
3053 if (minf >> 31LL) {minf = 0x7fefffff; hwm = 0x7fffffff;}
3054 else if (hwm >> 31LL) minf = 0x7fffffff;
3055 DiskMin =
static_cast<int>(minf);
3056 DiskHWM =
static_cast<int>(hwm);
3078 StorageHelper(
char **v1,
char **v2) : val1(v1), val2(v2) {}
3079 ~StorageHelper() {
if (*val1) free(*val1);
3080 if (*val2) free(*val2);
3082 char **val1, **val2;
3085 char *val, *hSpec = 0, *hPort = 0;
3086 StorageHelper SHelp(&hSpec, &hPort);
3090 if (isMeta || isServer || isPeer || isProxy)
return CFile.
noEcho();
3095 if (val && !strcmp(
"of", val)) val = CFile.
GetWord();
3100 {
eDest->
Emsg(
"Config",
"cluster manager host name not specified");
3103 hSpec = strdup(val);
3130 {
const char *invp =
"superport port";
3131 char *val, cport[32];
3135 {
eDest->
Emsg(
"Config",
"tcp port not specified");
return 1;}
3137 strncpy(cport, val,
sizeof(cport)-1); cport[
sizeof(cport)-1] =
'\0';
3139 if ((val = CFile.
GetWord()) && !strcmp(
"if", val))
3141 myName,myInsName,myProg))<=0)
3142 {
if (!rc) CFile.
noEcho();
return rc < 0;}
3144 if (!strcmp(cport,
"any")) pnum = 0;
3145 else if (!strcmp(cport,
"-p")) pnum = PortTCP;
3146 else if (isdigit(*cport))
3149 {
eDest->
Emsg(
"Config",
"Unable to find superport", cport);
3174 static struct traceopts {
const char *opname;
int opval;} tropts[] =
3185 int i, neg, trval = 0, numopts =
sizeof(tropts)/
sizeof(
struct traceopts);
3188 {
eDest->
Emsg(
"config",
"trace option not specified");
return 1;}
3190 {
if (!strcmp(val,
"off")) trval = 0;
3191 else {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
3192 for (i = 0; i < numopts; i++)
3193 {
if (!strcmp(val, tropts[i].opname))
3194 {
if (neg) trval &= ~tropts[i].opval;
3195 else trval |= tropts[i].opval;
3200 eDest->
Say(
"Config warning: ignoring invalid trace option '",val,
"'.");
3227 char *val, parms[1024];
3231 if (!(val = CFile.
GetWord()) || !val[0])
3232 {
eDest->
Emsg(
"Config",
"vnid not specified");
return 1;}
3236 if (VNID_Lib) free(VNID_Lib);
3237 VNID_Lib = strdup(val);
3241 if (VNID_Parms) {free(VNID_Parms); VNID_Parms = 0;}
3242 if (*VNID_Lib ==
'@')
3243 {
if (!CFile.
GetRest(parms,
sizeof(parms)))
3244 {
eDest->
Emsg(
"Config",
"vnid plug-in parameters too long");
return 1;}
3245 if (*parms) VNID_Parms = strdup(parms);
void Usage(const char *msg)
void * XrdCmsStartAdmin(void *carg)
void * XrdCmsStartMonPerf(void *carg)
void * XrdCmsStartMonStat(void *carg)
void * XrdCmsStartAnote(void *carg)
void * XrdCmsStartMonRefs(void *carg)
void * XrdCmsStartSupervising(void *carg)
void * XrdCmsStartPreparing(void *carg)
#define XrdCmsMAX_PATH_LEN
static XrdSysError eDest(0,"crypto_")
XrdOss * XrdOssGetSS(XrdSysLogger *Logger, const char *config_fn, const char *OssLib, const char *OssParms, XrdOucEnv *envP, XrdVersionInfo &urVer)
ssize_t write(int fildes, const void *buf, size_t nbyte)
int access(const char *path, int amode)
static bool InitAREvents(void *arFunc)
void * Start(XrdNetSocket *AdminSock)
static void setSync(XrdSysSemaphore *sync)
void * Notes(XrdNetSocket *AdminSock)
void SetTries(bool xdfs, int tcnt)
void Init(int Opts, int DMlife, int DPLife)
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)
static const int min_nxTime
int GenLocalPath(const char *oldp, char *newp)
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)
int Monitor(char *pgm, int itv)
void setVirtual(vType vVal)
static void do_StateDFS(XrdCmsBaseFR *rP, int rc)
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)
static const char * Name(RoleID rid)
static RoleID Convert(const char *Tok1, const char *Tok2)
static const char * Type(RoleID rid)
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)
void Update(StateType StateT, int ActivVal, int StageVal=0)
static int Init(const char *AdminPath, int AdminMode)
static char * ParseManPort(XrdSysError *eDest, XrdOucStream &CFile, char *hSpec)
static bool ParseMan(XrdSysError *eDest, XrdOucTList **oldMans, char *hSpec, char *hPort, int *sPort=0, bool hush=false)
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.
const char * Set(const char *hSpec, int pNum=PortInSpec)
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)
static int Export(const char *Var, const char *Val)
void * GetPtr(const char *varname)
void PutPtr(const char *varname, void *value)
static unsigned long long ParseDefs(XrdOucStream &Config, XrdSysError &Eroute, unsigned long long Flags)
static XrdOucPList * ParsePath(XrdOucStream &Config, XrdSysError &Eroute, XrdOucPListAnchor &Export, unsigned long long Defopts)
unsigned long long Flag()
char * GetWord(int lowcase=0)
XrdOucEnv * SetEnv(XrdOucEnv *newEnv)
int GetRest(char *theBuf, int Blen, int lowcase=0)
static char * genPath(const char *path, const char *inst, const char *psfx=0)
static bool parseLib(XrdSysError &eDest, XrdOucStream &Config, const char *libName, char *&path, char **libparm)
static const char * InstName(int TranOpt=0)
static int doIf(XrdSysError *eDest, XrdOucStream &Config, const char *what, const char *hname, const char *nname, const char *pname)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
static int a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
void Schedule(XrdJob *jp)
static void SetQW(unsigned int qwVal)
static void SetQM(unsigned int qmVal)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
XrdSysLogger * logger(XrdSysLogger *lp=0)
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
static void Wait(int milliseconds)
void SetLogger(XrdSysLogger *logp)
XrdVERSIONINFODEF(myVersion, cmsclient, XrdVNUMBER, XrdVERSION)
Generic structure to pass security information back and forth.