CMS 3D CMS Logo

XrdStorageMaker.cc
Go to the documentation of this file.
1 
6 
12 
13 #include "XrdCl/XrdClDefaultEnv.hh"
14 #include "XrdNet/XrdNetUtils.hh"
15 
16 #include <atomic>
17 #include <mutex>
18 
19 namespace {
20 
21  class PrepareHandler : public XrdCl::ResponseHandler {
22  public:
23  PrepareHandler(const XrdCl::URL &url) : m_fs(url) { m_fileList.push_back(url.GetPath()); }
24 
25  void callAsyncPrepare() {
26  auto status = m_fs.Prepare(m_fileList, XrdCl::PrepareFlags::Stage, 0, this);
27  if (!status.IsOK()) {
28  LogDebug("StageInError") << "XrdCl::FileSystem::Prepare submit failed with error '" << status.ToStr()
29  << "' (errNo = " << status.errNo << ")";
30  delete this;
31  }
32  }
33 
34  void HandleResponse(XrdCl::XRootDStatus *status, XrdCl::AnyObject *response) override {
35  // Note: Prepare call has a response object.
36  if (!status->IsOK()) {
37  LogDebug("StageInError") << "XrdCl::FileSystem::Prepare failed with error '" << status->ToStr()
38  << "' (errNo = " << status->errNo << ")";
39  }
40  delete response;
41  delete status;
42  delete this;
43  }
44 
45  private:
46  XrdCl::FileSystem m_fs;
47  std::vector<std::string> m_fileList;
48  };
49 
50 } // namespace
51 
52 namespace edm::storage {
53  class XrdStorageMaker final : public StorageMaker {
54  public:
55  static const unsigned int XRD_DEFAULT_TIMEOUT = 3 * 60;
56 
58  : m_lastDebugLevel(1), //so that 0 will trigger change
59  m_lastTimeout(0) {
60  // When CMSSW loads, both XrdCl and XrdClient end up being loaded
61  // (ROOT loads XrdClient). XrdClient forces IPv4-only. Accordingly,
62  // we must explicitly set the default network stack in XrdCl to
63  // whatever is available on the node (IPv4 or IPv6).
64  XrdCl::Env *env = XrdCl::DefaultEnv::GetEnv();
65  if (env) {
66  env->PutString("NetworkStack", "IPAuto");
67  }
68  XrdNetUtils::SetAuto(XrdNetUtils::prefAuto);
70  setDebugLevel(0);
71  }
72 
75  std::unique_ptr<Storage> open(const std::string &proto,
76  const std::string &path,
77  int mode,
78  const AuxSettings &aux) const override {
79  setDebugLevel(aux.debugLevel);
80  setTimeout(aux.timeout);
81 
83  StorageFactory::ReadHint readHint = f->readHint();
84  StorageFactory::CacheHint cacheHint = f->cacheHint();
85 
87  mode &= ~IOFlags::OpenUnbuffered;
88  else
90 
91  std::string fullpath(proto + ":" + path);
92  auto file = std::make_unique<XrdFile>(fullpath, mode);
93  return f->wrapNonLocalFile(std::move(file), proto, std::string(), mode);
94  }
95 
96  void stagein(const std::string &proto, const std::string &path, const AuxSettings &aux) const override {
97  setDebugLevel(aux.debugLevel);
98  setTimeout(aux.timeout);
99 
100  std::string fullpath(proto + ":" + path);
102 
103  auto prep_handler = new PrepareHandler(url);
104  prep_handler->callAsyncPrepare();
105  }
106 
107  bool check(const std::string &proto,
108  const std::string &path,
109  const AuxSettings &aux,
110  IOOffset *size = nullptr) const override {
111  setDebugLevel(aux.debugLevel);
112  setTimeout(aux.timeout);
113 
114  std::string fullpath(proto + ":" + path);
116  XrdCl::FileSystem fs(url);
117 
118  XrdCl::StatInfo *stat;
119  if (!(fs.Stat(url.GetPath(), stat)).IsOK() || (stat == nullptr)) {
120  return false;
121  }
122 
123  if (size)
124  *size = stat->GetSize();
125  return true;
126  }
127 
128  void setDebugLevel(unsigned int level) const {
129  auto oldLevel = m_lastDebugLevel.load();
130  if (level == oldLevel) {
131  return;
132  }
133  std::lock_guard<std::mutex> guard(m_envMutex);
134  if (oldLevel != m_lastDebugLevel) {
135  //another thread just changed this value
136  return;
137  }
138 
139  // 'Error' is way too low of debug level - we have interest
140  // in warning in the default
141  switch (level) {
142  case 0:
143  XrdCl::DefaultEnv::SetLogLevel("Warning");
144  break;
145  case 1:
146  XrdCl::DefaultEnv::SetLogLevel("Info");
147  break;
148  case 2:
149  XrdCl::DefaultEnv::SetLogLevel("Debug");
150  break;
151  case 3:
152  XrdCl::DefaultEnv::SetLogLevel("Dump");
153  break;
154  case 4:
155  XrdCl::DefaultEnv::SetLogLevel("Dump");
156  break;
157  default:
159  ex << "Invalid log level specified " << level;
160  ex.addContext("Calling XrdStorageMaker::setDebugLevel()");
161  throw ex;
162  }
164  }
165 
166  void setTimeout(unsigned int timeout) const {
168 
169  auto oldTimeout = m_lastTimeout.load();
170  if (oldTimeout == timeout) {
171  return;
172  }
173 
174  std::lock_guard<std::mutex> guard(m_envMutex);
175  if (oldTimeout != m_lastTimeout) {
176  //Another thread beat us to changing the value
177  return;
178  }
179 
180  XrdCl::Env *env = XrdCl::DefaultEnv::GetEnv();
181  if (env) {
182  env->PutInt("StreamTimeout", timeout);
183  env->PutInt("RequestTimeout", timeout);
184  env->PutInt("ConnectionWindow", timeout);
185  env->PutInt("StreamErrorWindow", timeout);
186  // Crank down some of the connection defaults. We have more
187  // aggressive error recovery than the default client so we
188  // can error out sooner.
189  env->PutInt("ConnectionWindow", timeout / 6 + 1);
190  env->PutInt("ConnectionRetry", 2);
191  //disable fork handler as this appears to interfere with fork/exec calls
192  env->PutInt("RunForkHandler", 0);
193  }
195  }
196 
197  private:
199  mutable std::atomic<unsigned int> m_lastDebugLevel;
200  mutable std::atomic<unsigned int> m_lastTimeout;
201  };
202 } // namespace edm::storage
203 
204 using namespace edm::storage;
205 
207 using XrdStatisticsMaker =
bool check(const std::string &proto, const std::string &path, const AuxSettings &aux, IOOffset *size=nullptr) const override
int64_t IOOffset
Definition: IOTypes.h:20
#define DEFINE_FWK_SERVICE_MAKER(concrete, maker)
Definition: ServiceMaker.h:102
void setDebugLevel(unsigned int level) const
void stagein(const std::string &proto, const std::string &path, const AuxSettings &aux) const override
static std::mutex mutex
Definition: Proxy.cc:8
std::atomic< unsigned int > m_lastTimeout
int timeout
Definition: mps_check.py:53
static const unsigned int XRD_DEFAULT_TIMEOUT
double f[11][100]
std::unique_ptr< Storage > open(const std::string &proto, const std::string &path, int mode, const AuxSettings &aux) const override
void addContext(std::string const &context)
Definition: Exception.cc:169
#define DEFINE_EDM_PLUGIN(factory, type, name)
void setTimeout(unsigned int timeout) const
std::atomic< unsigned int > m_lastDebugLevel
static const StorageFactory * get(void)
def move(src, dest)
Definition: eostools.py:511
#define LogDebug(id)