/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FWStorage/XrdAdaptor/plugins/XrdStorageMaker.cc
210 строк
7 KB
Chris Jones
Moved Utilities/XrdAdaptor to FWStorage/XrdAdaptor
10 дек 2025, 18:22
10 дек 2025, 18:22
d455443
Код
Авторство
О чём код?
#include "FWCore/Utilities/interface/EDMException.h" #include "FWCore/ServiceRegistry/interface/ServiceMaker.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Utilities/interface/thread_safety_macros.h" #include "FWStorage/StorageFactory/interface/StorageMaker.h" #include "FWStorage/StorageFactory/interface/StorageMakerFactory.h" #include "FWStorage/StorageFactory/interface/StorageFactory.h" #include "FWStorage/XrdAdaptor/src/XrdStatistics.h" #include "FWStorage/XrdAdaptor/src/XrdFile.h" #include "XrdCl/XrdClDefaultEnv.hh" #include "XrdNet/XrdNetUtils.hh" #include <atomic> #include <mutex> namespace { class PrepareHandler : public XrdCl::ResponseHandler { public: PrepareHandler(const XrdCl::URL &url) : m_fs(url) { m_fileList.push_back(url.GetPath()); } void callAsyncPrepare() { auto status = m_fs.Prepare(m_fileList, XrdCl::PrepareFlags::Stage, 0, this); if (!status.IsOK()) { LogDebug("StageInError") << "XrdCl::FileSystem::Prepare submit failed with error '" << status.ToStr() << "' (errNo = " << status.errNo << ")"; delete this; } } void HandleResponse(XrdCl::XRootDStatus *status, XrdCl::AnyObject *response) override { // Note: Prepare call has a response object. if (!status->IsOK()) { LogDebug("StageInError") << "XrdCl::FileSystem::Prepare failed with error '" << status->ToStr() << "' (errNo = " << status->errNo << ")"; } delete response; delete status; delete this; } private: XrdCl::FileSystem m_fs; std::vector<std::string> m_fileList; }; } // namespace namespace edm::storage { class XrdStorageMaker final : public StorageMaker { public: static const unsigned int XRD_DEFAULT_TIMEOUT = 3 * 60; XrdStorageMaker() : m_lastDebugLevel(1), //so that 0 will trigger change m_lastTimeout(0) { // When CMSSW loads, both XrdCl and XrdClient end up being loaded // (ROOT loads XrdClient). XrdClient forces IPv4-only. Accordingly, // we must explicitly set the default network stack in XrdCl to // whatever is available on the node (IPv4 or IPv6). XrdCl::Env *env = XrdCl::DefaultEnv::GetEnv(); if (env) { env->PutString("NetworkStack", "IPAuto"); } XrdNetUtils::SetAuto(XrdNetUtils::prefAuto); setTimeout(XRD_DEFAULT_TIMEOUT); setDebugLevel(0); } /** Open a storage object for the given URL (protocol + path), using the @a mode bits. No temporary files are downloaded. */ std::unique_ptr<Storage> open(const std::string &proto, const std::string &path, int mode, const AuxSettings &aux) const override { setDebugLevel(aux.debugLevel); setTimeout(aux.timeout); const StorageFactory *f = StorageFactory::get(); StorageFactory::ReadHint readHint = f->readHint(); StorageFactory::CacheHint cacheHint = f->cacheHint(); if (readHint != StorageFactory::READ_HINT_UNBUFFERED || cacheHint == StorageFactory::CACHE_HINT_STORAGE) mode &= ~IOFlags::OpenUnbuffered; else mode |= IOFlags::OpenUnbuffered; std::string fullpath(proto + ":" + path); return std::make_unique<XrdFile>(fullpath, mode); } void stagein(const std::string &proto, const std::string &path, const AuxSettings &aux) const override { setDebugLevel(aux.debugLevel); setTimeout(aux.timeout); std::string fullpath(proto + ":" + path); XrdCl::URL url(fullpath); auto prep_handler = new PrepareHandler(url); prep_handler->callAsyncPrepare(); } bool check(const std::string &proto, const std::string &path, const AuxSettings &aux, IOOffset *size = nullptr) const override { setDebugLevel(aux.debugLevel); setTimeout(aux.timeout); std::string fullpath(proto + ":" + path); XrdCl::URL url(fullpath); XrdCl::FileSystem fs(url); XrdCl::StatInfo *stat; if (!(fs.Stat(url.GetPath(), stat)).IsOK() || (stat == nullptr)) { return false; } if (size) *size = stat->GetSize(); return true; } UseLocalFile usesLocalFile() const override { return UseLocalFile::kNo; } void setDebugLevel(unsigned int level) const { auto oldLevel = m_lastDebugLevel.load(); if (level == oldLevel) { return; } std::lock_guard<std::mutex> guard(m_envMutex); if (oldLevel != m_lastDebugLevel) { //another thread just changed this value return; } // 'Error' is way too low of debug level - we have interest // in warning in the default switch (level) { case 0: XrdCl::DefaultEnv::SetLogLevel("Warning"); break; case 1: XrdCl::DefaultEnv::SetLogLevel("Info"); break; case 2: XrdCl::DefaultEnv::SetLogLevel("Debug"); break; case 3: XrdCl::DefaultEnv::SetLogLevel("Dump"); break; case 4: XrdCl::DefaultEnv::SetLogLevel("Dump"); break; default: edm::Exception ex(edm::errors::Configuration); ex << "Invalid log level specified " << level; ex.addContext("Calling XrdStorageMaker::setDebugLevel()"); throw ex; } m_lastDebugLevel = level; } void setTimeout(unsigned int timeout) const { timeout = timeout ? timeout : XRD_DEFAULT_TIMEOUT; auto oldTimeout = m_lastTimeout.load(); if (oldTimeout == timeout) { return; } std::lock_guard<std::mutex> guard(m_envMutex); if (oldTimeout != m_lastTimeout) { //Another thread beat us to changing the value return; } XrdCl::Env *env = XrdCl::DefaultEnv::GetEnv(); if (env) { env->PutInt("StreamTimeout", timeout); env->PutInt("RequestTimeout", timeout * 3); env->PutInt("ConnectionWindow", timeout); env->PutInt("StreamErrorWindow", timeout); // Crank down some of the connection defaults. We have more // aggressive error recovery than the default client so we // can error out sooner. env->PutInt("ConnectionWindow", timeout / 6 + 1); env->PutInt("ConnectionRetry", 2); //disable fork handler as this appears to interfere with fork/exec calls env->PutInt("RunForkHandler", 0); } m_lastTimeout = timeout; } private: mutable std::mutex m_envMutex; mutable std::atomic<unsigned int> m_lastDebugLevel; mutable std::atomic<unsigned int> m_lastTimeout; }; } // namespace edm::storage using namespace edm::storage; DEFINE_EDM_PLUGIN(StorageMakerFactory, XrdStorageMaker, "root"); using XrdStatisticsMaker = edm::serviceregistry::AllArgsMaker<xrd_adaptor::XrdStatistics, XrdAdaptor::XrdStatisticsService>; using XrdAdaptor::XrdStatisticsService; DEFINE_FWK_SERVICE_MAKER(XrdStatisticsService, XrdStatisticsMaker);