(roleID);
strcpy(myRType, XrdCmsRole::Type(roleID));
return 0;
}
/******************************************************************************/
/* x s c h e d */
/******************************************************************************/
/* Function: xsched
Purpose: To parse directive: sched [cpu ] [gsdflt
] [gshr
]
[io
] [runq
]
[mem
] [pag
] [space
]
[fuzz
] [maxload
] [refreset ]
[affinity [default] {none | weak | strong | strict}]
is the percentage to include in the load as a value
between 0 and 100. For fuzz this is the largest
difference two load values may have to be treated equal.
maxload is the largest load allowed before server is
not selected. refreset is the minimum number of seconds
between reference counter resets. gshr is the percentage
share of requests that should be redirected here via the
metamanager (i.e. global share). The gsdflt is the
default to be used by the metamanager.
Type: Any, dynamic.
Output: retc upon success or -EINVAL upon failure.
*/
int XrdCmsConfig::xsched(XrdSysError *eDest, XrdOucStream &CFile)
{
char *val;
int i, ppp, V_hntry = -1;
static struct schedopts {const char *opname; int maxv; int *oploc;}
scopts[] =
{
{"cpu", 100, &P_cpu},
{"fuzz", 100, &P_fuzz},
{"gsdflt", 100, &P_gsdf},
{"gshr", 100, &P_gshr},
{"io", 100, &P_io},
{"runq", 100, &P_load}, // Actually load, runq to avoid confusion
{"mem", 100, &P_mem},
{"pag", 100, &P_pag},
{"space", 100, &P_dsk},
{"maxload", 100, &MaxLoad},
{"refreset", -1, &RefReset},
{"affinity", -2, 0},
{"tryhname", 1, &V_hntry}
};
int numopts = sizeof(scopts)/sizeof(struct schedopts);
if (!(val = CFile.GetWord()))
{eDest->Emsg("Config", "sched option not specified"); return 1;}
while (val)
{for (i = 0; i < numopts; i++)
if (!strcmp(val, scopts[i].opname))
{if (!(val = CFile.GetWord()))
{eDest->Emsg("Config", "sched ", scopts[i].opname,
"argument not specified.");
return 1;
}
if (scopts[i].maxv == -2)
{if (!xschedm(val, eDest, CFile)) return 1;
break;
}
if (scopts[i].maxv < 0)
{if (XrdOuca2x::a2tm(*eDest,"sched value", val, &ppp, 0))
return 1;
}
else if (XrdOuca2x::a2i(*eDest,"sched value", val, &ppp,
0, scopts[i].maxv)) return 1;
*scopts[i].oploc = ppp;
break;
}
if (i >= numopts)
eDest->Say("Config warning: ignoring invalid sched option '",val,"'.");
val = CFile.GetWord();
}
// Handle non-int settings
//
if (V_hntry >= 0) DoHnTry = static_cast(V_hntry);
return 0;
}
/******************************************************************************/
int XrdCmsConfig::xschedm(char *val, XrdSysError *eDest, XrdOucStream &CFile)
{
if (!strcmp(val, "default"))
{sched_Force = 0;
if (!(val = CFile.GetWord()))
{eDest->Emsg("Config", "sched affinity not specified"); return 0;}
} else sched_Force = 1;
if (!strcmp(val, "none"))
{sched_Pack = sched_Level = 0;
return 1;
}
sched_Pack = sched_Level = 1;
if (!strcmp(val, "weak")) return 1;
sched_Pack = 2;
if (!strcmp(val, "strong")) return 1;
if (!strcmp(val, "strict"))
{sched_Level = 0;
return 1;
}
eDest->Emsg("Config", "Invalid sched affinity -", val);
return 0;
}
/******************************************************************************/
/* x s e c l */
/******************************************************************************/
/* Function: xsecl
Purpose: To parse the directive: seclib
the location of the security library.
Type: Server only, non-dynamic.
Output: 0 upon success or !0 upon failure.
*/
int XrdCmsConfig::xsecl(XrdSysError *eDest, XrdOucStream &CFile)
{
char *val;
// If we are a server, ignore this option
//
if (!isManager) return CFile.noEcho();
// Get path
//
val = CFile.GetWord();
if (!val || !val[0])
{eDest->Emsg("Config", "seclib path not specified"); return 1;}
// Assign new path
//
if (SecLib) free(SecLib);
SecLib = strdup(val);
return 0;
}
/******************************************************************************/
/* x s p a c e */
/******************************************************************************/
/* Function: xspace
Purpose: To parse the directive: space [linger ] [recalc ]
[[min] { [] | } [[] ]]
[mwfiles]
Maximum number of times a server may be reselected without
a break. The default is 0.
Min free space needed as percentage of the largest partition.
Min free space needed in bytes (or K, M, G) in a partition.
The default is 10G.
Percentage of free space needed to requalify.
Bytes (or K, M,G) of free space needed when bytes falls below
to requalify a server for selection.
The default is 11G.
Number of seconds that must elapse before a disk free space
calculation will occur.
mwfiles
space supports multiple writable file copies. This suppresses
multiple file check when open a file in write mode.
Notes: This is used by the manager and the server.
Type: All, dynamic.
Output: 0 upon success or !0 upon failure.
*/
int XrdCmsConfig::xspace(XrdSysError *eDest, XrdOucStream &CFile)
{
char *val;
int i, alinger = -1, arecalc = -1, minfP = -1, hwmP = -1;
long long minf = -1, hwm = -1;
bool haveopt = false;
while((val = CFile.GetWord()))
{ if (!strcmp("linger", val))
{if (!(val = CFile.GetWord()))
{eDest->Emsg("Config", "linger value not specified"); return 1;}
if (XrdOuca2x::a2i(*eDest,"linger",val,&alinger,0)) return 1;
}
else if (!strcmp("recalc", val))
{if (!(val = CFile.GetWord()))
{eDest->Emsg("Config", "recalc value not specified"); return 1;}
if (XrdOuca2x::a2i(*eDest,"recalc",val,&arecalc,1)) return 1;
}
else if (!strcmp("min", val))
{if (!(val = CFile.GetWord()) || !isdigit(*val))
{eDest->Emsg("Config", "space min value not specified"); return 1;}
break;
}
else if (!strcmp("mwfiles", val)) {DoMWChk = 0; haveopt = true;}
else if (isdigit(*val)) break;
else {eDest->Emsg("Config", "invalid space parameters"); return 1;}
}
if (val && isdigit(*val))
{i = strlen(val);
if (val[i-1] == '%')
{val[i-1] = '\0';
if (XrdOuca2x::a2i(*eDest,"space % minfree",val,&minfP,1,99)) return 1;
val = CFile.GetWord();
}
}
if (val && isdigit(*val))
{i = strlen(val);
if (val[i-1] != '%')
{if (XrdOuca2x::a2sz(*eDest,"space minfree",val,&minf,0)) return 1;
val = CFile.GetWord();
}
}
if (minfP >= 0 && minf < 0)
{eDest->Emsg("Config", "absolute min value not specified"); return 1;}
if (val && isdigit(*val))
{i = strlen(val);
if (val[i-1] == '%')
{val[i-1] = '\0';
if (XrdOuca2x::a2i(*eDest,"space % high watermark",val,&hwmP,1,99)) return 1;
val = CFile.GetWord();
}
}
if (val && isdigit(*val))
{i = strlen(val);
if (val[i-1] != '%')
{if (XrdOuca2x::a2sz(*eDest,"space high watermark",val,&hwm,0)) return 1;
val = CFile.GetWord();
}
}
if (hwmP >= 0 && hwm < 0)
{eDest->Emsg("Config", "absolute high watermark value not specified"); return 1;}
if (val) {eDest->Emsg("Config", "invalid space parameter -", val); return 1;}
if (!haveopt && alinger < 0 && arecalc < 0 && minf < 0)
{eDest->Emsg("Config", "no space values specified"); return 1;}
if (alinger >= 0) DiskLinger = alinger;
if (arecalc >= 0) DiskAsk = arecalc;
if (minfP > 0)
{if (hwmP < minfP) hwmP = minfP + 1;
DiskMinP = minfP; DiskHWMP = hwmP;
} else DiskMinP = DiskHWMP = 0;
if (minf >= 0)
{if (hwm < minf) hwm = minf+1073741824; // Minimum + 1GB
minf = minf >> 20LL; hwm = hwm >> 20LL; // Now Megabytes
if (minf >> 31LL) {minf = 0x7fefffff; hwm = 0x7fffffff;}
else if (hwm >> 31LL) minf = 0x7fffffff;
DiskMin = static_cast(minf);
DiskHWM = static_cast(hwm);
}
return 0;
}
/******************************************************************************/
/* x s u b c */
/******************************************************************************/
/* Function: subc
Purpose: To parse the directive: subcluster of [+][:|]
Type: Manager only, non-dynamic.
Output: 0 upon success or !0 upon failure.
*/
int XrdCmsConfig::xsubc(XrdSysError *eDest, XrdOucStream &CFile)
{
class StorageHelper
{public:
StorageHelper(char **v1, char **v2) : val1(v1), val2(v2) {}
~StorageHelper() {if (*val1) free(*val1);
if (*val2) free(*val2);
}
char **val1, **val2;
};
char *val, *hSpec = 0, *hPort = 0;
StorageHelper SHelp(&hSpec, &hPort);
// Ignore this call if we are not a simple manager
//
if (isMeta || isServer || isPeer || isProxy) return CFile.noEcho();
// Skip the optional "of" keyword
//
val = CFile.GetWord();
if (val && !strcmp("of", val)) val = CFile.GetWord();
// Get the actual host name and copy it
//
if (!val)
{eDest->Emsg("Config","cluster manager host name not specified");
return 1;
}
hSpec = strdup(val);
// Grab the port number (either in hostname or following token)
//
if (!(hPort = XrdCmsUtils::ParseManPort(eDest, CFile, hSpec))) return 1;
// Parse the specification and return
//
return (XrdCmsUtils::ParseMan(eDest, &SanList, hSpec, hPort) ? 0 : 1);
}
/******************************************************************************/
/* x s u p p */
/******************************************************************************/
/* Function: xsupp
Purpose: To parse the directive: superport
[if [] [named ]]
number of the tcp port for incomming requests
list of applicable host patterns
list of applicable instance names.
Output: 0 upon success or !0 upon failure.
*/
int XrdCmsConfig::xsupp(XrdSysError *eDest, XrdOucStream &CFile)
{ const char *invp = "superport port";
char *val, cport[32];
int rc, pnum;
if (!(val = CFile.GetWord()))
{eDest->Emsg("Config", "tcp port not specified"); return 1;}
strncpy(cport, val, sizeof(cport)-1); cport[sizeof(cport)-1] = '\0';
if ((val = CFile.GetWord()) && !strcmp("if", val))
if ((rc = XrdOucUtils::doIf(eDest,CFile,"superport directive",
myName,myInsName,myProg))<=0)
{if (!rc) CFile.noEcho(); return rc < 0;}
if (!strcmp(cport, "any")) pnum = 0;
else if (!strcmp(cport, "-p")) pnum = PortTCP;
else if (isdigit(*cport))
{if (XrdOuca2x::a2i(*eDest,invp,cport,&pnum,1,65535)) return 0;}
else if (!(pnum = XrdNetUtils::ServPort(cport)))
{eDest->Emsg("Config", "Unable to find superport", cport);
return 1;
}
PortSUP = pnum;
return 0;
}
/******************************************************************************/
/* x t r a c e */
/******************************************************************************/
/* Function: xtrace
Purpose: To parse the directive: trace
Type: Manager or Server, dynamic.
Output: 0 upon success or !0 upon failure.
*/
int XrdCmsConfig::xtrace(XrdSysError *eDest, XrdOucStream &CFile)
{
char *val;
static struct traceopts {const char *opname; int opval;} tropts[] =
{
{"all", TRACE_ALL},
{"debug", TRACE_Debug},
{"defer", TRACE_Defer},
{"files", TRACE_Files},
{"forward", TRACE_Forward},
{"redirect", TRACE_Redirect},
{"stage", TRACE_Stage}
};
int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
if (!(val = CFile.GetWord()))
{eDest->Emsg("config", "trace option not specified"); return 1;}
while (val)
{if (!strcmp(val, "off")) trval = 0;
else {if ((neg = (val[0] == '-' && val[1]))) val++;
for (i = 0; i < numopts; i++)
{if (!strcmp(val, tropts[i].opname))
{if (neg) trval &= ~tropts[i].opval;
else trval |= tropts[i].opval;
break;
}
}
if (i >= numopts)
eDest->Say("Config warning: ignoring invalid trace option '",val,"'.");
}
val = CFile.GetWord();
}
Trace.What = trval;
return 0;
}
/******************************************************************************/
/* x v n i d */
/******************************************************************************/
/* Function: xvnid
Purpose: To parse the directive: vnid {=|<|@} []
= - the actual vnid value
< - the path of the file to be read for the vnid.
@ - the path of the plugin library to be used.
optional parms to be passed
Output: 0 upon success or !0 upon failure.
*/
int XrdCmsConfig::xvnid(XrdSysError *eDest, XrdOucStream &CFile)
{
char *val, parms[1024];
// Get the argument
//
if (!(val = CFile.GetWord()) || !val[0])
{eDest->Emsg("Config", "vnid not specified"); return 1;}
// Record the path
//
if (VNID_Lib) free(VNID_Lib);
VNID_Lib = strdup(val);
// Record any parms (only if it starts with an @)
//
if (VNID_Parms) {free(VNID_Parms); VNID_Parms = 0;}
if (*VNID_Lib == '@')
{if (!CFile.GetRest(parms, sizeof(parms)))
{eDest->Emsg("Config", "vnid plug-in parameters too long"); return 1;}
if (*parms) VNID_Parms = strdup(parms);
}
return 0;
}