48 #include <sys/param.h>
49 #include <sys/types.h>
63 #define EMSG(x) std::cerr <<"xrdmapc: " <<x <<std::endl
68 #define OPT_TYPE (char *)
87 clMap(
const char *addr) : nextMan(0), nextSrv(0), nextLvl(0),
88 state(
""), hasfile(
' '), verfile(
' '),
92 epAddr.
Set(addr); epAddr.
Name();
93 epAddr.
Format(name,
sizeof(name));
112 bool listMan =
true, listSrv =
true, doVerify =
false, doHush =
false;
129 const char *MakeURL(
const char *name,
char *buff,
int blen)
131 snprintf(buff, blen,
"xroot://%s//", name);
149 {
switch(Status.
errNo)
150 {
case kXR_FSError: node->state =
" [fs error]";
break;
151 case kXR_IOError: node->state =
" [io error]";
break;
155 node->state =
" [no subscribers]";
156 else {node->state =
"";
160 case kXR_NotFile: node->state =
" [not a file]";
break;
161 default: sprintf(buff,
" [xrootd error %d]", Status.
errNo);
162 node->state = strdup(buff);
191 default:
if (!(*Status.
ToStr().c_str()))
192 sprintf(buff,
" [client error %d]", Status.
code);
193 else snprintf(buff,
sizeof(buff),
" [%s]",
194 Status.
ToStr().c_str());
195 node->state = strdup(buff);
207 void MapCluster(clMap *node, clMap *origin)
211 XrdCl::URL theURL((
const std::string)MakeURL(node->name,buff,
sizeof(buff)));
217 clMap *clmP, *branch;
221 Status = xrdFS.Locate((
const std::string)
"*", flags, info, theTO);
227 EMSG(
"Unable to get " <<node->name <<
" subscribers; "
228 <<Status.
ToStr().c_str());
229 MapCode(Status, origin,
true);
236 for( it = info->
Begin(); it != info->
End(); ++it )
237 {clmP =
new clMap(it->GetAddress().c_str());
238 locType = it->GetType();
241 {clmP->nextSrv = node->nextSrv;
242 node->nextSrv = clmP;
244 clmP->nextMan = node->nextMan;
245 node->nextMan = clmP;
248 clHash.Add(clmP->key, clmP, 0,
Hash_keep);
253 clmP = node->nextMan;
255 {branch =
new clMap(clmP->name);
256 MapCluster(branch, clmP);
258 clmP->nextLvl = branch;
260 clmP = clmP->nextMan;
275 void MapPath(clMap *node,
const char *
Path,
bool doRefresh=
false)
279 XrdCl::URL theURL((
const std::string)MakeURL(node->name,buff,
sizeof(buff)));
292 Status = xrdFS.Locate((
const std::string)
Path, flags, info, theTO);
298 EMSG(
"Unable to query " <<node->name <<
" about path; "
299 <<Status.
ToStr().c_str());
300 MapCode(Status, node);
306 for( it = info->
Begin(); it != info->
End(); ++it )
307 {
const char *clAddr = it->GetAddress().c_str();
308 if ((clmP = clHash.Find(clAddr)))
309 {clmP->hasfile =
'>';
310 if (clmP->isMan) MapPath(clmP,
Path);
312 clmP =
new clMap(clAddr);
313 clmP->nextSrv = clLost;
330 const char *OpName(
char *Argv[])
332 static char oName[4] = {
'-', 0, 0, 0};
347 void PathChk(clMap *node)
350 XrdCl::URL theURL((
const std::string)MakeURL(node->name,buff,
sizeof(buff)));
357 Status = xrdFS.Stat((
const std::string)
Path, info);
361 if (!Status.
IsOK()) MapCode(Status, node);
362 else node->verfile =
'+';
376 void PrintMap(clMap *clmP,
int lvl)
379 const char *pfx =
"";
386 {pfxbuff = (
char *)malloc(n+1);
387 memset(pfxbuff,
' ', n); pfxbuff[n] = 0;
394 {clnow = clmP->nextSrv;
396 {
if (doVerify) PathChk(clnow);
398 {pfxbuff[1] = clnow->hasfile;
399 pfxbuff[2] = clnow->verfile;
401 std::cout <<
' ' <<pfx <<
"Srv " <<clnow->name <<clnow->state <<std::endl;
402 clnow = clnow->nextSrv;
409 {clnow = clmP->nextMan;
410 if (lvl) pfxbuff[2] =
' ';
412 {
if (lvl) pfxbuff[1] = clnow->hasfile;
413 std::cout <<lvl <<pfx <<
"Man " <<clnow->name <<clnow->state <<std::endl;
414 if (clnow->valid && clnow->nextLvl) PrintMap(clnow->nextLvl,lvl+1);
415 clnow = clnow->nextMan;
421 if (lvl) free(pfxbuff);
439 env->
PutInt(
"ConnectionWindow", cwValue);
440 env->
PutInt(
"ConnectionRetry", crValue);
441 env->
PutInt(
"TimeoutResolution",trValue);
454 std::cerr <<
"Usage: xrdmapc [<opt>] <host>:<port> [<path>]\n"
455 <<
"<opt>: [--help] [--list {all|m|s}] [--quiet] [--refresh] [--verify]" <<std::endl;
458 "--list | -l 'all' lists managers and servers (default), 'm' lists only\n"
459 " managers and 's' lists only servers.\n"
460 "--quiet | -q does not print error messages to std::cerr; errors appear inline.\n"
461 "--refresh | -r does not use cached information but will refresh the cache.\n"
462 "--verify | -v verifies <path> existence status at each server.\n"
463 "<path> when specified, uses <host>:<port> to determine the locations\n"
464 " of path and does optional verification."
467 exit((
emsg ? 1 : 0));
475 int main(
int argc,
char *argv[])
477 const char *opLetters =
":hl:rv";
478 struct option opVec[] =
483 {
OPT_TYPE "refresh", 0, 0, (int)
'r'},
484 {
OPT_TYPE "verify", 0, 0, (int)
'v'},
487 extern int optind, opterr;
490 clMap *baseNode, *clNow;
494 bool doRefresh =
false;
500 while((opC = getopt_long(argc, argv, opLetters, opVec, &i)) != (
char)-1)
504 case 'l':
if (!strcmp(
"all",optarg))
505 {listMan =
true; listSrv =
true;}
506 else if (!strcmp(
"m", optarg))
507 {listMan =
true; listSrv =
false;}
508 else if (!strcmp(
"s", optarg))
509 {listMan =
false; listSrv =
true;}
510 else Usage(
"Invalid list argument.");
512 case 'q': doHush =
true;
514 case 'r': doRefresh =
true;
516 case 'v': doVerify =
true;
518 case ':':
EMSG(
"'" <<OpName(argv) <<
"' argument missing.");
520 case '?':
EMSG(
"Invalid option, '" <<OpName(argv) <<
"'.");
522 default:
EMSG(
"Internal error processing '" <<OpName(argv) <<
"'.");
528 if (
optind >= argc)
Usage(
"Initial node not specified.");
533 {
EMSG(
"Unable to validate initial node; " <<
eMsg);
546 baseNode =
new clMap(argv[
optind]);
551 else doVerify =
false;
559 MapCluster(baseNode, baseNode);
564 {MapPath(baseNode,
Path, doRefresh);
565 eMsg = (doVerify ?
"0*rv* " :
"0*r** ");
566 }
else eMsg =
"0**** ";
570 std::cout <<
eMsg <<baseNode->name <<baseNode->state <<std::endl;
571 PrintMap(baseNode, 1);
576 {std::cerr <<
"Warning! " <<baseNode->name
577 <<
" referred to the following unconnected node:" <<std::endl;
580 {std::cerr <<
"????? " <<clNow->name <<std::endl;
581 clNow = clNow->nextSrv;
void Usage(const char *msg)
int main(int argc, char *argv[])
int emsg(int rc, char *msg)
static Env * GetEnv()
Get default client environment.
bool PutInt(const std::string &key, int value)
Send file/filesystem queries to an XRootD cluster.
Iterator Begin()
Get the location begin iterator.
LocationType
Describes the node type and file status for a given location.
@ ServerPending
server node where the file is pending to be online
@ ServerOnline
server node where the file is online
LocationList::iterator Iterator
Iterator over locations.
Iterator End()
Get the location end iterator.
std::string ToStr() const
Convert to string.
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
const char * Name(const char *eName=0, const char **eText=0)
const char * Set(const char *hSpec, int pNum=PortInSpec)
const uint16_t errInvalidAddr
const uint16_t errStreamDisconnect
const uint16_t errRedirectLimit
const uint16_t errErrorResponse
const uint16_t errOperationExpired
const uint16_t errLoginFailed
const uint16_t errSocketTimeout
const uint16_t errHandShakeFailed
const uint16_t errConnectionError
const uint16_t errSocketError
const uint16_t errSocketDisconnected
const uint16_t errAuthFailed
Flags
Open flags, may be or'd when appropriate.
uint16_t code
Error type, or additional hints on what to do.
bool IsOK() const
We're fine.
uint32_t errNo
Errno, if any.