CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
XrdFile.cc
Go to the documentation of this file.
6 #include <vector>
7 #include <sstream>
8 
9 #define JOB_UNIQUE_ID_ENV "CRAB_UNIQUE_JOB_ID"
10 #define JOB_UNIQUE_ID_ENV_V2 "DashboardJobId"
11 
13  : m_client (0),
14  m_offset (0),
15  m_stat(),
16  m_close (false),
17  m_name()
18 {
19  memset(&m_stat, 0, sizeof (m_stat));
20  pthread_mutex_init(&m_readv_mutex, 0);
21 }
22 
23 XrdFile::XrdFile (const char *name,
24  int flags /* = IOFlags::OpenRead */,
25  int perms /* = 066 */)
26  : m_client (0),
27  m_offset (0),
28  m_stat(),
29  m_close (false),
30  m_name()
31 {
32  memset(&m_stat, 0, sizeof (m_stat));
33  pthread_mutex_init(&m_readv_mutex, 0);
34  open (name, flags, perms);
35 }
36 
37 XrdFile::XrdFile (const std::string &name,
38  int flags /* = IOFlags::OpenRead */,
39  int perms /* = 066 */)
40  : m_client (0),
41  m_offset (0),
42  m_stat(),
43  m_close (false),
44  m_name()
45 {
46  memset(&m_stat, 0, sizeof (m_stat));
47  pthread_mutex_init(&m_readv_mutex, 0);
48  open (name.c_str (), flags, perms);
49 }
50 
52 {
53  if (m_close)
54  edm::LogError("XrdFileError")
55  << "Destructor called on XROOTD file '" << m_name
56  << "' but the file is still open";
57  pthread_mutex_destroy(&m_readv_mutex);
58 }
59 
61 void
62 XrdFile::create (const char *name,
63  bool exclusive /* = false */,
64  int perms /* = 066 */)
65 {
66  open (name,
68  | (exclusive ? IOFlags::OpenExclusive : 0)),
69  perms);
70 }
71 
72 void
73 XrdFile::create (const std::string &name,
74  bool exclusive /* = false */,
75  int perms /* = 066 */)
76 {
77  open (name.c_str (),
79  | (exclusive ? IOFlags::OpenExclusive : 0)),
80  perms);
81 }
82 
83 void
84 XrdFile::open (const std::string &name,
85  int flags /* = IOFlags::OpenRead */,
86  int perms /* = 066 */)
87 { open (name.c_str (), flags, perms); }
88 
89 void
90 XrdFile::open (const char *name,
91  int flags /* = IOFlags::OpenRead */,
92  int perms /* = 066 */)
93 {
94  // Actual open
95  if ((name == 0) || (*name == 0)) {
97  ex << "Cannot open a file without a name";
98  ex.addContext("Calling XrdFile::open()");
99  throw ex;
100  }
101  if ((flags & (IOFlags::OpenRead | IOFlags::OpenWrite)) == 0) {
103  ex << "Must open file '" << name << "' at least for read or write";
104  ex.addContext("Calling XrdFile::open()");
105  throw ex;
106  }
107  // If I am already open, close old file first
108  if (m_client && m_close)
109  close();
110  else
111  abort();
112 
113  // Translate our flags to system flags
114  int openflags = 0;
115 
116  if (flags & IOFlags::OpenWrite)
117  openflags |= kXR_open_updt;
118  else if (flags & IOFlags::OpenRead)
119  openflags |= kXR_open_read;
120 
121  if (flags & IOFlags::OpenAppend) {
123  ex << "Opening file '" << name << "' in append mode not supported";
124  ex.addContext("Calling XrdFile::open()");
125  throw ex;
126  }
127 
128  if (flags & IOFlags::OpenCreate)
129  {
130  if (! (flags & IOFlags::OpenExclusive))
131  openflags |= kXR_delete;
132  openflags |= kXR_new;
133  openflags |= kXR_mkpath;
134  }
135 
136  if ((flags & IOFlags::OpenTruncate) && (flags & IOFlags::OpenWrite))
137  openflags |= kXR_delete;
138 
139  m_name = name;
140  m_client = new XrdClient(name);
141  m_client->UseCache(false); // Hack from Prof. Bockelman
142 
143  if (! m_client->Open(perms, openflags)
144  || m_client->LastServerResp()->status != kXR_ok) {
146  ex << "XrdClient::Open(name='" << name
147  << "', flags=0x" << std::hex << openflags
148  << ", permissions=0" << std::oct << perms << std::dec
149  << ") => error '" << m_client->LastServerError()->errmsg
150  << "' (errno=" << m_client->LastServerError()->errnum << ")";
151  ex.addContext("Calling XrdFile::open()");
152  addConnection(ex);
153  throw ex;
154  }
155  if (! m_client->Stat(&m_stat)) {
157  ex << "XrdClient::Stat(name='" << name
158  << ") => error '" << m_client->LastServerError()->errmsg
159  << "' (errno=" << m_client->LastServerError()->errnum << ")";
160  ex.addContext("Calling XrdFile::open()");
161  addConnection(ex);
162  throw ex;
163  }
164  m_offset = 0;
165  m_close = true;
166 
167  // Send the monitoring info, if available.
168  // Note: getenv is not reentrant.
169  const char * crabJobId = getenv(JOB_UNIQUE_ID_ENV);
170  // Dashboard developers requested that we migrate to this environment variable.
171  if (!crabJobId) { crabJobId = getenv(JOB_UNIQUE_ID_ENV_V2); }
172  if (crabJobId) {
173  kXR_unt32 dictId;
174  m_client->SendMonitoringInfo(crabJobId, &dictId);
175  edm::LogInfo("XrdFileInfo") << "Set monitoring ID to " << crabJobId << " with resulting dictId " << dictId << ".";
176  }
177 
178  edm::LogInfo("XrdFileInfo") << "Opened " << m_name;
179 
180  XrdClientConn *conn = m_client->GetClientConn();
181  edm::LogInfo("XrdFileInfo") << "Connection URL " << conn->GetCurrentUrl().GetUrl().c_str();
182 }
183 
184 void
186 {
187  if (! m_client)
188  {
189  edm::LogError("XrdFileError")
190  << "XrdFile::close(name='" << m_name
191  << "') called but the file is not open";
192  m_close = false;
193  return;
194  }
195 
196  if (! m_client->Close())
197  edm::LogWarning("XrdFileWarning")
198  << "XrdFile::close(name='" << m_name
199  << "') failed with error '" << m_client->LastServerError()->errmsg
200  << "' (errno=" << m_client->LastServerError()->errnum << ")";
201  delete m_client;
202  m_client = 0;
203 
204  m_close = false;
205  m_offset = 0;
206  memset(&m_stat, 0, sizeof (m_stat));
207  edm::LogInfo("XrdFileInfo") << "Closed " << m_name;
208 }
209 
210 void
212 {
213  delete m_client;
214  m_client = 0;
215  m_close = false;
216  m_offset = 0;
217  memset(&m_stat, 0, sizeof (m_stat));
218 }
219 
221 IOSize
222 XrdFile::read (void *into, IOSize n)
223 {
224  if (n > 0x7fffffff) {
226  ex << "XrdFile::read(name='" << m_name << "', n=" << n
227  << ") too many bytes, limit is 0x7fffffff";
228  ex.addContext("Calling XrdFile::read()");
229  addConnection(ex);
230  throw ex;
231  }
232  int s = m_client->Read(into, m_offset, n);
233  if (s < 0) {
235  ex << "XrdClient::Read(name='" << m_name
236  << "', offset=" << m_offset << ", n=" << n
237  << ") failed with error '" << m_client->LastServerError()->errmsg
238  << "' (errno=" << m_client->LastServerError()->errnum << ")";
239  ex.addContext("Calling XrdFile::read()");
240  addConnection(ex);
241  throw ex;
242  }
243  m_offset += s;
244  return s;
245 }
246 
247 IOSize
249 {
250  if (n > 0x7fffffff) {
252  ex << "XrdFile::read(name='" << m_name << "', n=" << n
253  << ") exceeds read size limit 0x7fffffff";
254  ex.addContext("Calling XrdFile::read()");
255  addConnection(ex);
256  throw ex;
257  }
258  int s = m_client->Read(into, pos, n);
259  if (s < 0) {
261  ex << "XrdClient::Read(name='" << m_name
262  << "', offset=" << m_offset << ", n=" << n
263  << ") failed with error '" << m_client->LastServerError()->errmsg
264  << "' (errno=" << m_client->LastServerError()->errnum << ")";
265  ex.addContext("Calling XrdFile::read()");
266  addConnection(ex);
267  throw ex;
268  }
269  return s;
270 }
271 
272 IOSize
273 XrdFile::write (const void *from, IOSize n)
274 {
275  if (n > 0x7fffffff) {
276  cms::Exception ex("FileWriteError");
277  ex << "XrdFile::write(name='" << m_name << "', n=" << n
278  << ") too many bytes, limit is 0x7fffffff";
279  ex.addContext("Calling XrdFile::write()");
280  addConnection(ex);
281  throw ex;
282  }
283  ssize_t s = m_client->Write(from, m_offset, n);
284  if (s < 0) {
285  cms::Exception ex("FileWriteError");
286  ex << "XrdFile::write(name='" << m_name << "', n=" << n
287  << ") failed with error '" << m_client->LastServerError()->errmsg
288  << "' (errno=" << m_client->LastServerError()->errnum << ")";
289  ex.addContext("Calling XrdFile::write()");
290  addConnection(ex);
291  throw ex;
292  }
293  m_offset += s;
294  if (m_offset > m_stat.size)
295  m_stat.size = m_offset;
296 
297  return s;
298 }
299 
300 IOSize
302 {
303  if (n > 0x7fffffff) {
304  cms::Exception ex("FileWriteError");
305  ex << "XrdFile::write(name='" << m_name << "', n=" << n
306  << ") too many bytes, limit is 0x7fffffff";
307  ex.addContext("Calling XrdFile::write()");
308  addConnection(ex);
309  throw ex;
310  }
311  ssize_t s = m_client->Write(from, pos, n);
312  if (s < 0) {
313  cms::Exception ex("FileWriteError");
314  ex << "XrdFile::write(name='" << m_name << "', n=" << n
315  << ") failed with error '" << m_client->LastServerError()->errmsg
316  << "' (errno=" << m_client->LastServerError()->errnum << ")";
317  ex.addContext("Calling XrdFile::write()");
318  addConnection(ex);
319  throw ex;
320  }
321  if (pos + s > m_stat.size)
322  m_stat.size = pos + s;
323 
324  return s;
325 }
326 
327 bool
329 {
330  return false;
331 }
332 
336 IOOffset
338 {
339  if (! m_client) {
340  cms::Exception ex("FilePositionError");
341  ex << "XrdFile::position() called on a closed file";
342  ex.addContext("Calling XrdFile::position()");
343  addConnection(ex);
344  throw ex;
345  }
346  switch (whence)
347  {
348  case SET:
349  m_offset = offset;
350  break;
351 
352  case CURRENT:
353  m_offset += offset;
354  break;
355 
356  case END:
357  m_offset = m_stat.size + offset;
358  break;
359 
360  default:
361  cms::Exception ex("FilePositionError");
362  ex << "XrdFile::position() called with incorrect 'whence' parameter";
363  ex.addContext("Calling XrdFile::position()");
364  addConnection(ex);
365  throw ex;
366  }
367 
368  if (m_offset < 0)
369  m_offset = 0;
370  if (m_offset > m_stat.size)
371  m_stat.size = m_offset;
372 
373  return m_offset;
374 }
375 
376 void
378 {
379  cms::Exception ex("FileResizeError");
380  ex << "XrdFile::resize(name='" << m_name << "') not implemented";
381  ex.addContext("Calling XrdFile::resize()");
382  addConnection(ex);
383  throw ex;
384 }
385 
386 void
388 {
389  XrdClientConn *conn = m_client->GetClientConn();
390  if (conn) {
391  std::stringstream ss;
392  ss << "Current server connection: " << conn->GetCurrentUrl().GetUrl().c_str();
393  ex.addAdditionalInfo(ss.str());
394  }
395 }
396 
virtual void resize(IOOffset size)
Definition: XrdFile.cc:377
virtual void close(void)
Definition: XrdFile.cc:185
XrdClientStatInfo m_stat
Definition: XrdFile.h:63
virtual void create(const char *name, bool exclusive=false, int perms=0666)
Definition: XrdFile.cc:62
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
bool m_close
Definition: XrdFile.h:64
#define JOB_UNIQUE_ID_ENV_V2
Definition: XrdFile.cc:10
IOOffset m_offset
Definition: XrdFile.h:62
Relative
Definition: Storage.h:11
virtual bool prefetch(const IOPosBuffer *what, IOSize n)
Definition: XrdFile.cc:328
XrdFile(void)
Definition: XrdFile.cc:12
virtual IOOffset position(void) const
Definition: Storage.cc:95
void addAdditionalInfo(std::string const &info)
Definition: Exception.cc:235
int read(void)
Definition: IOInput.cc:54
unsigned int offset(bool)
XrdClient * m_client
Definition: XrdFile.h:61
std::string m_name
Definition: XrdFile.h:65
static std::string from(" from ")
~XrdFile(void)
Definition: XrdFile.cc:51
void addContext(std::string const &context)
Definition: Exception.cc:227
int64_t IOOffset
Definition: IOTypes.h:19
pthread_mutex_t m_readv_mutex
Definition: XrdFile.h:68
#define JOB_UNIQUE_ID_ENV
Definition: XrdFile.cc:9
size_t IOSize
Definition: IOTypes.h:14
void addConnection(cms::Exception &)
Definition: XrdFile.cc:387
virtual void open(const char *name, int flags=IOFlags::OpenRead, int perms=0666)
Definition: XrdFile.cc:90
virtual IOSize write(const void *from, IOSize n)
Definition: XrdFile.cc:273
tuple conn
Definition: results_mgr.py:53
virtual void abort(void)
Definition: XrdFile.cc:211