//------------------------------------------------------------------------------ // Copyright (c) 2014 by European Organization for Nuclear Research (CERN) // Author: Lukasz Janyst //------------------------------------------------------------------------------ // 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 . // // 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/XrdClFileSystemUtils.hh" #include "XrdCl/XrdClFileSystem.hh" #include "XrdCl/XrdClFileSystem.hh" #include "XrdCl/XrdClUglyHacks.hh" #include "XrdCl/XrdClURL.hh" #include #include #include namespace XrdCl { //---------------------------------------------------------------------------- // Recursively get space information for given path //---------------------------------------------------------------------------- XRootDStatus FileSystemUtils::GetSpaceInfo( SpaceInfo *&result, FileSystem *fs, const std::string &path ) { //-------------------------------------------------------------------------- // Locate all the disk servers containing the space //-------------------------------------------------------------------------- LocationInfo *locationInfo = 0; XRootDStatus st = fs->DeepLocate( path, OpenFlags::Compress, locationInfo ); if( !st.IsOK() ) return st; XRDCL_SMART_PTR_T locationInfoPtr( locationInfo ); bool partial = st.code == suPartial ? true : false; std::vector > resp; resp.push_back( std::make_pair( std::string("oss.space"), (uint64_t)0 ) ); resp.push_back( std::make_pair( std::string("oss.free"), (uint64_t)0 ) ); resp.push_back( std::make_pair( std::string("oss.used"), (uint64_t)0 ) ); resp.push_back( std::make_pair( std::string("oss.maxf"), (uint64_t)0 ) ); //-------------------------------------------------------------------------- // Loop over the file servers and get the space info from each of them //-------------------------------------------------------------------------- LocationInfo::Iterator it; Buffer pathArg; pathArg.FromString( path ); for( it = locationInfo->Begin(); it != locationInfo->End(); ++it ) { //------------------------------------------------------------------------ // Query the server //------------------------------------------------------------------------ Buffer *spaceInfo = 0; FileSystem fs1( it->GetAddress() ); st = fs1.Query( QueryCode::Space, pathArg, spaceInfo ); if( !st.IsOK() ) return st; XRDCL_SMART_PTR_T spaceInfoPtr( spaceInfo ); //------------------------------------------------------------------------ // Parse the cgi //------------------------------------------------------------------------ std::string fakeUrl = "root://fake/fake?" + spaceInfo->ToString(); URL url( fakeUrl ); if( !url.IsValid() ) return XRootDStatus( stError, errInvalidResponse ); URL::ParamsMap params = url.GetParams(); //------------------------------------------------------------------------ // Convert and add up the params //------------------------------------------------------------------------ st = XRootDStatus( stError, errInvalidResponse ); for( size_t i = 0; i < resp.size(); ++i ) { URL::ParamsMap::iterator paramIt = params.find( resp[i].first ); if( paramIt == params.end() ) return st; char *res; uint64_t num = ::strtoll( paramIt->second.c_str(), &res, 0 ); if( *res != 0 ) return st; if( resp[i].first == "oss.maxf" ) { if( num > resp[i].second ) resp[i].second = num; } else resp[i].second += num; } } result = new SpaceInfo( resp[0].second, resp[1].second, resp[2].second, resp[3].second ); st = XRootDStatus(); if( partial ) st.code = suPartial; return st; } }