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, "%s", 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, "[%p@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, "[%p@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, "[%p@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, "[%p@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: %s",
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, "[%p@%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, "[%p@%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, "[%p@%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 bool isserver = false;
1741 //------------------------------------------------------------------------
1742 // Check if destination is a data server
1743 //------------------------------------------------------------------------
1744 {
1745 AnyObject obj;
1747 *pImpl->fsdata->pUrl, XRootDQuery::ServerFlags, obj);
1748
1749 if( st.IsOK() )
1750 {
1751 int *ptr = 0;
1752 obj.Get( ptr );
1753 isserver = ( *ptr & kXR_isServer );
1754 delete ptr;
1755 }
1756 }
1757
1758 if (isserver) {
1759 // Just disable the locate flag if we are talking to a single server
1760 flags &= ~DirListFlags::Locate;
1761 } else {
1762 //------------------------------------------------------------------------
1763 // Locate all the disk servers holding the directory
1764 //------------------------------------------------------------------------
1765 LocationInfo *locations;
1766 std::string locatePath = "*"; locatePath += path;
1767
1768 XRootDStatus st = DeepLocate(locatePath,
1772 locations);
1773
1774 if( !st.IsOK() )
1775 return st;
1776
1777 if( locations->GetSize() == 0 )
1778 {
1779 delete locations;
1780 return XRootDStatus( stError, errNotFound );
1781 }
1782
1783 //------------------------------------------------------------------------
1784 // Ask each server for a directory list
1785 //------------------------------------------------------------------------
1786 flags &= ~DirListFlags::Locate;
1787 FileSystem *fs;
1788 DirectoryList *currentResp = 0;
1789 uint32_t errors = 0;
1790 uint32_t numLocations = locations->GetSize();
1791 bool partial = st.code == suPartial ? true : false;
1792
1793 response = new DirectoryList();
1794 response->SetParentName( path );
1795
1796 for( uint32_t i = 0; i < locations->GetSize(); ++i )
1797 {
1798 URL locationURL( locations->At(i).GetAddress() );
1799 // make sure the original protocol is preserved (root vs roots)
1800 locationURL.SetProtocol( pImpl->fsdata->pUrl->GetProtocol() );
1801 fs = new FileSystem( locationURL );
1802 st = fs->DirList( path, flags, currentResp, timeout );
1803 if( !st.IsOK() )
1804 {
1805 ++errors;
1806 delete fs;
1807 continue;
1808 }
1809
1810 if( st.code == suPartial )
1811 partial = true;
1812
1814
1815 for( it = currentResp->Begin(); it != currentResp->End(); ++it )
1816 {
1817 response->Add( *it );
1818 *it = 0;
1819 }
1820
1821 delete fs;
1822 delete currentResp;
1823 fs = 0;
1824 currentResp = 0;
1825 }
1826
1827 delete locations;
1828
1829 if( flags & DirListFlags::Merge )
1830 MergeDirListHandler::Merge( response );
1831
1832 if( errors || partial )
1833 {
1834 if( errors == numLocations )
1835 return st;
1836 return XRootDStatus( stOK, suPartial );
1837 }
1838 return XRootDStatus();
1839 }
1840 }
1841
1842 //--------------------------------------------------------------------------
1843 // We just ask the current server
1844 //--------------------------------------------------------------------------
1845 SyncResponseHandler handler;
1846 XRootDStatus st = DirList( path, flags, &handler, timeout );
1847 if( !st.IsOK() )
1848 return st;
1849
1850 st = MessageUtils::WaitForResponse( &handler, response );
1851 if( !st.IsOK() )
1852 return st;
1853
1854 //--------------------------------------------------------------------------
1855 // Do the stats on all the entries if necessary.
1856 // If we already have the stat objects it means that the bulk stat has
1857 // succeeded.
1858 //--------------------------------------------------------------------------
1859 if( !(flags & DirListFlags::Stat) )
1860 return st;
1861
1862 if( response->GetSize() && response->At(0)->GetStatInfo() )
1863 return st;
1864
1865 uint32_t quota = response->GetSize() <= 1024 ? response->GetSize() : 1024;
1866 RequestSync sync( response->GetSize(), quota );
1867 for( uint32_t i = 0; i < response->GetSize(); ++i )
1868 {
1869 std::string fullPath = response->GetParentName()+response->At(i)->GetName();
1870 ResponseHandler *handler = new DirListStatHandler( response, i, &sync );
1871 st = Stat( fullPath, handler, timeout );
1872 if( !st.IsOK() )
1873 {
1874 sync.TaskDone( false );
1875 delete handler;
1876 }
1877 sync.WaitForQuota();
1878 }
1879 sync.WaitForAll();
1880
1881 if( sync.FailureCount() )
1882 return XRootDStatus( stOK, suPartial );
1883
1884 return XRootDStatus();
1885 }
1886
1887 //----------------------------------------------------------------------------
1888 // Send cache info to the server - async
1889 //----------------------------------------------------------------------------
1890 XRootDStatus FileSystem::SendCache( const std::string &info,
1891 ResponseHandler *handler,
1892 uint16_t timeout )
1893 {
1894 // Note: adding SendCache() to the FileSystemPlugin class breaks ABI!
1895 // So, the class is missing this until we do a major release. TODO
1896 //if( pPlugIn )
1897 // return pPlugIn->SendCache( info, handler, timeout );
1898 return SendSet("cache ", info, handler, timeout );
1899 }
1900
1901 //----------------------------------------------------------------------------
1903 //----------------------------------------------------------------------------
1904 XRootDStatus FileSystem::SendCache( const std::string &info,
1905 Buffer *&response,
1906 uint16_t timeout )
1907 {
1908 SyncResponseHandler handler;
1909 Status st = SendCache( info, &handler, timeout );
1910 if( !st.IsOK() )
1911 return st;
1912
1913 return MessageUtils::WaitForResponse( &handler, response );
1914 }
1915
1916 //----------------------------------------------------------------------------
1917 // Send info to the server - async
1918 //----------------------------------------------------------------------------
1919 XRootDStatus FileSystem::SendInfo( const std::string &info,
1920 ResponseHandler *handler,
1921 uint16_t timeout )
1922 {
1923 if( pPlugIn )
1924 return pPlugIn->SendInfo( info, handler, timeout );
1925 return SendSet("monitor info ", info, handler, timeout );
1926 }
1927
1928 //----------------------------------------------------------------------------
1930 //----------------------------------------------------------------------------
1931 XRootDStatus FileSystem::SendInfo( const std::string &info,
1932 Buffer *&response,
1933 uint16_t timeout )
1934 {
1935 SyncResponseHandler handler;
1936 Status st = SendInfo( info, &handler, timeout );
1937 if( !st.IsOK() )
1938 return st;
1939
1940 return MessageUtils::WaitForResponse( &handler, response );
1941 }
1942
1943 //----------------------------------------------------------------------------
1944 // Send set request to the server - async
1945 //----------------------------------------------------------------------------
1946 XRootDStatus FileSystem::SendSet( const char *prefix,
1947 const std::string &info,
1948 ResponseHandler *handler,
1949 uint16_t timeout )
1950 {
1951
1952 Message *msg;
1953 ClientSetRequest *req;
1954 size_t prefixLen = strlen( prefix );
1955 MessageUtils::CreateRequest( msg, req, info.length()+prefixLen );
1956
1957 req->requestid = kXR_set;
1958 req->dlen = info.length()+prefixLen;
1959 msg->Append( prefix, prefixLen, 24 );
1960 msg->Append( info.c_str(), info.length(), 24+prefixLen );
1961 MessageSendParams params; params.timeout = timeout;
1964
1965 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1966 }
1967
1968 //----------------------------------------------------------------------------
1969 // Prepare one or more files for access - async
1970 //----------------------------------------------------------------------------
1971 XRootDStatus FileSystem::Prepare( const std::vector<std::string> &fileList,
1972 PrepareFlags::Flags flags,
1973 uint8_t priority,
1974 ResponseHandler *handler,
1975 uint16_t timeout )
1976 {
1977 if( pPlugIn )
1978 return pPlugIn->Prepare( fileList, flags, priority, handler, timeout );
1979
1980 std::vector<std::string>::const_iterator it;
1981 std::string list;
1982 for( it = fileList.begin(); it != fileList.end(); ++it )
1983 {
1984 list += *it;
1985 list += "\n";
1986 }
1987 list.erase( list.length()-1, 1 );
1988
1989 Message *msg;
1991 MessageUtils::CreateRequest( msg, req, list.length() );
1992
1993 req->requestid = kXR_prepare;
1994 req->options = 0xff & flags;
1995 req->optionX = 0xffff & ( flags >> 8 );
1996 req->prty = priority;
1997 req->dlen = list.length();
1998
1999 msg->Append( list.c_str(), list.length(), 24 );
2000
2001 MessageSendParams params; params.timeout = timeout;
2004
2005 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
2006 }
2007
2008 //------------------------------------------------------------------------
2009 // Prepare one or more files for access - sync
2010 //------------------------------------------------------------------------
2011 XRootDStatus FileSystem::Prepare( const std::vector<std::string> &fileList,
2012 PrepareFlags::Flags flags,
2013 uint8_t priority,
2014 Buffer *&response,
2015 uint16_t timeout )
2016 {
2017 SyncResponseHandler handler;
2018 Status st = Prepare( fileList, flags, priority, &handler, timeout );
2019 if( !st.IsOK() )
2020 return st;
2021
2022 return MessageUtils::WaitForResponse( &handler, response );
2023 }
2024
2025 //------------------------------------------------------------------------
2026 // Set extended attributes - async
2027 //------------------------------------------------------------------------
2028 XRootDStatus FileSystem::SetXAttr( const std::string &path,
2029 const std::vector<xattr_t> &attrs,
2030 ResponseHandler *handler,
2031 uint16_t timeout )
2032 {
2033 if( pPlugIn )
2035
2036 return XAttrOperationImpl( kXR_fattrSet, 0, path, attrs, handler, timeout );
2037 }
2038
2039 //------------------------------------------------------------------------
2040 // Set extended attributes - sync
2041 //------------------------------------------------------------------------
2042 XRootDStatus FileSystem::SetXAttr( const std::string &path,
2043 const std::vector<xattr_t> &attrs,
2044 std::vector<XAttrStatus> &result,
2045 uint16_t timeout )
2046 {
2047 SyncResponseHandler handler;
2048 XRootDStatus st = SetXAttr( path, attrs, &handler, timeout );
2049 if( !st.IsOK() )
2050 return st;
2051
2052 std::vector<XAttrStatus> *resp = 0;
2053 st = MessageUtils::WaitForResponse( &handler, resp );
2054 if( resp ) result.swap( *resp );
2055 delete resp;
2056
2057 return st;
2058 }
2059
2060 //------------------------------------------------------------------------
2061 // Get extended attributes - async
2062 //------------------------------------------------------------------------
2063 XRootDStatus FileSystem::GetXAttr( const std::string &path,
2064 const std::vector<std::string> &attrs,
2065 ResponseHandler *handler,
2066 uint16_t timeout )
2067 {
2068 if( pPlugIn )
2070
2071 return XAttrOperationImpl( kXR_fattrGet, 0, path, attrs, handler, timeout );
2072 }
2073
2074 //------------------------------------------------------------------------
2075 // Get extended attributes - sync
2076 //------------------------------------------------------------------------
2077 XRootDStatus FileSystem::GetXAttr( const std::string &path,
2078 const std::vector<std::string> &attrs,
2079 std::vector<XAttr> &result,
2080 uint16_t timeout )
2081 {
2082 SyncResponseHandler handler;
2083 XRootDStatus st = GetXAttr( path, attrs, &handler, timeout );
2084 if( !st.IsOK() )
2085 return st;
2086
2087 std::vector<XAttr> *resp = 0;
2088 st = MessageUtils::WaitForResponse( &handler, resp );
2089 if( resp ) result.swap( *resp );
2090 delete resp;
2091
2092 return st;
2093 }
2094
2095 //------------------------------------------------------------------------
2096 // Delete extended attributes - async
2097 //------------------------------------------------------------------------
2098 XRootDStatus FileSystem::DelXAttr( const std::string &path,
2099 const std::vector<std::string> &attrs,
2100 ResponseHandler *handler,
2101 uint16_t timeout )
2102 {
2103 if( pPlugIn )
2105
2106 return XAttrOperationImpl( kXR_fattrDel, 0, path, attrs, handler, timeout );
2107 }
2108
2109 //------------------------------------------------------------------------
2110 // Delete extended attributes - sync
2111 //------------------------------------------------------------------------
2112 XRootDStatus FileSystem::DelXAttr( const std::string &path,
2113 const std::vector<std::string> &attrs,
2114 std::vector<XAttrStatus> &result,
2115 uint16_t timeout )
2116 {
2117 SyncResponseHandler handler;
2118 XRootDStatus st = DelXAttr( path, attrs, &handler, timeout );
2119 if( !st.IsOK() )
2120 return st;
2121
2122 std::vector<XAttrStatus> *resp = 0;
2123 st = MessageUtils::WaitForResponse( &handler, resp );
2124 if( resp ) result.swap( *resp );
2125 delete resp;
2126
2127 return st;
2128 }
2129
2130 //------------------------------------------------------------------------
2131 // List extended attributes - async
2132 //------------------------------------------------------------------------
2133 XRootDStatus FileSystem::ListXAttr( const std::string &path,
2134 ResponseHandler *handler,
2135 uint16_t timeout )
2136 {
2137 if( pPlugIn )
2139
2140 static const std::vector<std::string> nothing;
2141 return XAttrOperationImpl( kXR_fattrList, ClientFattrRequest::aData,
2142 path, nothing, handler, timeout );
2143 }
2144
2145 //------------------------------------------------------------------------
2146 // List extended attributes - sync
2147 //------------------------------------------------------------------------
2148 XRootDStatus FileSystem::ListXAttr( const std::string &path,
2149 std::vector<XAttr> &result,
2150 uint16_t timeout )
2151 {
2152 SyncResponseHandler handler;
2153 XRootDStatus st = ListXAttr( path, &handler, timeout );
2154 if( !st.IsOK() )
2155 return st;
2156
2157 std::vector<XAttr> *resp = 0;
2158 st = MessageUtils::WaitForResponse( &handler, resp );
2159 if( resp ) result.swap( *resp );
2160 delete resp;
2161
2162 return st;
2163 }
2164
2165 //----------------------------------------------------------------------------
2166 // Set file property
2167 //----------------------------------------------------------------------------
2168 bool FileSystem::SetProperty( const std::string &name,
2169 const std::string &value )
2170 {
2171 if( pPlugIn )
2172 return pPlugIn->SetProperty( name, value );
2173
2174 if( name == "FollowRedirects" )
2175 {
2176 if( value == "true" ) pImpl->fsdata->pFollowRedirects = true;
2177 else pImpl->fsdata->pFollowRedirects = false;
2178 return true;
2179 }
2180 return false;
2181 }
2182
2183 //----------------------------------------------------------------------------
2184 // Get file property
2185 //----------------------------------------------------------------------------
2186 bool FileSystem::GetProperty( const std::string &name,
2187 std::string &value ) const
2188 {
2189 if( pPlugIn )
2190 return pPlugIn->GetProperty( name, value );
2191
2192 if( name == "FollowRedirects" )
2193 {
2194 if( pImpl->fsdata->pFollowRedirects ) value = "true";
2195 else value = "false";
2196 return true;
2197 }
2198 else if( name == "LastURL" )
2199 {
2200 if( pImpl->fsdata->pLastUrl )
2201 {
2202 value = pImpl->fsdata->pLastUrl->GetURL();
2203 return true;
2204 }
2205 else return false;
2206 }
2207
2208 return false;
2209 }
2210
2211 //------------------------------------------------------------------------
2212 // Generic implementation of xattr operation
2213 //------------------------------------------------------------------------
2214 template<typename T>
2215 Status FileSystem::XAttrOperationImpl( kXR_char subcode,
2216 kXR_char options,
2217 const std::string &path,
2218 const std::vector<T> &attrs,
2219 ResponseHandler *handler,
2220 uint16_t timeout )
2221 {
2222 Message *msg;
2223 ClientFattrRequest *req;
2224 MessageUtils::CreateRequest( msg, req );
2225
2226 req->requestid = kXR_fattr;
2227 req->subcode = subcode;
2228 req->options = options;
2229 req->numattr = attrs.size();
2230 memset( req->fhandle, 0, 4 );
2231 XRootDStatus st = MessageUtils::CreateXAttrBody( msg, attrs, path );
2232 if( !st.IsOK() ) return st;
2233
2234 MessageSendParams params; params.timeout = timeout;
2236
2238
2239 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
2240 }
2241
2242 //------------------------------------------------------------------------
2243 // Lock the internal lock
2244 //------------------------------------------------------------------------
2245 void FileSystem::Lock()
2246 {
2247 pImpl->fsdata->pMutex.Lock();
2248 }
2249
2250 //------------------------------------------------------------------------
2251 // Unlock the internal lock
2252 //------------------------------------------------------------------------
2253 void FileSystem::UnLock()
2254 {
2255 pImpl->fsdata->pMutex.UnLock();
2256 }
2257}
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:104
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