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