XRootD
Loading...
Searching...
No Matches
XrdClFileSystem.cc
Go to the documentation of this file.
1//------------------------------------------------------------------------------
2// Copyright (c) 2011-2014 by European Organization for Nuclear Research (CERN)
3// Author: Lukasz Janyst <ljanyst@cern.ch>
4//------------------------------------------------------------------------------
5// This file is part of the XRootD software suite.
6//
7// XRootD is free software: you can redistribute it and/or modify
8// it under the terms of the GNU Lesser General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// XRootD is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU Lesser General Public License
18// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
19//
20// In applying this licence, CERN does not waive the privileges and immunities
21// granted to it by virtue of its status as an Intergovernmental Organization
22// or submit itself to any jurisdiction.
23//------------------------------------------------------------------------------
24
28#include "XrdCl/XrdClLog.hh"
30#include "XrdCl/XrdClMessage.hh"
39#include "XrdSys/XrdSysE2T.hh"
41
42#include <sys/stat.h>
43
44#include <memory>
45#include <algorithm>
46#include <iterator>
47
48namespace
49{
50
51 class LocalFS
52 {
53 public:
54
55 XrdCl::XRootDStatus Stat( const std::string &path,
57 uint16_t timeout )
58 {
59 using namespace XrdCl;
60
61 Log *log = DefaultEnv::GetLog();
62
63 struct stat ssp;
64 if( stat( path.c_str(), &ssp ) == -1 )
65 {
66 log->Error( FileMsg, "Stat: failed: %s", XrdSysE2T( errno ) );
67 XRootDStatus *error = new XRootDStatus( stError, errLocalError,
68 XProtocol::mapError( errno ) );
69 return QueueTask( error, 0, handler );
70 }
71
72 // TODO support other mode options
73 uint32_t flags = S_ISDIR( ssp.st_mode ) ? kXR_isDir : 0;
74
75 std::ostringstream data;
76 data << ssp.st_dev << " " << ssp.st_size << " " << flags << " "
77 << ssp.st_mtime;
78 log->Debug( FileMsg, data.str().c_str() );
79
80 StatInfo *statInfo = new StatInfo();
81 if( !statInfo->ParseServerResponse( data.str().c_str() ) )
82 {
83 log->Error( FileMsg, "Stat: ParseServerResponse failed." );
84 delete statInfo;
85 return QueueTask( new XRootDStatus( stError, errErrorResponse, kXR_FSError ),
86 0, handler );
87 }
88
89 AnyObject *resp = new AnyObject();
90 resp->Set( statInfo );
91 return QueueTask( new XRootDStatus(), resp, handler );
92 }
93
94 XrdCl::XRootDStatus Rm( const std::string &path,
96 uint16_t timeout )
97 {
98 using namespace XrdCl;
99
100 Log *log = DefaultEnv::GetLog();
101 if( unlink( path.c_str() ) )
102 {
103 log->Error( FileMsg, "Rm: failed: %s", XrdSysE2T( errno ) );
104 XRootDStatus *error = new XRootDStatus( stError, errLocalError,
105 XProtocol::mapError( errno ) );
106 return QueueTask( error, 0, handler );
107 }
108
109 return QueueTask( new XRootDStatus(), 0, handler );
110 }
111
112 static LocalFS& Instance()
113 {
114 static LocalFS instance;
115 return instance;
116 }
117
118 private:
119
120 //------------------------------------------------------------------------
121 // Private constructors
122 //------------------------------------------------------------------------
123 LocalFS() : jmngr( XrdCl::DefaultEnv::GetPostMaster()->GetJobManager() )
124 {
125
126 }
127
128 //------------------------------------------------------------------------
129 // Private copy constructors
130 //------------------------------------------------------------------------
131 LocalFS( const LocalFS& );
132
133 //------------------------------------------------------------------------
134 // Private assignment operator
135 //------------------------------------------------------------------------
136 LocalFS& operator=( const LocalFS& );
137
138 //------------------------------------------------------------------------
139 // QueueTask - queues error/success tasks for all operations.
140 // Must always return stOK.
141 // Is always creating the same HostList containing only localhost.
142 //------------------------------------------------------------------------
144 XrdCl::ResponseHandler *handler )
145 {
146 using namespace XrdCl;
147
148 // if it is simply the sync handler we can release the semaphore
149 // and return there is no need to execute this in the thread-pool
150 SyncResponseHandler *syncHandler =
151 dynamic_cast<SyncResponseHandler*>( handler );
152 if( syncHandler )
153 {
154 syncHandler->HandleResponse( st, resp );
155 return XRootDStatus();
156 }
157
158 LocalFileTask *task = new LocalFileTask( st, resp, 0, handler );
159 jmngr->QueueJob( task );
160 return XRootDStatus();
161 }
162
163 XrdCl::JobManager *jmngr;
164
165 };
166
167 //----------------------------------------------------------------------------
168 // Get delimiter for the opaque info
169 //----------------------------------------------------------------------------
170 char GetCgiDelimiter( bool &hasCgi )
171 {
172 if( !hasCgi )
173 {
174 hasCgi = true;
175 return '?';
176 }
177
178 return '&';
179 }
180 //----------------------------------------------------------------------------
181 // Filters out client specific CGI
182 //----------------------------------------------------------------------------
183 std::string FilterXrdClCgi( const std::string &path )
184 {
185 // first check if there's an opaque info at all
186 size_t pos = path.find( '?' );
187 if( pos == std::string::npos )
188 return path;
189
190 std::string filteredPath = path.substr( 0 , pos );
191 std::string cgi = path.substr( pos + 1 );
192
193 bool hasCgi = false;
194 pos = 0;
195 size_t xrdcl = std::string::npos;
196 do
197 {
198 xrdcl = cgi.find( "xrdcl.", pos );
199
200 if( xrdcl == std::string:: npos )
201 {
202 filteredPath += GetCgiDelimiter( hasCgi );
203 filteredPath += cgi.substr( pos );
204 pos = cgi.size();
205 }
206 else
207 {
208 if( xrdcl != pos )
209 {
210 filteredPath += GetCgiDelimiter( hasCgi );
211 filteredPath += cgi.substr( pos, xrdcl - 1 - pos );
212 }
213
214 pos = cgi.find( '&', xrdcl );
215 if( pos != std::string::npos )
216 ++pos;
217 }
218
219 }
220 while( pos < cgi.size() && pos != std::string::npos );
221
222 return filteredPath;
223 }
224
225 //----------------------------------------------------------------------------
227 //----------------------------------------------------------------------------
228 class DeallocFSHandler: public XrdCl::ResponseHandler
229 {
230 public:
231 //------------------------------------------------------------------------
232 // Constructor and destructor
233 //------------------------------------------------------------------------
234 DeallocFSHandler( XrdCl::FileSystem *fs, ResponseHandler *userHandler ):
235 pFS(fs), pUserHandler(userHandler) {}
236
237 virtual ~DeallocFSHandler()
238 {
239 delete pFS;
240 }
241
242 //------------------------------------------------------------------------
243 // Handle the response
244 //------------------------------------------------------------------------
245 virtual void HandleResponse( XrdCl::XRootDStatus *status,
246 XrdCl::AnyObject *response )
247 {
248 pUserHandler->HandleResponse(status, response);
249 delete this;
250 }
251
252 private:
254 ResponseHandler *pUserHandler;
255 };
256
257 //----------------------------------------------------------------------------
258 // Deep locate handler
259 //----------------------------------------------------------------------------
260 class DeepLocateHandler: public XrdCl::ResponseHandler
261 {
262 public:
263 //------------------------------------------------------------------------
264 // Constructor
265 //------------------------------------------------------------------------
266 DeepLocateHandler( XrdCl::ResponseHandler *handler,
267 const std::string &path,
269 time_t timeout ):
270 pFirstTime( true ),
271 pPartial( false ),
272 pOutstanding( 1 ),
273 pHandler( handler ),
274 pPath( path ),
275 pFlags( flags )
276 {
277 if (timeout == 0) {
279 XrdCl::DefaultEnv::GetEnv()->GetInt("RequestTimeout", val);
280 timeout = val;
281 }
282
283 pExpires = ::time(nullptr) + timeout;
284 pLocations = new XrdCl::LocationInfo();
285 }
286
287 //------------------------------------------------------------------------
288 // Destructor
289 //------------------------------------------------------------------------
290 ~DeepLocateHandler()
291 {
292 delete pLocations;
293 }
294
295 //------------------------------------------------------------------------
296 // Handle the response
297 //------------------------------------------------------------------------
298 virtual void HandleResponse( XrdCl::XRootDStatus *status,
299 XrdCl::AnyObject *response )
300 {
301 XrdSysMutexHelper scopedLock( pMutex );
302 using namespace XrdCl;
303 Log *log = DefaultEnv::GetLog();
304 --pOutstanding;
305
306 //----------------------------------------------------------------------
307 // We've got an error, react accordingly
308 //----------------------------------------------------------------------
309 if( !status->IsOK() )
310 {
311 log->Dump( FileSystemMsg, "[0x%x@DeepLocate(%s)] Got error "
312 "response: %s", this, pPath.c_str(),
313 status->ToStr().c_str() );
314
315 //--------------------------------------------------------------------
316 // We have failed with the first request
317 //--------------------------------------------------------------------
318 if( pFirstTime )
319 {
320 log->Debug( FileSystemMsg, "[0x%x@DeepLocate(%s)] Failed to get "
321 "the initial location list: %s", this, pPath.c_str(),
322 status->ToStr().c_str() );
323 pHandler->HandleResponse( status, response );
324 scopedLock.UnLock();
325 delete this;
326 return;
327 }
328
329 pPartial = true;
330
331 //--------------------------------------------------------------------
332 // We have no more outstanding requests, so let give to the client
333 // what we have
334 //--------------------------------------------------------------------
335 if( !pOutstanding )
336 {
337 log->Debug( FileSystemMsg, "[0x%x@DeepLocate(%s)] No outstanding "
338 "requests, give out what we've got", this,
339 pPath.c_str() );
340 scopedLock.UnLock();
341 HandleFinalResponse();
342 }
343 delete status;
344 return;
345 }
346 pFirstTime = false;
347
348 //----------------------------------------------------------------------
349 // Extract the answer
350 //----------------------------------------------------------------------
351 LocationInfo *info = 0;
352 response->Get( info );
354
355 log->Dump( FileSystemMsg, "[0x%x@DeepLocate(%s)] Got %d locations",
356 this, pPath.c_str(), info->GetSize() );
357
358 for( it = info->Begin(); it != info->End(); ++it )
359 {
360 //--------------------------------------------------------------------
361 // Add the location to the list
362 //--------------------------------------------------------------------
363 if( it->IsServer() )
364 {
365 pLocations->Add( *it );
366 continue;
367 }
368
369 //--------------------------------------------------------------------
370 // Ask the manager for the location of servers
371 //--------------------------------------------------------------------
372 if( it->IsManager() )
373 {
374 ++pOutstanding;
375 FileSystem *fs = new FileSystem( it->GetAddress() );
376 if( pOutstanding == 0 || // protect against overflow, short circuiting
377 // will make sure the other part won't be executed
378 !fs->Locate( pPath, pFlags, new DeallocFSHandler(fs, this),
379 pExpires-::time(0)).IsOK() )
380 {
381 --pOutstanding;
382 pPartial = true;
383 delete fs;
384 }
385 }
386 }
387
388 //----------------------------------------------------------------------
389 // Clean up and check if we have anything else to do
390 //----------------------------------------------------------------------
391 delete response;
392 delete status;
393 if( !pOutstanding )
394 {
395 scopedLock.UnLock();
396 HandleFinalResponse();
397 }
398 }
399
400 //------------------------------------------------------------------------
401 // Build the response for the client
402 //------------------------------------------------------------------------
403 void HandleFinalResponse()
404 {
405 using namespace XrdCl;
406
407 //----------------------------------------------------------------------
408 // Nothing found
409 //----------------------------------------------------------------------
410 if( !pLocations->GetSize() )
411 {
412 pHandler->HandleResponse( new XRootDStatus( stError, errErrorResponse,
414 "No valid location found" ),
415 0 );
416 }
417 //----------------------------------------------------------------------
418 // We return an answer
419 //----------------------------------------------------------------------
420 else
421 {
422 AnyObject *obj = new AnyObject();
423 obj->Set( pLocations );
424 pLocations = 0;
425 XRootDStatus *st = new XRootDStatus();
426 if( pPartial ) st->code = suPartial;
427 pHandler->HandleResponse( st, obj );
428 }
429 delete this;
430 }
431
432 private:
433 bool pFirstTime;
434 bool pPartial;
435 uint16_t pOutstanding;
436 XrdCl::ResponseHandler *pHandler;
437 XrdCl::LocationInfo *pLocations;
438 std::string pPath;
440 time_t pExpires;
441 XrdSysMutex pMutex;
442 };
443
444 //----------------------------------------------------------------------------
445 // Handle stat results for a dirlist request
446 //----------------------------------------------------------------------------
447 class DirListStatHandler: public XrdCl::ResponseHandler
448 {
449 public:
450 //------------------------------------------------------------------------
451 // Constructor
452 //------------------------------------------------------------------------
453 DirListStatHandler( XrdCl::DirectoryList *list,
454 uint32_t index,
455 XrdCl::RequestSync *sync ):
456 pList( list ),
457 pIndex( index ),
458 pSync( sync )
459 {
460 }
461
462 //------------------------------------------------------------------------
463 // Check if we were successful and if so put the StatInfo object
464 // in the appropriate entry info
465 //------------------------------------------------------------------------
466 virtual void HandleResponse( XrdCl::XRootDStatus *status,
467 XrdCl::AnyObject *response )
468 {
469 if( !status->IsOK() )
470 {
471 delete status;
472 pSync->TaskDone( false );
473 delete this;
474 return;
475 }
476
477 XrdCl::StatInfo *info = 0;
478 response->Get( info );
479 response->Set( (char*) 0 );
480 pList->At( pIndex )->SetStatInfo( info );
481 delete status;
482 delete response;
483 pSync->TaskDone();
484 delete this;
485 }
486
487 private:
489 uint32_t pIndex;
490 XrdCl::RequestSync *pSync;
491 };
492
493 //----------------------------------------------------------------------------
494 // Recursive dirlist common context for all handlers
495 //----------------------------------------------------------------------------
496 struct RecursiveDirListCtx
497 {
498 RecursiveDirListCtx( const XrdCl::URL &url, const std::string &path,
500 XrdCl::ResponseHandler *handler, time_t expires ) :
501 finalst( 0 ), pending( 1 ),
502 dirList( new XrdCl::DirectoryList() ), expires( expires ),
503 handler( handler ), flags( flags ),
504 fs( new XrdCl::FileSystem( url ) )
505 {
506 dirList->SetParentName( path );
507 }
508
509 ~RecursiveDirListCtx()
510 {
511 delete finalst;
512 delete dirList;
513 delete fs;
514 }
515
516 void UpdateStatus( const XrdCl::XRootDStatus &st )
517 {
518 using namespace XrdCl;
519
520 if( !finalst )
521 {
522 finalst = st.IsOK() ? new XRootDStatus() : new XRootDStatus( st );
523 return;
524 }
525
526 // if they disagree set the status to partial
527 if( ( finalst->IsOK() && !st.IsOK() ) ||
528 ( !finalst->IsOK() && st.IsOK() ) )
529 *finalst = XRootDStatus( stOK, suPartial );
530 }
531
532 XrdCl::XRootDStatus *finalst;
533 int pending;
534 XrdCl::DirectoryList *dirList;
535 time_t expires;
536 XrdCl::ResponseHandler *handler;
539 XrdSysMutex mtx;
540 };
541
542 //----------------------------------------------------------------------------
543 // Handle results for a recursive dirlist request
544 //----------------------------------------------------------------------------
545 class RecursiveDirListHandler: public XrdCl::ResponseHandler
546 {
547 public:
548
549 RecursiveDirListHandler( const XrdCl::URL &url,
550 const std::string &path,
552 XrdCl::ResponseHandler *handler,
553 time_t timeout )
554 {
555 time_t expires = 0;
556 if( timeout )
557 expires = ::time( 0 ) + timeout;
558 pCtx = new RecursiveDirListCtx( url, path, flags,
559 handler, expires );
560 }
561
562 RecursiveDirListHandler( RecursiveDirListCtx *ctx ) : pCtx( ctx )
563 {
564
565 }
566
567 virtual void HandleResponse( XrdCl::XRootDStatus *status,
568 XrdCl::AnyObject *response )
569 {
570 using namespace XrdCl;
571
572 Log *log = DefaultEnv::GetLog();
573 bool finalrsp = !( status->IsOK() && status->code == XrdCl::suContinue );
574 XrdSysMutexHelper scoped( pCtx->mtx );
575
576 // check if we have to continue with the same handler (the response
577 // has been chunked), if not we can decrement the number of pending
578 // DieLists
579 if( finalrsp )
580 --pCtx->pending;
581
582 pCtx->UpdateStatus( *status );
583
584 if( status->IsOK() )
585 {
586 // get the response
587 DirectoryList *dirList = 0;
588 response->Get( dirList );
589
590 std::string parent = pCtx->dirList->GetParentName();
591
593 for( itr = dirList->Begin(); itr != dirList->End(); ++itr )
594 {
595 DirectoryList::ListEntry *entry = *itr;
596 StatInfo *info = entry->GetStatInfo();
597 if( !info )
598 {
599 log->Error( FileMsg, "Recursive directory list operation for %s failed: "
600 "kXR_dirlist with stat operation not supported.",
601 parent.c_str() );
602 pCtx->UpdateStatus( XRootDStatus( stError, errNotSupported ) );
603 continue;
604 }
605 std::string path = dirList->GetParentName() + entry->GetName();
606
607 // add new entry to the result
608 path = path.substr( parent.size() );
609 entry->SetStatInfo( 0 ); // StatInfo is no longer owned by dirList
611 new DirectoryList::ListEntry( entry->GetHostAddress(), path, info );
612 pCtx->dirList->Add( e );
613
614 // if it's a directory do a recursive call
615 if( info->TestFlags( StatInfo::IsDir ) )
616 {
617 // bump the pending counter
618 ++pCtx->pending;
619 // switch of the recursive flag, we will
620 // provide the respective handler ourself,
621 // make sure that stat is on
622 DirListFlags::Flags flags = ( pCtx->flags & (~DirListFlags::Recursive) )
623 | DirListFlags::Stat;
624 // the recursive dir list handler
625 RecursiveDirListHandler *handler = new RecursiveDirListHandler( pCtx );
626 // timeout
627 time_t timeout = 0;
628 if( pCtx->expires )
629 {
630 timeout = pCtx->expires - ::time( 0 );
631 if( timeout <= 0 )
632 {
633 log->Error( FileMsg, "Recursive directory list operation for %s expired.",
634 parent.c_str() );
635 pCtx->UpdateStatus( XRootDStatus( stError, errOperationExpired ) );
636 break;
637 }
638 }
639 // send the request
640 std::string child = parent + path;
641 XRootDStatus st = pCtx->fs->DirList( child, flags, handler, timeout );
642 if( !st.IsOK() )
643 {
644 log->Error( FileMsg, "Recursive directory list operation for %s failed: ",
645 child.c_str(), st.ToString().c_str() );
646 pCtx->UpdateStatus( st );
647 continue;
648 }
649 }
650 }
651 }
652
653 // if there are no more outstanding dirlist queries we can finalize the request
654 if( pCtx->pending == 0 )
655 {
656 AnyObject *resp = new AnyObject();
657 resp->Set( pCtx->dirList );
658 pCtx->dirList = 0; // dirList is no longer owned by pCtx
659 pCtx->handler->HandleResponse( pCtx->finalst, resp );
660 pCtx->finalst = 0; // status is no longer owned by pCtx
661
662 // finalize the common context
663 scoped.UnLock();
664 delete pCtx;
665 }
666 // if the user requested chunked response we give what we have to the user handler
667 else if( status->IsOK() && ( pCtx->flags & DirListFlags::Chunked ) )
668 {
669 std::string parent = pCtx->dirList->GetParentName();
670 AnyObject *resp = new AnyObject();
671 resp->Set( pCtx->dirList );
672 pCtx->dirList = new XrdCl::DirectoryList();
673 pCtx->dirList->SetParentName( parent );
674 pCtx->handler->HandleResponse( new XRootDStatus( stOK, suContinue ), resp );
675 }
676
677 // clean up the arguments
678 delete status;
679 delete response;
680 // if we won't be continuing with the same handler, it can be deleted
681 if( finalrsp )
682 delete this;
683 }
684
685 private:
686
687 RecursiveDirListCtx *pCtx;
688 };
689
690 //----------------------------------------------------------------------------
691 // Exception for a merge dirlist handler
692 //----------------------------------------------------------------------------
693 struct MergeDirLsErr
694 {
695 MergeDirLsErr( XrdCl::XRootDStatus *&status, XrdCl::AnyObject *&response ) :
696 status( status ), response( response )
697 {
698 status = 0; response = 0;
699 }
700
701 MergeDirLsErr() :
702 status( new XrdCl::XRootDStatus( XrdCl::stError, XrdCl::errInternal ) ),
703 response( 0 )
704 {
705
706 }
707
708 XrdCl::XRootDStatus *status;
709 XrdCl::AnyObject *response;
710 };
711
712
713
714 //----------------------------------------------------------------------------
715 // Handle results for a merge dirlist request
716 //----------------------------------------------------------------------------
717 class MergeDirListHandler: public XrdCl::ResponseHandler
718 {
719 public:
720
721 MergeDirListHandler( bool allowChunked, XrdCl::ResponseHandler *handler ) :
722 allowChunked( allowChunked ), pHandler( handler )
723 {
724
725 }
726
727 virtual void HandleResponse( XrdCl::XRootDStatus *status,
728 XrdCl::AnyObject *response )
729 {
730 XrdSysMutexHelper lck( mtx );
731
732 bool finalrsp = !( status->IsOK() && status->code == XrdCl::suContinue );
733
734 try
735 {
736 if( !status->IsOK() )
737 throw MergeDirLsErr( status, response );
738
739 if( !response )
740 throw MergeDirLsErr();
741
742 XrdCl::DirectoryList *dirlist = 0;
743 response->Get( dirlist );
744
745 if( !dirlist )
746 throw MergeDirLsErr();
747
748 if( allowChunked )
749 MergeChunked( dirlist );
750 else
751 Merge( dirlist );
752
753 response->Set( dirlist );
754 pHandler->HandleResponse( status, response );
755 }
756 catch( const MergeDirLsErr &err )
757 {
758 delete status; delete response;
759 pHandler->HandleResponse( err.status, err.response );
760 }
761
762 if( finalrsp )
763 {
764 lck.UnLock();
765 delete this;
766 }
767 }
768
769 void MergeChunked( XrdCl::DirectoryList *&response )
770 {
771 using namespace XrdCl;
772
773 std::set<ListEntry*, less> unique;
774 // set of unique list entries from the response
775 std::set<ListEntry*, less> tmp( response->Begin(), response->End() );
776 // all the unique list entries that were not reported so far
777 std::set_difference( tmp.begin(), tmp.end(),
778 uniquesofar.begin(), uniquesofar.end(),
779 std::inserter( unique, unique.end() ) );
780
781 // we update the set of unique list entries that were already
782 // reported to the user's handler
783 for( auto itr = unique.begin(); itr != unique.end(); ++itr )
784 {
785 ListEntry *ent = *itr;
786 if( !uniquesofar.count( ent ) )
787 {
788 StatInfo *info = ent->GetStatInfo() ? new StatInfo( *ent->GetStatInfo() ) : 0;
789 ListEntry *newent = new ListEntry( ent->GetHostAddress(), ent->GetName(), info );
790 uniquesofar.insert( newent );
791 }
792 }
793
794 DirectoryList *dirlist = new DirectoryList();
795 dirlist->SetParentName( response->GetParentName() );
796 for( auto itr = unique.begin(); itr != unique.end(); ++itr )
797 {
798 ListEntry *entry = *itr;
799 dirlist->Add( new ListEntry( entry->GetHostAddress(),
800 entry->GetName(),
801 entry->GetStatInfo() ) );
802 entry->SetStatInfo( 0 );
803 }
804
805 delete response;
806 response = dirlist;
807 }
808
809 static void Merge( XrdCl::DirectoryList *&response )
810 {
811 std::set<ListEntry*, less> unique( response->Begin(), response->End() );
812
814 dirlist->SetParentName( response->GetParentName() );
815 for( auto itr = unique.begin(); itr != unique.end(); ++itr )
816 {
817 ListEntry *entry = *itr;
818 dirlist->Add( new ListEntry( entry->GetHostAddress(),
819 entry->GetName(),
820 entry->GetStatInfo() ) );
821 entry->SetStatInfo( 0 );
822 }
823
824 delete response;
825 response = dirlist;
826}
827
828 private:
829
830 typedef XrdCl::DirectoryList::ListEntry ListEntry;
831
832 struct less
833 {
834 bool operator() (const ListEntry *x, const ListEntry *y) const
835 {
836 if( x->GetName() != y->GetName() )
837 return x->GetName() < y->GetName();
838
839 const XrdCl::StatInfo *xStatInfo = x->GetStatInfo();
840 const XrdCl::StatInfo *yStatInfo = y->GetStatInfo();
841
842 if( xStatInfo == yStatInfo )
843 return false;
844
845 if( xStatInfo == 0 )
846 return true;
847
848 if( yStatInfo == 0 )
849 return false;
850
851 if( xStatInfo->GetSize() != yStatInfo->GetSize() )
852 return xStatInfo->GetSize() < yStatInfo->GetSize();
853
854 if( xStatInfo->GetFlags() != yStatInfo->GetFlags() )
855 return xStatInfo->GetFlags() < yStatInfo->GetFlags();
856
857 return false;
858 }
859 };
860
861 bool allowChunked;
862 XrdSysMutex mtx;
863 std::set<ListEntry*, less> uniquesofar;
864 XrdCl::ResponseHandler *pHandler;
865 };
866}
867
868namespace XrdCl
869{
870 struct FileSystemData;
871
872 //----------------------------------------------------------------------------
874 //----------------------------------------------------------------------------
876 {
877 public:
878 //------------------------------------------------------------------------
879 // Constructor and destructor
880 //------------------------------------------------------------------------
881 AssignLBHandler( std::shared_ptr<FileSystemData> &fs,
882 ResponseHandler *userHandler ):
883 pFS(fs), pUserHandler(userHandler) {}
884
885 virtual ~AssignLBHandler() {}
886
887 //------------------------------------------------------------------------
888 // Response callback
889 //------------------------------------------------------------------------
890 virtual void HandleResponseWithHosts( XRootDStatus *status,
891 AnyObject *response,
892 HostList *hostList );
893
894 private:
895 std::shared_ptr<FileSystemData> pFS;
896 ResponseHandler *pUserHandler;
897 };
898
899 //----------------------------------------------------------------------------
901 //----------------------------------------------------------------------------
903 {
904 public:
905 //------------------------------------------------------------------------
906 // Constructor and destructor
907 //------------------------------------------------------------------------
908 AssignLastURLHandler( std::shared_ptr<FileSystemData> &fs,
909 ResponseHandler *userHandler ):
910 pFS(fs), pUserHandler(userHandler) {}
911
913
914 //------------------------------------------------------------------------
915 // Response callback
916 //------------------------------------------------------------------------
917 virtual void HandleResponseWithHosts( XRootDStatus *status,
918 AnyObject *response,
919 HostList *hostList );
920
921 private:
922 std::shared_ptr<FileSystemData> pFS;
923 ResponseHandler *pUserHandler;
924 };
925
926
928 {
929 FileSystemData( const URL &url ) :
931 pFollowRedirects( true ),
932 pUrl( new URL( url.GetURL() ) )
933 {
934 }
935
936 //------------------------------------------------------------------------
937 // Send a message in a locked environment
938 //------------------------------------------------------------------------
939 static XRootDStatus Send( std::shared_ptr<FileSystemData> &fs,
940 Message *msg,
941 ResponseHandler *handler,
942 MessageSendParams &params )
943 {
944 Log *log = DefaultEnv::GetLog();
945 XrdSysMutexHelper scopedLock( fs->pMutex );
946
947 log->Dump( FileSystemMsg, "[0x%x@%s] Sending %s", fs.get(),
948 fs->pUrl->GetHostId().c_str(), msg->GetObfuscatedDescription().c_str() );
949
950 AssignLastURLHandler *lastUrlHandler = new AssignLastURLHandler( fs, handler );
951 handler = lastUrlHandler;
952
953 AssignLBHandler *lbHandler = nullptr;
954 if( !fs->pLoadBalancerLookupDone && fs->pFollowRedirects )
955 {
956 lbHandler = new AssignLBHandler( fs, handler );
957 handler = lbHandler;
958 }
959
960 params.followRedirects = fs->pFollowRedirects;
961
962 auto st = MessageUtils::SendMessage( *fs->pUrl, msg, handler, params, 0 );
963 if( !st.IsOK() )
964 {
965 delete lastUrlHandler;
966 delete lbHandler;
967 }
968
969 return st;
970 }
971
972 //----------------------------------------------------------------------------
973 // Assign a load balancer if it has not already been assigned
974 //----------------------------------------------------------------------------
975 void AssignLoadBalancer( const URL &url )
976 {
977 Log *log = DefaultEnv::GetLog();
978 XrdSysMutexHelper scopedLock( pMutex );
979
981 return;
982
983 log->Dump( FileSystemMsg, "[0x%x@%s] Assigning %s as load balancer", this,
984 pUrl->GetHostId().c_str(), url.GetHostId().c_str() );
985
986 pUrl.reset( new URL( url ) );
988 }
989
990 //----------------------------------------------------------------------------
991 // Assign last URL
992 //----------------------------------------------------------------------------
993 void AssignLastURL( const URL &url )
994 {
995 Log *log = DefaultEnv::GetLog();
996 XrdSysMutexHelper scopedLock( pMutex );
997
998 log->Dump( FileSystemMsg, "[0x%x@%s] Assigning %s as last URL", this,
999 pUrl->GetHostId().c_str(), url.GetHostId().c_str() );
1000
1001 pLastUrl.reset( new URL( url ) );
1002 }
1003
1007 std::unique_ptr<URL> pUrl;
1008 std::unique_ptr<URL> pLastUrl;
1009 };
1010
1011 //----------------------------------------------------------------------------
1013 //----------------------------------------------------------------------------
1015 {
1016 FileSystemImpl( const URL &url ) :
1017 fsdata( std::make_shared<FileSystemData>( url ) )
1018 {
1019 }
1020
1021 std::shared_ptr<FileSystemData> fsdata;
1022 };
1023
1024 //------------------------------------------------------------------------
1025 // Response callback
1026 //------------------------------------------------------------------------
1028 AnyObject *response,
1029 HostList *hostList )
1030 {
1031 if( status->IsOK() )
1032 {
1033 HostList::reverse_iterator it;
1034 for( it = hostList->rbegin(); it != hostList->rend(); ++it )
1035 if( it->loadBalancer )
1036 {
1037 pFS->AssignLoadBalancer( it->url );
1038 break;
1039 }
1040 }
1041
1042 bool finalrsp = !( status->IsOK() && status->code == suContinue );
1043
1044 SyncResponseHandler * syncHandler = dynamic_cast<SyncResponseHandler*>( pUserHandler );
1045 if( !syncHandler )
1046 pUserHandler->HandleResponseWithHosts( status, response, hostList );
1047
1048 if( finalrsp )
1049 {
1050 if( syncHandler )
1051 pUserHandler->HandleResponseWithHosts( status, response, hostList );
1052 delete this;
1053 }
1054 }
1055
1056 //------------------------------------------------------------------------
1057 // Response callback
1058 //------------------------------------------------------------------------
1060 AnyObject *response,
1061 HostList *hostList )
1062 {
1063 if( status->IsOK() && hostList )
1064 pFS->AssignLastURL( hostList->front().url );
1065
1066 bool finalrsp = !( status->IsOK() && status->code == suContinue );
1067
1068 SyncResponseHandler *syncHandler = dynamic_cast<SyncResponseHandler*>( pUserHandler );
1069 if( !syncHandler )
1070 pUserHandler->HandleResponseWithHosts( status, response, hostList );
1071
1072 if( finalrsp )
1073 {
1074 if( syncHandler )
1075 pUserHandler->HandleResponseWithHosts( status, response, hostList );
1076 delete this;
1077 }
1078 }
1079
1080 //----------------------------------------------------------------------------
1081 // Constructor
1082 //----------------------------------------------------------------------------
1083 FileSystem::FileSystem( const URL &url, bool enablePlugIns ):
1084 pImpl( new FileSystemImpl( url ) ),
1085 pPlugIn(0)
1086 {
1087 //--------------------------------------------------------------------------
1088 // Check if we need to install a plug-in for this URL
1089 //--------------------------------------------------------------------------
1090 if( enablePlugIns )
1091 {
1092 Log *log = DefaultEnv::GetLog();
1093 std::string urlStr = url.GetURL();
1095 if( fact )
1096 {
1097 pPlugIn = fact->CreateFileSystem( urlStr );
1098 if( !pPlugIn )
1099 {
1100 log->Error( FileMsg, "Plug-in factory failed to produce a plug-in "
1101 "for %s, continuing without one", url.GetObfuscatedURL().c_str() );
1102 }
1103 }
1104 }
1105
1106 if( !pPlugIn )
1107 DefaultEnv::GetForkHandler()->RegisterFileSystemObject( this );
1108 }
1109
1110 //----------------------------------------------------------------------------
1111 // Destructor
1112 //----------------------------------------------------------------------------
1114 {
1115 if( !pPlugIn )
1116 {
1119 }
1120
1121 delete pPlugIn;
1122 delete pImpl;
1123 }
1124
1125 //----------------------------------------------------------------------------
1126 // Locate a file - async
1127 //----------------------------------------------------------------------------
1128 XRootDStatus FileSystem::Locate( const std::string &path,
1129 OpenFlags::Flags flags,
1130 ResponseHandler *handler,
1131 uint16_t timeout )
1132 {
1133 if( pPlugIn )
1134 return pPlugIn->Locate( path, flags, handler, timeout );
1135
1136 std::string fPath = FilterXrdClCgi( path );
1137
1138 Message *msg;
1140 MessageUtils::CreateRequest( msg, req, fPath.length() );
1141
1142 req->requestid = kXR_locate;
1143 req->options = flags;
1144 req->dlen = fPath.length();
1145 msg->Append( fPath.c_str(), fPath.length(), 24 );
1146 MessageSendParams params; params.timeout = timeout;
1148
1150
1151 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1152 }
1153
1154 //----------------------------------------------------------------------------
1155 // Locate a file - sync
1156 //----------------------------------------------------------------------------
1157 XRootDStatus FileSystem::Locate( const std::string &path,
1158 OpenFlags::Flags flags,
1159 LocationInfo *&response,
1160 uint16_t timeout )
1161 {
1162 SyncResponseHandler handler;
1163 Status st = Locate( path, flags, &handler, timeout );
1164 if( !st.IsOK() )
1165 return st;
1166
1167 return MessageUtils::WaitForResponse( &handler, response );
1168 }
1169
1170 //----------------------------------------------------------------------------
1171 // Locate a file, recursively locate all disk servers - async
1172 //----------------------------------------------------------------------------
1173 XRootDStatus FileSystem::DeepLocate( const std::string &path,
1174 OpenFlags::Flags flags,
1175 ResponseHandler *handler,
1176 uint16_t timeout )
1177 {
1178 return Locate( path, flags,
1179 new DeepLocateHandler( handler, path, flags, timeout ), timeout );
1180 }
1181
1182 //----------------------------------------------------------------------------
1183 // Locate a file, recursively locate all disk servers - sync
1184 //----------------------------------------------------------------------------
1185 XRootDStatus FileSystem::DeepLocate( const std::string &path,
1186 OpenFlags::Flags flags,
1187 LocationInfo *&response,
1188 uint16_t timeout )
1189 {
1190 SyncResponseHandler handler;
1191 Status st = DeepLocate( path, flags, &handler, timeout );
1192 if( !st.IsOK() )
1193 return st;
1194
1195 return MessageUtils::WaitForResponse( &handler, response );
1196 }
1197
1198 //----------------------------------------------------------------------------
1199 // Move a directory or a file - async
1200 //----------------------------------------------------------------------------
1201 XRootDStatus FileSystem::Mv( const std::string &source,
1202 const std::string &dest,
1203 ResponseHandler *handler,
1204 uint16_t timeout )
1205 {
1206 if( pPlugIn )
1207 return pPlugIn->Mv( source, dest, handler, timeout );
1208
1209 std::string fSource = FilterXrdClCgi( source );
1210 std::string fDest = FilterXrdClCgi( dest );
1211
1212 Message *msg;
1213 ClientMvRequest *req;
1214 MessageUtils::CreateRequest( msg, req, fSource.length() + fDest.length()+1 );
1215
1216 req->requestid = kXR_mv;
1217 req->dlen = fSource.length() + fDest.length()+1;
1218 req->arg1len = fSource.length();
1219 msg->Append( fSource.c_str(), fSource.length(), 24 );
1220 *msg->GetBuffer(24 + fSource.length()) = ' ';
1221 msg->Append( fDest.c_str(), fDest.length(), 25 + fSource.length() );
1222 MessageSendParams params; params.timeout = timeout;
1224
1226
1227 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1228 }
1229
1230 //----------------------------------------------------------------------------
1231 // Move a directory or a file - sync
1232 //----------------------------------------------------------------------------
1233 XRootDStatus FileSystem::Mv( const std::string &source,
1234 const std::string &dest,
1235 uint16_t timeout )
1236 {
1237 SyncResponseHandler handler;
1238 Status st = Mv( source, dest, &handler, timeout );
1239 if( !st.IsOK() )
1240 return st;
1241
1242 return MessageUtils::WaitForStatus( &handler );
1243 }
1244
1245 //----------------------------------------------------------------------------
1246 // Obtain server information - async
1247 //----------------------------------------------------------------------------
1249 const Buffer &arg,
1250 ResponseHandler *handler,
1251 uint16_t timeout )
1252 {
1253 if( pPlugIn )
1254 return pPlugIn->Query( queryCode, arg, handler, timeout );
1255
1256 Message *msg;
1257 ClientQueryRequest *req;
1258 MessageUtils::CreateRequest( msg, req, arg.GetSize() );
1259
1260 req->requestid = kXR_query;
1261 req->infotype = queryCode;
1262 req->dlen = arg.GetSize();
1263 msg->Append( arg.GetBuffer(), arg.GetSize(), 24 );
1264 MessageSendParams params; params.timeout = timeout;
1267
1268 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1269 }
1270
1271 //----------------------------------------------------------------------------
1272 // Obtain server information - sync
1273 //----------------------------------------------------------------------------
1275 const Buffer &arg,
1276 Buffer *&response,
1277 uint16_t timeout )
1278 {
1279 SyncResponseHandler handler;
1280 Status st = Query( queryCode, arg, &handler, timeout );
1281 if( !st.IsOK() )
1282 return st;
1283
1284 return MessageUtils::WaitForResponse( &handler, response );
1285 }
1286
1287 //----------------------------------------------------------------------------
1288 // Truncate a file - async
1289 //----------------------------------------------------------------------------
1290 XRootDStatus FileSystem::Truncate( const std::string &path,
1291 uint64_t size,
1292 ResponseHandler *handler,
1293 uint16_t timeout )
1294 {
1295 if( pPlugIn )
1296 return pPlugIn->Truncate( path, size, handler, timeout );
1297
1298 std::string fPath = FilterXrdClCgi( path );
1299
1300 Message *msg;
1302 MessageUtils::CreateRequest( msg, req, fPath.length() );
1303
1304 req->requestid = kXR_truncate;
1305 req->offset = size;
1306 req->dlen = fPath.length();
1307 msg->Append( fPath.c_str(), fPath.length(), 24 );
1308 MessageSendParams params; params.timeout = timeout;
1311
1312 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1313 }
1314
1315 //----------------------------------------------------------------------------
1316 // Truncate a file - sync
1317 //----------------------------------------------------------------------------
1318 XRootDStatus FileSystem::Truncate( const std::string &path,
1319 uint64_t size,
1320 uint16_t timeout )
1321 {
1322 SyncResponseHandler handler;
1323 Status st = Truncate( path, size, &handler, timeout );
1324 if( !st.IsOK() )
1325 return st;
1326
1327 return MessageUtils::WaitForStatus( &handler );
1328 }
1329
1330 //----------------------------------------------------------------------------
1331 // Remove a file - async
1332 //----------------------------------------------------------------------------
1333 XRootDStatus FileSystem::Rm( const std::string &path,
1334 ResponseHandler *handler,
1335 uint16_t timeout )
1336 {
1337 if( pPlugIn )
1338 return pPlugIn->Rm( path, handler, timeout );
1339
1340 if( pImpl->fsdata->pUrl->IsLocalFile() )
1341 return LocalFS::Instance().Rm( path, handler, timeout );
1342
1343 std::string fPath = FilterXrdClCgi( path );
1344
1345 Message *msg;
1346 ClientRmRequest *req;
1347 MessageUtils::CreateRequest( msg, req, fPath.length() );
1348
1349 req->requestid = kXR_rm;
1350 req->dlen = fPath.length();
1351 msg->Append( fPath.c_str(), fPath.length(), 24 );
1352 MessageSendParams params; params.timeout = timeout;
1355
1356 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1357 }
1358
1359 //----------------------------------------------------------------------------
1360 // Remove a file - sync
1361 //----------------------------------------------------------------------------
1362 XRootDStatus FileSystem::Rm( const std::string &path,
1363 uint16_t timeout )
1364 {
1365 SyncResponseHandler handler;
1366 Status st = Rm( path, &handler, timeout );
1367 if( !st.IsOK() )
1368 return st;
1369
1370 return MessageUtils::WaitForStatus( &handler );
1371 }
1372
1373 //----------------------------------------------------------------------------
1374 // Create a directory - async
1375 //----------------------------------------------------------------------------
1376 XRootDStatus FileSystem::MkDir( const std::string &path,
1377 MkDirFlags::Flags flags,
1378 Access::Mode mode,
1379 ResponseHandler *handler,
1380 uint16_t timeout )
1381 {
1382 if( pPlugIn )
1383 return pPlugIn->MkDir( path, flags, mode, handler, timeout );
1384
1385 std::string fPath = FilterXrdClCgi( path );
1386
1387 Message *msg;
1388 ClientMkdirRequest *req;
1389 MessageUtils::CreateRequest( msg, req, fPath.length() );
1390
1391 req->requestid = kXR_mkdir;
1392 req->options[0] = flags;
1393 req->mode = mode;
1394 req->dlen = fPath.length();
1395 msg->Append( fPath.c_str(), fPath.length(), 24 );
1396 MessageSendParams params; params.timeout = timeout;
1399
1400 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1401 }
1402
1403 //----------------------------------------------------------------------------
1404 // Create a directory - sync
1405 //----------------------------------------------------------------------------
1406 XRootDStatus FileSystem::MkDir( const std::string &path,
1407 MkDirFlags::Flags flags,
1408 Access::Mode mode,
1409 uint16_t timeout )
1410 {
1411 SyncResponseHandler handler;
1412 Status st = MkDir( path, flags, mode, &handler, timeout );
1413 if( !st.IsOK() )
1414 return st;
1415
1416 return MessageUtils::WaitForStatus( &handler );
1417 }
1418
1419 //----------------------------------------------------------------------------
1420 // Remove a directory - async
1421 //----------------------------------------------------------------------------
1422 XRootDStatus FileSystem::RmDir( const std::string &path,
1423 ResponseHandler *handler,
1424 uint16_t timeout )
1425 {
1426 if( pPlugIn )
1427 return pPlugIn->RmDir( path, handler, timeout );
1428
1429 std::string fPath = FilterXrdClCgi( path );
1430
1431 Message *msg;
1432 ClientRmdirRequest *req;
1433 MessageUtils::CreateRequest( msg, req, fPath.length() );
1434
1435 req->requestid = kXR_rmdir;
1436 req->dlen = fPath.length();
1437 msg->Append( fPath.c_str(), fPath.length(), 24 );
1438 MessageSendParams params; params.timeout = timeout;
1441
1442 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1443 }
1444
1445 //----------------------------------------------------------------------------
1446 // Remove a directory - sync
1447 //----------------------------------------------------------------------------
1448 XRootDStatus FileSystem::RmDir( const std::string &path,
1449 uint16_t timeout )
1450 {
1451 SyncResponseHandler handler;
1452 Status st = RmDir( path, &handler, timeout );
1453 if( !st.IsOK() )
1454 return st;
1455
1456 return MessageUtils::WaitForStatus( &handler );
1457 }
1458
1459 //----------------------------------------------------------------------------
1460 // Change access mode on a directory or a file - async
1461 //----------------------------------------------------------------------------
1462 XRootDStatus FileSystem::ChMod( const std::string &path,
1463 Access::Mode mode,
1464 ResponseHandler *handler,
1465 uint16_t timeout )
1466 {
1467 if( pPlugIn )
1468 return pPlugIn->ChMod( path, mode, handler, timeout );
1469
1470 std::string fPath = FilterXrdClCgi( path );
1471
1472 Message *msg;
1473 ClientChmodRequest *req;
1474 MessageUtils::CreateRequest( msg, req, fPath.length() );
1475
1476 req->requestid = kXR_chmod;
1477 req->mode = mode;
1478 req->dlen = fPath.length();
1479 msg->Append( fPath.c_str(), fPath.length(), 24 );
1480 MessageSendParams params; params.timeout = timeout;
1483
1484 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1485 }
1486
1487 //----------------------------------------------------------------------------
1488 // Change access mode on a directory or a file - async
1489 //----------------------------------------------------------------------------
1490 XRootDStatus FileSystem::ChMod( const std::string &path,
1491 Access::Mode mode,
1492 uint16_t timeout )
1493 {
1494 SyncResponseHandler handler;
1495 Status st = ChMod( path, mode, &handler, timeout );
1496 if( !st.IsOK() )
1497 return st;
1498
1499 return MessageUtils::WaitForStatus( &handler );
1500 }
1501
1502 //----------------------------------------------------------------------------
1503 // Check if the server is alive - async
1504 //----------------------------------------------------------------------------
1506 uint16_t timeout )
1507 {
1508 if( pPlugIn )
1509 return pPlugIn->Ping( handler, timeout );
1510
1511 Message *msg;
1512 ClientPingRequest *req;
1513 MessageUtils::CreateRequest( msg, req );
1514
1515 req->requestid = kXR_ping;
1516 MessageSendParams params; params.timeout = timeout;
1519
1520 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1521 }
1522
1523 //----------------------------------------------------------------------------
1524 // Check if the server is alive - sync
1525 //----------------------------------------------------------------------------
1526 XRootDStatus FileSystem::Ping( uint16_t timeout )
1527 {
1528 SyncResponseHandler handler;
1529 Status st = Ping( &handler, timeout );
1530 if( !st.IsOK() )
1531 return st;
1532
1533 return MessageUtils::WaitForStatus( &handler );
1534 }
1535
1536 //----------------------------------------------------------------------------
1537 // Obtain status information for a path - async
1538 //----------------------------------------------------------------------------
1539 XRootDStatus FileSystem::Stat( const std::string &path,
1540 ResponseHandler *handler,
1541 uint16_t timeout )
1542 {
1543 if( pPlugIn )
1544 return pPlugIn->Stat( path, handler, timeout );
1545
1546 if( pImpl->fsdata->pUrl->IsLocalFile() )
1547 return LocalFS::Instance().Stat( path, handler, timeout );
1548
1549 std::string fPath = FilterXrdClCgi( path );
1550
1551 Message *msg;
1552 ClientStatRequest *req;
1553 MessageUtils::CreateRequest( msg, req, fPath.length() );
1554
1555 req->requestid = kXR_stat;
1556 req->options = 0;
1557 req->dlen = fPath.length();
1558 msg->Append( fPath.c_str(), fPath.length(), 24 );
1559 MessageSendParams params; params.timeout = timeout;
1562
1563 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1564 }
1565
1566 //----------------------------------------------------------------------------
1567 // Obtain status information for a path - sync
1568 //----------------------------------------------------------------------------
1569 XRootDStatus FileSystem::Stat( const std::string &path,
1570 StatInfo *&response,
1571 uint16_t timeout )
1572 {
1573 SyncResponseHandler handler;
1574 Status st = Stat( path, &handler, timeout );
1575 if( !st.IsOK() )
1576 return st;
1577
1578 return MessageUtils::WaitForResponse( &handler, response );
1579 }
1580
1581 //----------------------------------------------------------------------------
1582 // Obtain status information for a path - async
1583 //----------------------------------------------------------------------------
1584 XRootDStatus FileSystem::StatVFS( const std::string &path,
1585 ResponseHandler *handler,
1586 uint16_t timeout )
1587 {
1588 if( pPlugIn )
1589 return pPlugIn->StatVFS( path, handler, timeout );
1590
1591 std::string fPath = FilterXrdClCgi( path );
1592
1593 Message *msg;
1594 ClientStatRequest *req;
1595 MessageUtils::CreateRequest( msg, req, fPath.length() );
1596
1597 req->requestid = kXR_stat;
1598 req->options = kXR_vfs;
1599 req->dlen = fPath.length();
1600 msg->Append( fPath.c_str(), fPath.length(), 24 );
1601 MessageSendParams params; params.timeout = timeout;
1604
1605 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1606 }
1607
1608 //----------------------------------------------------------------------------
1609 // Obtain status information for a path - sync
1610 //----------------------------------------------------------------------------
1611 XRootDStatus FileSystem::StatVFS( const std::string &path,
1612 StatInfoVFS *&response,
1613 uint16_t timeout )
1614 {
1615 SyncResponseHandler handler;
1616 Status st = StatVFS( path, &handler, timeout );
1617 if( !st.IsOK() )
1618 return st;
1619
1620 return MessageUtils::WaitForResponse( &handler, response );
1621 }
1622
1623 //----------------------------------------------------------------------------
1624 // Obtain server protocol information - async
1625 //----------------------------------------------------------------------------
1627 uint16_t timeout )
1628 {
1629 if( pPlugIn )
1630 return pPlugIn->Protocol( handler, timeout );
1631
1632 Message *msg;
1634 MessageUtils::CreateRequest( msg, req );
1635
1636 req->requestid = kXR_protocol;
1638 MessageSendParams params; params.timeout = timeout;
1641
1642 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1643 }
1644
1645 //----------------------------------------------------------------------------
1646 // Obtain server protocol information - sync
1647 //----------------------------------------------------------------------------
1649 uint16_t timeout )
1650 {
1651 SyncResponseHandler handler;
1652 Status st = Protocol( &handler, timeout );
1653 if( !st.IsOK() )
1654 return st;
1655
1656 return MessageUtils::WaitForResponse( &handler, response );
1657 }
1658
1659 //----------------------------------------------------------------------------
1660 // List entries of a directory - async
1661 //----------------------------------------------------------------------------
1662 XRootDStatus FileSystem::DirList( const std::string &path,
1663 DirListFlags::Flags flags,
1664 ResponseHandler *handler,
1665 uint16_t timeout )
1666 {
1667 if( pPlugIn )
1668 return pPlugIn->DirList( path, flags, handler, timeout );
1669
1670 URL url = URL( path );
1671 std::string fPath = FilterXrdClCgi( path );
1672
1673 if( flags & DirListFlags::Zip )
1674 {
1675 // stat the file to check if it is a directory or a file
1676 // the ZIP handler will take care of the rest
1677 ZipListHandler *zipHandler = new ZipListHandler( *pImpl->fsdata->pUrl, path, flags, handler, timeout );
1678 XRootDStatus st = Stat( path, zipHandler, timeout );
1679 if( !st.IsOK() )
1680 delete zipHandler;
1681 return st;
1682 }
1683
1684 Message *msg;
1686 MessageUtils::CreateRequest( msg, req, fPath.length() );
1687
1688 req->requestid = kXR_dirlist;
1689 req->dlen = fPath.length();
1690
1691 if( ( flags & DirListFlags::Stat ) || ( flags & DirListFlags::Recursive ) )
1692 req->options[0] = kXR_dstat;
1693
1694 if( ( flags & DirListFlags::Cksm ) )
1695 req->options[0] = kXR_dstat | kXR_dcksm;
1696
1697 if( flags & DirListFlags::Recursive )
1698 handler = new RecursiveDirListHandler( *pImpl->fsdata->pUrl, url.GetPath(), flags, handler, timeout );
1699
1700 if( flags & DirListFlags::Merge )
1701 handler = new MergeDirListHandler( flags & DirListFlags::Chunked, handler );
1702
1703 msg->Append( fPath.c_str(), fPath.length(), 24 );
1704 MessageSendParams params; params.timeout = timeout;
1705 if( flags & DirListFlags::Chunked )
1706 params.chunkedResponse = true;
1709
1710 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1711 }
1712
1713 //----------------------------------------------------------------------------
1714 // List entries of a directory - sync
1715 //----------------------------------------------------------------------------
1716 XRootDStatus FileSystem::DirList( const std::string &path,
1717 DirListFlags::Flags flags,
1718 DirectoryList *&response,
1719 uint16_t timeout )
1720 {
1721 //--------------------------------------------------------------------------
1722 // Chunked response is only possible for async DirList call
1723 //--------------------------------------------------------------------------
1724 if( flags & DirListFlags::Chunked )
1726
1727 //--------------------------------------------------------------------------
1728 // If the path ends with '.zip' extension add Zip flag
1729 //--------------------------------------------------------------------------
1730 static const std::string zip_sufix = ".zip";
1731 if( path.size() >= zip_sufix.size() &&
1732 std::equal( zip_sufix.rbegin(), zip_sufix.rend(), path.rbegin() ) )
1733 flags |= DirListFlags::Zip;
1734
1735 //--------------------------------------------------------------------------
1736 // We do the deep locate and ask all the returned servers for the list
1737 //--------------------------------------------------------------------------
1738 if( flags & DirListFlags::Locate )
1739 {
1740 //------------------------------------------------------------------------
1741 // Locate all the disk servers holding the directory
1742 //------------------------------------------------------------------------
1743 LocationInfo *locations;
1744 std::string locatePath = "*"; locatePath += path;
1745 XRootDStatus st = DeepLocate( locatePath,
1747
1748 if( !st.IsOK() )
1749 return st;
1750
1751 if( locations->GetSize() == 0 )
1752 {
1753 delete locations;
1754 return XRootDStatus( stError, errNotFound );
1755 }
1756
1757 // Check if destination is a data server
1758 bool isserver = false;
1759 AnyObject obj;
1761 if( st.IsOK() )
1762 {
1763 int *ptr = 0;
1764 obj.Get( ptr );
1765 isserver = ( *ptr & kXR_isServer );
1766 delete ptr;
1767 }
1768
1769 if( !isserver )
1770 {
1771 //------------------------------------------------------------------------
1772 // Ask each server for a directory list
1773 //------------------------------------------------------------------------
1774 flags &= ~DirListFlags::Locate;
1775 FileSystem *fs;
1776 DirectoryList *currentResp = 0;
1777 uint32_t errors = 0;
1778 uint32_t numLocations = locations->GetSize();
1779 bool partial = st.code == suPartial ? true : false;
1780
1781 response = new DirectoryList();
1782 response->SetParentName( path );
1783
1784 for( uint32_t i = 0; i < locations->GetSize(); ++i )
1785 {
1786 URL locationURL( locations->At(i).GetAddress() );
1787 // make sure the original protocol is preserved (root vs roots)
1788 locationURL.SetProtocol( pImpl->fsdata->pUrl->GetProtocol() );
1789 fs = new FileSystem( locationURL );
1790 st = fs->DirList( path, flags, currentResp, timeout );
1791 if( !st.IsOK() )
1792 {
1793 ++errors;
1794 delete fs;
1795 continue;
1796 }
1797
1798 if( st.code == suPartial )
1799 partial = true;
1800
1802
1803 for( it = currentResp->Begin(); it != currentResp->End(); ++it )
1804 {
1805 response->Add( *it );
1806 *it = 0;
1807 }
1808
1809 delete fs;
1810 delete currentResp;
1811 fs = 0;
1812 currentResp = 0;
1813 }
1814 delete locations;
1815
1816 if( flags & DirListFlags::Merge )
1817 MergeDirListHandler::Merge( response );
1818
1819 if( errors || partial )
1820 {
1821 if( errors == numLocations )
1822 return st;
1823 return XRootDStatus( stOK, suPartial );
1824 }
1825 return XRootDStatus();
1826 }
1827 else
1828 delete locations;
1829 }
1830
1831 //--------------------------------------------------------------------------
1832 // We just ask the current server
1833 //--------------------------------------------------------------------------
1834 SyncResponseHandler handler;
1835 XRootDStatus st = DirList( path, flags, &handler, timeout );
1836 if( !st.IsOK() )
1837 return st;
1838
1839 st = MessageUtils::WaitForResponse( &handler, response );
1840 if( !st.IsOK() )
1841 return st;
1842
1843 //--------------------------------------------------------------------------
1844 // Do the stats on all the entries if necessary.
1845 // If we already have the stat objects it means that the bulk stat has
1846 // succeeded.
1847 //--------------------------------------------------------------------------
1848 if( !(flags & DirListFlags::Stat) )
1849 return st;
1850
1851 if( response->GetSize() && response->At(0)->GetStatInfo() )
1852 return st;
1853
1854 uint32_t quota = response->GetSize() <= 1024 ? response->GetSize() : 1024;
1855 RequestSync sync( response->GetSize(), quota );
1856 for( uint32_t i = 0; i < response->GetSize(); ++i )
1857 {
1858 std::string fullPath = response->GetParentName()+response->At(i)->GetName();
1859 ResponseHandler *handler = new DirListStatHandler( response, i, &sync );
1860 st = Stat( fullPath, handler, timeout );
1861 if( !st.IsOK() )
1862 {
1863 sync.TaskDone( false );
1864 delete handler;
1865 }
1866 sync.WaitForQuota();
1867 }
1868 sync.WaitForAll();
1869
1870 if( sync.FailureCount() )
1871 return XRootDStatus( stOK, suPartial );
1872
1873 return XRootDStatus();
1874 }
1875
1876 //----------------------------------------------------------------------------
1877 // Send cache info to the server - async
1878 //----------------------------------------------------------------------------
1879 XRootDStatus FileSystem::SendCache( const std::string &info,
1880 ResponseHandler *handler,
1881 uint16_t timeout )
1882 {
1883 // Note: adding SendCache() to the FileSystemPlugin class breaks ABI!
1884 // So, the class is missing this until we do a major release. TODO
1885 //if( pPlugIn )
1886 // return pPlugIn->SendCache( info, handler, timeout );
1887 return SendSet("cache ", info, handler, timeout );
1888 }
1889
1890 //----------------------------------------------------------------------------
1892 //----------------------------------------------------------------------------
1893 XRootDStatus FileSystem::SendCache( const std::string &info,
1894 Buffer *&response,
1895 uint16_t timeout )
1896 {
1897 SyncResponseHandler handler;
1898 Status st = SendCache( info, &handler, timeout );
1899 if( !st.IsOK() )
1900 return st;
1901
1902 return MessageUtils::WaitForResponse( &handler, response );
1903 }
1904
1905 //----------------------------------------------------------------------------
1906 // Send info to the server - async
1907 //----------------------------------------------------------------------------
1908 XRootDStatus FileSystem::SendInfo( const std::string &info,
1909 ResponseHandler *handler,
1910 uint16_t timeout )
1911 {
1912 if( pPlugIn )
1913 return pPlugIn->SendInfo( info, handler, timeout );
1914 return SendSet("monitor info ", info, handler, timeout );
1915 }
1916
1917 //----------------------------------------------------------------------------
1919 //----------------------------------------------------------------------------
1920 XRootDStatus FileSystem::SendInfo( const std::string &info,
1921 Buffer *&response,
1922 uint16_t timeout )
1923 {
1924 SyncResponseHandler handler;
1925 Status st = SendInfo( info, &handler, timeout );
1926 if( !st.IsOK() )
1927 return st;
1928
1929 return MessageUtils::WaitForResponse( &handler, response );
1930 }
1931
1932 //----------------------------------------------------------------------------
1933 // Send set request to the server - async
1934 //----------------------------------------------------------------------------
1935 XRootDStatus FileSystem::SendSet( const char *prefix,
1936 const std::string &info,
1937 ResponseHandler *handler,
1938 uint16_t timeout )
1939 {
1940
1941 Message *msg;
1942 ClientSetRequest *req;
1943 size_t prefixLen = strlen( prefix );
1944 MessageUtils::CreateRequest( msg, req, info.length()+prefixLen );
1945
1946 req->requestid = kXR_set;
1947 req->dlen = info.length()+prefixLen;
1948 msg->Append( prefix, prefixLen, 24 );
1949 msg->Append( info.c_str(), info.length(), 24+prefixLen );
1950 MessageSendParams params; params.timeout = timeout;
1953
1954 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1955 }
1956
1957 //----------------------------------------------------------------------------
1958 // Prepare one or more files for access - async
1959 //----------------------------------------------------------------------------
1960 XRootDStatus FileSystem::Prepare( const std::vector<std::string> &fileList,
1961 PrepareFlags::Flags flags,
1962 uint8_t priority,
1963 ResponseHandler *handler,
1964 uint16_t timeout )
1965 {
1966 if( pPlugIn )
1967 return pPlugIn->Prepare( fileList, flags, priority, handler, timeout );
1968
1969 std::vector<std::string>::const_iterator it;
1970 std::string list;
1971 for( it = fileList.begin(); it != fileList.end(); ++it )
1972 {
1973 list += *it;
1974 list += "\n";
1975 }
1976 list.erase( list.length()-1, 1 );
1977
1978 Message *msg;
1980 MessageUtils::CreateRequest( msg, req, list.length() );
1981
1982 req->requestid = kXR_prepare;
1983 req->options = 0xff & flags;
1984 req->optionX = 0xffff & ( flags >> 8 );
1985 req->prty = priority;
1986 req->dlen = list.length();
1987
1988 msg->Append( list.c_str(), list.length(), 24 );
1989
1990 MessageSendParams params; params.timeout = timeout;
1993
1994 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1995 }
1996
1997 //------------------------------------------------------------------------
1998 // Prepare one or more files for access - sync
1999 //------------------------------------------------------------------------
2000 XRootDStatus FileSystem::Prepare( const std::vector<std::string> &fileList,
2001 PrepareFlags::Flags flags,
2002 uint8_t priority,
2003 Buffer *&response,
2004 uint16_t timeout )
2005 {
2006 SyncResponseHandler handler;
2007 Status st = Prepare( fileList, flags, priority, &handler, timeout );
2008 if( !st.IsOK() )
2009 return st;
2010
2011 return MessageUtils::WaitForResponse( &handler, response );
2012 }
2013
2014 //------------------------------------------------------------------------
2015 // Set extended attributes - async
2016 //------------------------------------------------------------------------
2017 XRootDStatus FileSystem::SetXAttr( const std::string &path,
2018 const std::vector<xattr_t> &attrs,
2019 ResponseHandler *handler,
2020 uint16_t timeout )
2021 {
2022 if( pPlugIn )
2024
2025 return XAttrOperationImpl( kXR_fattrSet, 0, path, attrs, handler, timeout );
2026 }
2027
2028 //------------------------------------------------------------------------
2029 // Set extended attributes - sync
2030 //------------------------------------------------------------------------
2031 XRootDStatus FileSystem::SetXAttr( const std::string &path,
2032 const std::vector<xattr_t> &attrs,
2033 std::vector<XAttrStatus> &result,
2034 uint16_t timeout )
2035 {
2036 SyncResponseHandler handler;
2037 XRootDStatus st = SetXAttr( path, attrs, &handler, timeout );
2038 if( !st.IsOK() )
2039 return st;
2040
2041 std::vector<XAttrStatus> *resp = 0;
2042 st = MessageUtils::WaitForResponse( &handler, resp );
2043 if( resp ) result.swap( *resp );
2044 delete resp;
2045
2046 return st;
2047 }
2048
2049 //------------------------------------------------------------------------
2050 // Get extended attributes - async
2051 //------------------------------------------------------------------------
2052 XRootDStatus FileSystem::GetXAttr( const std::string &path,
2053 const std::vector<std::string> &attrs,
2054 ResponseHandler *handler,
2055 uint16_t timeout )
2056 {
2057 if( pPlugIn )
2059
2060 return XAttrOperationImpl( kXR_fattrGet, 0, path, attrs, handler, timeout );
2061 }
2062
2063 //------------------------------------------------------------------------
2064 // Get extended attributes - sync
2065 //------------------------------------------------------------------------
2066 XRootDStatus FileSystem::GetXAttr( const std::string &path,
2067 const std::vector<std::string> &attrs,
2068 std::vector<XAttr> &result,
2069 uint16_t timeout )
2070 {
2071 SyncResponseHandler handler;
2072 XRootDStatus st = GetXAttr( path, attrs, &handler, timeout );
2073 if( !st.IsOK() )
2074 return st;
2075
2076 std::vector<XAttr> *resp = 0;
2077 st = MessageUtils::WaitForResponse( &handler, resp );
2078 if( resp ) result.swap( *resp );
2079 delete resp;
2080
2081 return st;
2082 }
2083
2084 //------------------------------------------------------------------------
2085 // Delete extended attributes - async
2086 //------------------------------------------------------------------------
2087 XRootDStatus FileSystem::DelXAttr( const std::string &path,
2088 const std::vector<std::string> &attrs,
2089 ResponseHandler *handler,
2090 uint16_t timeout )
2091 {
2092 if( pPlugIn )
2094
2095 return XAttrOperationImpl( kXR_fattrDel, 0, path, attrs, handler, timeout );
2096 }
2097
2098 //------------------------------------------------------------------------
2099 // Delete extended attributes - sync
2100 //------------------------------------------------------------------------
2101 XRootDStatus FileSystem::DelXAttr( const std::string &path,
2102 const std::vector<std::string> &attrs,
2103 std::vector<XAttrStatus> &result,
2104 uint16_t timeout )
2105 {
2106 SyncResponseHandler handler;
2107 XRootDStatus st = DelXAttr( path, attrs, &handler, timeout );
2108 if( !st.IsOK() )
2109 return st;
2110
2111 std::vector<XAttrStatus> *resp = 0;
2112 st = MessageUtils::WaitForResponse( &handler, resp );
2113 if( resp ) result.swap( *resp );
2114 delete resp;
2115
2116 return st;
2117 }
2118
2119 //------------------------------------------------------------------------
2120 // List extended attributes - async
2121 //------------------------------------------------------------------------
2122 XRootDStatus FileSystem::ListXAttr( const std::string &path,
2123 ResponseHandler *handler,
2124 uint16_t timeout )
2125 {
2126 if( pPlugIn )
2128
2129 static const std::vector<std::string> nothing;
2130 return XAttrOperationImpl( kXR_fattrList, ClientFattrRequest::aData,
2131 path, nothing, handler, timeout );
2132 }
2133
2134 //------------------------------------------------------------------------
2135 // List extended attributes - sync
2136 //------------------------------------------------------------------------
2137 XRootDStatus FileSystem::ListXAttr( const std::string &path,
2138 std::vector<XAttr> &result,
2139 uint16_t timeout )
2140 {
2141 SyncResponseHandler handler;
2142 XRootDStatus st = ListXAttr( path, &handler, timeout );
2143 if( !st.IsOK() )
2144 return st;
2145
2146 std::vector<XAttr> *resp = 0;
2147 st = MessageUtils::WaitForResponse( &handler, resp );
2148 if( resp ) result.swap( *resp );
2149 delete resp;
2150
2151 return st;
2152 }
2153
2154 //----------------------------------------------------------------------------
2155 // Set file property
2156 //----------------------------------------------------------------------------
2157 bool FileSystem::SetProperty( const std::string &name,
2158 const std::string &value )
2159 {
2160 if( pPlugIn )
2161 return pPlugIn->SetProperty( name, value );
2162
2163 if( name == "FollowRedirects" )
2164 {
2165 if( value == "true" ) pImpl->fsdata->pFollowRedirects = true;
2166 else pImpl->fsdata->pFollowRedirects = false;
2167 return true;
2168 }
2169 return false;
2170 }
2171
2172 //----------------------------------------------------------------------------
2173 // Get file property
2174 //----------------------------------------------------------------------------
2175 bool FileSystem::GetProperty( const std::string &name,
2176 std::string &value ) const
2177 {
2178 if( pPlugIn )
2179 return pPlugIn->GetProperty( name, value );
2180
2181 if( name == "FollowRedirects" )
2182 {
2183 if( pImpl->fsdata->pFollowRedirects ) value = "true";
2184 else value = "false";
2185 return true;
2186 }
2187 else if( name == "LastURL" )
2188 {
2189 if( pImpl->fsdata->pLastUrl )
2190 {
2191 value = pImpl->fsdata->pLastUrl->GetURL();
2192 return true;
2193 }
2194 else return false;
2195 }
2196
2197 return false;
2198 }
2199
2200 //------------------------------------------------------------------------
2201 // Generic implementation of xattr operation
2202 //------------------------------------------------------------------------
2203 template<typename T>
2204 Status FileSystem::XAttrOperationImpl( kXR_char subcode,
2205 kXR_char options,
2206 const std::string &path,
2207 const std::vector<T> &attrs,
2208 ResponseHandler *handler,
2209 uint16_t timeout )
2210 {
2211 Message *msg;
2212 ClientFattrRequest *req;
2213 MessageUtils::CreateRequest( msg, req );
2214
2215 req->requestid = kXR_fattr;
2216 req->subcode = subcode;
2217 req->options = options;
2218 req->numattr = attrs.size();
2219 memset( req->fhandle, 0, 4 );
2220 XRootDStatus st = MessageUtils::CreateXAttrBody( msg, attrs, path );
2221 if( !st.IsOK() ) return st;
2222
2223 MessageSendParams params; params.timeout = timeout;
2225
2227
2228 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
2229 }
2230
2231 //------------------------------------------------------------------------
2232 // Lock the internal lock
2233 //------------------------------------------------------------------------
2234 void FileSystem::Lock()
2235 {
2236 pImpl->fsdata->pMutex.Lock();
2237 }
2238
2239 //------------------------------------------------------------------------
2240 // Unlock the internal lock
2241 //------------------------------------------------------------------------
2242 void FileSystem::UnLock()
2243 {
2244 pImpl->fsdata->pMutex.UnLock();
2245 }
2246}
kXR_char options[1]
Definition XProtocol.hh:248
@ kXR_NotFound
@ kXR_FSError
Definition XProtocol.hh:995
kXR_int16 arg1len
Definition XProtocol.hh:430
kXR_unt16 requestid
Definition XProtocol.hh:630
@ kXR_fattrDel
Definition XProtocol.hh:270
@ kXR_fattrSet
Definition XProtocol.hh:273
@ kXR_fattrList
Definition XProtocol.hh:272
@ kXR_fattrGet
Definition XProtocol.hh:271
kXR_unt16 requestid
Definition XProtocol.hh:546
kXR_int32 dlen
Definition XProtocol.hh:431
@ kXR_dstat
Definition XProtocol.hh:240
@ kXR_dcksm
Definition XProtocol.hh:241
kXR_unt16 requestid
Definition XProtocol.hh:428
@ kXR_mkdir
Definition XProtocol.hh:120
@ kXR_chmod
Definition XProtocol.hh:114
@ kXR_dirlist
Definition XProtocol.hh:116
@ kXR_fattr
Definition XProtocol.hh:132
@ kXR_rm
Definition XProtocol.hh:126
@ kXR_query
Definition XProtocol.hh:113
@ kXR_set
Definition XProtocol.hh:130
@ kXR_rmdir
Definition XProtocol.hh:127
@ kXR_truncate
Definition XProtocol.hh:140
@ kXR_protocol
Definition XProtocol.hh:118
@ kXR_mv
Definition XProtocol.hh:121
@ kXR_ping
Definition XProtocol.hh:123
@ kXR_stat
Definition XProtocol.hh:129
@ kXR_locate
Definition XProtocol.hh:139
@ kXR_prepare
Definition XProtocol.hh:133
kXR_int32 dlen
Definition XProtocol.hh:699
kXR_unt16 requestid
Definition XProtocol.hh:719
#define kXR_isServer
kXR_unt16 requestid
Definition XProtocol.hh:768
kXR_unt16 requestid
Definition XProtocol.hh:415
kXR_char options[1]
Definition XProtocol.hh:416
kXR_unt16 requestid
Definition XProtocol.hh:697
#define kXR_PROTOCOLVERSION
Definition XProtocol.hh:70
@ kXR_vfs
Definition XProtocol.hh:763
kXR_unt16 requestid
Definition XProtocol.hh:191
@ kXR_isDir
kXR_unt16 requestid
Definition XProtocol.hh:708
unsigned char kXR_char
Definition XPtypes.hh:65
struct stat Stat
Definition XrdCks.cc:49
static void child()
static void parent()
#define unlink(a)
Definition XrdPosix.hh:108
#define stat(a, b)
Definition XrdPosix.hh:96
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:99
static int mapError(int rc)
void Set(Type object, bool own=true)
void Get(Type &object)
Retrieve the object being held.
Wrapper class used to assign a load balancer.
AssignLBHandler(std::shared_ptr< FileSystemData > &fs, ResponseHandler *userHandler)
virtual void HandleResponseWithHosts(XRootDStatus *status, AnyObject *response, HostList *hostList)
Wrapper class used to assign last URL.
virtual void HandleResponseWithHosts(XRootDStatus *status, AnyObject *response, HostList *hostList)
AssignLastURLHandler(std::shared_ptr< FileSystemData > &fs, ResponseHandler *userHandler)
Binary blob representation.
void Append(const char *buffer, uint32_t size)
Append data at the position pointed to by the append cursor.
const char * GetBuffer(uint32_t offset=0) const
Get the message buffer.
uint32_t GetSize() const
Get the size of the message.
static PlugInManager * GetPlugInManager()
Get plug-in manager.
static Log * GetLog()
Get default log.
static PostMaster * GetPostMaster()
Get default post master.
static ForkHandler * GetForkHandler()
Get the fork handler.
static Env * GetEnv()
Get default client environment.
void SetStatInfo(StatInfo *info)
Set the stat info object (and transfer the ownership)
const std::string & GetName() const
Get file name.
const std::string & GetHostAddress() const
Get host address.
StatInfo * GetStatInfo()
Get the stat info object.
void Add(ListEntry *entry)
Add an entry to the list - takes ownership.
uint32_t GetSize() const
Get the size of the listing.
const std::string & GetParentName() const
Get parent directory name.
Iterator End()
Get the end iterator.
DirList::iterator Iterator
Directory listing iterator.
Iterator Begin()
Get the begin iterator.
void SetParentName(const std::string &parent)
Set name of the parent directory.
ListEntry * At(uint32_t index)
Get an entry at given index.
bool GetInt(const std::string &key, int &value)
Definition XrdClEnv.cc:89
virtual XRootDStatus Mv(const std::string &source, const std::string &dest, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus Ping(ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus SendInfo(const std::string &info, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus DirList(const std::string &path, DirListFlags::Flags flags, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus ChMod(const std::string &path, Access::Mode mode, ResponseHandler *handler, uint16_t timeout)
virtual bool GetProperty(const std::string &name, std::string &value) const
virtual XRootDStatus MkDir(const std::string &path, MkDirFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus Locate(const std::string &path, OpenFlags::Flags flags, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus StatVFS(const std::string &path, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus Protocol(ResponseHandler *handler, uint16_t timeout=0)
virtual XRootDStatus RmDir(const std::string &path, ResponseHandler *handler, uint16_t timeout)
virtual bool SetProperty(const std::string &name, const std::string &value)
virtual XRootDStatus Query(QueryCode::Code queryCode, const Buffer &arg, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus Prepare(const std::vector< std::string > &fileList, PrepareFlags::Flags flags, uint8_t priority, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus Rm(const std::string &path, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus Stat(const std::string &path, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus Truncate(const std::string &path, uint64_t size, ResponseHandler *handler, uint16_t timeout)
Send file/filesystem queries to an XRootD cluster.
XRootDStatus SetXAttr(const std::string &path, const std::vector< xattr_t > &attrs, ResponseHandler *handler, uint16_t timeout=0)
XRootDStatus RmDir(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
bool SetProperty(const std::string &name, const std::string &value)
XRootDStatus Protocol(ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus DirList(const std::string &path, DirListFlags::Flags flags, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Mv(const std::string &source, const std::string &dest, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Query(QueryCode::Code queryCode, const Buffer &arg, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Locate(const std::string &path, OpenFlags::Flags flags, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus SendInfo(const std::string &info, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Stat(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Prepare(const std::vector< std::string > &fileList, PrepareFlags::Flags flags, uint8_t priority, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus ChMod(const std::string &path, Access::Mode mode, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus DelXAttr(const std::string &path, const std::vector< std::string > &attrs, ResponseHandler *handler, uint16_t timeout=0)
XRootDStatus ListXAttr(const std::string &path, ResponseHandler *handler, uint16_t timeout=0)
XRootDStatus Rm(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
FileSystem(const URL &url, bool enablePlugIns=true)
XRootDStatus DeepLocate(const std::string &path, OpenFlags::Flags flags, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus SendCache(const std::string &info, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus GetXAttr(const std::string &path, const std::vector< std::string > &attrs, ResponseHandler *handler, uint16_t timeout=0)
XRootDStatus Ping(ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Truncate(const std::string &path, uint64_t size, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
bool GetProperty(const std::string &name, std::string &value) const
XRootDStatus MkDir(const std::string &path, MkDirFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus StatVFS(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
void UnRegisterFileSystemObject(FileSystem *fs)
Un-register a file system object.
A synchronized queue.
const std::string & GetAddress() const
Get address.
Path location info.
LocationList::iterator Iterator
Iterator over locations.
uint32_t GetSize() const
Get number of locations.
Iterator Begin()
Get the location begin iterator.
Location & At(uint32_t index)
Get the location at index.
Iterator End()
Get the location end iterator.
Handle diagnostics.
Definition XrdClLog.hh:101
void Error(uint64_t topic, const char *format,...)
Report an error.
Definition XrdClLog.cc:231
void Dump(uint64_t topic, const char *format,...)
Print a dump message.
Definition XrdClLog.cc:299
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
Definition XrdClLog.cc:282
static void ProcessSendParams(MessageSendParams &sendParams)
Process sending params.
static Status CreateXAttrBody(Message *msg, const std::vector< T > &vec, const std::string &path="")
static XrdCl::XRootDStatus WaitForResponse(SyncResponseHandler *handler, Type *&response)
Wait for the response.
static XRootDStatus SendMessage(const URL &url, Message *msg, ResponseHandler *handler, MessageSendParams &sendParams, LocalFileHandler *lFileHandler)
Send message.
static void CreateRequest(Message *&msg, Request *&req, uint32_t payloadSize=0)
Create a message.
static XRootDStatus WaitForStatus(SyncResponseHandler *handler)
Wait and return the status of the query.
The message representation used throughout the system.
const std::string & GetObfuscatedDescription() const
Get the description of the message with authz parameter obfuscated.
virtual FileSystemPlugIn * CreateFileSystem(const std::string &url)=0
Create a file system plug-in for the given URL.
PlugInFactory * GetFactory(const std::string url)
Status QueryTransport(const URL &url, uint16_t query, AnyObject &result)
A helper running a fixed number of requests at a given time.
void WaitForAll()
Wait for all the requests to be finished.
void TaskDone(bool success=true)
Report the request finish.
uint32_t FailureCount() const
Number of tasks finishing with an error.
void WaitForQuota()
Wait for the request quota.
Handle an async response.
virtual void HandleResponseWithHosts(XRootDStatus *status, AnyObject *response, HostList *hostList)
Object stat info.
bool TestFlags(uint32_t flags) const
Test flags.
uint64_t GetSize() const
Get size (in bytes)
bool ParseServerResponse(const char *data)
Parse server response and fill up the object.
uint32_t GetFlags() const
Get flags.
Synchronize the response.
virtual void HandleResponse(XRootDStatus *status, AnyObject *response)
Handle the response.
URL representation.
Definition XrdClURL.hh:31
const std::string & GetPath() const
Get the path.
Definition XrdClURL.hh:217
std::string GetHostId() const
Get the host part of the URL (user:password@host:port)
Definition XrdClURL.hh:99
std::string GetURL() const
Get the URL.
Definition XrdClURL.hh:86
std::string GetObfuscatedURL() const
Get the URL with authz information obfuscated.
Definition XrdClURL.cc:491
void SetProtocol(const std::string &protocol)
Set protocol.
Definition XrdClURL.hh:126
std::string ToStr() const
Convert to string.
static void SetDescription(Message *msg)
Get the description of a message.
const uint16_t suPartial
SendInfoImpl< false > SendInfo
ChModImpl< false > ChMod
MkDirImpl< false > MkDir
RmImpl< false > Rm
const uint16_t stError
An error occurred that could potentially be retried.
const uint16_t errNotFound
MvImpl< false > Mv
LocateImpl< false > Locate
std::vector< HostInfo > HostList
const uint16_t errInternal
Internal error.
const uint16_t stOK
Everything went OK.
const uint64_t FileMsg
DeepLocateImpl< false > DeepLocate
ProtocolImpl< false > Protocol
const int DefaultRequestTimeout
const uint16_t errNotSupported
RmDirImpl< false > RmDir
PrepareImpl< false > Prepare
StatVFSImpl< false > StatVFS
PingImpl< false > Ping
const uint16_t suContinue
DirListImpl< false > DirList
QueryImpl< false > Query
const uint64_t FileSystemMsg
static const int aData
Definition XProtocol.hh:298
kXR_char fhandle[4]
Definition XProtocol.hh:288
kXR_unt16 requestid
Definition XProtocol.hh:287
@ Stat
Stat each entry.
@ Merge
Merge duplicates.
@ Zip
List content of ZIP files.
@ Recursive
Do a recursive listing.
@ Cksm
Get checksum for every entry.
@ Chunked
Serve chunked results for better performance.
static XRootDStatus Send(std::shared_ptr< FileSystemData > &fs, Message *msg, ResponseHandler *handler, MessageSendParams &params)
FileSystemData(const URL &url)
void AssignLastURL(const URL &url)
std::unique_ptr< URL > pLastUrl
std::unique_ptr< URL > pUrl
void AssignLoadBalancer(const URL &url)
Implementation holding the data members.
FileSystemImpl(const URL &url)
std::shared_ptr< FileSystemData > fsdata
Flags
Open flags, may be or'd when appropriate.
Code
XRootD query request codes.
Procedure execution status.
uint16_t code
Error type, or additional hints on what to do.
bool IsOK() const
We're fine.
std::string ToString() const
Create a string representation.
static const uint16_t ServerFlags
returns server flags