Logo ROOT   6.10/09
Reference Guide
TNetXNGSystem.cxx
Go to the documentation of this file.
1 // @(#)root/netx:$Id$
2 /*************************************************************************
3  * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers. *
4  * All rights reserved. *
5  * *
6  * For the licensing terms see $ROOTSYS/LICENSE. *
7  * For the list of contributors see $ROOTSYS/README/CREDITS. *
8  *************************************************************************/
9 
10 
11 ////////////////////////////////////////////////////////////////////////////////
12 // //
13 // TNetXNGSystem //
14 // //
15 // Authors: Justin Salmon, Lukasz Janyst //
16 // CERN, 2013 //
17 // //
18 // Enables access to XRootD filesystem interface using the new client. //
19 // //
20 ////////////////////////////////////////////////////////////////////////////////
21 
22 #include "TNetXNGSystem.h"
23 #include "TFileStager.h"
24 #include "Rtypes.h"
25 #include "TList.h"
26 #include "TUrl.h"
27 #include "TVirtualMutex.h"
28 #include <XrdCl/XrdClFileSystem.hh>
29 #include <XrdCl/XrdClXRootDResponses.hh>
30 #include <XrdSys/XrdSysDNS.hh>
31 
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 /// PluginManager creation function
35 
36 TSystem* ROOT_Plugin_TNetXNGSystem(const char *url, Bool_t owner) {
37  return new TNetXNGSystem(url, owner);
38 }
39 
40 
42 
45 
46 namespace
47 {
48  struct DirectoryInfo {
49  XrdCl::URL *fUrl; // Path of this directory
50  XrdCl::DirectoryList *fDirList; // Directory listing
51  XrdCl::DirectoryList::Iterator *fDirListIter; // Iterator for this listing
52 
53  public:
54  DirectoryInfo(const char *dir) : fUrl(new XrdCl::URL(dir)), fDirList(0), fDirListIter(0) {}
55 
56  ~DirectoryInfo() {
57  delete fUrl;
58  delete fDirList;
59  }
60  };
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// Constructor: Create system class without connecting to server
65 ///
66 /// param owner: (unused)
67 
69  TSystem("-root", "Net file Helper System"), fUrl(0), fFileSystem(0)
70 {
71  // Name must start with '-' to bypass the TSystem singleton check, then
72  // be changed to "root"
73  SetName("root");
74 }
75 
76 ////////////////////////////////////////////////////////////////////////////////
77 /// Constructor: Create system class and connect to server
78 ///
79 /// param url: URL of the entry-point server to be contacted
80 /// param owner: (unused)
81 
82 TNetXNGSystem::TNetXNGSystem(const char *url, Bool_t /*owner*/) :
83  TSystem("-root", "Net file Helper System")
84 {
85  using namespace XrdCl;
86 
87  // Name must start with '-' to bypass the TSystem singleton check
88  SetName("root");
89  fUrl = new URL(std::string(url));
90  fFileSystem = new FileSystem(fUrl->GetURL());
91 }
92 
93 ////////////////////////////////////////////////////////////////////////////////
94 /// Destructor
95 
97 {
98  delete fFileSystem;
99  delete fUrl;
100 }
101 
102 ////////////////////////////////////////////////////////////////////////////////
103 /// Open a directory
104 ///
105 /// param dir: the name of the directory to open
106 /// returns: a non-zero pointer (with no special purpose) in case of
107 /// success, 0 in case of error
108 
109 void* TNetXNGSystem::OpenDirectory(const char *dir)
110 {
111  using namespace XrdCl;
112 
113  DirectoryInfo *dirInfo = new DirectoryInfo(dir);
114  fDirPtrs.insert( (void*)dirInfo );
115  return (void *) dirInfo;
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Create a directory
120 ///
121 /// param dir: the directory name
122 /// returns: 0 on success, -1 otherwise
123 
125 {
126  using namespace XrdCl;
127  URL url(dir);
128  XRootDStatus st = fFileSystem->MkDir(url.GetPath(), MkDirFlags::MakePath,
129  Access::None);
130  if (!st.IsOK()) {
131  Error("MakeDirectory", "%s", st.GetErrorMessage().c_str());
132  return -1;
133  }
134 
135  return 0;
136 }
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 /// Free a directory
140 ///
141 /// param dirp: the pointer to the directory to be freed
142 
144 {
145  fDirPtrs.erase( dirp );
146  delete (DirectoryInfo *) dirp;
147 }
148 
149 ////////////////////////////////////////////////////////////////////////////////
150 /// Get a directory entry.
151 ///
152 /// param dirp: the directory pointer
153 /// returns: 0 in case there are no more entries
154 
155 const char* TNetXNGSystem::GetDirEntry(void *dirp)
156 {
157  using namespace XrdCl;
158  DirectoryInfo *dirInfo = (DirectoryInfo *) dirp;
159 
160  if (!dirInfo->fDirList) {
161  XRootDStatus st = fFileSystem->DirList(dirInfo->fUrl->GetPath(),
162  DirListFlags::Locate,
163  dirInfo->fDirList);
164  if (!st.IsOK()) {
165  Error("GetDirEntry", "%s", st.GetErrorMessage().c_str());
166  return 0;
167  }
168  dirInfo->fDirListIter = new DirectoryList::Iterator(dirInfo->fDirList->Begin());
169  }
170 
171  if (*(dirInfo->fDirListIter) != dirInfo->fDirList->End()) {
172  const char *filename = (**(dirInfo->fDirListIter))->GetName().c_str();
173  (*(dirInfo->fDirListIter))++;
174  return filename;
175 
176  } else {
177  return 0;
178  }
179 }
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 /// Get info about a file (stat)
183 ///
184 /// param path: the path of the file to stat (in)
185 /// param buf: structure that will hold the stat info (out)
186 /// returns: 0 if success, 1 if the file could not be stat'ed
187 
189 {
190  using namespace XrdCl;
191  StatInfo *info = 0;
192  URL target(path);
193  XRootDStatus st = fFileSystem->Stat(target.GetPath(), info);
194 
195  if (!st.IsOK()) {
196 
197  if (gDebug > 1) {
198  Info("GetPathInfo", "Stat error: %s", st.GetErrorMessage().c_str());
199  }
200  delete info;
201  return 1;
202 
203  } else {
204 
205  // Flag offline files
206  if (info->TestFlags(StatInfo::Offline)) {
207  buf.fMode = kS_IFOFF;
208  } else {
209  std::stringstream sstr(info->GetId());
210  Long64_t id;
211  sstr >> id;
212 
213  buf.fDev = (id >> 32);
214  buf.fIno = (id & 0x00000000FFFFFFFF);
215  buf.fUid = -1; // not available
216  buf.fGid = -1; // not available
217  buf.fIsLink = 0; // not available
218  buf.fSize = info->GetSize();
219  buf.fMtime = info->GetModTime();
220 
221  if (info->TestFlags(StatInfo::XBitSet))
222  buf.fMode = (kS_IFREG | kS_IXUSR | kS_IXGRP | kS_IXOTH);
223  if (info->GetFlags() == 0) buf.fMode = kS_IFREG;
224  if (info->TestFlags(StatInfo::IsDir)) buf.fMode = kS_IFDIR;
225  if (info->TestFlags(StatInfo::Other)) buf.fMode = kS_IFSOCK;
226  if (info->TestFlags(StatInfo::IsReadable)) buf.fMode |= kS_IRUSR;
227  if (info->TestFlags(StatInfo::IsWritable)) buf.fMode |= kS_IWUSR;
228  }
229  }
230 
231  delete info;
232  return 0;
233 }
234 
235 ////////////////////////////////////////////////////////////////////////////////
236 /// Check consistency of this helper with the one required by 'path' or
237 /// 'dirptr'
238 ///
239 /// param path: the path to check
240 /// param dirptr: the directory pointer to check
241 
242 Bool_t TNetXNGSystem::ConsistentWith(const char *path, void *dirptr)
243 {
244  using namespace XrdCl;
245 
246  if( path )
247  {
248  URL url(path);
249 
250  if( gDebug > 1 )
251  Info("ConsistentWith", "Protocol: '%s' (%s), Username: '%s' (%s), "
252  "Password: '%s' (%s), Hostname: '%s' (%s), Port: %d (%d)",
253  fUrl->GetProtocol().c_str(), url.GetProtocol().c_str(),
254  fUrl->GetUserName().c_str(), url.GetUserName().c_str(),
255  fUrl->GetPassword().c_str(), url.GetPassword().c_str(),
256  fUrl->GetHostName().c_str(), url.GetHostName().c_str(),
257  fUrl->GetPort(), url.GetPort());
258 
259  // Require match of protocol, user, password, host and port
260  if( fUrl->GetProtocol() == url.GetProtocol() &&
261  fUrl->GetUserName() == url.GetUserName() &&
262  fUrl->GetPassword() == url.GetPassword() &&
263  fUrl->GetHostName() == url.GetHostName() &&
264  fUrl->GetPort() == url.GetPort())
265  return kTRUE;
266  }
267 
268  if( dirptr )
269  return fDirPtrs.find( dirptr ) != fDirPtrs.end();
270 
271  return kFALSE;
272 }
273 
274 ////////////////////////////////////////////////////////////////////////////////
275 /// Unlink a file on the remote server
276 ///
277 /// param path: the path of the file to unlink
278 /// returns: 0 on success, -1 otherwise
279 
280 int TNetXNGSystem::Unlink(const char *path)
281 {
282  using namespace XrdCl;
283  StatInfo *info;
284  URL url(path);
285 
286  // Stat the path to find out if it's a file or a directory
287  XRootDStatus st = fFileSystem->Stat(url.GetPath(), info);
288  if (!st.IsOK()) {
289  Error("Unlink", "%s", st.GetErrorMessage().c_str());
290  return -1;
291  }
292 
293  if (info->TestFlags(StatInfo::IsDir))
294  st = fFileSystem->RmDir(url.GetPath());
295  else
296  st = fFileSystem->Rm(url.GetPath());
297  delete info;
298 
299  if (!st.IsOK()) {
300  Error("Unlink", "%s", st.GetErrorMessage().c_str());
301  return -1;
302  }
303 
304  return 0;
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 /// Is this path a local path?
309 ///
310 /// param path: the URL of the path to check
311 /// returns: kTRUE if the path is local, kFALSE otherwise
312 
314 {
315  return TSystem::IsPathLocal(path);
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 /// Get the endpoint URL of a file.
320 ///
321 /// param path: the entry-point URL of the file (in)
322 /// param endurl: the endpoint URL of the file (out)
323 /// returns: 0 in case of success and 1 if the file could not be
324 /// stat'ed.
325 
326 Int_t TNetXNGSystem::Locate(const char *path, TString &endurl)
327 {
328  using namespace XrdCl;
329  LocationInfo *info = 0;
330  URL pathUrl(path);
331 
332  // Locate the file
333  XRootDStatus st = fFileSystem->Locate(pathUrl.GetPath(), OpenFlags::None,
334  info);
335  if (!st.IsOK()) {
336  Error("Locate", "%s", st.GetErrorMessage().c_str());
337  delete info;
338  return 1;
339  }
340 
341  // Use the first endpoint address returned by the client
342  URL locUrl(info->Begin()->GetAddress());
343  TString loc = locUrl.GetHostName();
344  delete info;
345  info = 0;
346 
348 
349  // The location returned by the client library is the numeric host address
350  // without path. Try to lookup a hostname and replace the path portion of
351  // the url before returning the result.
352  TNamed *hn = 0;
353  if (fgAddrFQDN.GetSize() <= 0 ||
354  !(hn = dynamic_cast<TNamed *>(fgAddrFQDN.FindObject(loc)))) {
355  char *addr[1] = {0}, *name[1] = {0};
356  int naddr = XrdSysDNS::getAddrName(loc.Data(), 1, addr, name);
357  if (naddr == 1) {
358  hn = new TNamed(loc.Data(), name[0]);
359  } else {
360  hn = new TNamed(loc, loc);
361  }
362  fgAddrFQDN.Add(hn);
363  free(addr[0]);
364  free(name[0]);
365  if (gDebug > 0)
366  Info("Locate","caching host name: %s", hn->GetTitle());
367  }
368 
369  TUrl res(path);
370  res.SetHost(hn->GetTitle());
371  res.SetPort(locUrl.GetPort());
372  endurl = res.GetUrl();
373 
374  return 0;
375 }
376 
377 ////////////////////////////////////////////////////////////////////////////////
378 /// Issue a stage request for a single file
379 ///
380 /// param path: the path of the file to stage
381 /// param opt: defines 'option' and 'priority' for 'Prepare': the format is
382 /// opt = "option=o priority=p"
383 /// returns: 0 for success, -1 for error
384 
385 Int_t TNetXNGSystem::Stage(const char* path, UChar_t priority)
386 {
387  TList *files = new TList();
388  files->Add((TObject *) new TUrl(path));
389  return Stage((TCollection *) files, priority);
390 }
391 
392 ////////////////////////////////////////////////////////////////////////////////
393 /// Issue stage requests for multiple files
394 ///
395 /// param pathlist: list of paths of files to stage
396 /// param opt: defines 'option' and 'priority' for 'Prepare': the
397 /// format is opt = "option=o priority=p"
398 /// returns: 0 for success, -1 for error
399 
401 {
402  using namespace XrdCl;
403  std::vector<std::string> fileList;
404  TIter it(files);
405  TObject *object = 0;
406 
407  while ((object = (TObject *) it.Next())) {
408 
409  TString path = TFileStager::GetPathName(object);
410  if (path == "") {
411  Warning("Stage", "object is of unexpected type %s - ignoring",
412  object->ClassName());
413  continue;
414  }
415 
416  fileList.push_back(std::string(URL(path.Data()).GetPath()));
417  }
418 
419  Buffer *response;
420  XRootDStatus st = fFileSystem->Prepare(fileList, PrepareFlags::Stage,
421  (uint8_t) priority, response);
422  if (!st.IsOK()) {
423  Error("Stage", "%s", st.GetErrorMessage().c_str());
424  return -1;
425  }
426 
427  return 0;
428 }
429 
std::set< void * > fDirPtrs
Definition: TNetXNGSystem.h:39
virtual Int_t MakeDirectory(const char *dir)
Create a directory.
Definition: TMutex.h:30
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:847
static TString GetPathName(TObject *o)
Return the path name contained in object &#39;o&#39; allowing for TUrl, TObjString or TFileInfo.
virtual Bool_t IsPathLocal(const char *path)
Returns TRUE if the url in &#39;path&#39; points to the local file system.
Definition: TSystem.cxx:1281
long long Long64_t
Definition: RtypesCore.h:69
virtual Bool_t IsPathLocal(const char *path)
Is this path a local path?
This class represents a WWW compatible URL.
Definition: TUrl.h:35
Int_t fUid
Definition: TSystem.h:129
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
virtual Int_t Stage(const char *path, UChar_t priority)
Issue a stage request for a single file.
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Long_t fMtime
Definition: TSystem.h:132
TNetXNGSystem(Bool_t owner=kTRUE)
Constructor: Create system class without connecting to server.
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:213
virtual Bool_t ConsistentWith(const char *path, void *dirptr)
Check consistency of this helper with the one required by &#39;path&#39; or &#39;dirptr&#39;.
Long64_t fSize
Definition: TSystem.h:131
Int_t fMode
Definition: TSystem.h:128
XrdCl::URL * fUrl
Definition: TNetXNGSystem.h:44
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:135
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
static TMutex fgAddrMutex
Definition: TNetXNGSystem.h:41
Int_t fGid
Definition: TSystem.h:130
virtual int Unlink(const char *path)
Unlink a file on the remote server.
A doubly linked list.
Definition: TList.h:43
#define None
Definition: TGWin32.h:55
Bool_t fIsLink
Definition: TSystem.h:133
TObject * Next()
Definition: TCollection.h:153
Collection abstract base class.
Definition: TCollection.h:42
TSystem * ROOT_Plugin_TNetXNGSystem(const char *url, Bool_t owner)
PluginManager creation function.
virtual const char * GetDirEntry(void *dirp)
Get a directory entry.
virtual void FreeDirectory(void *dirp)
Free a directory.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:873
virtual ~TNetXNGSystem()
Destructor.
const Bool_t kFALSE
Definition: RtypesCore.h:92
#define ClassImp(name)
Definition: Rtypes.h:336
virtual Int_t GetPathInfo(const char *path, FileStat_t &buf)
Get info about a file (stat)
TNamed()
Definition: TNamed.h:36
#define free
Definition: civetweb.c:821
#define R__LOCKGUARD(mutex)
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void Add(TObject *obj)
Definition: TList.h:77
static THashList fgAddrFQDN
Definition: TNetXNGSystem.h:40
Long_t fIno
Definition: TSystem.h:127
R__EXTERN Int_t gDebug
Definition: Rtypes.h:83
virtual void * OpenDirectory(const char *dir)
Open a directory.
unsigned char UChar_t
Definition: RtypesCore.h:34
Long_t fDev
Definition: TSystem.h:126
virtual Int_t GetSize() const
Definition: TCollection.h:89
Abstract base class defining a generic interface to the underlying Operating System.
Definition: TSystem.h:248
const Bool_t kTRUE
Definition: RtypesCore.h:91
XrdCl::FileSystem * fFileSystem
Definition: TNetXNGSystem.h:45
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:859
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual Int_t Locate(const char *path, TString &endurl)
Get the endpoint URL of a file.