Loading...
Searching...
No Matches
XrdClFileSystem.cc
Go to the documentation of this file.
//------------------------------------------------------------------------------
// Copyright (c) 2011-2014 by European Organization for Nuclear Research (CERN)
// Author: Lukasz Janyst <ljanyst@cern.ch>
//------------------------------------------------------------------------------
// This file is part of the XRootD software suite.
//
// XRootD is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// XRootD is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
//
// In applying this licence, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
//------------------------------------------------------------------------------
#include "XrdCl/XrdClMessageUtils.hh"
#include "XrdCl/XrdClFileSystem.hh"
#include "XrdCl/XrdClDefaultEnv.hh"
#include "XrdCl/XrdClLog.hh"
#include "XrdCl/XrdClConstants.hh"
#include "XrdCl/XrdClMessage.hh"
#include "XrdCl/XrdClXRootDResponses.hh"
#include "XrdCl/XrdClRequestSync.hh"
#include "XrdCl/XrdClXRootDTransport.hh"
#include "XrdCl/XrdClForkHandler.hh"
#include "XrdCl/XrdClPlugInInterface.hh"
#include "XrdCl/XrdClPlugInManager.hh"
#include "XrdCl/XrdClLocalFileTask.hh"
#include "XrdCl/XrdClZipListHandler.hh"
#include "XrdSys/XrdSysE2T.hh"
#include "XrdSys/XrdSysPthread.hh"
#include <sys/stat.h>
#include <memory>
#include <algorithm>
#include <iterator>
namespace
{
class LocalFS
{
public:
XrdCl::XRootDStatus Stat( const std::string &path,
XrdCl::ResponseHandler *handler,
uint16_t timeout )
{
using namespace XrdCl;
Log *log = DefaultEnv::GetLog();
struct stat ssp;
if( stat( path.c_str(), &ssp ) == -1 )
{
log->Error( FileMsg, "Stat: failed: %s", XrdSysE2T( errno ) );
XRootDStatus *error = new XRootDStatus( stError, errLocalError,
XProtocol::mapError( errno ) );
return QueueTask( error, 0, handler );
}
// TODO support other mode options
uint32_t flags = S_ISDIR( ssp.st_mode ) ? kXR_isDir : 0;
std::ostringstream data;
data << ssp.st_dev << " " << ssp.st_size << " " << flags << " "
<< ssp.st_mtime;
log->Debug( FileMsg, "%s", data.str().c_str() );
StatInfo *statInfo = new StatInfo();
if( !statInfo->ParseServerResponse( data.str().c_str() ) )
{
log->Error( FileMsg, "Stat: ParseServerResponse failed." );
delete statInfo;
return QueueTask( new XRootDStatus( stError, errErrorResponse, kXR_FSError ),
0, handler );
}
AnyObject *resp = new AnyObject();
resp->Set( statInfo );
return QueueTask( new XRootDStatus(), resp, handler );
}
XrdCl::XRootDStatus Rm( const std::string &path,
XrdCl::ResponseHandler *handler,
uint16_t timeout )
{
using namespace XrdCl;
Log *log = DefaultEnv::GetLog();
if( unlink( path.c_str() ) )
{
log->Error( FileMsg, "Rm: failed: %s", XrdSysE2T( errno ) );
XRootDStatus *error = new XRootDStatus( stError, errLocalError,
XProtocol::mapError( errno ) );
return QueueTask( error, 0, handler );
}
return QueueTask( new XRootDStatus(), 0, handler );
}
static LocalFS& Instance()
{
static LocalFS instance;
return instance;
}
private:
//------------------------------------------------------------------------
// Private constructors
//------------------------------------------------------------------------
LocalFS() : jmngr( XrdCl::DefaultEnv::GetPostMaster()->GetJobManager() )
{
}
//------------------------------------------------------------------------
// Private copy constructors
//------------------------------------------------------------------------
LocalFS( const LocalFS& );
//------------------------------------------------------------------------
// Private assignment operator
//------------------------------------------------------------------------
LocalFS& operator=( const LocalFS& );
//------------------------------------------------------------------------
// QueueTask - queues error/success tasks for all operations.
// Must always return stOK.
// Is always creating the same HostList containing only localhost.
//------------------------------------------------------------------------
XrdCl::XRootDStatus QueueTask( XrdCl::XRootDStatus *st, XrdCl::AnyObject *resp,
XrdCl::ResponseHandler *handler )
{
using namespace XrdCl;
// if it is simply the sync handler we can release the semaphore
// and return there is no need to execute this in the thread-pool
SyncResponseHandler *syncHandler =
dynamic_cast<SyncResponseHandler*>( handler );
if( syncHandler )
{
syncHandler->HandleResponse( st, resp );
return XRootDStatus();
}
LocalFileTask *task = new LocalFileTask( st, resp, 0, handler );
jmngr->QueueJob( task );
return XRootDStatus();
}
XrdCl::JobManager *jmngr;
};
//----------------------------------------------------------------------------
// Get delimiter for the opaque info
//----------------------------------------------------------------------------
char GetCgiDelimiter( bool &hasCgi )
{
if( !hasCgi )
{
hasCgi = true;
return '?';
}
return '&';
}
//----------------------------------------------------------------------------
// Filters out client specific CGI
//----------------------------------------------------------------------------
std::string FilterXrdClCgi( const std::string &path )
{
// first check if there's an opaque info at all
size_t pos = path.find( '?' );
if( pos == std::string::npos )
return path;
std::string filteredPath = path.substr( 0 , pos );
std::string cgi = path.substr( pos + 1 );
bool hasCgi = false;
pos = 0;
size_t xrdcl = std::string::npos;
do
{
xrdcl = cgi.find( "xrdcl.", pos );
if( xrdcl == std::string:: npos )
{
filteredPath += GetCgiDelimiter( hasCgi );
filteredPath += cgi.substr( pos );
pos = cgi.size();
}
else
{
if( xrdcl != pos )
{
filteredPath += GetCgiDelimiter( hasCgi );
filteredPath += cgi.substr( pos, xrdcl - 1 - pos );
}
pos = cgi.find( '&', xrdcl );
if( pos != std::string::npos )
++pos;
}
}
while( pos < cgi.size() && pos != std::string::npos );
return filteredPath;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
class DeallocFSHandler: public XrdCl::ResponseHandler
{
public:
//------------------------------------------------------------------------
// Constructor and destructor
//------------------------------------------------------------------------
DeallocFSHandler( XrdCl::FileSystem *fs, ResponseHandler *userHandler ):
pFS(fs), pUserHandler(userHandler) {}
virtual ~DeallocFSHandler()
{
delete pFS;
}
//------------------------------------------------------------------------
// Handle the response
//------------------------------------------------------------------------
virtual void HandleResponse( XrdCl::XRootDStatus *status,
XrdCl::AnyObject *response )
{
pUserHandler->HandleResponse(status, response);
delete this;
}
private:
XrdCl::FileSystem *pFS;
ResponseHandler *pUserHandler;
};
//----------------------------------------------------------------------------
// Deep locate handler
//----------------------------------------------------------------------------
class DeepLocateHandler: public XrdCl::ResponseHandler
{
public:
//------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------
DeepLocateHandler( XrdCl::ResponseHandler *handler,
const std::string &path,
XrdCl::OpenFlags::Flags flags,
time_t timeout ):
pFirstTime( true ),
pPartial( false ),
pOutstanding( 1 ),
pHandler( handler ),
pPath( path ),
pFlags( flags )
{
if (timeout == 0) {
int val = XrdCl::DefaultRequestTimeout;
XrdCl::DefaultEnv::GetEnv()->GetInt("RequestTimeout", val);
timeout = val;
}
pExpires = ::time(nullptr) + timeout;
pLocations = new XrdCl::LocationInfo();
}
//------------------------------------------------------------------------
// Destructor
//------------------------------------------------------------------------
~DeepLocateHandler()
{
delete pLocations;
}
//------------------------------------------------------------------------
// Handle the response
//------------------------------------------------------------------------
virtual void HandleResponse( XrdCl::XRootDStatus *status,
XrdCl::AnyObject *response )
{
XrdSysMutexHelper scopedLock( pMutex );
using namespace XrdCl;
Log *log = DefaultEnv::GetLog();
--pOutstanding;
//----------------------------------------------------------------------
// We've got an error, react accordingly
//----------------------------------------------------------------------
if( !status->IsOK() )
{
log->Dump( FileSystemMsg, "[%p@DeepLocate(%s)] Got error "
"response: %s", (void*)this, pPath.c_str(),
status->ToStr().c_str() );
//--------------------------------------------------------------------
// We have failed with the first request
//--------------------------------------------------------------------
if( pFirstTime )
{
log->Debug( FileSystemMsg, "[%p@DeepLocate(%s)] Failed to get "
"the initial location list: %s", (void*)this, pPath.c_str(),
status->ToStr().c_str() );
pHandler->HandleResponse( status, response );
scopedLock.UnLock();
delete this;
return;
}
pPartial = true;
//--------------------------------------------------------------------
// We have no more outstanding requests, so let give to the client
// what we have
//--------------------------------------------------------------------
if( !pOutstanding )
{
log->Debug( FileSystemMsg, "[%p@DeepLocate(%s)] No outstanding "
"requests, give out what we've got", (void*)this,
pPath.c_str() );
scopedLock.UnLock();
HandleFinalResponse();
}
delete status;
return;
}
pFirstTime = false;
//----------------------------------------------------------------------
// Extract the answer
//----------------------------------------------------------------------
LocationInfo *info = 0;
response->Get( info );
LocationInfo::Iterator it;
if(!info) {
log->Error(FileSystemMsg,
"[%p@DeepLocate(%s)] No locations received in response",
(void*)this, pPath.c_str());
return;
}
log->Dump( FileSystemMsg, "[%p@DeepLocate(%s)] Got %d locations",
(void*)this, pPath.c_str(), info->GetSize() );
for( it = info->Begin(); it != info->End(); ++it )
{
//--------------------------------------------------------------------
// Add the location to the list
//--------------------------------------------------------------------
if( it->IsServer() )
{
pLocations->Add( *it );
continue;
}
//--------------------------------------------------------------------
// Ask the manager for the location of servers
//--------------------------------------------------------------------
if( it->IsManager() )
{
++pOutstanding;
FileSystem *fs = new FileSystem( it->GetAddress() );
if( pOutstanding == 0 || // protect against overflow, short circuiting
// will make sure the other part won't be executed
!fs->Locate( pPath, pFlags, new DeallocFSHandler(fs, this),
pExpires-::time(0)).IsOK() )
{
--pOutstanding;
pPartial = true;
delete fs;
}
}
}
//----------------------------------------------------------------------
// Clean up and check if we have anything else to do
//----------------------------------------------------------------------
delete response;
delete status;
if( !pOutstanding )
{
scopedLock.UnLock();
HandleFinalResponse();
}
}
//------------------------------------------------------------------------
// Build the response for the client
//------------------------------------------------------------------------
void HandleFinalResponse()
{
using namespace XrdCl;
//----------------------------------------------------------------------
// Nothing found
//----------------------------------------------------------------------
if( !pLocations->GetSize() )
{
pHandler->HandleResponse( new XRootDStatus( stError, errErrorResponse,
kXR_NotFound,
"No valid location found" ),
0 );
}
//----------------------------------------------------------------------
// We return an answer
//----------------------------------------------------------------------
else
{
AnyObject *obj = new AnyObject();
obj->Set( pLocations );
pLocations = 0;
XRootDStatus *st = new XRootDStatus();
if( pPartial ) st->code = suPartial;
pHandler->HandleResponse( st, obj );
}
delete this;
}
private:
bool pFirstTime;
bool pPartial;
uint16_t pOutstanding;
XrdCl::ResponseHandler *pHandler;
XrdCl::LocationInfo *pLocations;
std::string pPath;
XrdCl::OpenFlags::Flags pFlags;
time_t pExpires;
XrdSysMutex pMutex;
};
//----------------------------------------------------------------------------
// Handle stat results for a dirlist request
//----------------------------------------------------------------------------
class DirListStatHandler: public XrdCl::ResponseHandler
{
public:
//------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------
DirListStatHandler( XrdCl::DirectoryList *list,
uint32_t index,
XrdCl::RequestSync *sync ):
pList( list ),
pIndex( index ),
pSync( sync )
{
}
//------------------------------------------------------------------------
// Check if we were successful and if so put the StatInfo object
// in the appropriate entry info
//------------------------------------------------------------------------
virtual void HandleResponse( XrdCl::XRootDStatus *status,
XrdCl::AnyObject *response )
{
if( !status->IsOK() )
{
delete status;
pSync->TaskDone( false );
delete this;
return;
}
XrdCl::StatInfo *info = 0;
response->Get( info );
response->Set( (char*) 0 );
pList->At( pIndex )->SetStatInfo( info );
delete status;
delete response;
pSync->TaskDone();
delete this;
}
private:
XrdCl::DirectoryList *pList;
uint32_t pIndex;
XrdCl::RequestSync *pSync;
};
//----------------------------------------------------------------------------
// Recursive dirlist common context for all handlers
//----------------------------------------------------------------------------
struct RecursiveDirListCtx
{
RecursiveDirListCtx( const XrdCl::URL &url, const std::string &path,
XrdCl::DirListFlags::Flags flags,
XrdCl::ResponseHandler *handler, time_t expires ) :
finalst( 0 ), pending( 1 ),
dirList( new XrdCl::DirectoryList() ), expires( expires ),
handler( handler ), flags( flags ),
fs( new XrdCl::FileSystem( url ) )
{
dirList->SetParentName( path );
}
~RecursiveDirListCtx()
{
delete finalst;
delete dirList;
delete fs;
}
void UpdateStatus( const XrdCl::XRootDStatus &st )
{
using namespace XrdCl;
if( !finalst )
{
finalst = st.IsOK() ? new XRootDStatus() : new XRootDStatus( st );
return;
}
// if they disagree set the status to partial
if( ( finalst->IsOK() && !st.IsOK() ) ||
( !finalst->IsOK() && st.IsOK() ) )
*finalst = XRootDStatus( stOK, suPartial );
}
XrdCl::XRootDStatus *finalst;
int pending;
XrdCl::DirectoryList *dirList;
time_t expires;
XrdCl::ResponseHandler *handler;
XrdCl::DirListFlags::Flags flags;
XrdCl::FileSystem *fs;
XrdSysMutex mtx;
};
//----------------------------------------------------------------------------
// Handle results for a recursive dirlist request
//----------------------------------------------------------------------------
class RecursiveDirListHandler: public XrdCl::ResponseHandler
{
public:
RecursiveDirListHandler( const XrdCl::URL &url,
const std::string &path,
XrdCl::DirListFlags::Flags flags,
XrdCl::ResponseHandler *handler,
time_t timeout )
{
time_t expires = 0;
if( timeout )
expires = ::time( 0 ) + timeout;
pCtx = new RecursiveDirListCtx( url, path, flags,
handler, expires );
}
RecursiveDirListHandler( RecursiveDirListCtx *ctx ) : pCtx( ctx )
{
}
virtual void HandleResponse( XrdCl::XRootDStatus *status,
XrdCl::AnyObject *response )
{
using namespace XrdCl;
Log *log = DefaultEnv::GetLog();
bool finalrsp = !( status->IsOK() && status->code == XrdCl::suContinue );
XrdSysMutexHelper scoped( pCtx->mtx );
// check if we have to continue with the same handler (the response
// has been chunked), if not we can decrement the number of pending
// DieLists
if( finalrsp )
--pCtx->pending;
pCtx->UpdateStatus( *status );
if( status->IsOK() )
{
// get the response
DirectoryList *dirList = 0;
response->Get( dirList );
std::string parent = pCtx->dirList->GetParentName();
DirectoryList::Iterator itr;
for( itr = dirList->Begin(); itr != dirList->End(); ++itr )
{
DirectoryList::ListEntry *entry = *itr;
StatInfo *info = entry->GetStatInfo();
if( !info )
{
log->Error( FileMsg, "Recursive directory list operation for %s failed: "
"kXR_dirlist with stat operation not supported.",
parent.c_str() );
pCtx->UpdateStatus( XRootDStatus( stError, errNotSupported ) );
continue;
}
std::string path = dirList->GetParentName() + entry->GetName();
// add new entry to the result
path = path.substr( parent.size() );
entry->SetStatInfo( 0 ); // StatInfo is no longer owned by dirList
DirectoryList::ListEntry *e =
new DirectoryList::ListEntry( entry->GetHostAddress(), path, info );
pCtx->dirList->Add( e );
// if it's a directory do a recursive call
if( info->TestFlags( StatInfo::IsDir ) )
{
// bump the pending counter
++pCtx->pending;
// switch of the recursive flag, we will
// provide the respective handler ourself,
// make sure that stat is on
DirListFlags::Flags flags = ( pCtx->flags & (~DirListFlags::Recursive) )
| DirListFlags::Stat;
// the recursive dir list handler
RecursiveDirListHandler *handler = new RecursiveDirListHandler( pCtx );
// timeout
time_t timeout = 0;
if( pCtx->expires )
{
timeout = pCtx->expires - ::time( 0 );
if( timeout <= 0 )
{
log->Error( FileMsg, "Recursive directory list operation for %s expired.",
parent.c_str() );
pCtx->UpdateStatus( XRootDStatus( stError, errOperationExpired ) );
break;
}
}
// send the request
std::string child = parent + path;
XRootDStatus st = pCtx->fs->DirList( child, flags, handler, timeout );
if( !st.IsOK() )
{
log->Error( FileMsg, "Recursive directory list operation for %s failed: %s",
child.c_str(), st.ToString().c_str() );
pCtx->UpdateStatus( st );
continue;
}
}
}
}
// if there are no more outstanding dirlist queries we can finalize the request
if( pCtx->pending == 0 )
{
AnyObject *resp = new AnyObject();
resp->Set( pCtx->dirList );
pCtx->dirList = 0; // dirList is no longer owned by pCtx
pCtx->handler->HandleResponse( pCtx->finalst, resp );
pCtx->finalst = 0; // status is no longer owned by pCtx
// finalize the common context
scoped.UnLock();
delete pCtx;
}
// if the user requested chunked response we give what we have to the user handler
else if( status->IsOK() && ( pCtx->flags & DirListFlags::Chunked ) )
{
std::string parent = pCtx->dirList->GetParentName();
AnyObject *resp = new AnyObject();
resp->Set( pCtx->dirList );
pCtx->dirList = new XrdCl::DirectoryList();
pCtx->dirList->SetParentName( parent );
pCtx->handler->HandleResponse( new XRootDStatus( stOK, suContinue ), resp );
}
// clean up the arguments
delete status;
delete response;
// if we won't be continuing with the same handler, it can be deleted
if( finalrsp )
delete this;
}
private:
RecursiveDirListCtx *pCtx;
};
//----------------------------------------------------------------------------
// Exception for a merge dirlist handler
//----------------------------------------------------------------------------
struct MergeDirLsErr
{
MergeDirLsErr( XrdCl::XRootDStatus *&status, XrdCl::AnyObject *&response ) :
status( status ), response( response )
{
status = 0; response = 0;
}
MergeDirLsErr() :
status( new XrdCl::XRootDStatus( XrdCl::stError, XrdCl::errInternal ) ),
response( 0 )
{
}
XrdCl::XRootDStatus *status;
XrdCl::AnyObject *response;
};
//----------------------------------------------------------------------------
// Handle results for a merge dirlist request
//----------------------------------------------------------------------------
class MergeDirListHandler: public XrdCl::ResponseHandler
{
public:
MergeDirListHandler( bool allowChunked, XrdCl::ResponseHandler *handler ) :
allowChunked( allowChunked ), pHandler( handler )
{
}
virtual void HandleResponse( XrdCl::XRootDStatus *status,
XrdCl::AnyObject *response )
{
XrdSysMutexHelper lck( mtx );
bool finalrsp = !( status->IsOK() && status->code == XrdCl::suContinue );
try
{
if( !status->IsOK() )
throw MergeDirLsErr( status, response );
if( !response )
throw MergeDirLsErr();
XrdCl::DirectoryList *dirlist = 0;
response->Get( dirlist );
if( !dirlist )
throw MergeDirLsErr();
if( allowChunked )
MergeChunked( dirlist );
else
Merge( dirlist );
response->Set( dirlist );
pHandler->HandleResponse( status, response );
}
catch( const MergeDirLsErr &err )
{
delete status; delete response;
pHandler->HandleResponse( err.status, err.response );
}
if( finalrsp )
{
lck.UnLock();
delete this;
}
}
void MergeChunked( XrdCl::DirectoryList *&response )
{
using namespace XrdCl;
std::set<ListEntry*, less> unique;
// set of unique list entries from the response
std::set<ListEntry*, less> tmp( response->Begin(), response->End() );
// all the unique list entries that were not reported so far
std::set_difference( tmp.begin(), tmp.end(),
uniquesofar.begin(), uniquesofar.end(),
std::inserter( unique, unique.end() ) );
// we update the set of unique list entries that were already
// reported to the user's handler
for( auto itr = unique.begin(); itr != unique.end(); ++itr )
{
ListEntry *ent = *itr;
if( !uniquesofar.count( ent ) )
{
StatInfo *info = ent->GetStatInfo() ? new StatInfo( *ent->GetStatInfo() ) : 0;
ListEntry *newent = new ListEntry( ent->GetHostAddress(), ent->GetName(), info );
uniquesofar.insert( newent );
}
}
DirectoryList *dirlist = new DirectoryList();
dirlist->SetParentName( response->GetParentName() );
for( auto itr = unique.begin(); itr != unique.end(); ++itr )
{
ListEntry *entry = *itr;
dirlist->Add( new ListEntry( entry->GetHostAddress(),
entry->GetName(),
entry->GetStatInfo() ) );
entry->SetStatInfo( 0 );
}
delete response;
response = dirlist;
}
static void Merge( XrdCl::DirectoryList *&response )
{
std::set<ListEntry*, less> unique( response->Begin(), response->End() );
XrdCl::DirectoryList *dirlist = new XrdCl::DirectoryList();
dirlist->SetParentName( response->GetParentName() );
for( auto itr = unique.begin(); itr != unique.end(); ++itr )
{
ListEntry *entry = *itr;
dirlist->Add( new ListEntry( entry->GetHostAddress(),
entry->GetName(),
entry->GetStatInfo() ) );
entry->SetStatInfo( 0 );
}
delete response;
response = dirlist;
}
private:
typedef XrdCl::DirectoryList::ListEntry ListEntry;
struct less
{
bool operator() (const ListEntry *x, const ListEntry *y) const
{
if( x->GetName() != y->GetName() )
return x->GetName() < y->GetName();
const XrdCl::StatInfo *xStatInfo = x->GetStatInfo();
const XrdCl::StatInfo *yStatInfo = y->GetStatInfo();
if( xStatInfo == yStatInfo )
return false;
if( xStatInfo == 0 )
return true;
if( yStatInfo == 0 )
return false;
if( xStatInfo->GetSize() != yStatInfo->GetSize() )
return xStatInfo->GetSize() < yStatInfo->GetSize();
if( xStatInfo->GetFlags() != yStatInfo->GetFlags() )
return xStatInfo->GetFlags() < yStatInfo->GetFlags();
return false;
}
};
bool allowChunked;
XrdSysMutex mtx;
std::set<ListEntry*, less> uniquesofar;
XrdCl::ResponseHandler *pHandler;
};
}
namespace XrdCl
{
struct FileSystemData;
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
class AssignLBHandler: public ResponseHandler
{
public:
//------------------------------------------------------------------------
// Constructor and destructor
//------------------------------------------------------------------------
AssignLBHandler( std::shared_ptr<FileSystemData> &fs,
ResponseHandler *userHandler ):
pFS(fs), pUserHandler(userHandler) {}
virtual ~AssignLBHandler() {}
//------------------------------------------------------------------------
// Response callback
//------------------------------------------------------------------------
virtual void HandleResponseWithHosts( XRootDStatus *status,
AnyObject *response,
HostList *hostList );
private:
std::shared_ptr<FileSystemData> pFS;
ResponseHandler *pUserHandler;
};
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
class AssignLastURLHandler: public ResponseHandler
{
public:
//------------------------------------------------------------------------
// Constructor and destructor
//------------------------------------------------------------------------
AssignLastURLHandler( std::shared_ptr<FileSystemData> &fs,
ResponseHandler *userHandler ):
pFS(fs), pUserHandler(userHandler) {}
virtual ~AssignLastURLHandler() {}
//------------------------------------------------------------------------
// Response callback
//------------------------------------------------------------------------
virtual void HandleResponseWithHosts( XRootDStatus *status,
AnyObject *response,
HostList *hostList );
private:
std::shared_ptr<FileSystemData> pFS;
ResponseHandler *pUserHandler;
};
struct FileSystemData
{
FileSystemData( const URL &url ) :
pLoadBalancerLookupDone( false ),
pFollowRedirects( true ),
pUrl( new URL( url.GetURL() ) )
{
}
//------------------------------------------------------------------------
// Send a message in a locked environment
//------------------------------------------------------------------------
static XRootDStatus Send( std::shared_ptr<FileSystemData> &fs,
Message *msg,
ResponseHandler *handler,
MessageSendParams &params )
{
Log *log = DefaultEnv::GetLog();
XrdSysMutexHelper scopedLock( fs->pMutex );
log->Dump( FileSystemMsg, "[%p@%s] Sending %s", (void*)fs.get(),
fs->pUrl->GetHostId().c_str(), msg->GetObfuscatedDescription().c_str() );
AssignLastURLHandler *lastUrlHandler = new AssignLastURLHandler( fs, handler );
handler = lastUrlHandler;
AssignLBHandler *lbHandler = nullptr;
if( !fs->pLoadBalancerLookupDone && fs->pFollowRedirects )
{
lbHandler = new AssignLBHandler( fs, handler );
handler = lbHandler;
}
params.followRedirects = fs->pFollowRedirects;
auto st = MessageUtils::SendMessage( *fs->pUrl, msg, handler, params, 0 );
if( !st.IsOK() )
{
delete lastUrlHandler;
delete lbHandler;
}
return st;
}
//----------------------------------------------------------------------------
// Assign a load balancer if it has not already been assigned
//----------------------------------------------------------------------------
void AssignLoadBalancer( const URL &url )
{
Log *log = DefaultEnv::GetLog();
XrdSysMutexHelper scopedLock( pMutex );
if( pLoadBalancerLookupDone )
return;
log->Dump( FileSystemMsg, "[%p@%s] Assigning %s as load balancer", (void*)this,
pUrl->GetHostId().c_str(), url.GetHostId().c_str() );
pUrl.reset( new URL( url ) );
pLoadBalancerLookupDone = true;
}
//----------------------------------------------------------------------------
// Assign last URL
//----------------------------------------------------------------------------
void AssignLastURL( const URL &url )
{
Log *log = DefaultEnv::GetLog();
XrdSysMutexHelper scopedLock( pMutex );
log->Dump( FileSystemMsg, "[%p@%s] Assigning %s as last URL", (void*)this,
pUrl->GetHostId().c_str(), url.GetHostId().c_str() );
pLastUrl.reset( new URL( url ) );
}
XrdSysMutex pMutex;
bool pLoadBalancerLookupDone;
bool pFollowRedirects;
std::unique_ptr<URL> pUrl;
std::unique_ptr<URL> pLastUrl;
};
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
struct FileSystemImpl
{
FileSystemImpl( const URL &url ) :
fsdata( std::make_shared<FileSystemData>( url ) )
{
}
std::shared_ptr<FileSystemData> fsdata;
};
//------------------------------------------------------------------------
// Response callback
//------------------------------------------------------------------------
void AssignLBHandler::HandleResponseWithHosts( XRootDStatus *status,
AnyObject *response,
HostList *hostList )
{
if( status->IsOK() )
{
HostList::reverse_iterator it;
for( it = hostList->rbegin(); it != hostList->rend(); ++it )
if( it->loadBalancer )
{
pFS->AssignLoadBalancer( it->url );
break;
}
}
bool finalrsp = !( status->IsOK() && status->code == suContinue );
SyncResponseHandler * syncHandler = dynamic_cast<SyncResponseHandler*>( pUserHandler );
if( !syncHandler )
pUserHandler->HandleResponseWithHosts( status, response, hostList );
if( finalrsp )
{
if( syncHandler )
pUserHandler->HandleResponseWithHosts( status, response, hostList );
delete this;
}
}
//------------------------------------------------------------------------
// Response callback
//------------------------------------------------------------------------
void AssignLastURLHandler::HandleResponseWithHosts( XRootDStatus *status,
AnyObject *response,
HostList *hostList )
{
if( status->IsOK() && hostList )
pFS->AssignLastURL( hostList->front().url );
bool finalrsp = !( status->IsOK() && status->code == suContinue );
SyncResponseHandler *syncHandler = dynamic_cast<SyncResponseHandler*>( pUserHandler );
if( !syncHandler )
pUserHandler->HandleResponseWithHosts( status, response, hostList );
if( finalrsp )
{
if( syncHandler )
pUserHandler->HandleResponseWithHosts( status, response, hostList );
delete this;
}
}
//----------------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------------
FileSystem::FileSystem( const URL &url, bool enablePlugIns ):
pImpl( new FileSystemImpl( url ) ),
pPlugIn(0)
{
//--------------------------------------------------------------------------
// Check if we need to install a plug-in for this URL
//--------------------------------------------------------------------------
if( enablePlugIns )
{
Log *log = DefaultEnv::GetLog();
std::string urlStr = url.GetURL();
PlugInFactory *fact = DefaultEnv::GetPlugInManager()->GetFactory(urlStr);
if( fact )
{
pPlugIn = fact->CreateFileSystem( urlStr );
if( !pPlugIn )
{
log->Error( FileMsg, "Plug-in factory failed to produce a plug-in "
"for %s, continuing without one", url.GetObfuscatedURL().c_str() );
}
}
}
if( !pPlugIn )
DefaultEnv::GetForkHandler()->RegisterFileSystemObject( this );
}
//----------------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------------
FileSystem::~FileSystem()
{
if( !pPlugIn )
{
if( DefaultEnv::GetForkHandler() )
DefaultEnv::GetForkHandler()->UnRegisterFileSystemObject( this );
}
delete pPlugIn;
delete pImpl;
}
//----------------------------------------------------------------------------
// Locate a file - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Locate( const std::string &path,
OpenFlags::Flags flags,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->Locate( path, flags, handler, timeout );
std::string fPath = FilterXrdClCgi( path );
Message *msg;
ClientLocateRequest *req;
MessageUtils::CreateRequest( msg, req, fPath.length() );
req->requestid = kXR_locate;
req->options = flags;
req->dlen = fPath.length();
msg->Append( fPath.c_str(), fPath.length(), 24 );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Locate a file - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Locate( const std::string &path,
OpenFlags::Flags flags,
LocationInfo *&response,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = Locate( path, flags, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForResponse( &handler, response );
}
//----------------------------------------------------------------------------
// Locate a file, recursively locate all disk servers - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::DeepLocate( const std::string &path,
OpenFlags::Flags flags,
ResponseHandler *handler,
uint16_t timeout )
{
return Locate( path, flags,
new DeepLocateHandler( handler, path, flags, timeout ), timeout );
}
//----------------------------------------------------------------------------
// Locate a file, recursively locate all disk servers - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::DeepLocate( const std::string &path,
OpenFlags::Flags flags,
LocationInfo *&response,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = DeepLocate( path, flags, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForResponse( &handler, response );
}
//----------------------------------------------------------------------------
// Move a directory or a file - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Mv( const std::string &source,
const std::string &dest,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->Mv( source, dest, handler, timeout );
std::string fSource = FilterXrdClCgi( source );
std::string fDest = FilterXrdClCgi( dest );
Message *msg;
ClientMvRequest *req;
MessageUtils::CreateRequest( msg, req, fSource.length() + fDest.length()+1 );
req->requestid = kXR_mv;
req->dlen = fSource.length() + fDest.length()+1;
req->arg1len = fSource.length();
msg->Append( fSource.c_str(), fSource.length(), 24 );
*msg->GetBuffer(24 + fSource.length()) = ' ';
msg->Append( fDest.c_str(), fDest.length(), 25 + fSource.length() );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Move a directory or a file - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Mv( const std::string &source,
const std::string &dest,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = Mv( source, dest, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForStatus( &handler );
}
//----------------------------------------------------------------------------
// Obtain server information - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Query( QueryCode::Code queryCode,
const Buffer &arg,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->Query( queryCode, arg, handler, timeout );
Message *msg;
ClientQueryRequest *req;
MessageUtils::CreateRequest( msg, req, arg.GetSize() );
req->requestid = kXR_query;
req->infotype = queryCode;
req->dlen = arg.GetSize();
msg->Append( arg.GetBuffer(), arg.GetSize(), 24 );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Obtain server information - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Query( QueryCode::Code queryCode,
const Buffer &arg,
Buffer *&response,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = Query( queryCode, arg, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForResponse( &handler, response );
}
//----------------------------------------------------------------------------
// Truncate a file - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Truncate( const std::string &path,
uint64_t size,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->Truncate( path, size, handler, timeout );
std::string fPath = FilterXrdClCgi( path );
Message *msg;
ClientTruncateRequest *req;
MessageUtils::CreateRequest( msg, req, fPath.length() );
req->requestid = kXR_truncate;
req->offset = size;
req->dlen = fPath.length();
msg->Append( fPath.c_str(), fPath.length(), 24 );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Truncate a file - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Truncate( const std::string &path,
uint64_t size,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = Truncate( path, size, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForStatus( &handler );
}
//----------------------------------------------------------------------------
// Remove a file - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Rm( const std::string &path,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->Rm( path, handler, timeout );
if( pImpl->fsdata->pUrl->IsLocalFile() )
return LocalFS::Instance().Rm( path, handler, timeout );
std::string fPath = FilterXrdClCgi( path );
Message *msg;
ClientRmRequest *req;
MessageUtils::CreateRequest( msg, req, fPath.length() );
req->requestid = kXR_rm;
req->dlen = fPath.length();
msg->Append( fPath.c_str(), fPath.length(), 24 );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Remove a file - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Rm( const std::string &path,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = Rm( path, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForStatus( &handler );
}
//----------------------------------------------------------------------------
// Create a directory - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::MkDir( const std::string &path,
MkDirFlags::Flags flags,
Access::Mode mode,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->MkDir( path, flags, mode, handler, timeout );
std::string fPath = FilterXrdClCgi( path );
Message *msg;
ClientMkdirRequest *req;
MessageUtils::CreateRequest( msg, req, fPath.length() );
req->requestid = kXR_mkdir;
req->options[0] = flags;
req->mode = mode;
req->dlen = fPath.length();
msg->Append( fPath.c_str(), fPath.length(), 24 );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Create a directory - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::MkDir( const std::string &path,
MkDirFlags::Flags flags,
Access::Mode mode,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = MkDir( path, flags, mode, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForStatus( &handler );
}
//----------------------------------------------------------------------------
// Remove a directory - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::RmDir( const std::string &path,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->RmDir( path, handler, timeout );
std::string fPath = FilterXrdClCgi( path );
Message *msg;
ClientRmdirRequest *req;
MessageUtils::CreateRequest( msg, req, fPath.length() );
req->requestid = kXR_rmdir;
req->dlen = fPath.length();
msg->Append( fPath.c_str(), fPath.length(), 24 );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Remove a directory - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::RmDir( const std::string &path,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = RmDir( path, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForStatus( &handler );
}
//----------------------------------------------------------------------------
// Change access mode on a directory or a file - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::ChMod( const std::string &path,
Access::Mode mode,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->ChMod( path, mode, handler, timeout );
std::string fPath = FilterXrdClCgi( path );
Message *msg;
ClientChmodRequest *req;
MessageUtils::CreateRequest( msg, req, fPath.length() );
req->requestid = kXR_chmod;
req->mode = mode;
req->dlen = fPath.length();
msg->Append( fPath.c_str(), fPath.length(), 24 );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Change access mode on a directory or a file - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::ChMod( const std::string &path,
Access::Mode mode,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = ChMod( path, mode, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForStatus( &handler );
}
//----------------------------------------------------------------------------
// Check if the server is alive - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Ping( ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->Ping( handler, timeout );
Message *msg;
ClientPingRequest *req;
MessageUtils::CreateRequest( msg, req );
req->requestid = kXR_ping;
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Check if the server is alive - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Ping( uint16_t timeout )
{
SyncResponseHandler handler;
Status st = Ping( &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForStatus( &handler );
}
//----------------------------------------------------------------------------
// Obtain status information for a path - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Stat( const std::string &path,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->Stat( path, handler, timeout );
if( pImpl->fsdata->pUrl->IsLocalFile() )
return LocalFS::Instance().Stat( path, handler, timeout );
std::string fPath = FilterXrdClCgi( path );
Message *msg;
ClientStatRequest *req;
MessageUtils::CreateRequest( msg, req, fPath.length() );
req->requestid = kXR_stat;
req->options = 0;
req->dlen = fPath.length();
msg->Append( fPath.c_str(), fPath.length(), 24 );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Obtain status information for a path - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Stat( const std::string &path,
StatInfo *&response,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = Stat( path, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForResponse( &handler, response );
}
//----------------------------------------------------------------------------
// Obtain status information for a path - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::StatVFS( const std::string &path,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->StatVFS( path, handler, timeout );
std::string fPath = FilterXrdClCgi( path );
Message *msg;
ClientStatRequest *req;
MessageUtils::CreateRequest( msg, req, fPath.length() );
req->requestid = kXR_stat;
req->options = kXR_vfs;
req->dlen = fPath.length();
msg->Append( fPath.c_str(), fPath.length(), 24 );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Obtain status information for a path - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::StatVFS( const std::string &path,
StatInfoVFS *&response,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = StatVFS( path, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForResponse( &handler, response );
}
//----------------------------------------------------------------------------
// Obtain server protocol information - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Protocol( ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->Protocol( handler, timeout );
Message *msg;
ClientProtocolRequest *req;
MessageUtils::CreateRequest( msg, req );
req->requestid = kXR_protocol;
req->clientpv = kXR_PROTOCOLVERSION;
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Obtain server protocol information - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Protocol( ProtocolInfo *&response,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = Protocol( &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForResponse( &handler, response );
}
//----------------------------------------------------------------------------
// List entries of a directory - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::DirList( const std::string &path,
DirListFlags::Flags flags,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->DirList( path, flags, handler, timeout );
URL url = URL( path );
std::string fPath = FilterXrdClCgi( path );
if( flags & DirListFlags::Zip )
{
// stat the file to check if it is a directory or a file
// the ZIP handler will take care of the rest
ZipListHandler *zipHandler = new ZipListHandler( *pImpl->fsdata->pUrl, path, flags, handler, timeout );
XRootDStatus st = Stat( path, zipHandler, timeout );
if( !st.IsOK() )
delete zipHandler;
return st;
}
Message *msg;
ClientDirlistRequest *req;
MessageUtils::CreateRequest( msg, req, fPath.length() );
req->requestid = kXR_dirlist;
req->dlen = fPath.length();
if( ( flags & DirListFlags::Stat ) || ( flags & DirListFlags::Recursive ) )
req->options[0] = kXR_dstat;
if( ( flags & DirListFlags::Cksm ) )
req->options[0] = kXR_dstat | kXR_dcksm;
if( flags & DirListFlags::Recursive )
handler = new RecursiveDirListHandler( *pImpl->fsdata->pUrl, url.GetPath(), flags, handler, timeout );
if( flags & DirListFlags::Merge )
handler = new MergeDirListHandler( flags & DirListFlags::Chunked, handler );
msg->Append( fPath.c_str(), fPath.length(), 24 );
MessageSendParams params; params.timeout = timeout;
if( flags & DirListFlags::Chunked )
params.chunkedResponse = true;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// List entries of a directory - sync
//----------------------------------------------------------------------------
XRootDStatus FileSystem::DirList( const std::string &path,
DirListFlags::Flags flags,
DirectoryList *&response,
uint16_t timeout )
{
//--------------------------------------------------------------------------
// Chunked response is only possible for async DirList call
//--------------------------------------------------------------------------
if( flags & DirListFlags::Chunked )
return XRootDStatus( stError, errNotSupported );
//--------------------------------------------------------------------------
// If the path ends with '.zip' extension add Zip flag
//--------------------------------------------------------------------------
static const std::string zip_sufix = ".zip";
if( path.size() >= zip_sufix.size() &&
std::equal( zip_sufix.rbegin(), zip_sufix.rend(), path.rbegin() ) )
flags |= DirListFlags::Zip;
//--------------------------------------------------------------------------
// We do the deep locate and ask all the returned servers for the list
//--------------------------------------------------------------------------
if( flags & DirListFlags::Locate )
{
bool isserver = false;
//------------------------------------------------------------------------
// Check if destination is a data server
//------------------------------------------------------------------------
{
AnyObject obj;
XRootDStatus st = DefaultEnv::GetPostMaster()->QueryTransport(
*pImpl->fsdata->pUrl, XRootDQuery::ServerFlags, obj);
if( st.IsOK() )
{
int *ptr = 0;
obj.Get( ptr );
isserver = ( ptr && (*ptr & kXR_isServer) );
delete ptr;
}
}
if (isserver) {
// Just disable the locate flag if we are talking to a single server
flags &= ~DirListFlags::Locate;
} else {
//------------------------------------------------------------------------
// Locate all the disk servers holding the directory
//------------------------------------------------------------------------
LocationInfo *locations;
std::string locatePath = "*"; locatePath += path;
XRootDStatus st = DeepLocate(locatePath,
OpenFlags::PrefName |
OpenFlags::Compress |
OpenFlags::IntentDirList,
locations);
if( !st.IsOK() )
return st;
if( locations->GetSize() == 0 )
{
delete locations;
return XRootDStatus( stError, errNotFound );
}
//------------------------------------------------------------------------
// Ask each server for a directory list
//------------------------------------------------------------------------
flags &= ~DirListFlags::Locate;
FileSystem *fs;
DirectoryList *currentResp = 0;
uint32_t errors = 0;
uint32_t numLocations = locations->GetSize();
bool partial = st.code == suPartial ? true : false;
response = new DirectoryList();
response->SetParentName( path );
for( uint32_t i = 0; i < locations->GetSize(); ++i )
{
URL locationURL( locations->At(i).GetAddress() );
// make sure the original protocol is preserved (root vs roots)
locationURL.SetProtocol( pImpl->fsdata->pUrl->GetProtocol() );
fs = new FileSystem( locationURL );
st = fs->DirList( path, flags, currentResp, timeout );
if( !st.IsOK() )
{
++errors;
delete fs;
continue;
}
if( st.code == suPartial )
partial = true;
DirectoryList::Iterator it;
for( it = currentResp->Begin(); it != currentResp->End(); ++it )
{
response->Add( *it );
*it = 0;
}
delete fs;
delete currentResp;
fs = 0;
currentResp = 0;
}
delete locations;
if( flags & DirListFlags::Merge )
MergeDirListHandler::Merge( response );
if( errors || partial )
{
if( errors == numLocations )
return st;
return XRootDStatus( stOK, suPartial );
}
return XRootDStatus();
}
}
//--------------------------------------------------------------------------
// We just ask the current server
//--------------------------------------------------------------------------
SyncResponseHandler handler;
XRootDStatus st = DirList( path, flags, &handler, timeout );
if( !st.IsOK() )
return st;
st = MessageUtils::WaitForResponse( &handler, response );
if( !st.IsOK() )
return st;
//--------------------------------------------------------------------------
// Do the stats on all the entries if necessary.
// If we already have the stat objects it means that the bulk stat has
// succeeded.
//--------------------------------------------------------------------------
if( !(flags & DirListFlags::Stat) )
return st;
if( response->GetSize() && response->At(0)->GetStatInfo() )
return st;
uint32_t quota = response->GetSize() <= 1024 ? response->GetSize() : 1024;
RequestSync sync( response->GetSize(), quota );
for( uint32_t i = 0; i < response->GetSize(); ++i )
{
std::string fullPath = response->GetParentName()+response->At(i)->GetName();
ResponseHandler *handler = new DirListStatHandler( response, i, &sync );
st = Stat( fullPath, handler, timeout );
if( !st.IsOK() )
{
sync.TaskDone( false );
delete handler;
}
sync.WaitForQuota();
}
sync.WaitForAll();
if( sync.FailureCount() )
return XRootDStatus( stOK, suPartial );
return XRootDStatus();
}
//----------------------------------------------------------------------------
// Send cache info to the server - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::SendCache( const std::string &info,
ResponseHandler *handler,
uint16_t timeout )
{
// Note: adding SendCache() to the FileSystemPlugin class breaks ABI!
// So, the class is missing this until we do a major release. TODO
//if( pPlugIn )
// return pPlugIn->SendCache( info, handler, timeout );
return SendSet("cache ", info, handler, timeout );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
XRootDStatus FileSystem::SendCache( const std::string &info,
Buffer *&response,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = SendCache( info, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForResponse( &handler, response );
}
//----------------------------------------------------------------------------
// Send info to the server - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::SendInfo( const std::string &info,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->SendInfo( info, handler, timeout );
return SendSet("monitor info ", info, handler, timeout );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
XRootDStatus FileSystem::SendInfo( const std::string &info,
Buffer *&response,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = SendInfo( info, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForResponse( &handler, response );
}
//----------------------------------------------------------------------------
// Send set request to the server - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::SendSet( const char *prefix,
const std::string &info,
ResponseHandler *handler,
uint16_t timeout )
{
Message *msg;
ClientSetRequest *req;
size_t prefixLen = strlen( prefix );
MessageUtils::CreateRequest( msg, req, info.length()+prefixLen );
req->requestid = kXR_set;
req->dlen = info.length()+prefixLen;
msg->Append( prefix, prefixLen, 24 );
msg->Append( info.c_str(), info.length(), 24+prefixLen );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//----------------------------------------------------------------------------
// Prepare one or more files for access - async
//----------------------------------------------------------------------------
XRootDStatus FileSystem::Prepare( const std::vector<std::string> &fileList,
PrepareFlags::Flags flags,
uint8_t priority,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return pPlugIn->Prepare( fileList, flags, priority, handler, timeout );
std::vector<std::string>::const_iterator it;
std::string list;
for( it = fileList.begin(); it != fileList.end(); ++it )
{
list += *it;
list += "\n";
}
list.erase( list.length()-1, 1 );
Message *msg;
ClientPrepareRequest *req;
MessageUtils::CreateRequest( msg, req, list.length() );
req->requestid = kXR_prepare;
req->options = 0xff & flags;
req->optionX = 0xffff & ( flags >> 8 );
req->prty = priority;
req->dlen = list.length();
msg->Append( list.c_str(), list.length(), 24 );
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//------------------------------------------------------------------------
// Prepare one or more files for access - sync
//------------------------------------------------------------------------
XRootDStatus FileSystem::Prepare( const std::vector<std::string> &fileList,
PrepareFlags::Flags flags,
uint8_t priority,
Buffer *&response,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = Prepare( fileList, flags, priority, &handler, timeout );
if( !st.IsOK() )
return st;
return MessageUtils::WaitForResponse( &handler, response );
}
//------------------------------------------------------------------------
// Set extended attributes - async
//------------------------------------------------------------------------
XRootDStatus FileSystem::SetXAttr( const std::string &path,
const std::vector<xattr_t> &attrs,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return XRootDStatus( stError, errNotSupported );
return XAttrOperationImpl( kXR_fattrSet, 0, path, attrs, handler, timeout );
}
//------------------------------------------------------------------------
// Set extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus FileSystem::SetXAttr( const std::string &path,
const std::vector<xattr_t> &attrs,
std::vector<XAttrStatus> &result,
uint16_t timeout )
{
SyncResponseHandler handler;
XRootDStatus st = SetXAttr( path, attrs, &handler, timeout );
if( !st.IsOK() )
return st;
std::vector<XAttrStatus> *resp = 0;
st = MessageUtils::WaitForResponse( &handler, resp );
if( resp ) result.swap( *resp );
delete resp;
return st;
}
//------------------------------------------------------------------------
// Get extended attributes - async
//------------------------------------------------------------------------
XRootDStatus FileSystem::GetXAttr( const std::string &path,
const std::vector<std::string> &attrs,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return XRootDStatus( stError, errNotSupported );
return XAttrOperationImpl( kXR_fattrGet, 0, path, attrs, handler, timeout );
}
//------------------------------------------------------------------------
// Get extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus FileSystem::GetXAttr( const std::string &path,
const std::vector<std::string> &attrs,
std::vector<XAttr> &result,
uint16_t timeout )
{
SyncResponseHandler handler;
XRootDStatus st = GetXAttr( path, attrs, &handler, timeout );
if( !st.IsOK() )
return st;
std::vector<XAttr> *resp = 0;
st = MessageUtils::WaitForResponse( &handler, resp );
if( resp ) result.swap( *resp );
delete resp;
return st;
}
//------------------------------------------------------------------------
// Delete extended attributes - async
//------------------------------------------------------------------------
XRootDStatus FileSystem::DelXAttr( const std::string &path,
const std::vector<std::string> &attrs,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return XRootDStatus( stError, errNotSupported );
return XAttrOperationImpl( kXR_fattrDel, 0, path, attrs, handler, timeout );
}
//------------------------------------------------------------------------
// Delete extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus FileSystem::DelXAttr( const std::string &path,
const std::vector<std::string> &attrs,
std::vector<XAttrStatus> &result,
uint16_t timeout )
{
SyncResponseHandler handler;
XRootDStatus st = DelXAttr( path, attrs, &handler, timeout );
if( !st.IsOK() )
return st;
std::vector<XAttrStatus> *resp = 0;
st = MessageUtils::WaitForResponse( &handler, resp );
if( resp ) result.swap( *resp );
delete resp;
return st;
}
//------------------------------------------------------------------------
// List extended attributes - async
//------------------------------------------------------------------------
XRootDStatus FileSystem::ListXAttr( const std::string &path,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return XRootDStatus( stError, errNotSupported );
static const std::vector<std::string> nothing;
return XAttrOperationImpl( kXR_fattrList, ClientFattrRequest::aData,
path, nothing, handler, timeout );
}
//------------------------------------------------------------------------
// List extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus FileSystem::ListXAttr( const std::string &path,
std::vector<XAttr> &result,
uint16_t timeout )
{
SyncResponseHandler handler;
XRootDStatus st = ListXAttr( path, &handler, timeout );
if( !st.IsOK() )
return st;
std::vector<XAttr> *resp = 0;
st = MessageUtils::WaitForResponse( &handler, resp );
if( resp ) result.swap( *resp );
delete resp;
return st;
}
//----------------------------------------------------------------------------
// Set file property
//----------------------------------------------------------------------------
bool FileSystem::SetProperty( const std::string &name,
const std::string &value )
{
if( pPlugIn )
return pPlugIn->SetProperty( name, value );
if( name == "FollowRedirects" )
{
if( value == "true" ) pImpl->fsdata->pFollowRedirects = true;
else pImpl->fsdata->pFollowRedirects = false;
return true;
}
return false;
}
//----------------------------------------------------------------------------
// Get file property
//----------------------------------------------------------------------------
bool FileSystem::GetProperty( const std::string &name,
std::string &value ) const
{
if( pPlugIn )
return pPlugIn->GetProperty( name, value );
if( name == "FollowRedirects" )
{
if( pImpl->fsdata->pFollowRedirects ) value = "true";
else value = "false";
return true;
}
else if( name == "LastURL" )
{
if( pImpl->fsdata->pLastUrl )
{
value = pImpl->fsdata->pLastUrl->GetURL();
return true;
}
else return false;
}
return false;
}
//------------------------------------------------------------------------
// Generic implementation of xattr operation
//------------------------------------------------------------------------
template<typename T>
Status FileSystem::XAttrOperationImpl( kXR_char subcode,
kXR_char options,
const std::string &path,
const std::vector<T> &attrs,
ResponseHandler *handler,
uint16_t timeout )
{
Message *msg;
ClientFattrRequest *req;
MessageUtils::CreateRequest( msg, req );
req->requestid = kXR_fattr;
req->subcode = subcode;
req->options = options;
req->numattr = attrs.size();
memset( req->fhandle, 0, 4 );
XRootDStatus st = MessageUtils::CreateXAttrBody( msg, attrs, path );
if( !st.IsOK() ) return st;
MessageSendParams params; params.timeout = timeout;
MessageUtils::ProcessSendParams( params );
XRootDTransport::SetDescription( msg );
return FileSystemData::Send( pImpl->fsdata, msg, handler, params );
}
//------------------------------------------------------------------------
// Lock the internal lock
//------------------------------------------------------------------------
void FileSystem::Lock()
{
pImpl->fsdata->pMutex.Lock();
}
//------------------------------------------------------------------------
// Unlock the internal lock
//------------------------------------------------------------------------
void FileSystem::UnLock()
{
pImpl->fsdata->pMutex.UnLock();
}
}
ClientDirlistRequest::options
kXR_char options[1]
Definition XProtocol.hh:248
kXR_NotFound
@ kXR_NotFound
Definition XProtocol.hh:1001
kXR_FSError
@ kXR_FSError
Definition XProtocol.hh:995
ClientMvRequest::arg1len
kXR_int16 arg1len
Definition XProtocol.hh:430
ClientQueryRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:630
ClientQueryRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:635
kXR_fattrDel
@ kXR_fattrDel
Definition XProtocol.hh:270
kXR_fattrSet
@ kXR_fattrSet
Definition XProtocol.hh:273
kXR_fattrList
@ kXR_fattrList
Definition XProtocol.hh:272
kXR_fattrGet
@ kXR_fattrGet
Definition XProtocol.hh:271
ClientPingRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:546
ClientPrepareRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:601
ClientRmdirRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:710
ClientMvRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:431
ClientMkdirRequest::mode
kXR_unt16 mode
Definition XProtocol.hh:418
ClientPrepareRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:607
ClientChmodRequest::mode
kXR_unt16 mode
Definition XProtocol.hh:193
ClientPrepareRequest::optionX
kXR_unt16 optionX
Definition XProtocol.hh:605
ClientTruncateRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:793
ClientLocateRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:345
ClientDirlistRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:246
kXR_dstat
@ kXR_dstat
Definition XProtocol.hh:240
kXR_dcksm
@ kXR_dcksm
Definition XProtocol.hh:241
ClientMvRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:428
ClientQueryRequest::infotype
kXR_unt16 infotype
Definition XProtocol.hh:631
ClientLocateRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:348
ClientPrepareRequest::options
kXR_char options
Definition XProtocol.hh:602
kXR_mkdir
@ kXR_mkdir
Definition XProtocol.hh:120
kXR_chmod
@ kXR_chmod
Definition XProtocol.hh:114
kXR_dirlist
@ kXR_dirlist
Definition XProtocol.hh:116
kXR_fattr
@ kXR_fattr
Definition XProtocol.hh:132
kXR_rm
@ kXR_rm
Definition XProtocol.hh:126
kXR_query
@ kXR_query
Definition XProtocol.hh:113
kXR_set
@ kXR_set
Definition XProtocol.hh:130
kXR_rmdir
@ kXR_rmdir
Definition XProtocol.hh:127
kXR_truncate
@ kXR_truncate
Definition XProtocol.hh:140
kXR_protocol
@ kXR_protocol
Definition XProtocol.hh:118
kXR_mv
@ kXR_mv
Definition XProtocol.hh:121
kXR_ping
@ kXR_ping
Definition XProtocol.hh:123
kXR_stat
@ kXR_stat
Definition XProtocol.hh:129
kXR_locate
@ kXR_locate
Definition XProtocol.hh:139
kXR_prepare
@ kXR_prepare
Definition XProtocol.hh:133
ClientRmRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:699
ClientTruncateRequest::offset
kXR_int64 offset
Definition XProtocol.hh:795
ClientSetRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:719
ClientDirlistRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:249
kXR_isServer
#define kXR_isServer
Definition XProtocol.hh:1157
ClientChmodRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:194
ClientStatRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:768
ClientTruncateRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:797
ClientMkdirRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:415
ClientLocateRequest::options
kXR_unt16 options
Definition XProtocol.hh:346
ClientMkdirRequest::options
kXR_char options[1]
Definition XProtocol.hh:416
ClientRmRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:697
kXR_PROTOCOLVERSION
#define kXR_PROTOCOLVERSION
Definition XProtocol.hh:70
kXR_vfs
@ kXR_vfs
Definition XProtocol.hh:763
ClientSetRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:722
ClientChmodRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:191
ClientStatRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:772
ClientStatRequest::options
kXR_char options
Definition XProtocol.hh:769
kXR_isDir
@ kXR_isDir
Definition XProtocol.hh:1221
ClientPrepareRequest::prty
kXR_char prty
Definition XProtocol.hh:603
ClientRmdirRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:708
ClientMkdirRequest::dlen
kXR_int32 dlen
Definition XProtocol.hh:419
ClientLocateRequest
Definition XProtocol.hh:343
ClientTruncateRequest
Definition XProtocol.hh:791
ClientPingRequest
Definition XProtocol.hh:544
ClientDirlistRequest
Definition XProtocol.hh:244
ClientChmodRequest
Definition XProtocol.hh:189
ClientRmdirRequest
Definition XProtocol.hh:706
ClientQueryRequest
Definition XProtocol.hh:628
ClientSetRequest
Definition XProtocol.hh:717
ClientRmRequest
Definition XProtocol.hh:695
ClientPrepareRequest
Definition XProtocol.hh:599
ClientStatRequest
Definition XProtocol.hh:766
ClientMvRequest
Definition XProtocol.hh:426
ClientMkdirRequest
Definition XProtocol.hh:413
kXR_char
unsigned char kXR_char
Definition XPtypes.hh:65
Stat
struct stat Stat
Definition XrdCks.cc:49
XrdClConstants.hh
child
static void child()
Definition XrdClDefaultEnv.cc:105
parent
static void parent()
Definition XrdClDefaultEnv.cc:80
XrdClDefaultEnv.hh
XrdClFileSystem.hh
XrdClForkHandler.hh
XrdClLocalFileTask.hh
XrdClLog.hh
XrdClMessageUtils.hh
XrdClMessage.hh
XrdClPlugInInterface.hh
XrdClPlugInManager.hh
XrdClRequestSync.hh
XrdClXRootDResponses.hh
XrdClXRootDTransport.hh
XrdClZipListHandler.hh
unlink
#define unlink(a)
Definition XrdPosix.hh:113
stat
#define stat(a, b)
Definition XrdPosix.hh:101
XrdSysE2T
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:104
XrdSysE2T.hh
XrdSysPthread.hh
XProtocol::mapError
static int mapError(int rc)
Definition XProtocol.hh:1362
XrdCl::AnyObject
Definition XrdClAnyObject.hh:33
XrdCl::AnyObject::Set
void Set(Type object, bool own=true)
Definition XrdClAnyObject.hh:59
XrdCl::AnyObject::Get
void Get(Type &object)
Retrieve the object being held.
Definition XrdClAnyObject.hh:78
XrdCl::AssignLBHandler
Wrapper class used to assign a load balancer.
Definition XrdClFileSystem.cc:883
XrdCl::AssignLBHandler::~AssignLBHandler
virtual ~AssignLBHandler()
Definition XrdClFileSystem.cc:892
XrdCl::AssignLBHandler::AssignLBHandler
AssignLBHandler(std::shared_ptr< FileSystemData > &fs, ResponseHandler *userHandler)
Definition XrdClFileSystem.cc:888
XrdCl::AssignLBHandler::HandleResponseWithHosts
virtual void HandleResponseWithHosts(XRootDStatus *status, AnyObject *response, HostList *hostList)
Definition XrdClFileSystem.cc:1034
XrdCl::AssignLastURLHandler
Wrapper class used to assign last URL.
Definition XrdClFileSystem.cc:910
XrdCl::AssignLastURLHandler::HandleResponseWithHosts
virtual void HandleResponseWithHosts(XRootDStatus *status, AnyObject *response, HostList *hostList)
Definition XrdClFileSystem.cc:1066
XrdCl::AssignLastURLHandler::~AssignLastURLHandler
virtual ~AssignLastURLHandler()
Definition XrdClFileSystem.cc:919
XrdCl::AssignLastURLHandler::AssignLastURLHandler
AssignLastURLHandler(std::shared_ptr< FileSystemData > &fs, ResponseHandler *userHandler)
Definition XrdClFileSystem.cc:915
XrdCl::Buffer
Binary blob representation.
Definition XrdClBuffer.hh:34
XrdCl::Buffer::Append
void Append(const char *buffer, uint32_t size)
Append data at the position pointed to by the append cursor.
Definition XrdClBuffer.hh:164
XrdCl::Buffer::GetBuffer
const char * GetBuffer(uint32_t offset=0) const
Get the message buffer.
Definition XrdClBuffer.hh:72
XrdCl::Buffer::GetSize
uint32_t GetSize() const
Get the size of the message.
Definition XrdClBuffer.hh:132
XrdCl::DefaultEnv::GetPlugInManager
static PlugInManager * GetPlugInManager()
Get plug-in manager.
Definition XrdClDefaultEnv.cc:670
XrdCl::DefaultEnv::GetLog
static Log * GetLog()
Get default log.
Definition XrdClDefaultEnv.cc:493
XrdCl::DefaultEnv::GetPostMaster
static PostMaster * GetPostMaster()
Get default post master.
Definition XrdClDefaultEnv.cc:453
XrdCl::DefaultEnv::GetForkHandler
static ForkHandler * GetForkHandler()
Get the fork handler.
Definition XrdClDefaultEnv.cc:551
XrdCl::DefaultEnv::GetEnv
static Env * GetEnv()
Get default client environment.
Definition XrdClDefaultEnv.cc:445
XrdCl::DirectoryList::ListEntry::SetStatInfo
void SetStatInfo(StatInfo *info)
Set the stat info object (and transfer the ownership).
Definition XrdClXRootDResponses.hh:714
XrdCl::DirectoryList::ListEntry::GetName
const std::string & GetName() const
Get file name.
Definition XrdClXRootDResponses.hh:690
XrdCl::DirectoryList::ListEntry::GetHostAddress
const std::string & GetHostAddress() const
Get host address.
Definition XrdClXRootDResponses.hh:682
XrdCl::DirectoryList::ListEntry::GetStatInfo
StatInfo * GetStatInfo()
Get the stat info object.
Definition XrdClXRootDResponses.hh:698
XrdCl::DirectoryList
Directory list.
Definition XrdClXRootDResponses.hh:651
XrdCl::DirectoryList::Add
void Add(ListEntry *entry)
Add an entry to the list - takes ownership.
Definition XrdClXRootDResponses.hh:762
XrdCl::DirectoryList::GetSize
uint32_t GetSize() const
Get the size of the listing.
Definition XrdClXRootDResponses.hh:810
XrdCl::DirectoryList::GetParentName
const std::string & GetParentName() const
Get parent directory name.
Definition XrdClXRootDResponses.hh:818
XrdCl::DirectoryList::Iterator
DirList::iterator Iterator
Directory listing iterator.
Definition XrdClXRootDResponses.hh:752
XrdCl::DirectoryList::End
Iterator End()
Get the end iterator.
Definition XrdClXRootDResponses.hh:794
XrdCl::DirectoryList::Begin
Iterator Begin()
Get the begin iterator.
Definition XrdClXRootDResponses.hh:778
XrdCl::DirectoryList::SetParentName
void SetParentName(const std::string &parent)
Set name of the parent directory.
Definition XrdClXRootDResponses.hh:826
XrdCl::DirectoryList::At
ListEntry * At(uint32_t index)
Get an entry at given index.
Definition XrdClXRootDResponses.hh:770
XrdCl::Env::GetInt
bool GetInt(const std::string &key, int &value)
Definition XrdClEnv.cc:89
XrdCl::FileSystem::SetXAttr
XRootDStatus SetXAttr(const std::string &path, const std::vector< xattr_t > &attrs, ResponseHandler *handler, uint16_t timeout=0)
Definition XrdClFileSystem.cc:2035
XrdCl::FileSystem::RmDir
XRootDStatus RmDir(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1429
XrdCl::FileSystem::SetProperty
bool SetProperty(const std::string &name, const std::string &value)
Definition XrdClFileSystem.cc:2175
XrdCl::FileSystem::Protocol
XRootDStatus Protocol(ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1633
XrdCl::FileSystem::DirList
XRootDStatus DirList(const std::string &path, DirListFlags::Flags flags, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1669
XrdCl::FileSystem::Mv
XRootDStatus Mv(const std::string &source, const std::string &dest, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1208
XrdCl::FileSystem::Query
XRootDStatus Query(QueryCode::Code queryCode, const Buffer &arg, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1255
XrdCl::FileSystem::Locate
XRootDStatus Locate(const std::string &path, OpenFlags::Flags flags, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1135
XrdCl::FileSystem::SendInfo
XRootDStatus SendInfo(const std::string &info, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1926
XrdCl::FileSystem::Stat
XRootDStatus Stat(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1546
XrdCl::FileSystem::Prepare
XRootDStatus Prepare(const std::vector< std::string > &fileList, PrepareFlags::Flags flags, uint8_t priority, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1978
XrdCl::FileSystem::ChMod
XRootDStatus ChMod(const std::string &path, Access::Mode mode, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1469
XrdCl::FileSystem::DelXAttr
XRootDStatus DelXAttr(const std::string &path, const std::vector< std::string > &attrs, ResponseHandler *handler, uint16_t timeout=0)
Definition XrdClFileSystem.cc:2105
XrdCl::FileSystem::ListXAttr
XRootDStatus ListXAttr(const std::string &path, ResponseHandler *handler, uint16_t timeout=0)
Definition XrdClFileSystem.cc:2140
XrdCl::FileSystem::Rm
XRootDStatus Rm(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1340
XrdCl::FileSystem::FileSystem
FileSystem(const URL &url, bool enablePlugIns=true)
Definition XrdClFileSystem.cc:1090
XrdCl::FileSystem::DeepLocate
XRootDStatus DeepLocate(const std::string &path, OpenFlags::Flags flags, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1180
XrdCl::FileSystem::SendCache
XRootDStatus SendCache(const std::string &info, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1897
XrdCl::FileSystem::~FileSystem
~FileSystem()
Destructor.
Definition XrdClFileSystem.cc:1120
XrdCl::FileSystem::GetXAttr
XRootDStatus GetXAttr(const std::string &path, const std::vector< std::string > &attrs, ResponseHandler *handler, uint16_t timeout=0)
Definition XrdClFileSystem.cc:2070
XrdCl::FileSystem::Ping
XRootDStatus Ping(ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1512
XrdCl::FileSystem::Truncate
XRootDStatus Truncate(const std::string &path, uint64_t size, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1297
XrdCl::FileSystem::GetProperty
bool GetProperty(const std::string &name, std::string &value) const
Definition XrdClFileSystem.cc:2193
XrdCl::FileSystem::MkDir
XRootDStatus MkDir(const std::string &path, MkDirFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1383
XrdCl::FileSystem::StatVFS
XRootDStatus StatVFS(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition XrdClFileSystem.cc:1591
XrdCl::ForkHandler::UnRegisterFileSystemObject
void UnRegisterFileSystemObject(FileSystem *fs)
Un-register a file system object.
Definition XrdClForkHandler.hh:70
XrdCl::LocationInfo::Location::GetAddress
const std::string & GetAddress() const
Get address.
Definition XrdClXRootDResponses.hh:86
XrdCl::LocationInfo
Path location info.
Definition XrdClXRootDResponses.hh:44
XrdCl::LocationInfo::GetSize
uint32_t GetSize() const
Get number of locations.
Definition XrdClXRootDResponses.hh:152
XrdCl::LocationInfo::Begin
Iterator Begin()
Get the location begin iterator.
Definition XrdClXRootDResponses.hh:168
XrdCl::LocationInfo::At
Location & At(uint32_t index)
Get the location at index.
Definition XrdClXRootDResponses.hh:160
XrdCl::LocationInfo::End
Iterator End()
Get the location end iterator.
Definition XrdClXRootDResponses.hh:184
XrdCl::Log
Handle diagnostics.
Definition XrdClLog.hh:101
XrdCl::Log::Error
void Error(uint64_t topic, const char *format,...)
Report an error.
Definition XrdClLog.cc:231
XrdCl::Log::Dump
void Dump(uint64_t topic, const char *format,...)
Print a dump message.
Definition XrdClLog.cc:299
XrdCl::Log::Debug
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
Definition XrdClLog.cc:282
XrdCl::MessageUtils::ProcessSendParams
static void ProcessSendParams(MessageSendParams &sendParams)
Process sending params.
Definition XrdClMessageUtils.cc:220
XrdCl::MessageUtils::CreateXAttrBody
static Status CreateXAttrBody(Message *msg, const std::vector< T > &vec, const std::string &path="")
Definition XrdClMessageUtils.hh:286
XrdCl::MessageUtils::WaitForResponse
static XrdCl::XRootDStatus WaitForResponse(SyncResponseHandler *handler, Type *&response)
Wait for the response.
Definition XrdClMessageUtils.hh:168
XrdCl::MessageUtils::SendMessage
static XRootDStatus SendMessage(const URL &url, Message *msg, ResponseHandler *handler, MessageSendParams &sendParams, LocalFileHandler *lFileHandler)
Send message.
Definition XrdClMessageUtils.cc:43
XrdCl::MessageUtils::CreateRequest
static void CreateRequest(Message *&msg, Request *&req, uint32_t payloadSize=0)
Create a message.
Definition XrdClMessageUtils.hh:198
XrdCl::MessageUtils::WaitForStatus
static XRootDStatus WaitForStatus(SyncResponseHandler *handler)
Wait and return the status of the query.
Definition XrdClMessageUtils.hh:155
XrdCl::Message
The message representation used throughout the system.
Definition XrdClMessage.hh:32
XrdCl::Message::GetObfuscatedDescription
const std::string & GetObfuscatedDescription() const
Get the description of the message with authz parameter obfuscated.
Definition XrdClMessage.hh:106
XrdCl::PlugInFactory
Plugin factory.
Definition XrdClPlugInInterface.hh:549
XrdCl::PlugInFactory::CreateFileSystem
virtual FileSystemPlugIn * CreateFileSystem(const std::string &url)=0
Create a file system plug-in for the given URL.
XrdCl::PlugInManager::GetFactory
PlugInFactory * GetFactory(const std::string url)
Definition XrdClPlugInManager.cc:145
XrdCl::PostMaster::QueryTransport
Status QueryTransport(const URL &url, uint16_t query, AnyObject &result)
Definition XrdClPostMaster.cc:252
XrdCl::ProtocolInfo
Protocol response.
Definition XrdClXRootDResponses.hh:342
XrdCl::RequestSync
A helper running a fixed number of requests at a given time.
Definition XrdClRequestSync.hh:36
XrdCl::RequestSync::WaitForAll
void WaitForAll()
Wait for all the requests to be finished.
Definition XrdClRequestSync.hh:74
XrdCl::RequestSync::TaskDone
void TaskDone(bool success=true)
Report the request finish.
Definition XrdClRequestSync.hh:82
XrdCl::RequestSync::FailureCount
uint32_t FailureCount() const
Number of tasks finishing with an error.
Definition XrdClRequestSync.hh:96
XrdCl::RequestSync::WaitForQuota
void WaitForQuota()
Wait for the request quota.
Definition XrdClRequestSync.hh:66
XrdCl::ResponseHandler
Handle an async response.
Definition XrdClXRootDResponses.hh:1127
XrdCl::ResponseHandler::HandleResponseWithHosts
virtual void HandleResponseWithHosts(XRootDStatus *status, AnyObject *response, HostList *hostList)
Definition XrdClXRootDResponses.hh:1140
XrdCl::StatInfoVFS
VFS stat info.
Definition XrdClXRootDResponses.hh:574
XrdCl::StatInfo
Object stat info.
Definition XrdClXRootDResponses.hh:401
XrdCl::StatInfo::TestFlags
bool TestFlags(uint32_t flags) const
Test flags.
Definition XrdClXRootDResponses.cc:306
XrdCl::StatInfo::GetSize
uint64_t GetSize() const
Get size (in bytes).
Definition XrdClXRootDResponses.cc:274
XrdCl::StatInfo::ParseServerResponse
bool ParseServerResponse(const char *data)
Parse server response and fill up the object.
Definition XrdClXRootDResponses.cc:258
XrdCl::StatInfo::GetFlags
uint32_t GetFlags() const
Get flags.
Definition XrdClXRootDResponses.cc:290
XrdCl::SyncResponseHandler
Synchronize the response.
Definition XrdClMessageUtils.hh:44
XrdCl::SyncResponseHandler::HandleResponse
virtual void HandleResponse(XRootDStatus *status, AnyObject *response)
Handle the response.
Definition XrdClMessageUtils.hh:65
XrdCl::URL
URL representation.
Definition XrdClURL.hh:31
XrdCl::URL::GetPath
const std::string & GetPath() const
Get the path.
Definition XrdClURL.hh:217
XrdCl::URL::GetHostId
std::string GetHostId() const
Get the host part of the URL (user:password@host:port).
Definition XrdClURL.hh:99
XrdCl::URL::GetURL
std::string GetURL() const
Get the URL.
Definition XrdClURL.hh:86
XrdCl::URL::GetObfuscatedURL
std::string GetObfuscatedURL() const
Get the URL with authz information obfuscated.
Definition XrdClURL.cc:498
XrdCl::URL::SetProtocol
void SetProtocol(const std::string &protocol)
Set protocol.
Definition XrdClURL.hh:126
XrdCl::XRootDStatus
Request status.
Definition XrdClXRootDResponses.hh:219
XrdCl::XRootDStatus::ToStr
std::string ToStr() const
Convert to string.
Definition XrdClXRootDResponses.hh:258
XrdCl::XRootDTransport::SetDescription
static void SetDescription(Message *msg)
Get the description of a message.
Definition XrdClXRootDTransport.hh:245
XrdCl::ZipListHandler
Definition XrdClZipListHandler.hh:45
XrdSysMutexHelper
Definition XrdSysPthread.hh:263
XrdSysMutex
Definition XrdSysPthread.hh:165
XrdCl
Definition XrdClAction.hh:34
XrdCl::suPartial
const uint16_t suPartial
Definition XrdClStatus.hh:41
XrdCl::SendInfo
SendInfoImpl< false > SendInfo
Definition XrdClFileSystemOperations.hh:793
XrdCl::ChMod
ChModImpl< false > ChMod
Definition XrdClFileSystemOperations.hh:521
XrdCl::MkDir
MkDirImpl< false > MkDir
Definition XrdClFileSystemOperations.hh:427
XrdCl::Rm
RmImpl< false > Rm
Definition XrdClFileSystemOperations.hh:378
XrdCl::stError
const uint16_t stError
An error occurred that could potentially be retried.
Definition XrdClStatus.hh:32
XrdCl::errNotFound
const uint16_t errNotFound
Definition XrdClStatus.hh:100
XrdCl::Mv
MvImpl< false > Mv
Definition XrdClFileSystemOperations.hh:232
XrdCl::Locate
LocateImpl< false > Locate
Definition XrdClFileSystemOperations.hh:136
XrdCl::HostList
std::vector< HostInfo > HostList
Definition XrdClXRootDResponses.hh:1121
XrdCl::errInternal
const uint16_t errInternal
Internal error.
Definition XrdClStatus.hh:56
XrdCl::stOK
const uint16_t stOK
Everything went OK.
Definition XrdClStatus.hh:31
XrdCl::FileMsg
const uint64_t FileMsg
Definition XrdClConstants.hh:34
XrdCl::DeepLocate
DeepLocateImpl< false > DeepLocate
Definition XrdClFileSystemOperations.hh:184
XrdCl::Protocol
ProtocolImpl< false > Protocol
Definition XrdClFileSystemOperations.hh:698
XrdCl::DefaultRequestTimeout
const int DefaultRequestTimeout
Definition XrdClConstants.hh:54
XrdCl::errNotSupported
const uint16_t errNotSupported
Definition XrdClStatus.hh:62
XrdCl::RmDir
RmDirImpl< false > RmDir
Definition XrdClFileSystemOperations.hh:473
XrdCl::Prepare
PrepareImpl< false > Prepare
Definition XrdClFileSystemOperations.hh:843
XrdCl::StatVFS
StatVFSImpl< false > StatVFS
Definition XrdClFileSystemOperations.hh:658
XrdCl::Ping
PingImpl< false > Ping
Definition XrdClFileSystemOperations.hh:560
XrdCl::suContinue
const uint16_t suContinue
Definition XrdClStatus.hh:39
XrdCl::DirList
DirListImpl< false > DirList
Definition XrdClFileSystemOperations.hh:746
XrdCl::Query
QueryImpl< false > Query
Definition XrdClFileSystemOperations.hh:280
XrdCl::FileSystemMsg
const uint64_t FileSystemMsg
Definition XrdClConstants.hh:40
XrdCl::value
Response NullRef< Response >::value
Definition XrdClOperationHandlers.hh:128
XrdGlobal::Log
XrdSysError Log
Definition XrdConfig.cc:113
ClientFattrRequest
Definition XProtocol.hh:285
ClientFattrRequest::numattr
kXR_char numattr
Definition XProtocol.hh:290
ClientFattrRequest::aData
static const int aData
Definition XProtocol.hh:298
ClientFattrRequest::fhandle
kXR_char fhandle[4]
Definition XProtocol.hh:288
ClientFattrRequest::subcode
kXR_char subcode
Definition XProtocol.hh:289
ClientFattrRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:287
ClientFattrRequest::options
kXR_char options
Definition XProtocol.hh:291
ClientProtocolRequest
Definition XProtocol.hh:555
ClientProtocolRequest::clientpv
kXR_int32 clientpv
Definition XProtocol.hh:558
ClientProtocolRequest::requestid
kXR_unt16 requestid
Definition XProtocol.hh:557
XrdCl::Access::Mode
Mode
Access mode.
Definition XrdClFileSystem.hh:122
XrdCl::DirListFlags
DirList flags.
Definition XrdClFileSystem.hh:154
XrdCl::DirListFlags::Flags
Flags
Definition XrdClFileSystem.hh:156
XrdCl::DirListFlags::Stat
@ Stat
Stat each entry.
Definition XrdClFileSystem.hh:158
XrdCl::DirListFlags::Merge
@ Merge
Merge duplicates.
Definition XrdClFileSystem.hh:162
XrdCl::DirListFlags::Zip
@ Zip
List content of ZIP files.
Definition XrdClFileSystem.hh:164
XrdCl::DirListFlags::Locate
@ Locate
Definition XrdClFileSystem.hh:159
XrdCl::DirListFlags::Recursive
@ Recursive
Do a recursive listing.
Definition XrdClFileSystem.hh:161
XrdCl::DirListFlags::Cksm
@ Cksm
Get checksum for every entry.
Definition XrdClFileSystem.hh:165
XrdCl::DirListFlags::Chunked
@ Chunked
Serve chunked results for better performance.
Definition XrdClFileSystem.hh:163
XrdCl::FileSystemData
Definition XrdClFileSystem.cc:935
XrdCl::FileSystemData::Send
static XRootDStatus Send(std::shared_ptr< FileSystemData > &fs, Message *msg, ResponseHandler *handler, MessageSendParams &params)
Definition XrdClFileSystem.cc:946
XrdCl::FileSystemData::FileSystemData
FileSystemData(const URL &url)
Definition XrdClFileSystem.cc:936
XrdCl::FileSystemData::AssignLastURL
void AssignLastURL(const URL &url)
Definition XrdClFileSystem.cc:1000
XrdCl::FileSystemData::pLoadBalancerLookupDone
bool pLoadBalancerLookupDone
Definition XrdClFileSystem.cc:1012
XrdCl::FileSystemData::pMutex
XrdSysMutex pMutex
Definition XrdClFileSystem.cc:1011
XrdCl::FileSystemData::pFollowRedirects
bool pFollowRedirects
Definition XrdClFileSystem.cc:1013
XrdCl::FileSystemData::pLastUrl
std::unique_ptr< URL > pLastUrl
Definition XrdClFileSystem.cc:1015
XrdCl::FileSystemData::pUrl
std::unique_ptr< URL > pUrl
Definition XrdClFileSystem.cc:1014
XrdCl::FileSystemData::AssignLoadBalancer
void AssignLoadBalancer(const URL &url)
Definition XrdClFileSystem.cc:982
XrdCl::FileSystemImpl
Implementation holding the data members.
Definition XrdClFileSystem.cc:1022
XrdCl::FileSystemImpl::FileSystemImpl
FileSystemImpl(const URL &url)
Definition XrdClFileSystem.cc:1023
XrdCl::FileSystemImpl::fsdata
std::shared_ptr< FileSystemData > fsdata
Definition XrdClFileSystem.cc:1028
XrdCl::MessageSendParams
Definition XrdClMessageUtils.hh:132
XrdCl::MessageSendParams::timeout
uint16_t timeout
Definition XrdClMessageUtils.hh:136
XrdCl::MessageSendParams::chunkedResponse
bool chunkedResponse
Definition XrdClMessageUtils.hh:140
XrdCl::MessageSendParams::followRedirects
bool followRedirects
Definition XrdClMessageUtils.hh:139
XrdCl::MkDirFlags::Flags
Flags
Definition XrdClFileSystem.hh:143
XrdCl::OpenFlags::Flags
Flags
Open flags, may be or'd when appropriate.
Definition XrdClFileSystem.hh:76
XrdCl::OpenFlags::Compress
@ Compress
Definition XrdClFileSystem.hh:78
XrdCl::OpenFlags::PrefName
@ PrefName
Definition XrdClFileSystem.hh:105
XrdCl::OpenFlags::IntentDirList
@ IntentDirList
Definition XrdClFileSystem.hh:107
XrdCl::PrepareFlags::Flags
Flags
Definition XrdClFileSystem.hh:176
XrdCl::QueryCode::Code
Code
XRootD query request codes.
Definition XrdClFileSystem.hh:53
XrdCl::Status
Procedure execution status.
Definition XrdClStatus.hh:115
XrdCl::Status::code
uint16_t code
Error type, or additional hints on what to do.
Definition XrdClStatus.hh:147
XrdCl::Status::IsOK
bool IsOK() const
We're fine.
Definition XrdClStatus.hh:124
XrdCl::Status::ToString
std::string ToString() const
Create a string representation.
Definition XrdClStatus.cc:97
XrdCl::XRootDQuery::ServerFlags
static const uint16_t ServerFlags
returns server flags
Definition XrdClPostMasterInterfaces.hh:290