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