ROOT  6.06/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  delete info;
291  return -1;
292  }
293 
294  if (info->TestFlags(StatInfo::IsDir))
295  st = fFileSystem->RmDir(url.GetPath());
296  else
297  st = fFileSystem->Rm(url.GetPath());
298  delete info;
299 
300  if (!st.IsOK()) {
301  Error("Unlink", "%s", st.GetErrorMessage().c_str());
302  return -1;
303  }
304 
305  return 0;
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 /// Is this path a local path?
310 ///
311 /// param path: the URL of the path to check
312 /// returns: kTRUE if the path is local, kFALSE otherwise
313 
315 {
316  return TSystem::IsPathLocal(path);
317 }
318 
319 ////////////////////////////////////////////////////////////////////////////////
320 /// Get the endpoint URL of a file.
321 ///
322 /// param path: the entry-point URL of the file (in)
323 /// param endurl: the endpoint URL of the file (out)
324 /// returns: 0 in case of success and 1 if the file could not be
325 /// stat'ed.
326 
327 Int_t TNetXNGSystem::Locate(const char *path, TString &endurl)
328 {
329  using namespace XrdCl;
330  LocationInfo *info = 0;
331  URL pathUrl(path);
332 
333  // Locate the file
334  XRootDStatus st = fFileSystem->Locate(pathUrl.GetPath(), OpenFlags::None,
335  info);
336  if (!st.IsOK()) {
337  Error("Locate", "%s", st.GetErrorMessage().c_str());
338  delete info;
339  return 1;
340  }
341 
342  // Use the first endpoint address returned by the client
343  URL locUrl(info->Begin()->GetAddress());
344  TString loc = locUrl.GetHostName();
345  delete info;
346  info = 0;
347 
349 
350  // The location returned by the client library is the numeric host address
351  // without path. Try to lookup a hostname and replace the path portion of
352  // the url before returning the result.
353  TNamed *hn = 0;
354  if (fgAddrFQDN.GetSize() <= 0 ||
355  !(hn = dynamic_cast<TNamed *>(fgAddrFQDN.FindObject(loc)))) {
356  char *addr[1] = {0}, *name[1] = {0};
357  int naddr = XrdSysDNS::getAddrName(loc.Data(), 1, addr, name);
358  if (naddr == 1) {
359  hn = new TNamed(loc.Data(), name[0]);
360  } else {
361  hn = new TNamed(loc, loc);
362  }
363  fgAddrFQDN.Add(hn);
364  free(addr[0]);
365  free(name[0]);
366  if (gDebug > 0)
367  Info("Locate","caching host name: %s", hn->GetTitle());
368  }
369 
370  TUrl res(path);
371  res.SetHost(hn->GetTitle());
372  res.SetPort(locUrl.GetPort());
373  endurl = res.GetUrl();
374 
375  return 0;
376 }
377 
378 ////////////////////////////////////////////////////////////////////////////////
379 /// Issue a stage request for a single file
380 ///
381 /// param path: the path of the file to stage
382 /// param opt: defines 'option' and 'priority' for 'Prepare': the format is
383 /// opt = "option=o priority=p"
384 /// returns: 0 for success, -1 for error
385 
386 Int_t TNetXNGSystem::Stage(const char* path, UChar_t priority)
387 {
388  TList *files = new TList();
389  files->Add((TObject *) new TUrl(path));
390  return Stage((TCollection *) files, priority);
391 }
392 
393 ////////////////////////////////////////////////////////////////////////////////
394 /// Issue stage requests for multiple files
395 ///
396 /// param pathlist: list of paths of files to stage
397 /// param opt: defines 'option' and 'priority' for 'Prepare': the
398 /// format is opt = "option=o priority=p"
399 /// returns: 0 for success, -1 for error
400 
402 {
403  using namespace XrdCl;
404  std::vector<std::string> fileList;
405  TIter it(files);
406  TObject *object = 0;
407 
408  while ((object = (TObject *) it.Next())) {
409 
410  TString path = TFileStager::GetPathName(object);
411  if (path == "") {
412  Warning("Stage", "object is of unexpected type %s - ignoring",
413  object->ClassName());
414  continue;
415  }
416 
417  fileList.push_back(std::string(URL(path.Data()).GetPath()));
418  }
419 
420  Buffer *response;
421  XRootDStatus st = fFileSystem->Prepare(fileList, PrepareFlags::Stage,
422  (uint8_t) priority, response);
423  if (!st.IsOK()) {
424  Error("Stage", "%s", st.GetErrorMessage().c_str());
425  return -1;
426  }
427 
428  return 0;
429 }
430 
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
std::set< void * > fDirPtrs
Definition: TNetXNGSystem.h:39
virtual Int_t MakeDirectory(const char *dir)
Create a directory.
Definition: TMutex.h:37
void SetPort(Int_t port)
Definition: TUrl.h:97
static TString GetPathName(TObject *o)
Return the path name contained in object 'o' allowing for TUrl, TObjString or TFileInfo.
virtual Bool_t IsPathLocal(const char *path)
Returns TRUE if the url in 'path' points to the local file system.
Definition: TSystem.cxx:1274
long long Long64_t
Definition: RtypesCore.h:69
virtual Bool_t IsPathLocal(const char *path)
Is this path a local path?
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:212
This class represents a WWW compatible URL.
Definition: TUrl.h:41
Int_t fUid
Definition: TSystem.h:139
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
virtual Int_t Stage(const char *path, UChar_t priority)
Issue a stage request for a single file.
static const char * filename()
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
Long_t fMtime
Definition: TSystem.h:142
TNetXNGSystem(Bool_t owner=kTRUE)
Constructor: Create system class without connecting to server.
virtual Bool_t ConsistentWith(const char *path, void *dirptr)
Check consistency of this helper with the one required by 'path' or 'dirptr'.
Long64_t fSize
Definition: TSystem.h:141
Int_t fMode
Definition: TSystem.h:138
const char * Data() const
Definition: TString.h:349
XrdCl::URL * fUrl
Definition: TNetXNGSystem.h:44
Vc_ALWAYS_INLINE void free(T *p)
Frees memory that was allocated with Vc::malloc.
Definition: memory.h:94
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:36
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
ClassImp(TNetXNGSystem)
if(pyself &&pyself!=Py_None)
static TMutex fgAddrMutex
Definition: TNetXNGSystem.h:41
XFontStruct * id
Definition: TGX11.cxx:108
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Int_t fGid
Definition: TSystem.h:140
virtual int Unlink(const char *path)
Unlink a file on the remote server.
A doubly linked list.
Definition: TList.h:47
#define None
Definition: TGWin32.h:68
Bool_t fIsLink
Definition: TSystem.h:143
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
TObject * Next()
Definition: TCollection.h:158
Collection abstract base class.
Definition: TCollection.h:48
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 ~TNetXNGSystem()
Destructor.
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:385
void SetHost(const char *host)
Definition: TUrl.h:93
virtual Int_t GetSize() const
Definition: TCollection.h:95
virtual Int_t GetPathInfo(const char *path, FileStat_t &buf)
Get info about a file (stat)
TNamed()
Definition: TNamed.h:40
#define R__LOCKGUARD(mutex)
#define name(a, b)
Definition: linkTestLib0.cpp:5
Mother of all ROOT objects.
Definition: TObject.h:58
virtual void Add(TObject *obj)
Definition: TList.h:81
static THashList fgAddrFQDN
Definition: TNetXNGSystem.h:40
Long_t fIno
Definition: TSystem.h:137
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
virtual void * OpenDirectory(const char *dir)
Open a directory.
unsigned char UChar_t
Definition: RtypesCore.h:34
Long_t fDev
Definition: TSystem.h:136
Abstract base class defining a generic interface to the underlying Operating System.
Definition: TSystem.h:258
const Bool_t kTRUE
Definition: Rtypes.h:91
XrdCl::FileSystem * fFileSystem
Definition: TNetXNGSystem.h:45
virtual Int_t Locate(const char *path, TString &endurl)
Get the endpoint URL of a file.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904