37 #include "XrdOuc/XrdOucString.hh"
39 #include "XrdClient/XrdClientAdmin.hh"
43 #include "XProtocol/XProtocol.hh"
51 TSystem* ROOT_Plugin_TXNetSystem(
const char *url, Bool_t owner) {
52 return new TXNetSystem(url, owner);
56 ClassImp(TXNetSystem);
58 Bool_t TXNetSystem::fgInitDone = kFALSE;
59 Bool_t TXNetSystem::fgRootdBC = kTRUE;
60 THashList TXNetSystem::fgAddrFQDN;
61 THashList TXNetSystem::fgAdminHash;
63 typedef XrdClientVector<XrdOucString> VecString_t;
68 TXNetSystem::TXNetSystem(Bool_t owner) : TNetSystem(owner), fDirList(0)
70 SetTitle(
"(x)rootd system administration");
81 TXNetSystem::TXNetSystem(
const char *url, Bool_t owner) : TNetSystem(owner), fDirList(0)
83 SetTitle(
"(x)rootd system administration");
90 fgAddrFQDN.SetOwner();
91 fgAdminHash.SetOwner();
94 EnvPutInt(NAME_DEBUG, gEnv->GetValue(
"XNet.Debug", -1));
101 TNetSystem::InitRemoteEntity(url);
103 TXNetSystemConnectGuard cguard(
this, url);
104 if (!cguard.IsValid() && !fIsRootd)
105 Error(
"TXNetSystem",
"fatal error: connection creation failed.");
115 XrdClientAdmin *TXNetSystem::Connect(
const char *url)
121 XrdClientAdmin *cadm = TXNetSystem::GetClientAdmin(dummy);
124 Error(
"Connect",
"fatal error: new object creation failed.");
129 Int_t maxOld = EnvGetLong(NAME_FIRSTCONNECTMAXCNT);
132 gEnv->SetValue(
"XNet.FirstConnectMaxCnt", 1);
133 EnvPutInt(NAME_FIRSTCONNECTMAXCNT, 1);
134 if (cadm->Connect()) {
136 EnvPutInt(NAME_FIRSTCONNECTMAXCNT, maxOld);
138 EnvPutInt(NAME_FIRSTCONNECTMAXCNT, maxOld);
141 (cadm->GetClientConn()->GetServerType() == kSTRootd);
142 Int_t sd = cadm->GetClientConn()->GetOpenSockFD();
143 if (isRootd && sd > -1) {
146 TSocket *s =
new TSocket(sd);
149 R__LOCKGUARD(gROOTMutex);
150 gROOT->GetListOfSockets()->Remove(s);
152 s->SetOption(kNoBlock, 0);
155 Int_t rproto = TXNetFile::GetRootdProtocol(s);
157 Error(
"TXNetSystem",
"getting protocol of the rootd server");
162 s->SetRemoteProtocol(rproto);
163 TUrl uut((cadm->GetClientConn()
164 ->GetCurrentUrl()).GetUrl().c_str());
166 TXNetFile::FormUrl(uut,uu);
168 Info(
"Connect",
" url: %s",uu.Data());
170 s->SetUrl(uu.Data());
171 s->SetService(
"rootd");
172 s->SetServType(TSocket::kROOTD);
179 TNetSystem::Create(uu, s);
184 TNetSystem::Create(uu);
192 Error(
"Connect",
"some severe error occurred while opening"
193 " the connection at %s - exit", url);
194 if (cadm && cadm->LastServerError())
195 Printf(
" '%s'", cadm->LastServerError()->errmsg);
197 Printf(
" (error message not available)");
203 "while opening the connection at %s - exit", url);
215 void TXNetSystem::InitXrdClient()
224 if (gEnv->GetValue(
"XNet.PrintTAG",0) == 1)
225 Info(
"TXNetFile",
"(C) 2005 SLAC TXNetSystem (eXtended TNetSystem) %s",
226 gROOT->GetVersion());
233 void* TXNetSystem::OpenDirectory(
const char* dir)
237 TXNetSystemConnectGuard cg(
this, dir);
241 fDir = TUrl(dir).GetFile();
242 fDirp = (
void*)&fDir;
246 XrdOucString s(fDir.Data());
248 cg.ClientAdmin()->ExistDirs(dirs, existDirs);
249 cg.ClientAdmin()->GoBackToRedirector();
250 if (existDirs.GetSize()>0 && existDirs[0])
253 cg.NotifyLastError();
259 Info(
"OpenDirectory",
"calling TNetSystem::OpenDirectory");
260 return TNetSystem::OpenDirectory(dir);
266 void TXNetSystem::FreeDirectory(
void *dirp)
270 Error(
"FreeDirectory",
"invalid directory pointer (%p, %p)", dirp, fDirp);
277 ((VecString_t*)fDirList)->Clear();
278 delete ((VecString_t*)fDirList);
285 Info(
"FreeDirectory",
"calling TNetSystem::FreeDirectory");
286 return TNetSystem::FreeDirectory(dirp);
292 Int_t TXNetSystem::MakeDirectory(
const char* dir)
295 TXNetSystemConnectGuard cg(
this, dir);
298 Bool_t ok = cg.ClientAdmin()->Mkdir(TUrl(dir).GetFile(),7,5,5);
299 cg.ClientAdmin()->GoBackToRedirector();
303 cg.NotifyLastError();
310 Info(
"MakeDirectory",
"Calling TNetSystem::MakeDirectory");
311 return TNetSystem::MakeDirectory(dir);
318 const char* TXNetSystem::GetDirEntry(
void *dirp)
322 Error(
"GetDirEntry",
"invalid directory pointer");
328 TXNetSystemConnectGuard cg(
this, fUrl);
330 fDirList =
new VecString_t;
331 Bool_t ok = cg.ClientAdmin()->DirList(fDir, *(VecString_t*)fDirList);
332 cg.ClientAdmin()->GoBackToRedirector();
334 cg.NotifyLastError();
335 delete (VecString_t*)fDirList;
343 if (fDirList && ((VecString_t*)fDirList)->GetSize() > 0) {
344 fDirEntry = ((VecString_t*)fDirList)->Pop_front().c_str();
345 return fDirEntry.Data();
350 if (gDebug > 1) Info(
"GetDirEntry",
"Calling TNetSystem::GetDirEntry");
351 return TNetSystem::GetDirEntry(dirp);
361 Int_t TXNetSystem::GetPathInfo(
const char* path, FileStat_t &buf)
364 TXNetSystemConnectGuard cg(
this, path);
374 Bool_t ok = cg.ClientAdmin()->Stat(urlpath.GetFile(),id,size,flags,modtime);
377 urlpath.SetProtocol(cg.ClientAdmin()->GetCurrentUrl().Proto.c_str());
378 urlpath.SetHost(cg.ClientAdmin()->GetCurrentUrl().Host.c_str());
379 urlpath.SetPort(cg.ClientAdmin()->GetCurrentUrl().Port);
380 buf.fUrl = urlpath.GetUrl();
382 cg.ClientAdmin()->GoBackToRedirector();
385 if (flags & kXR_offline) {
386 buf.fMode = kS_IFOFF;
388 buf.fDev = (
id >> 24);
389 buf.fIno = (
id & 0x00FFFFFF);
393 buf.fMtime = modtime;
395 if (flags == 0) buf.fMode = kS_IFREG;
396 if (flags & kXR_xset) buf.fMode = (kS_IFREG|kS_IXUSR|kS_IXGRP|kS_IXOTH);
397 if (flags & kXR_isDir) buf.fMode = kS_IFDIR;
398 if (flags & kXR_other) buf.fMode = kS_IFSOCK;
399 if (flags & kXR_readable) buf.fMode |= kS_IRUSR;
400 if (flags & kXR_writable) buf.fMode |= kS_IWUSR;
406 cg.NotifyLastError();
413 Info(
"GetPathInfo",
"Calling TNetSystem::GetPathInfo");
414 return TNetSystem::GetPathInfo(path,buf);
421 Bool_t TXNetSystem::ConsistentWith(
const char *path,
void *dirptr)
424 Info(
"ConsistentWith",
425 "calling for path: %s, dir: %p", path, dirptr);
427 return TNetSystem::ConsistentWith(path,dirptr);
437 Bool_t TXNetSystem::AccessPathName(
const char *path, EAccessMode mode)
442 if (GetPathInfo(path, buf) == 0)
443 if (buf.fMode != kS_IFSOCK)
450 Info(
"AccessPathName",
"calling TNetSystem::AccessPathName");
451 return TNetSystem::AccessPathName(path,mode);
458 int TXNetSystem::Unlink(
const char *path)
462 TXNetSystemConnectGuard cg(
this, path);
471 TString edir = TUrl(path).GetFile();
472 Bool_t ok = cg.ClientAdmin()->Stat(edir.Data(), id, size, flags, modtime);
475 if (ok && !(flags & kXR_offline)) {
476 if (flags & kXR_isDir)
477 ok = cg.ClientAdmin()->Rmdir(edir.Data());
479 ok = cg.ClientAdmin()->Rm(edir.Data());
480 cg.ClientAdmin()->GoBackToRedirector();
483 return ((ok) ? 0 : -1);
485 cg.ClientAdmin()->GoBackToRedirector();
486 cg.NotifyLastError();
492 Info(
"Unlink",
"calling TNetSystem::Unlink");
499 Bool_t TXNetSystem::IsOnline(
const char *path)
503 if (GetPathInfo(path, st) != 0) {
505 Info(
"IsOnline",
"path '%s' cannot be stat'ed", path);
508 if (R_ISOFF(st.fMode)) {
510 Info(
"IsOnline",
"path '%s' is offline", path);
520 Bool_t TXNetSystem::Prepare(
const char *path, UChar_t option, UChar_t priority)
522 TXNetSystemConnectGuard cg(
this, path);
524 XrdOucString pathname = TUrl(path).GetFileAndOptions();
526 vs.Push_back(pathname);
527 cg.ClientAdmin()->Prepare(vs, (kXR_char)option, (kXR_char)priority);
528 cg.ClientAdmin()->GoBackToRedirector();
530 Info(
"Prepare",
"Got Status %d for %s",
531 cg.ClientAdmin()->LastServerResp()->status, pathname.c_str());
532 if (!(cg.ClientAdmin()->LastServerResp()->status)){
535 cg.NotifyLastError();
549 Int_t TXNetSystem::Prepare(TCollection *paths,
550 UChar_t opt, UChar_t prio, TString *bufout)
553 Warning(
"Prepare",
"input list is empty!");
559 TXNetSystemConnectGuard cg(
this,
"");
562 TString *buf = (bufout) ? bufout :
new TString();
569 while ((o = nxt())) {
571 TString pn = TFileStager::GetPathName(o);
573 Warning(
"Prepare",
"object is of unexpected type %s - ignoring", o->ClassName());
578 path = u.GetFileAndOptions();
579 path.ReplaceAll(
"\n",
"\r");
581 *buf += Form(
"%s\n", path.Data());
584 Info(
"Prepare",
"buffer ready: issuing prepare (opt=%d, prio=%d) ...",
586 cg.ClientAdmin()->Prepare(buf->Data(), (kXR_char)opt, (kXR_char)prio);
587 cg.ClientAdmin()->GoBackToRedirector();
591 Info(
"Prepare",
"Got Status %d",
592 cg.ClientAdmin()->LastServerResp()->status);
593 if (!(cg.ClientAdmin()->LastServerResp()->status)){
596 cg.NotifyLastError();
608 Bool_t TXNetSystem::GetPathsInfo(
const char *paths, UChar_t *info)
611 Warning(
"GetPathsInfo",
"input list is empty!");
615 TXNetSystemConnectGuard cg(
this,
"");
617 cg.ClientAdmin()->SysStatX(paths, info);
618 cg.ClientAdmin()->GoBackToRedirector();
620 Info(
"GetPathsInfo",
"Got Status %d",
621 cg.ClientAdmin()->LastServerResp()->status);
622 if (!(cg.ClientAdmin()->LastServerResp()->status)){
625 cg.NotifyLastError();
636 Bool_t TXNetSystem::IsPathLocal(
const char *path)
639 TXNetSystemConnectGuard cg(
this, path);
641 if (cg.ClientAdmin()->GetClientConn()->GetServerType() != kSTDataXrootd) {
648 return TSystem::IsPathLocal(path);
656 Int_t TXNetSystem::Locate(
const char *path, TString &eurl)
659 TXNetSystemConnectGuard cg(
this, path);
663 XrdClientLocate_Info li;
664 TString edir = TUrl(path).GetFile();
666 if (cg.ClientAdmin()->Locate((kXR_char *)edir.Data(), li)) {
668 XrdClientUrlInfo ui((
const char *)&li.Location[0]);
672 if (fgAddrFQDN.GetSize() <= 0 ||
673 !(hn =
dynamic_cast<TNamed *
>(fgAddrFQDN.FindObject(ui.Host.c_str())))) {
674 TInetAddress a(gSystem->GetHostByName(ui.Host.c_str()));
675 if (strlen(a.GetHostName()) > 0)
676 hn =
new TNamed(ui.Host.c_str(), a.GetHostName());
678 hn =
new TNamed(ui.Host.c_str(), ui.Host.c_str());
681 Info(
"Locate",
"caching host name: %s", hn->GetTitle());
684 u.SetHost(hn->GetTitle());
686 u.SetHost(ui.Host.c_str());
691 cg.NotifyLastError();
697 if (gDebug > 0) Info(
"Locate",
"server not Xrootd: method not implemented!");
705 XrdClientAdmin *TXNetSystem::GetClientAdmin(
const char *url)
707 XrdClientAdmin *ca = 0;
710 TString key = TXNetSystem::GetKey(url);
713 TXrdClientAdminWrapper *caw = 0;
714 if (fgAdminHash.GetSize() > 0 &&
715 (caw =
dynamic_cast<TXrdClientAdminWrapper *
>(fgAdminHash.FindObject(key.Data()))))
719 ca =
new XrdClientAdmin(url);
720 fgAdminHash.Add(
new TXrdClientAdminWrapper(key, ca));
729 TString TXNetSystem::GetKey(
const char *url)
732 TString key(u.GetUser());
736 if (u.GetPort() > 0) {
751 TXrdClientAdminWrapper::~TXrdClientAdminWrapper()
762 TXNetSystemConnectGuard::TXNetSystemConnectGuard(TXNetSystem *xn,
const char *url)
767 fClientAdmin = (url && strlen(url) > 0) ? xn->Connect(url)
768 : xn->Connect(xn->fUrl);
774 TXNetSystemConnectGuard::~TXNetSystemConnectGuard()
782 void TXNetSystemConnectGuard::NotifyLastError()
785 if (fClientAdmin->GetClientConn())
786 Printf(
"Srv err: %s", fClientAdmin->GetClientConn()->LastServerError.errmsg);