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", (void*)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", (void*)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", (void*)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 if(!info) {
356 log->Error(FileSystemMsg,
357 "[%p@DeepLocate(%s)] No locations received in response",
358 (void*)this, pPath.c_str());
359 return;
360 }
361
362 log->Dump( FileSystemMsg, "[%p@DeepLocate(%s)] Got %d locations",
363 (void*)this, pPath.c_str(), info->GetSize() );
364
365 for( it = info->Begin(); it != info->End(); ++it )
366 {
367 //--------------------------------------------------------------------
368 // Add the location to the list
369 //--------------------------------------------------------------------
370 if( it->IsServer() )
371 {
372 pLocations->Add( *it );
373 continue;
374 }
375
376 //--------------------------------------------------------------------
377 // Ask the manager for the location of servers
378 //--------------------------------------------------------------------
379 if( it->IsManager() )
380 {
381 ++pOutstanding;
382 FileSystem *fs = new FileSystem( it->GetAddress() );
383 if( pOutstanding == 0 || // protect against overflow, short circuiting
384 // will make sure the other part won't be executed
385 !fs->Locate( pPath, pFlags, new DeallocFSHandler(fs, this),
386 pExpires-::time(0)).IsOK() )
387 {
388 --pOutstanding;
389 pPartial = true;
390 delete fs;
391 }
392 }
393 }
394
395 //----------------------------------------------------------------------
396 // Clean up and check if we have anything else to do
397 //----------------------------------------------------------------------
398 delete response;
399 delete status;
400 if( !pOutstanding )
401 {
402 scopedLock.UnLock();
403 HandleFinalResponse();
404 }
405 }
406
407 //------------------------------------------------------------------------
408 // Build the response for the client
409 //------------------------------------------------------------------------
410 void HandleFinalResponse()
411 {
412 using namespace XrdCl;
413
414 //----------------------------------------------------------------------
415 // Nothing found
416 //----------------------------------------------------------------------
417 if( !pLocations->GetSize() )
418 {
419 pHandler->HandleResponse( new XRootDStatus( stError, errErrorResponse,
421 "No valid location found" ),
422 0 );
423 }
424 //----------------------------------------------------------------------
425 // We return an answer
426 //----------------------------------------------------------------------
427 else
428 {
429 AnyObject *obj = new AnyObject();
430 obj->Set( pLocations );
431 pLocations = 0;
432 XRootDStatus *st = new XRootDStatus();
433 if( pPartial ) st->code = suPartial;
434 pHandler->HandleResponse( st, obj );
435 }
436 delete this;
437 }
438
439 private:
440 bool pFirstTime;
441 bool pPartial;
442 uint16_t pOutstanding;
443 XrdCl::ResponseHandler *pHandler;
444 XrdCl::LocationInfo *pLocations;
445 std::string pPath;
447 time_t pExpires;
448 XrdSysMutex pMutex;
449 };
450
451 //----------------------------------------------------------------------------
452 // Handle stat results for a dirlist request
453 //----------------------------------------------------------------------------
454 class DirListStatHandler: public XrdCl::ResponseHandler
455 {
456 public:
457 //------------------------------------------------------------------------
458 // Constructor
459 //------------------------------------------------------------------------
460 DirListStatHandler( XrdCl::DirectoryList *list,
461 uint32_t index,
462 XrdCl::RequestSync *sync ):
463 pList( list ),
464 pIndex( index ),
465 pSync( sync )
466 {
467 }
468
469 //------------------------------------------------------------------------
470 // Check if we were successful and if so put the StatInfo object
471 // in the appropriate entry info
472 //------------------------------------------------------------------------
473 virtual void HandleResponse( XrdCl::XRootDStatus *status,
474 XrdCl::AnyObject *response )
475 {
476 if( !status->IsOK() )
477 {
478 delete status;
479 pSync->TaskDone( false );
480 delete this;
481 return;
482 }
483
484 XrdCl::StatInfo *info = 0;
485 response->Get( info );
486 response->Set( (char*) 0 );
487 pList->At( pIndex )->SetStatInfo( info );
488 delete status;
489 delete response;
490 pSync->TaskDone();
491 delete this;
492 }
493
494 private:
496 uint32_t pIndex;
497 XrdCl::RequestSync *pSync;
498 };
499
500 //----------------------------------------------------------------------------
501 // Recursive dirlist common context for all handlers
502 //----------------------------------------------------------------------------
503 struct RecursiveDirListCtx
504 {
505 RecursiveDirListCtx( const XrdCl::URL &url, const std::string &path,
507 XrdCl::ResponseHandler *handler, time_t expires ) :
508 finalst( 0 ), pending( 1 ),
509 dirList( new XrdCl::DirectoryList() ), expires( expires ),
510 handler( handler ), flags( flags ),
511 fs( new XrdCl::FileSystem( url ) )
512 {
513 dirList->SetParentName( path );
514 }
515
516 ~RecursiveDirListCtx()
517 {
518 delete finalst;
519 delete dirList;
520 delete fs;
521 }
522
523 void UpdateStatus( const XrdCl::XRootDStatus &st )
524 {
525 using namespace XrdCl;
526
527 if( !finalst )
528 {
529 finalst = st.IsOK() ? new XRootDStatus() : new XRootDStatus( st );
530 return;
531 }
532
533 // if they disagree set the status to partial
534 if( ( finalst->IsOK() && !st.IsOK() ) ||
535 ( !finalst->IsOK() && st.IsOK() ) )
536 *finalst = XRootDStatus( stOK, suPartial );
537 }
538
539 XrdCl::XRootDStatus *finalst;
540 int pending;
541 XrdCl::DirectoryList *dirList;
542 time_t expires;
543 XrdCl::ResponseHandler *handler;
546 XrdSysMutex mtx;
547 };
548
549 //----------------------------------------------------------------------------
550 // Handle results for a recursive dirlist request
551 //----------------------------------------------------------------------------
552 class RecursiveDirListHandler: public XrdCl::ResponseHandler
553 {
554 public:
555
556 RecursiveDirListHandler( const XrdCl::URL &url,
557 const std::string &path,
559 XrdCl::ResponseHandler *handler,
560 time_t timeout )
561 {
562 time_t expires = 0;
563 if( timeout )
564 expires = ::time( 0 ) + timeout;
565 pCtx = new RecursiveDirListCtx( url, path, flags,
566 handler, expires );
567 }
568
569 RecursiveDirListHandler( RecursiveDirListCtx *ctx ) : pCtx( ctx )
570 {
571
572 }
573
574 virtual void HandleResponse( XrdCl::XRootDStatus *status,
575 XrdCl::AnyObject *response )
576 {
577 using namespace XrdCl;
578
579 Log *log = DefaultEnv::GetLog();
580 bool finalrsp = !( status->IsOK() && status->code == XrdCl::suContinue );
581 XrdSysMutexHelper scoped( pCtx->mtx );
582
583 // check if we have to continue with the same handler (the response
584 // has been chunked), if not we can decrement the number of pending
585 // DieLists
586 if( finalrsp )
587 --pCtx->pending;
588
589 pCtx->UpdateStatus( *status );
590
591 if( status->IsOK() )
592 {
593 // get the response
594 DirectoryList *dirList = 0;
595 response->Get( dirList );
596
597 std::string parent = pCtx->dirList->GetParentName();
598
600 for( itr = dirList->Begin(); itr != dirList->End(); ++itr )
601 {
602 DirectoryList::ListEntry *entry = *itr;
603 StatInfo *info = entry->GetStatInfo();
604 if( !info )
605 {
606 log->Error( FileMsg, "Recursive directory list operation for %s failed: "
607 "kXR_dirlist with stat operation not supported.",
608 parent.c_str() );
609 pCtx->UpdateStatus( XRootDStatus( stError, errNotSupported ) );
610 continue;
611 }
612 std::string path = dirList->GetParentName() + entry->GetName();
613
614 // add new entry to the result
615 path = path.substr( parent.size() );
616 entry->SetStatInfo( 0 ); // StatInfo is no longer owned by dirList
618 new DirectoryList::ListEntry( entry->GetHostAddress(), path, info );
619 pCtx->dirList->Add( e );
620
621 // if it's a directory do a recursive call
622 if( info->TestFlags( StatInfo::IsDir ) )
623 {
624 // bump the pending counter
625 ++pCtx->pending;
626 // switch of the recursive flag, we will
627 // provide the respective handler ourself,
628 // make sure that stat is on
629 DirListFlags::Flags flags = ( pCtx->flags & (~DirListFlags::Recursive) )
631 // the recursive dir list handler
632 RecursiveDirListHandler *handler = new RecursiveDirListHandler( pCtx );
633 // timeout
634 time_t timeout = 0;
635 if( pCtx->expires )
636 {
637 timeout = pCtx->expires - ::time( 0 );
638 if( timeout <= 0 )
639 {
640 log->Error( FileMsg, "Recursive directory list operation for %s expired.",
641 parent.c_str() );
642 pCtx->UpdateStatus( XRootDStatus( stError, errOperationExpired ) );
643 break;
644 }
645 }
646 // send the request
647 std::string child = parent + path;
648 XRootDStatus st = pCtx->fs->DirList( child, flags, handler, timeout );
649 if( !st.IsOK() )
650 {
651 log->Error( FileMsg, "Recursive directory list operation for %s failed: %s",
652 child.c_str(), st.ToString().c_str() );
653 pCtx->UpdateStatus( st );
654 continue;
655 }
656 }
657 }
658 }
659
660 // if there are no more outstanding dirlist queries we can finalize the request
661 if( pCtx->pending == 0 )
662 {
663 AnyObject *resp = new AnyObject();
664 resp->Set( pCtx->dirList );
665 pCtx->dirList = 0; // dirList is no longer owned by pCtx
666 pCtx->handler->HandleResponse( pCtx->finalst, resp );
667 pCtx->finalst = 0; // status is no longer owned by pCtx
668
669 // finalize the common context
670 scoped.UnLock();
671 delete pCtx;
672 }
673 // if the user requested chunked response we give what we have to the user handler
674 else if( status->IsOK() && ( pCtx->flags & DirListFlags::Chunked ) )
675 {
676 std::string parent = pCtx->dirList->GetParentName();
677 AnyObject *resp = new AnyObject();
678 resp->Set( pCtx->dirList );
679 pCtx->dirList = new XrdCl::DirectoryList();
680 pCtx->dirList->SetParentName( parent );
681 pCtx->handler->HandleResponse( new XRootDStatus( stOK, suContinue ), resp );
682 }
683
684 // clean up the arguments
685 delete status;
686 delete response;
687 // if we won't be continuing with the same handler, it can be deleted
688 if( finalrsp )
689 delete this;
690 }
691
692 private:
693
694 RecursiveDirListCtx *pCtx;
695 };
696
697 //----------------------------------------------------------------------------
698 // Exception for a merge dirlist handler
699 //----------------------------------------------------------------------------
700 struct MergeDirLsErr
701 {
702 MergeDirLsErr( XrdCl::XRootDStatus *&status, XrdCl::AnyObject *&response ) :
703 status( status ), response( response )
704 {
705 status = 0; response = 0;
706 }
707
708 MergeDirLsErr() :
709 status( new XrdCl::XRootDStatus( XrdCl::stError, XrdCl::errInternal ) ),
710 response( 0 )
711 {
712
713 }
714
715 XrdCl::XRootDStatus *status;
716 XrdCl::AnyObject *response;
717 };
718
719
720
721 //----------------------------------------------------------------------------
722 // Handle results for a merge dirlist request
723 //----------------------------------------------------------------------------
724 class MergeDirListHandler: public XrdCl::ResponseHandler
725 {
726 public:
727
728 MergeDirListHandler( bool allowChunked, XrdCl::ResponseHandler *handler ) :
729 allowChunked( allowChunked ), pHandler( handler )
730 {
731
732 }
733
734 virtual void HandleResponse( XrdCl::XRootDStatus *status,
735 XrdCl::AnyObject *response )
736 {
737 XrdSysMutexHelper lck( mtx );
738
739 bool finalrsp = !( status->IsOK() && status->code == XrdCl::suContinue );
740
741 try
742 {
743 if( !status->IsOK() )
744 throw MergeDirLsErr( status, response );
745
746 if( !response )
747 throw MergeDirLsErr();
748
749 XrdCl::DirectoryList *dirlist = 0;
750 response->Get( dirlist );
751
752 if( !dirlist )
753 throw MergeDirLsErr();
754
755 if( allowChunked )
756 MergeChunked( dirlist );
757 else
758 Merge( dirlist );
759
760 response->Set( dirlist );
761 pHandler->HandleResponse( status, response );
762 }
763 catch( const MergeDirLsErr &err )
764 {
765 delete status; delete response;
766 pHandler->HandleResponse( err.status, err.response );
767 }
768
769 if( finalrsp )
770 {
771 lck.UnLock();
772 delete this;
773 }
774 }
775
776 void MergeChunked( XrdCl::DirectoryList *&response )
777 {
778 using namespace XrdCl;
779
780 std::set<ListEntry*, less> unique;
781 // set of unique list entries from the response
782 std::set<ListEntry*, less> tmp( response->Begin(), response->End() );
783 // all the unique list entries that were not reported so far
784 std::set_difference( tmp.begin(), tmp.end(),
785 uniquesofar.begin(), uniquesofar.end(),
786 std::inserter( unique, unique.end() ) );
787
788 // we update the set of unique list entries that were already
789 // reported to the user's handler
790 for( auto itr = unique.begin(); itr != unique.end(); ++itr )
791 {
792 ListEntry *ent = *itr;
793 if( !uniquesofar.count( ent ) )
794 {
795 StatInfo *info = ent->GetStatInfo() ? new StatInfo( *ent->GetStatInfo() ) : 0;
796 ListEntry *newent = new ListEntry( ent->GetHostAddress(), ent->GetName(), info );
797 uniquesofar.insert( newent );
798 }
799 }
800
801 DirectoryList *dirlist = new DirectoryList();
802 dirlist->SetParentName( response->GetParentName() );
803 for( auto itr = unique.begin(); itr != unique.end(); ++itr )
804 {
805 ListEntry *entry = *itr;
806 dirlist->Add( new ListEntry( entry->GetHostAddress(),
807 entry->GetName(),
808 entry->GetStatInfo() ) );
809 entry->SetStatInfo( 0 );
810 }
811
812 delete response;
813 response = dirlist;
814 }
815
816 static void Merge( XrdCl::DirectoryList *&response )
817 {
818 std::set<ListEntry*, less> unique( response->Begin(), response->End() );
819
821 dirlist->SetParentName( response->GetParentName() );
822 for( auto itr = unique.begin(); itr != unique.end(); ++itr )
823 {
824 ListEntry *entry = *itr;
825 dirlist->Add( new ListEntry( entry->GetHostAddress(),
826 entry->GetName(),
827 entry->GetStatInfo() ) );
828 entry->SetStatInfo( 0 );
829 }
830
831 delete response;
832 response = dirlist;
833}
834
835 private:
836
837 typedef XrdCl::DirectoryList::ListEntry ListEntry;
838
839 struct less
840 {
841 bool operator() (const ListEntry *x, const ListEntry *y) const
842 {
843 if( x->GetName() != y->GetName() )
844 return x->GetName() < y->GetName();
845
846 const XrdCl::StatInfo *xStatInfo = x->GetStatInfo();
847 const XrdCl::StatInfo *yStatInfo = y->GetStatInfo();
848
849 if( xStatInfo == yStatInfo )
850 return false;
851
852 if( xStatInfo == 0 )
853 return true;
854
855 if( yStatInfo == 0 )
856 return false;
857
858 if( xStatInfo->GetSize() != yStatInfo->GetSize() )
859 return xStatInfo->GetSize() < yStatInfo->GetSize();
860
861 if( xStatInfo->GetFlags() != yStatInfo->GetFlags() )
862 return xStatInfo->GetFlags() < yStatInfo->GetFlags();
863
864 return false;
865 }
866 };
867
868 bool allowChunked;
869 XrdSysMutex mtx;
870 std::set<ListEntry*, less> uniquesofar;
871 XrdCl::ResponseHandler *pHandler;
872 };
873}
874
875namespace XrdCl
876{
877 struct FileSystemData;
878
879 //----------------------------------------------------------------------------
881 //----------------------------------------------------------------------------
883 {
884 public:
885 //------------------------------------------------------------------------
886 // Constructor and destructor
887 //------------------------------------------------------------------------
888 AssignLBHandler( std::shared_ptr<FileSystemData> &fs,
889 ResponseHandler *userHandler ):
890 pFS(fs), pUserHandler(userHandler) {}
891
892 virtual ~AssignLBHandler() {}
893
894 //------------------------------------------------------------------------
895 // Response callback
896 //------------------------------------------------------------------------
897 virtual void HandleResponseWithHosts( XRootDStatus *status,
898 AnyObject *response,
899 HostList *hostList );
900
901 private:
902 std::shared_ptr<FileSystemData> pFS;
903 ResponseHandler *pUserHandler;
904 };
905
906 //----------------------------------------------------------------------------
908 //----------------------------------------------------------------------------
910 {
911 public:
912 //------------------------------------------------------------------------
913 // Constructor and destructor
914 //------------------------------------------------------------------------
915 AssignLastURLHandler( std::shared_ptr<FileSystemData> &fs,
916 ResponseHandler *userHandler ):
917 pFS(fs), pUserHandler(userHandler) {}
918
920
921 //------------------------------------------------------------------------
922 // Response callback
923 //------------------------------------------------------------------------
924 virtual void HandleResponseWithHosts( XRootDStatus *status,
925 AnyObject *response,
926 HostList *hostList );
927
928 private:
929 std::shared_ptr<FileSystemData> pFS;
930 ResponseHandler *pUserHandler;
931 };
932
933
935 {
936 FileSystemData( const URL &url ) :
938 pFollowRedirects( true ),
939 pUrl( new URL( url.GetURL() ) )
940 {
941 }
942
943 //------------------------------------------------------------------------
944 // Send a message in a locked environment
945 //------------------------------------------------------------------------
946 static XRootDStatus Send( std::shared_ptr<FileSystemData> &fs,
947 Message *msg,
948 ResponseHandler *handler,
949 MessageSendParams &params )
950 {
951 Log *log = DefaultEnv::GetLog();
952 XrdSysMutexHelper scopedLock( fs->pMutex );
953
954 log->Dump( FileSystemMsg, "[%p@%s] Sending %s", (void*)fs.get(),
955 fs->pUrl->GetHostId().c_str(), msg->GetObfuscatedDescription().c_str() );
956
957 AssignLastURLHandler *lastUrlHandler = new AssignLastURLHandler( fs, handler );
958 handler = lastUrlHandler;
959
960 AssignLBHandler *lbHandler = nullptr;
961 if( !fs->pLoadBalancerLookupDone && fs->pFollowRedirects )
962 {
963 lbHandler = new AssignLBHandler( fs, handler );
964 handler = lbHandler;
965 }
966
967 params.followRedirects = fs->pFollowRedirects;
968
969 auto st = MessageUtils::SendMessage( *fs->pUrl, msg, handler, params, 0 );
970 if( !st.IsOK() )
971 {
972 delete lastUrlHandler;
973 delete lbHandler;
974 }
975
976 return st;
977 }
978
979 //----------------------------------------------------------------------------
980 // Assign a load balancer if it has not already been assigned
981 //----------------------------------------------------------------------------
982 void AssignLoadBalancer( const URL &url )
983 {
984 Log *log = DefaultEnv::GetLog();
985 XrdSysMutexHelper scopedLock( pMutex );
986
988 return;
989
990 log->Dump( FileSystemMsg, "[%p@%s] Assigning %s as load balancer", (void*)this,
991 pUrl->GetHostId().c_str(), url.GetHostId().c_str() );
992
993 pUrl.reset( new URL( url ) );
995 }
996
997 //----------------------------------------------------------------------------
998 // Assign last URL
999 //----------------------------------------------------------------------------
1000 void AssignLastURL( const URL &url )
1001 {
1002 Log *log = DefaultEnv::GetLog();
1003 XrdSysMutexHelper scopedLock( pMutex );
1004
1005 log->Dump( FileSystemMsg, "[%p@%s] Assigning %s as last URL", (void*)this,
1006 pUrl->GetHostId().c_str(), url.GetHostId().c_str() );
1007
1008 pLastUrl.reset( new URL( url ) );
1009 }
1010
1014 std::unique_ptr<URL> pUrl;
1015 std::unique_ptr<URL> pLastUrl;
1016 };
1017
1018 //----------------------------------------------------------------------------
1020 //----------------------------------------------------------------------------
1022 {
1023 FileSystemImpl( const URL &url ) :
1024 fsdata( std::make_shared<FileSystemData>( url ) )
1025 {
1026 }
1027
1028 std::shared_ptr<FileSystemData> fsdata;
1029 };
1030
1031 //------------------------------------------------------------------------
1032 // Response callback
1033 //------------------------------------------------------------------------
1035 AnyObject *response,
1036 HostList *hostList )
1037 {
1038 if( status->IsOK() )
1039 {
1040 HostList::reverse_iterator it;
1041 for( it = hostList->rbegin(); it != hostList->rend(); ++it )
1042 if( it->loadBalancer )
1043 {
1044 pFS->AssignLoadBalancer( it->url );
1045 break;
1046 }
1047 }
1048
1049 bool finalrsp = !( status->IsOK() && status->code == suContinue );
1050
1051 SyncResponseHandler * syncHandler = dynamic_cast<SyncResponseHandler*>( pUserHandler );
1052 if( !syncHandler )
1053 pUserHandler->HandleResponseWithHosts( status, response, hostList );
1054
1055 if( finalrsp )
1056 {
1057 if( syncHandler )
1058 pUserHandler->HandleResponseWithHosts( status, response, hostList );
1059 delete this;
1060 }
1061 }
1062
1063 //------------------------------------------------------------------------
1064 // Response callback
1065 //------------------------------------------------------------------------
1067 AnyObject *response,
1068 HostList *hostList )
1069 {
1070 if( status->IsOK() && hostList )
1071 pFS->AssignLastURL( hostList->front().url );
1072
1073 bool finalrsp = !( status->IsOK() && status->code == suContinue );
1074
1075 SyncResponseHandler *syncHandler = dynamic_cast<SyncResponseHandler*>( pUserHandler );
1076 if( !syncHandler )
1077 pUserHandler->HandleResponseWithHosts( status, response, hostList );
1078
1079 if( finalrsp )
1080 {
1081 if( syncHandler )
1082 pUserHandler->HandleResponseWithHosts( status, response, hostList );
1083 delete this;
1084 }
1085 }
1086
1087 //----------------------------------------------------------------------------
1088 // Constructor
1089 //----------------------------------------------------------------------------
1090 FileSystem::FileSystem( const URL &url, bool enablePlugIns ):
1091 pImpl( new FileSystemImpl( url ) ),
1092 pPlugIn(0)
1093 {
1094 //--------------------------------------------------------------------------
1095 // Check if we need to install a plug-in for this URL
1096 //--------------------------------------------------------------------------
1097 if( enablePlugIns )
1098 {
1099 Log *log = DefaultEnv::GetLog();
1100 std::string urlStr = url.GetURL();
1102 if( fact )
1103 {
1104 pPlugIn = fact->CreateFileSystem( urlStr );
1105 if( !pPlugIn )
1106 {
1107 log->Error( FileMsg, "Plug-in factory failed to produce a plug-in "
1108 "for %s, continuing without one", url.GetObfuscatedURL().c_str() );
1109 }
1110 }
1111 }
1112
1113 if( !pPlugIn )
1115 }
1116
1117 //----------------------------------------------------------------------------
1118 // Destructor
1119 //----------------------------------------------------------------------------
1121 {
1122 if( !pPlugIn )
1123 {
1126 }
1127
1128 delete pPlugIn;
1129 delete pImpl;
1130 }
1131
1132 //----------------------------------------------------------------------------
1133 // Locate a file - async
1134 //----------------------------------------------------------------------------
1135 XRootDStatus FileSystem::Locate( const std::string &path,
1136 OpenFlags::Flags flags,
1137 ResponseHandler *handler,
1138 uint16_t timeout )
1139 {
1140 if( pPlugIn )
1141 return pPlugIn->Locate( path, flags, handler, timeout );
1142
1143 std::string fPath = FilterXrdClCgi( path );
1144
1145 Message *msg;
1147 MessageUtils::CreateRequest( msg, req, fPath.length() );
1148
1149 req->requestid = kXR_locate;
1150 req->options = flags;
1151 req->dlen = fPath.length();
1152 msg->Append( fPath.c_str(), fPath.length(), 24 );
1153 MessageSendParams params; params.timeout = timeout;
1155
1157
1158 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1159 }
1160
1161 //----------------------------------------------------------------------------
1162 // Locate a file - sync
1163 //----------------------------------------------------------------------------
1164 XRootDStatus FileSystem::Locate( const std::string &path,
1165 OpenFlags::Flags flags,
1166 LocationInfo *&response,
1167 uint16_t timeout )
1168 {
1169 SyncResponseHandler handler;
1170 Status st = Locate( path, flags, &handler, timeout );
1171 if( !st.IsOK() )
1172 return st;
1173
1174 return MessageUtils::WaitForResponse( &handler, response );
1175 }
1176
1177 //----------------------------------------------------------------------------
1178 // Locate a file, recursively locate all disk servers - async
1179 //----------------------------------------------------------------------------
1180 XRootDStatus FileSystem::DeepLocate( const std::string &path,
1181 OpenFlags::Flags flags,
1182 ResponseHandler *handler,
1183 uint16_t timeout )
1184 {
1185 return Locate( path, flags,
1186 new DeepLocateHandler( handler, path, flags, timeout ), timeout );
1187 }
1188
1189 //----------------------------------------------------------------------------
1190 // Locate a file, recursively locate all disk servers - sync
1191 //----------------------------------------------------------------------------
1192 XRootDStatus FileSystem::DeepLocate( const std::string &path,
1193 OpenFlags::Flags flags,
1194 LocationInfo *&response,
1195 uint16_t timeout )
1196 {
1197 SyncResponseHandler handler;
1198 Status st = DeepLocate( path, flags, &handler, timeout );
1199 if( !st.IsOK() )
1200 return st;
1201
1202 return MessageUtils::WaitForResponse( &handler, response );
1203 }
1204
1205 //----------------------------------------------------------------------------
1206 // Move a directory or a file - async
1207 //----------------------------------------------------------------------------
1208 XRootDStatus FileSystem::Mv( const std::string &source,
1209 const std::string &dest,
1210 ResponseHandler *handler,
1211 uint16_t timeout )
1212 {
1213 if( pPlugIn )
1214 return pPlugIn->Mv( source, dest, handler, timeout );
1215
1216 std::string fSource = FilterXrdClCgi( source );
1217 std::string fDest = FilterXrdClCgi( dest );
1218
1219 Message *msg;
1220 ClientMvRequest *req;
1221 MessageUtils::CreateRequest( msg, req, fSource.length() + fDest.length()+1 );
1222
1223 req->requestid = kXR_mv;
1224 req->dlen = fSource.length() + fDest.length()+1;
1225 req->arg1len = fSource.length();
1226 msg->Append( fSource.c_str(), fSource.length(), 24 );
1227 *msg->GetBuffer(24 + fSource.length()) = ' ';
1228 msg->Append( fDest.c_str(), fDest.length(), 25 + fSource.length() );
1229 MessageSendParams params; params.timeout = timeout;
1231
1233
1234 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1235 }
1236
1237 //----------------------------------------------------------------------------
1238 // Move a directory or a file - sync
1239 //----------------------------------------------------------------------------
1240 XRootDStatus FileSystem::Mv( const std::string &source,
1241 const std::string &dest,
1242 uint16_t timeout )
1243 {
1244 SyncResponseHandler handler;
1245 Status st = Mv( source, dest, &handler, timeout );
1246 if( !st.IsOK() )
1247 return st;
1248
1249 return MessageUtils::WaitForStatus( &handler );
1250 }
1251
1252 //----------------------------------------------------------------------------
1253 // Obtain server information - async
1254 //----------------------------------------------------------------------------
1256 const Buffer &arg,
1257 ResponseHandler *handler,
1258 uint16_t timeout )
1259 {
1260 if( pPlugIn )
1261 return pPlugIn->Query( queryCode, arg, handler, timeout );
1262
1263 Message *msg;
1264 ClientQueryRequest *req;
1265 MessageUtils::CreateRequest( msg, req, arg.GetSize() );
1266
1267 req->requestid = kXR_query;
1268 req->infotype = queryCode;
1269 req->dlen = arg.GetSize();
1270 msg->Append( arg.GetBuffer(), arg.GetSize(), 24 );
1271 MessageSendParams params; params.timeout = timeout;
1274
1275 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1276 }
1277
1278 //----------------------------------------------------------------------------
1279 // Obtain server information - sync
1280 //----------------------------------------------------------------------------
1282 const Buffer &arg,
1283 Buffer *&response,
1284 uint16_t timeout )
1285 {
1286 SyncResponseHandler handler;
1287 Status st = Query( queryCode, arg, &handler, timeout );
1288 if( !st.IsOK() )
1289 return st;
1290
1291 return MessageUtils::WaitForResponse( &handler, response );
1292 }
1293
1294 //----------------------------------------------------------------------------
1295 // Truncate a file - async
1296 //----------------------------------------------------------------------------
1297 XRootDStatus FileSystem::Truncate( const std::string &path,
1298 uint64_t size,
1299 ResponseHandler *handler,
1300 uint16_t timeout )
1301 {
1302 if( pPlugIn )
1303 return pPlugIn->Truncate( path, size, handler, timeout );
1304
1305 std::string fPath = FilterXrdClCgi( path );
1306
1307 Message *msg;
1309 MessageUtils::CreateRequest( msg, req, fPath.length() );
1310
1311 req->requestid = kXR_truncate;
1312 req->offset = size;
1313 req->dlen = fPath.length();
1314 msg->Append( fPath.c_str(), fPath.length(), 24 );
1315 MessageSendParams params; params.timeout = timeout;
1318
1319 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1320 }
1321
1322 //----------------------------------------------------------------------------
1323 // Truncate a file - sync
1324 //----------------------------------------------------------------------------
1325 XRootDStatus FileSystem::Truncate( const std::string &path,
1326 uint64_t size,
1327 uint16_t timeout )
1328 {
1329 SyncResponseHandler handler;
1330 Status st = Truncate( path, size, &handler, timeout );
1331 if( !st.IsOK() )
1332 return st;
1333
1334 return MessageUtils::WaitForStatus( &handler );
1335 }
1336
1337 //----------------------------------------------------------------------------
1338 // Remove a file - async
1339 //----------------------------------------------------------------------------
1340 XRootDStatus FileSystem::Rm( const std::string &path,
1341 ResponseHandler *handler,
1342 uint16_t timeout )
1343 {
1344 if( pPlugIn )
1345 return pPlugIn->Rm( path, handler, timeout );
1346
1347 if( pImpl->fsdata->pUrl->IsLocalFile() )
1348 return LocalFS::Instance().Rm( path, handler, timeout );
1349
1350 std::string fPath = FilterXrdClCgi( path );
1351
1352 Message *msg;
1353 ClientRmRequest *req;
1354 MessageUtils::CreateRequest( msg, req, fPath.length() );
1355
1356 req->requestid = kXR_rm;
1357 req->dlen = fPath.length();
1358 msg->Append( fPath.c_str(), fPath.length(), 24 );
1359 MessageSendParams params; params.timeout = timeout;
1362
1363 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1364 }
1365
1366 //----------------------------------------------------------------------------
1367 // Remove a file - sync
1368 //----------------------------------------------------------------------------
1369 XRootDStatus FileSystem::Rm( const std::string &path,
1370 uint16_t timeout )
1371 {
1372 SyncResponseHandler handler;
1373 Status st = Rm( path, &handler, timeout );
1374 if( !st.IsOK() )
1375 return st;
1376
1377 return MessageUtils::WaitForStatus( &handler );
1378 }
1379
1380 //----------------------------------------------------------------------------
1381 // Create a directory - async
1382 //----------------------------------------------------------------------------
1383 XRootDStatus FileSystem::MkDir( const std::string &path,
1384 MkDirFlags::Flags flags,
1385 Access::Mode mode,
1386 ResponseHandler *handler,
1387 uint16_t timeout )
1388 {
1389 if( pPlugIn )
1390 return pPlugIn->MkDir( path, flags, mode, handler, timeout );
1391
1392 std::string fPath = FilterXrdClCgi( path );
1393
1394 Message *msg;
1395 ClientMkdirRequest *req;
1396 MessageUtils::CreateRequest( msg, req, fPath.length() );
1397
1398 req->requestid = kXR_mkdir;
1399 req->options[0] = flags;
1400 req->mode = mode;
1401 req->dlen = fPath.length();
1402 msg->Append( fPath.c_str(), fPath.length(), 24 );
1403 MessageSendParams params; params.timeout = timeout;
1406
1407 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1408 }
1409
1410 //----------------------------------------------------------------------------
1411 // Create a directory - sync
1412 //----------------------------------------------------------------------------
1413 XRootDStatus FileSystem::MkDir( const std::string &path,
1414 MkDirFlags::Flags flags,
1415 Access::Mode mode,
1416 uint16_t timeout )
1417 {
1418 SyncResponseHandler handler;
1419 Status st = MkDir( path, flags, mode, &handler, timeout );
1420 if( !st.IsOK() )
1421 return st;
1422
1423 return MessageUtils::WaitForStatus( &handler );
1424 }
1425
1426 //----------------------------------------------------------------------------
1427 // Remove a directory - async
1428 //----------------------------------------------------------------------------
1429 XRootDStatus FileSystem::RmDir( const std::string &path,
1430 ResponseHandler *handler,
1431 uint16_t timeout )
1432 {
1433 if( pPlugIn )
1434 return pPlugIn->RmDir( path, handler, timeout );
1435
1436 std::string fPath = FilterXrdClCgi( path );
1437
1438 Message *msg;
1439 ClientRmdirRequest *req;
1440 MessageUtils::CreateRequest( msg, req, fPath.length() );
1441
1442 req->requestid = kXR_rmdir;
1443 req->dlen = fPath.length();
1444 msg->Append( fPath.c_str(), fPath.length(), 24 );
1445 MessageSendParams params; params.timeout = timeout;
1448
1449 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1450 }
1451
1452 //----------------------------------------------------------------------------
1453 // Remove a directory - sync
1454 //----------------------------------------------------------------------------
1455 XRootDStatus FileSystem::RmDir( const std::string &path,
1456 uint16_t timeout )
1457 {
1458 SyncResponseHandler handler;
1459 Status st = RmDir( path, &handler, timeout );
1460 if( !st.IsOK() )
1461 return st;
1462
1463 return MessageUtils::WaitForStatus( &handler );
1464 }
1465
1466 //----------------------------------------------------------------------------
1467 // Change access mode on a directory or a file - async
1468 //----------------------------------------------------------------------------
1469 XRootDStatus FileSystem::ChMod( const std::string &path,
1470 Access::Mode mode,
1471 ResponseHandler *handler,
1472 uint16_t timeout )
1473 {
1474 if( pPlugIn )
1475 return pPlugIn->ChMod( path, mode, handler, timeout );
1476
1477 std::string fPath = FilterXrdClCgi( path );
1478
1479 Message *msg;
1480 ClientChmodRequest *req;
1481 MessageUtils::CreateRequest( msg, req, fPath.length() );
1482
1483 req->requestid = kXR_chmod;
1484 req->mode = mode;
1485 req->dlen = fPath.length();
1486 msg->Append( fPath.c_str(), fPath.length(), 24 );
1487 MessageSendParams params; params.timeout = timeout;
1490
1491 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1492 }
1493
1494 //----------------------------------------------------------------------------
1495 // Change access mode on a directory or a file - async
1496 //----------------------------------------------------------------------------
1497 XRootDStatus FileSystem::ChMod( const std::string &path,
1498 Access::Mode mode,
1499 uint16_t timeout )
1500 {
1501 SyncResponseHandler handler;
1502 Status st = ChMod( path, mode, &handler, timeout );
1503 if( !st.IsOK() )
1504 return st;
1505
1506 return MessageUtils::WaitForStatus( &handler );
1507 }
1508
1509 //----------------------------------------------------------------------------
1510 // Check if the server is alive - async
1511 //----------------------------------------------------------------------------
1513 uint16_t timeout )
1514 {
1515 if( pPlugIn )
1516 return pPlugIn->Ping( handler, timeout );
1517
1518 Message *msg;
1519 ClientPingRequest *req;
1520 MessageUtils::CreateRequest( msg, req );
1521
1522 req->requestid = kXR_ping;
1523 MessageSendParams params; params.timeout = timeout;
1526
1527 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1528 }
1529
1530 //----------------------------------------------------------------------------
1531 // Check if the server is alive - sync
1532 //----------------------------------------------------------------------------
1533 XRootDStatus FileSystem::Ping( uint16_t timeout )
1534 {
1535 SyncResponseHandler handler;
1536 Status st = Ping( &handler, timeout );
1537 if( !st.IsOK() )
1538 return st;
1539
1540 return MessageUtils::WaitForStatus( &handler );
1541 }
1542
1543 //----------------------------------------------------------------------------
1544 // Obtain status information for a path - async
1545 //----------------------------------------------------------------------------
1546 XRootDStatus FileSystem::Stat( const std::string &path,
1547 ResponseHandler *handler,
1548 uint16_t timeout )
1549 {
1550 if( pPlugIn )
1551 return pPlugIn->Stat( path, handler, timeout );
1552
1553 if( pImpl->fsdata->pUrl->IsLocalFile() )
1554 return LocalFS::Instance().Stat( path, handler, timeout );
1555
1556 std::string fPath = FilterXrdClCgi( path );
1557
1558 Message *msg;
1559 ClientStatRequest *req;
1560 MessageUtils::CreateRequest( msg, req, fPath.length() );
1561
1562 req->requestid = kXR_stat;
1563 req->options = 0;
1564 req->dlen = fPath.length();
1565 msg->Append( fPath.c_str(), fPath.length(), 24 );
1566 MessageSendParams params; params.timeout = timeout;
1569
1570 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1571 }
1572
1573 //----------------------------------------------------------------------------
1574 // Obtain status information for a path - sync
1575 //----------------------------------------------------------------------------
1576 XRootDStatus FileSystem::Stat( const std::string &path,
1577 StatInfo *&response,
1578 uint16_t timeout )
1579 {
1580 SyncResponseHandler handler;
1581 Status st = Stat( path, &handler, timeout );
1582 if( !st.IsOK() )
1583 return st;
1584
1585 return MessageUtils::WaitForResponse( &handler, response );
1586 }
1587
1588 //----------------------------------------------------------------------------
1589 // Obtain status information for a path - async
1590 //----------------------------------------------------------------------------
1591 XRootDStatus FileSystem::StatVFS( const std::string &path,
1592 ResponseHandler *handler,
1593 uint16_t timeout )
1594 {
1595 if( pPlugIn )
1596 return pPlugIn->StatVFS( path, handler, timeout );
1597
1598 std::string fPath = FilterXrdClCgi( path );
1599
1600 Message *msg;
1601 ClientStatRequest *req;
1602 MessageUtils::CreateRequest( msg, req, fPath.length() );
1603
1604 req->requestid = kXR_stat;
1605 req->options = kXR_vfs;
1606 req->dlen = fPath.length();
1607 msg->Append( fPath.c_str(), fPath.length(), 24 );
1608 MessageSendParams params; params.timeout = timeout;
1611
1612 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1613 }
1614
1615 //----------------------------------------------------------------------------
1616 // Obtain status information for a path - sync
1617 //----------------------------------------------------------------------------
1618 XRootDStatus FileSystem::StatVFS( const std::string &path,
1619 StatInfoVFS *&response,
1620 uint16_t timeout )
1621 {
1622 SyncResponseHandler handler;
1623 Status st = StatVFS( path, &handler, timeout );
1624 if( !st.IsOK() )
1625 return st;
1626
1627 return MessageUtils::WaitForResponse( &handler, response );
1628 }
1629
1630 //----------------------------------------------------------------------------
1631 // Obtain server protocol information - async
1632 //----------------------------------------------------------------------------
1634 uint16_t timeout )
1635 {
1636 if( pPlugIn )
1637 return pPlugIn->Protocol( handler, timeout );
1638
1639 Message *msg;
1641 MessageUtils::CreateRequest( msg, req );
1642
1643 req->requestid = kXR_protocol;
1645 MessageSendParams params; params.timeout = timeout;
1648
1649 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1650 }
1651
1652 //----------------------------------------------------------------------------
1653 // Obtain server protocol information - sync
1654 //----------------------------------------------------------------------------
1656 uint16_t timeout )
1657 {
1658 SyncResponseHandler handler;
1659 Status st = Protocol( &handler, timeout );
1660 if( !st.IsOK() )
1661 return st;
1662
1663 return MessageUtils::WaitForResponse( &handler, response );
1664 }
1665
1666 //----------------------------------------------------------------------------
1667 // List entries of a directory - async
1668 //----------------------------------------------------------------------------
1669 XRootDStatus FileSystem::DirList( const std::string &path,
1670 DirListFlags::Flags flags,
1671 ResponseHandler *handler,
1672 uint16_t timeout )
1673 {
1674 if( pPlugIn )
1675 return pPlugIn->DirList( path, flags, handler, timeout );
1676
1677 URL url = URL( path );
1678 std::string fPath = FilterXrdClCgi( path );
1679
1680 if( flags & DirListFlags::Zip )
1681 {
1682 // stat the file to check if it is a directory or a file
1683 // the ZIP handler will take care of the rest
1684 ZipListHandler *zipHandler = new ZipListHandler( *pImpl->fsdata->pUrl, path, flags, handler, timeout );
1685 XRootDStatus st = Stat( path, zipHandler, timeout );
1686 if( !st.IsOK() )
1687 delete zipHandler;
1688 return st;
1689 }
1690
1691 Message *msg;
1693 MessageUtils::CreateRequest( msg, req, fPath.length() );
1694
1695 req->requestid = kXR_dirlist;
1696 req->dlen = fPath.length();
1697
1698 if( ( flags & DirListFlags::Stat ) || ( flags & DirListFlags::Recursive ) )
1699 req->options[0] = kXR_dstat;
1700
1701 if( ( flags & DirListFlags::Cksm ) )
1702 req->options[0] = kXR_dstat | kXR_dcksm;
1703
1704 if( flags & DirListFlags::Recursive )
1705 handler = new RecursiveDirListHandler( *pImpl->fsdata->pUrl, url.GetPath(), flags, handler, timeout );
1706
1707 if( flags & DirListFlags::Merge )
1708 handler = new MergeDirListHandler( flags & DirListFlags::Chunked, handler );
1709
1710 msg->Append( fPath.c_str(), fPath.length(), 24 );
1711 MessageSendParams params; params.timeout = timeout;
1712 if( flags & DirListFlags::Chunked )
1713 params.chunkedResponse = true;
1716
1717 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1718 }
1719
1720 //----------------------------------------------------------------------------
1721 // List entries of a directory - sync
1722 //----------------------------------------------------------------------------
1723 XRootDStatus FileSystem::DirList( const std::string &path,
1724 DirListFlags::Flags flags,
1725 DirectoryList *&response,
1726 uint16_t timeout )
1727 {
1728 //--------------------------------------------------------------------------
1729 // Chunked response is only possible for async DirList call
1730 //--------------------------------------------------------------------------
1731 if( flags & DirListFlags::Chunked )
1733
1734 //--------------------------------------------------------------------------
1735 // If the path ends with '.zip' extension add Zip flag
1736 //--------------------------------------------------------------------------
1737 static const std::string zip_sufix = ".zip";
1738 if( path.size() >= zip_sufix.size() &&
1739 std::equal( zip_sufix.rbegin(), zip_sufix.rend(), path.rbegin() ) )
1740 flags |= DirListFlags::Zip;
1741
1742 //--------------------------------------------------------------------------
1743 // We do the deep locate and ask all the returned servers for the list
1744 //--------------------------------------------------------------------------
1745 if( flags & DirListFlags::Locate )
1746 {
1747 bool isserver = false;
1748 //------------------------------------------------------------------------
1749 // Check if destination is a data server
1750 //------------------------------------------------------------------------
1751 {
1752 AnyObject obj;
1754 *pImpl->fsdata->pUrl, XRootDQuery::ServerFlags, obj);
1755
1756 if( st.IsOK() )
1757 {
1758 int *ptr = 0;
1759 obj.Get( ptr );
1760 isserver = ( ptr && (*ptr & kXR_isServer) );
1761 delete ptr;
1762 }
1763 }
1764
1765 if (isserver) {
1766 // Just disable the locate flag if we are talking to a single server
1767 flags &= ~DirListFlags::Locate;
1768 } else {
1769 //------------------------------------------------------------------------
1770 // Locate all the disk servers holding the directory
1771 //------------------------------------------------------------------------
1772 LocationInfo *locations;
1773 std::string locatePath = "*"; locatePath += path;
1774
1775 XRootDStatus st = DeepLocate(locatePath,
1779 locations);
1780
1781 if( !st.IsOK() )
1782 return st;
1783
1784 if( locations->GetSize() == 0 )
1785 {
1786 delete locations;
1787 return XRootDStatus( stError, errNotFound );
1788 }
1789
1790 //------------------------------------------------------------------------
1791 // Ask each server for a directory list
1792 //------------------------------------------------------------------------
1793 flags &= ~DirListFlags::Locate;
1794 FileSystem *fs;
1795 DirectoryList *currentResp = 0;
1796 uint32_t errors = 0;
1797 uint32_t numLocations = locations->GetSize();
1798 bool partial = st.code == suPartial ? true : false;
1799
1800 response = new DirectoryList();
1801 response->SetParentName( path );
1802
1803 for( uint32_t i = 0; i < locations->GetSize(); ++i )
1804 {
1805 URL locationURL( locations->At(i).GetAddress() );
1806 // make sure the original protocol is preserved (root vs roots)
1807 locationURL.SetProtocol( pImpl->fsdata->pUrl->GetProtocol() );
1808 fs = new FileSystem( locationURL );
1809 st = fs->DirList( path, flags, currentResp, timeout );
1810 if( !st.IsOK() )
1811 {
1812 ++errors;
1813 delete fs;
1814 continue;
1815 }
1816
1817 if( st.code == suPartial )
1818 partial = true;
1819
1821
1822 for( it = currentResp->Begin(); it != currentResp->End(); ++it )
1823 {
1824 response->Add( *it );
1825 *it = 0;
1826 }
1827
1828 delete fs;
1829 delete currentResp;
1830 fs = 0;
1831 currentResp = 0;
1832 }
1833
1834 delete locations;
1835
1836 if( flags & DirListFlags::Merge )
1837 MergeDirListHandler::Merge( response );
1838
1839 if( errors || partial )
1840 {
1841 if( errors == numLocations )
1842 return st;
1843 return XRootDStatus( stOK, suPartial );
1844 }
1845 return XRootDStatus();
1846 }
1847 }
1848
1849 //--------------------------------------------------------------------------
1850 // We just ask the current server
1851 //--------------------------------------------------------------------------
1852 SyncResponseHandler handler;
1853 XRootDStatus st = DirList( path, flags, &handler, timeout );
1854 if( !st.IsOK() )
1855 return st;
1856
1857 st = MessageUtils::WaitForResponse( &handler, response );
1858 if( !st.IsOK() )
1859 return st;
1860
1861 //--------------------------------------------------------------------------
1862 // Do the stats on all the entries if necessary.
1863 // If we already have the stat objects it means that the bulk stat has
1864 // succeeded.
1865 //--------------------------------------------------------------------------
1866 if( !(flags & DirListFlags::Stat) )
1867 return st;
1868
1869 if( response->GetSize() && response->At(0)->GetStatInfo() )
1870 return st;
1871
1872 uint32_t quota = response->GetSize() <= 1024 ? response->GetSize() : 1024;
1873 RequestSync sync( response->GetSize(), quota );
1874 for( uint32_t i = 0; i < response->GetSize(); ++i )
1875 {
1876 std::string fullPath = response->GetParentName()+response->At(i)->GetName();
1877 ResponseHandler *handler = new DirListStatHandler( response, i, &sync );
1878 st = Stat( fullPath, handler, timeout );
1879 if( !st.IsOK() )
1880 {
1881 sync.TaskDone( false );
1882 delete handler;
1883 }
1884 sync.WaitForQuota();
1885 }
1886 sync.WaitForAll();
1887
1888 if( sync.FailureCount() )
1889 return XRootDStatus( stOK, suPartial );
1890
1891 return XRootDStatus();
1892 }
1893
1894 //----------------------------------------------------------------------------
1895 // Send cache info to the server - async
1896 //----------------------------------------------------------------------------
1897 XRootDStatus FileSystem::SendCache( const std::string &info,
1898 ResponseHandler *handler,
1899 uint16_t timeout )
1900 {
1901 // Note: adding SendCache() to the FileSystemPlugin class breaks ABI!
1902 // So, the class is missing this until we do a major release. TODO
1903 //if( pPlugIn )
1904 // return pPlugIn->SendCache( info, handler, timeout );
1905 return SendSet("cache ", info, handler, timeout );
1906 }
1907
1908 //----------------------------------------------------------------------------
1910 //----------------------------------------------------------------------------
1911 XRootDStatus FileSystem::SendCache( const std::string &info,
1912 Buffer *&response,
1913 uint16_t timeout )
1914 {
1915 SyncResponseHandler handler;
1916 Status st = SendCache( info, &handler, timeout );
1917 if( !st.IsOK() )
1918 return st;
1919
1920 return MessageUtils::WaitForResponse( &handler, response );
1921 }
1922
1923 //----------------------------------------------------------------------------
1924 // Send info to the server - async
1925 //----------------------------------------------------------------------------
1926 XRootDStatus FileSystem::SendInfo( const std::string &info,
1927 ResponseHandler *handler,
1928 uint16_t timeout )
1929 {
1930 if( pPlugIn )
1931 return pPlugIn->SendInfo( info, handler, timeout );
1932 return SendSet("monitor info ", info, handler, timeout );
1933 }
1934
1935 //----------------------------------------------------------------------------
1937 //----------------------------------------------------------------------------
1938 XRootDStatus FileSystem::SendInfo( const std::string &info,
1939 Buffer *&response,
1940 uint16_t timeout )
1941 {
1942 SyncResponseHandler handler;
1943 Status st = SendInfo( info, &handler, timeout );
1944 if( !st.IsOK() )
1945 return st;
1946
1947 return MessageUtils::WaitForResponse( &handler, response );
1948 }
1949
1950 //----------------------------------------------------------------------------
1951 // Send set request to the server - async
1952 //----------------------------------------------------------------------------
1953 XRootDStatus FileSystem::SendSet( const char *prefix,
1954 const std::string &info,
1955 ResponseHandler *handler,
1956 uint16_t timeout )
1957 {
1958
1959 Message *msg;
1960 ClientSetRequest *req;
1961 size_t prefixLen = strlen( prefix );
1962 MessageUtils::CreateRequest( msg, req, info.length()+prefixLen );
1963
1964 req->requestid = kXR_set;
1965 req->dlen = info.length()+prefixLen;
1966 msg->Append( prefix, prefixLen, 24 );
1967 msg->Append( info.c_str(), info.length(), 24+prefixLen );
1968 MessageSendParams params; params.timeout = timeout;
1971
1972 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
1973 }
1974
1975 //----------------------------------------------------------------------------
1976 // Prepare one or more files for access - async
1977 //----------------------------------------------------------------------------
1978 XRootDStatus FileSystem::Prepare( const std::vector<std::string> &fileList,
1979 PrepareFlags::Flags flags,
1980 uint8_t priority,
1981 ResponseHandler *handler,
1982 uint16_t timeout )
1983 {
1984 if( pPlugIn )
1985 return pPlugIn->Prepare( fileList, flags, priority, handler, timeout );
1986
1987 std::vector<std::string>::const_iterator it;
1988 std::string list;
1989 for( it = fileList.begin(); it != fileList.end(); ++it )
1990 {
1991 list += *it;
1992 list += "\n";
1993 }
1994 list.erase( list.length()-1, 1 );
1995
1996 Message *msg;
1998 MessageUtils::CreateRequest( msg, req, list.length() );
1999
2000 req->requestid = kXR_prepare;
2001 req->options = 0xff & flags;
2002 req->optionX = 0xffff & ( flags >> 8 );
2003 req->prty = priority;
2004 req->dlen = list.length();
2005
2006 msg->Append( list.c_str(), list.length(), 24 );
2007
2008 MessageSendParams params; params.timeout = timeout;
2011
2012 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
2013 }
2014
2015 //------------------------------------------------------------------------
2016 // Prepare one or more files for access - sync
2017 //------------------------------------------------------------------------
2018 XRootDStatus FileSystem::Prepare( const std::vector<std::string> &fileList,
2019 PrepareFlags::Flags flags,
2020 uint8_t priority,
2021 Buffer *&response,
2022 uint16_t timeout )
2023 {
2024 SyncResponseHandler handler;
2025 Status st = Prepare( fileList, flags, priority, &handler, timeout );
2026 if( !st.IsOK() )
2027 return st;
2028
2029 return MessageUtils::WaitForResponse( &handler, response );
2030 }
2031
2032 //------------------------------------------------------------------------
2033 // Set extended attributes - async
2034 //------------------------------------------------------------------------
2035 XRootDStatus FileSystem::SetXAttr( const std::string &path,
2036 const std::vector<xattr_t> &attrs,
2037 ResponseHandler *handler,
2038 uint16_t timeout )
2039 {
2040 if( pPlugIn )
2042
2043 return XAttrOperationImpl( kXR_fattrSet, 0, path, attrs, handler, timeout );
2044 }
2045
2046 //------------------------------------------------------------------------
2047 // Set extended attributes - sync
2048 //------------------------------------------------------------------------
2049 XRootDStatus FileSystem::SetXAttr( const std::string &path,
2050 const std::vector<xattr_t> &attrs,
2051 std::vector<XAttrStatus> &result,
2052 uint16_t timeout )
2053 {
2054 SyncResponseHandler handler;
2055 XRootDStatus st = SetXAttr( path, attrs, &handler, timeout );
2056 if( !st.IsOK() )
2057 return st;
2058
2059 std::vector<XAttrStatus> *resp = 0;
2060 st = MessageUtils::WaitForResponse( &handler, resp );
2061 if( resp ) result.swap( *resp );
2062 delete resp;
2063
2064 return st;
2065 }
2066
2067 //------------------------------------------------------------------------
2068 // Get extended attributes - async
2069 //------------------------------------------------------------------------
2070 XRootDStatus FileSystem::GetXAttr( const std::string &path,
2071 const std::vector<std::string> &attrs,
2072 ResponseHandler *handler,
2073 uint16_t timeout )
2074 {
2075 if( pPlugIn )
2077
2078 return XAttrOperationImpl( kXR_fattrGet, 0, path, attrs, handler, timeout );
2079 }
2080
2081 //------------------------------------------------------------------------
2082 // Get extended attributes - sync
2083 //------------------------------------------------------------------------
2084 XRootDStatus FileSystem::GetXAttr( const std::string &path,
2085 const std::vector<std::string> &attrs,
2086 std::vector<XAttr> &result,
2087 uint16_t timeout )
2088 {
2089 SyncResponseHandler handler;
2090 XRootDStatus st = GetXAttr( path, attrs, &handler, timeout );
2091 if( !st.IsOK() )
2092 return st;
2093
2094 std::vector<XAttr> *resp = 0;
2095 st = MessageUtils::WaitForResponse( &handler, resp );
2096 if( resp ) result.swap( *resp );
2097 delete resp;
2098
2099 return st;
2100 }
2101
2102 //------------------------------------------------------------------------
2103 // Delete extended attributes - async
2104 //------------------------------------------------------------------------
2105 XRootDStatus FileSystem::DelXAttr( const std::string &path,
2106 const std::vector<std::string> &attrs,
2107 ResponseHandler *handler,
2108 uint16_t timeout )
2109 {
2110 if( pPlugIn )
2112
2113 return XAttrOperationImpl( kXR_fattrDel, 0, path, attrs, handler, timeout );
2114 }
2115
2116 //------------------------------------------------------------------------
2117 // Delete extended attributes - sync
2118 //------------------------------------------------------------------------
2119 XRootDStatus FileSystem::DelXAttr( const std::string &path,
2120 const std::vector<std::string> &attrs,
2121 std::vector<XAttrStatus> &result,
2122 uint16_t timeout )
2123 {
2124 SyncResponseHandler handler;
2125 XRootDStatus st = DelXAttr( path, attrs, &handler, timeout );
2126 if( !st.IsOK() )
2127 return st;
2128
2129 std::vector<XAttrStatus> *resp = 0;
2130 st = MessageUtils::WaitForResponse( &handler, resp );
2131 if( resp ) result.swap( *resp );
2132 delete resp;
2133
2134 return st;
2135 }
2136
2137 //------------------------------------------------------------------------
2138 // List extended attributes - async
2139 //------------------------------------------------------------------------
2140 XRootDStatus FileSystem::ListXAttr( const std::string &path,
2141 ResponseHandler *handler,
2142 uint16_t timeout )
2143 {
2144 if( pPlugIn )
2146
2147 static const std::vector<std::string> nothing;
2148 return XAttrOperationImpl( kXR_fattrList, ClientFattrRequest::aData,
2149 path, nothing, handler, timeout );
2150 }
2151
2152 //------------------------------------------------------------------------
2153 // List extended attributes - sync
2154 //------------------------------------------------------------------------
2155 XRootDStatus FileSystem::ListXAttr( const std::string &path,
2156 std::vector<XAttr> &result,
2157 uint16_t timeout )
2158 {
2159 SyncResponseHandler handler;
2160 XRootDStatus st = ListXAttr( path, &handler, timeout );
2161 if( !st.IsOK() )
2162 return st;
2163
2164 std::vector<XAttr> *resp = 0;
2165 st = MessageUtils::WaitForResponse( &handler, resp );
2166 if( resp ) result.swap( *resp );
2167 delete resp;
2168
2169 return st;
2170 }
2171
2172 //----------------------------------------------------------------------------
2173 // Set file property
2174 //----------------------------------------------------------------------------
2175 bool FileSystem::SetProperty( const std::string &name,
2176 const std::string &value )
2177 {
2178 if( pPlugIn )
2179 return pPlugIn->SetProperty( name, value );
2180
2181 if( name == "FollowRedirects" )
2182 {
2183 if( value == "true" ) pImpl->fsdata->pFollowRedirects = true;
2184 else pImpl->fsdata->pFollowRedirects = false;
2185 return true;
2186 }
2187 return false;
2188 }
2189
2190 //----------------------------------------------------------------------------
2191 // Get file property
2192 //----------------------------------------------------------------------------
2193 bool FileSystem::GetProperty( const std::string &name,
2194 std::string &value ) const
2195 {
2196 if( pPlugIn )
2197 return pPlugIn->GetProperty( name, value );
2198
2199 if( name == "FollowRedirects" )
2200 {
2201 if( pImpl->fsdata->pFollowRedirects ) value = "true";
2202 else value = "false";
2203 return true;
2204 }
2205 else if( name == "LastURL" )
2206 {
2207 if( pImpl->fsdata->pLastUrl )
2208 {
2209 value = pImpl->fsdata->pLastUrl->GetURL();
2210 return true;
2211 }
2212 else return false;
2213 }
2214
2215 return false;
2216 }
2217
2218 //------------------------------------------------------------------------
2219 // Generic implementation of xattr operation
2220 //------------------------------------------------------------------------
2221 template<typename T>
2222 Status FileSystem::XAttrOperationImpl( kXR_char subcode,
2223 kXR_char options,
2224 const std::string &path,
2225 const std::vector<T> &attrs,
2226 ResponseHandler *handler,
2227 uint16_t timeout )
2228 {
2229 Message *msg;
2230 ClientFattrRequest *req;
2231 MessageUtils::CreateRequest( msg, req );
2232
2233 req->requestid = kXR_fattr;
2234 req->subcode = subcode;
2235 req->options = options;
2236 req->numattr = attrs.size();
2237 memset( req->fhandle, 0, 4 );
2238 XRootDStatus st = MessageUtils::CreateXAttrBody( msg, attrs, path );
2239 if( !st.IsOK() ) return st;
2240
2241 MessageSendParams params; params.timeout = timeout;
2243
2245
2246 return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
2247 }
2248
2249 //------------------------------------------------------------------------
2250 // Lock the internal lock
2251 //------------------------------------------------------------------------
2252 void FileSystem::Lock()
2253 {
2254 pImpl->fsdata->pMutex.Lock();
2255 }
2256
2257 //------------------------------------------------------------------------
2258 // Unlock the internal lock
2259 //------------------------------------------------------------------------
2260 void FileSystem::UnLock()
2261 {
2262 pImpl->fsdata->pMutex.UnLock();
2263 }
2264}
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:113
#define stat(a, b)
Definition XrdPosix.hh:101
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.
DirList::iterator Iterator
Directory listing iterator.
Iterator End()
Get the end 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 RegisterFileSystemObject(FileSystem *fs)
void UnRegisterFileSystemObject(FileSystem *fs)
Un-register a file system object.
A synchronized queue.
const std::string & GetAddress() const
Get address.
Path location info.
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.
LocationList::iterator Iterator
Iterator over locations.
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)
virtual void HandleResponse(XRootDStatus *status, AnyObject *response)
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:498
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