XRootD
XrdSsiSfs.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S s i S f s . c c */
4 /* */
5 /* (c) 2013 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Deprtment of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include <unistd.h>
31 #include <dirent.h>
32 #include <cerrno>
33 #include <fcntl.h>
34 #include <memory.h>
35 #include <cstring>
36 #include <cstdio>
37 #include <ctime>
38 #include <netdb.h>
39 #include <cstdlib>
40 #include <sys/param.h>
41 #include <sys/stat.h>
42 #include <sys/time.h>
43 #include <sys/types.h>
44 
45 #include "XrdNet/XrdNetAddr.hh"
46 #include "XrdNet/XrdNetIF.hh"
47 
48 #include "XrdSsi/XrdSsiDir.hh"
49 #include "XrdSsi/XrdSsiFile.hh"
50 #include "XrdSsi/XrdSsiProvider.hh"
51 #include "XrdSsi/XrdSsiSfs.hh"
53 #include "XrdSsi/XrdSsiStats.hh"
54 #include "XrdSsi/XrdSsiTrace.hh"
55 
56 #include "XrdCms/XrdCmsClient.hh"
57 
58 #include "XrdSys/XrdSysError.hh"
59 #include "XrdSys/XrdSysHeaders.hh"
60 #include "XrdSys/XrdSysLogger.hh"
61 #include "XrdSys/XrdSysPlatform.hh"
62 #include "XrdSys/XrdSysPthread.hh"
63 #include "XrdSys/XrdSysTrace.hh"
64 
65 #include "XrdOuc/XrdOucEnv.hh"
66 #include "XrdOuc/XrdOucERoute.hh"
67 #include "XrdOuc/XrdOucLock.hh"
68 #include "XrdOuc/XrdOucPList.hh"
69 #include "XrdOuc/XrdOucTList.hh"
70 #include "XrdSec/XrdSecEntity.hh"
71 #include "XrdSfs/XrdSfsAio.hh"
73 #include "XrdSfs/XrdSfsFlags.hh"
74 
75 #include "XrdVersion.hh"
76 
77 #ifdef AIX
78 #include <sys/mode.h>
79 #endif
80 
81 /******************************************************************************/
82 /* V e r s i o n I d e n t i f i c a t i o n */
83 /******************************************************************************/
84 
86 
87 /******************************************************************************/
88 /* G l o b a l O b j e c t s */
89 /******************************************************************************/
90 
91 namespace XrdSsi
92 {
93 extern XrdSsiProvider *Provider;
94 
95 extern XrdNetIF *myIF;
96 
98 
100 
101 extern bool fsChk;
102 
103 extern XrdSysError Log;
104 
105 extern XrdSysLogger *Logger;
106 
108 
109 extern XrdSsiStats Stats;
110 };
111 
112 using namespace XrdSsi;
113 
114 /******************************************************************************/
115 /* S t a t i c O b j e c t s */
116 /******************************************************************************/
117 
118 int XrdSsiSfs::freeMax = 256;
119 
120 /******************************************************************************/
121 /* X r d S f s G e t F i l e S y s t e m */
122 /******************************************************************************/
123 
124 extern "C"
125 {
127  XrdSysLogger *logger,
128  const char *configFn,
129  XrdOucEnv *envP)
130 {
131  static XrdSsiSfs mySfs;
132  static XrdSsiSfsConfig myConfig;
133 
134 // Set pointer to the config and file system
135 //
136  theFS = nativeFS;
137  Stats.setFS(nativeFS);
138 
139 // No need to herald this as it's now the default filesystem
140 //
141  Log.SetPrefix("ssi_");
142  Log.logger(logger);
143  Logger = logger;
144  Trace.SetLogger(logger);
145 
146 // Initialize the subsystems
147 //
148  if (!myConfig.Configure(configFn, envP)) return 0;
149 
150 // All done, we can return the callout vector to these routines.
151 //
152  mySfs.setFeatures(nativeFS);
153  return &mySfs;
154 }
155 }
156 
157 /******************************************************************************/
158 /* c h k s u m */
159 /******************************************************************************/
160 
161 int XrdSsiSfs::chksum( csFunc Func, // In
162  const char *csName, // In
163  const char *Path, // In
164  XrdOucErrInfo &einfo, // Out
165  const XrdSecEntity *client, // In
166  const char *opaque) // In
167 {
168 // Reroute this request if we can
169 //
170  if (fsChk) return theFS->chksum(Func, csName, Path, einfo, client, opaque);
171  einfo.setErrInfo(ENOTSUP, "Checksums are not supported.");
172  return SFS_ERROR;
173 }
174 
175 /******************************************************************************/
176 /* c h m o d */
177 /******************************************************************************/
178 
179 int XrdSsiSfs::chmod(const char *path, // In
180  XrdSfsMode Mode, // In
181  XrdOucErrInfo &einfo, // Out
182  const XrdSecEntity *client, // In
183  const char *info) // In
184 {
185 // Reroute this request if we can
186 //
187  if (fsChk)
188  {if (FSPath.Find(path))
189  return theFS->chmod(path, Mode, einfo, client, info);
190  einfo.setErrInfo(ENOTSUP, "chmod is not supported for given path.");
191  } else einfo.setErrInfo(ENOTSUP, "chmod is not supported.");
192  return SFS_ERROR;
193 }
194 
195 /******************************************************************************/
196 /* Private: E m s g */
197 /******************************************************************************/
198 
199 int XrdSsiSfs::Emsg(const char *pfx, // Message prefix value
200  XrdOucErrInfo &einfo, // Place to put text & error code
201  int ecode, // The error code
202  const char *op, // Operation being performed
203  const char *target) // The target (e.g., fname)
204 {
205  char buffer[MAXPATHLEN+80];
206 
207 // Format the error message
208 //
209  XrdOucERoute::Format(buffer, sizeof(buffer), ecode, op, target);
210 
211 // Print it out if debugging is enabled
212 //
213 #ifndef NODEBUG
214  Log.Emsg(pfx, einfo.getErrUser(), buffer);
215 #endif
216 
217 // Place the error message in the error object and return
218 //
219  einfo.setErrInfo(ecode, buffer);
220  return SFS_ERROR;
221 }
222 
223 /******************************************************************************/
224 /* e x i s t s */
225 /******************************************************************************/
226 
227 int XrdSsiSfs::exists(const char *path, // In
228  XrdSfsFileExistence &file_exists, // Out
229  XrdOucErrInfo &einfo, // Out
230  const XrdSecEntity *client, // In
231  const char *info) // In
232 {
233 // Reroute this request if we can
234 //
235  if (fsChk)
236  {if (FSPath.Find(path))
237  return theFS->exists(path, file_exists, einfo, client, info);
238  einfo.setErrInfo(ENOTSUP, "exists is not supported for given path.");
239  } else einfo.setErrInfo(ENOTSUP, "exists is not supported.");
240  return SFS_ERROR;
241 }
242 
243 /******************************************************************************/
244 /* f s c t l */
245 /******************************************************************************/
246 
247 int XrdSsiSfs::fsctl(const int cmd,
248  const char *args,
249  XrdOucErrInfo &einfo,
250  const XrdSecEntity *client)
251 /*
252  Function: Perform filesystem operations:
253 
254  Input: cmd - Operation command (currently supported):
255  SFS_FSCTL_LOCATE - locate resource
256  args - Command dependent argument:
257  - Locate: The path whose location is wanted
258  einfo - Error/Response information structure.
259  client - Authentication credentials, if any.
260 
261  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
262 */
263 {
264  EPNAME("fsctl");
265  const char *tident = einfo.getErrUser();
266 
267  char pbuff[1024], rType[3] = {'S', 'w', 0};
268  const char *Resp[2] = {rType, pbuff};
269  const char *opq, *Path = Split(args,&opq,pbuff,sizeof(pbuff));
270  XrdNetIF::ifType ifType;
271  int Resp1Len;
272 
273 // Do some debugging
274 //
275  DEBUG(args);
276 
277 // We only process the locate request here. Reroute it if we can otherwise.
278 //
279  if ((cmd & SFS_FSCTL_CMD) != SFS_FSCTL_LOCATE)
280  {if (fsChk) return theFS->fsctl(cmd, args, einfo, client);
281  einfo.setErrInfo(ENOTSUP, "Requested fsctl operation not supported.");
282  return SFS_ERROR;
283  }
284 
285 // Preprocess the argument
286 //
287  if (*Path == '*') Path++;
288  else if (cmd & SFS_O_TRUNC) Path = 0;
289 
290 // Check if we should reoute this request
291 //
292  if (fsChk && Path && FSPath.Find(Path))
293  return theFS->fsctl(cmd, args, einfo, client);
294 
295 // If we have a path then see if we really have it
296 //
297  if (Path)
298  {if (!Provider) return Emsg(epname, einfo, EHOSTUNREACH, "locate", Path);
300  if (rStat == XrdSsiProvider::isPresent) rType[0] = 'S';
301  else if (rStat == XrdSsiProvider::isPending) rType[0] = 's';
302  else return Emsg(epname, einfo, ENOENT, "locate", Path);
303  }
304  }
305 
306 // Compute interface return options
307 //
308  ifType = XrdNetIF::GetIFType((einfo.getUCap() & XrdOucEI::uIPv4) != 0,
309  (einfo.getUCap() & XrdOucEI::uIPv64) != 0,
310  (einfo.getUCap() & XrdOucEI::uPrip) != 0);
311  bool retHN = (cmd & SFS_O_HNAME) != 0;
312 
313 // Get our destination
314 //
315  if ((Resp1Len = myIF->GetDest(pbuff, sizeof(pbuff), ifType, retHN)))
316  {einfo.setErrInfo(Resp1Len+3, (const char **)Resp, 2);
317  return SFS_DATA;
318  }
319 
320 // We failed for some unknown reason
321 //
322  return Emsg(epname, einfo, ENETUNREACH, "locate", Path);
323 }
324 
325 
326 /******************************************************************************/
327 /* g e t S t a t s */
328 /******************************************************************************/
329 
330 int XrdSsiSfs::getStats(char *buff, int blen)
331 {
332 // Return statustics
333 //
334  return Stats.Stats(buff, blen);
335 }
336 
337 /******************************************************************************/
338 /* g e t V e r s i o n */
339 /******************************************************************************/
340 
341 const char *XrdSsiSfs::getVersion() {return XrdVERSION;}
342 
343 /******************************************************************************/
344 /* m k d i r */
345 /******************************************************************************/
346 
347 int XrdSsiSfs::mkdir(const char *path, // In
348  XrdSfsMode Mode, // In
349  XrdOucErrInfo &einfo, // Out
350  const XrdSecEntity *client, // In
351  const char *info) // In
352 {
353 // Reroute this request if we can
354 //
355  if (fsChk)
356  {if (FSPath.Find(path))
357  return theFS->mkdir(path, Mode, einfo, client, info);
358  einfo.setErrInfo(ENOTSUP, "mkdir is not supported for given path.");
359  } else einfo.setErrInfo(ENOTSUP, "mkdir is not supported.");
360  return SFS_ERROR;
361 }
362 
363 /******************************************************************************/
364 /* p r e p a r e */
365 /******************************************************************************/
366 
367 int XrdSsiSfs::prepare( XrdSfsPrep &pargs, // In
368  XrdOucErrInfo &out_error, // Out
369  const XrdSecEntity *client) // In
370 {
371 // Reroute this if we can
372 //
373  if (theFS) return theFS->prepare(pargs, out_error, client);
374  return SFS_OK;
375 }
376 
377 /******************************************************************************/
378 /* r e m */
379 /******************************************************************************/
380 
381 int XrdSsiSfs::rem(const char *path, // In
382  XrdOucErrInfo &einfo, // Out
383  const XrdSecEntity *client, // In
384  const char *info) // In
385 {
386 // Reroute this request if we can
387 //
388  if (fsChk)
389  {if (FSPath.Find(path))
390  return theFS->rem(path, einfo, client, info);
391  einfo.setErrInfo(ENOTSUP, "rem is not supported for given path.");
392  } else einfo.setErrInfo(ENOTSUP, "rem is not supported.");
393  return SFS_ERROR;
394 }
395 
396 /******************************************************************************/
397 /* r e m d i r */
398 /******************************************************************************/
399 
400 int XrdSsiSfs::remdir(const char *path, // In
401  XrdOucErrInfo &einfo, // Out
402  const XrdSecEntity *client, // In
403  const char *info) // In
404 {
405 // Reroute this request if we can
406 //
407  if (fsChk)
408  {if (FSPath.Find(path))
409  return theFS->rem(path, einfo, client, info);
410  einfo.setErrInfo(ENOTSUP, "remdir is not supported for given path.");
411  } else einfo.setErrInfo(ENOTSUP, "remdir is not supported.");
412  return SFS_ERROR;
413 }
414 
415 /******************************************************************************/
416 /* r e n a m e */
417 /******************************************************************************/
418 
419 int XrdSsiSfs::rename(const char *old_name, // In
420  const char *new_name, // In
421  XrdOucErrInfo &einfo, //Out
422  const XrdSecEntity *client, // In
423  const char *infoO, // In
424  const char *infoN) // In
425 {
426 // Reroute this request if we can
427 //
428  if (fsChk)
429  {if (FSPath.Find(old_name))
430  return theFS->rename(old_name,new_name,einfo,client,infoO,infoN);
431  einfo.setErrInfo(ENOTSUP, "rename is not supported for given path.");
432  } else einfo.setErrInfo(ENOTSUP, "rename is not supported.");
433  return SFS_ERROR;
434 }
435 
436 /******************************************************************************/
437 /* Private: s e t F e a t u r e s */
438 /******************************************************************************/
439 
441 {
442  uint64_t fSet = (prevFS ? prevFS->Features() : 0);
443 
444  FeatureSet = fSet | XrdSfs::hasSXIO;
445 }
446 
447 /******************************************************************************/
448 /* Private: S p l i t */
449 /******************************************************************************/
450 
451 const char * XrdSsiSfs::Split(const char *Args, const char **Opq,
452  char *Path, int Plen)
453 {
454  int xlen;
455  *Opq = index(Args, '?');
456  if (!(*Opq)) return Args;
457  xlen = (*Opq)-Args;
458  if (xlen >= Plen) xlen = Plen-1;
459  strncpy(Path, Args, xlen);
460  return Path;
461 }
462 
463 /******************************************************************************/
464 /* s t a t */
465 /******************************************************************************/
466 
467 int XrdSsiSfs::stat(const char *path, // In
468  struct stat *buf, // Out
469  XrdOucErrInfo &einfo, // Out
470  const XrdSecEntity *client, // In
471  const char *info) // In
472 {
473 // Reroute this request if we can
474 //
475  if (fsChk)
476  {if (FSPath.Find(path))
477  return theFS->stat(path, buf, einfo, client, info);
478  einfo.setErrInfo(ENOTSUP, "stat is not supported for given path.");
479  } else einfo.setErrInfo(ENOTSUP, "stat is not supported.");
480  return SFS_ERROR;
481 }
482 
483 /******************************************************************************/
484 
485 int XrdSsiSfs::stat(const char *path, // In
486  mode_t &mode, // Out
487  XrdOucErrInfo &einfo, // Out
488  const XrdSecEntity *client, // In
489  const char *info) // In
490 {
491 // Reroute this request if we can
492 //
493  if (fsChk)
494  {if (FSPath.Find(path))
495  return theFS->stat(path, mode, einfo, client, info);
496  einfo.setErrInfo(ENOTSUP, "stat is not supported for given path.");
497  } else einfo.setErrInfo(ENOTSUP, "stat is not supported.");
498  return SFS_ERROR;
499 }
500 
501 /******************************************************************************/
502 /* t r u n c a t e */
503 /******************************************************************************/
504 
505 int XrdSsiSfs::truncate(const char *path, // In
506  XrdSfsFileOffset Size, // In
507  XrdOucErrInfo &einfo, // Out
508  const XrdSecEntity *client, // In
509  const char *info) // In
510 {
511 // Reroute this request if we can
512 //
513  if (fsChk)
514  {if (FSPath.Find(path))
515  return theFS->truncate(path, Size, einfo, client, info);
516  einfo.setErrInfo(ENOTSUP, "truncate is not supported for given path.");
517  } else einfo.setErrInfo(ENOTSUP, "truncate is not supported.");
518  return SFS_ERROR;
519 }
#define tident
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
int stat(const char *path, struct stat *buf)
int Mode
XrdOucString Path
int XrdSfsMode
#define SFS_O_HNAME
#define SFS_DATA
#define SFS_ERROR
XrdSfsFileExistence
#define SFS_FSCTL_CMD
#define SFS_FSCTL_LOCATE
#define SFS_OK
long long XrdSfsFileOffset
#define SFS_O_TRUNC
< Prepare parameters
XrdSfsFileSystem * XrdSfsGetFileSystem2(XrdSfsFileSystem *nativeFS, XrdSysLogger *logger, const char *configFn, XrdOucEnv *envP)
Definition: XrdSsiSfs.cc:126
XrdVERSIONINFO(XrdSfsGetFileSystem2, ssi)
static ifType GetIFType(bool conIPv4, bool hasIP64, bool pvtIP)
Definition: XrdNetIF.hh:250
int GetDest(char *dest, int dlen, ifType ifT=PublicV6, bool prefn=false)
Definition: XrdNetIF.cc:389
ifType
The enum that is used to index into ifData to get appropriate interface.
Definition: XrdNetIF.hh:65
static int Format(char *buff, int blen, int ecode, const char *etxt1, const char *etxt2=0)
Definition: XrdOucERoute.cc:44
int setErrInfo(int code, const char *emsg)
const char * getErrUser()
unsigned long long Find(const char *pathname)
Definition: XrdOucPList.hh:112
virtual int chmod(const char *path, XrdSfsMode mode, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual int fsctl(const int cmd, const char *args, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)=0
virtual int rename(const char *oPath, const char *nPath, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaqueO=0, const char *opaqueN=0)=0
virtual int mkdir(const char *path, XrdSfsMode mode, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual int truncate(const char *path, XrdSfsFileOffset fsize, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual int chksum(csFunc Func, const char *csName, const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)
virtual int exists(const char *path, XrdSfsFileExistence &eFlag, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual int prepare(XrdSfsPrep &pargs, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)=0
virtual int stat(const char *Name, struct stat *buf, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual int rem(const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual rStat QueryResource(const char *rName, const char *contact=0)=0
bool Configure(const char *cFN, XrdOucEnv *envP)
int getStats(char *buff, int blen)
Definition: XrdSsiSfs.cc:330
int rem(const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client, const char *info=0)
Definition: XrdSsiSfs.cc:381
int stat(const char *Name, struct stat *buf, XrdOucErrInfo &eInfo, const XrdSecEntity *client, const char *opaque=0)
Definition: XrdSsiSfs.cc:467
int chksum(csFunc Func, const char *csName, const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)
Definition: XrdSsiSfs.cc:161
int chmod(const char *Name, XrdSfsMode Mode, XrdOucErrInfo &eInfo, const XrdSecEntity *client, const char *opaque=0)
Definition: XrdSsiSfs.cc:179
void setFeatures(XrdSfsFileSystem *prevFS)
Definition: XrdSsiSfs.cc:440
const char * getVersion()
Definition: XrdSsiSfs.cc:341
int rename(const char *oldFileName, const char *newFileName, XrdOucErrInfo &eInfo, const XrdSecEntity *client, const char *infoO=0, const char *infoN=0)
Definition: XrdSsiSfs.cc:419
int remdir(const char *dirName, XrdOucErrInfo &eInfo, const XrdSecEntity *client, const char *info=0)
Definition: XrdSsiSfs.cc:400
int exists(const char *fileName, XrdSfsFileExistence &exists_flag, XrdOucErrInfo &eInfo, const XrdSecEntity *client, const char *opaque=0)
Definition: XrdSsiSfs.cc:227
int mkdir(const char *dirName, XrdSfsMode Mode, XrdOucErrInfo &eInfo, const XrdSecEntity *client, const char *opaque=0)
Definition: XrdSsiSfs.cc:347
int prepare(XrdSfsPrep &pargs, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)
Definition: XrdSsiSfs.cc:367
int truncate(const char *Name, XrdSfsFileOffset fileOffset, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)
Definition: XrdSsiSfs.cc:505
int fsctl(const int cmd, const char *args, XrdOucErrInfo &eInfo, const XrdSecEntity *client)
Definition: XrdSsiSfs.cc:247
int Stats(char *buff, int blen)
Definition: XrdSsiStats.cc:87
void setFS(XrdSfsFileSystem *fsp)
Definition: XrdSsiStats.hh:68
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition: XrdSysError.hh:141
const char * SetPrefix(const char *prefix)
Definition: XrdSysError.hh:160
void SetLogger(XrdSysLogger *logp)
Definition: XrdSysTrace.cc:65
XrdOucEnv * envP
Definition: XrdPss.cc:109
static const uint64_t hasSXIO
Feature: Supports SfsXio.
Definition: XrdSfsFlags.hh:68
XrdSsiStats Stats
XrdSfsFileSystem * theFS
Definition: XrdSsiFile.cc:54
bool fsChk
Definition: XrdSsiFile.cc:56
XrdSysTrace Trace
Definition: XrdSsiSfs.cc:107
XrdNetIF * myIF
XrdSysLogger * Logger
Definition: XrdSsiLogger.cc:57
XrdSsiProvider * Provider
XrdSysError Log
XrdOucPListAnchor FSPath
Definition: XrdSsiFile.cc:55
static const int uIPv64
ucap: Supports only IPv4 info
static const int uIPv4
ucap: Supports read redirects
static const int uPrip