XRootD
XrdPss.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d P s s . c c */
4 /* */
5 /* (c) 2007 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 /******************************************************************************/
31 /* I n c l u d e s */
32 /******************************************************************************/
33 
34 #include <unistd.h>
35 #include <cerrno>
36 #include <string>
37 #include <fcntl.h>
38 #include <signal.h>
39 #include <cstdint>
40 #include <strings.h>
41 #include <cstdio>
42 #include <sys/file.h>
43 #include <sys/param.h>
44 #include <sys/stat.h>
45 #include <sys/types.h>
46 #ifdef __solaris__
47 #include <sys/vnode.h>
48 #endif
49 #include <vector>
50 
51 #include "XrdVersion.hh"
52 
53 #include "XrdNet/XrdNetSecurity.hh"
54 #include "XrdPss/XrdPss.hh"
55 #include "XrdPss/XrdPssTrace.hh"
56 #include "XrdPss/XrdPssUrlInfo.hh"
57 #include "XrdPss/XrdPssUtils.hh"
60 #include "XrdPosix/XrdPosixInfo.hh"
62 #include "XrdOfs/XrdOfsFSctl_PI.hh"
63 
64 #include "XrdOss/XrdOssError.hh"
65 #include "XrdOuc/XrdOucEnv.hh"
66 #include "XrdOuc/XrdOucExport.hh"
69 #include "XrdSec/XrdSecEntity.hh"
70 #include "XrdSecsss/XrdSecsssID.hh"
72 #include "XrdSys/XrdSysError.hh"
73 #include "XrdSys/XrdSysHeaders.hh"
74 #include "XrdSys/XrdSysPlatform.hh"
75 
76 #ifndef O_DIRECT
77 #define O_DIRECT 0
78 #endif
79 
80 #ifndef ENOATTR
81 #define ENOATTR ENODATA
82 #endif
83 
84 /******************************************************************************/
85 /* D e f i n e s */
86 /******************************************************************************/
87 
88 #define isNOSTAGE(_x_) !(XRDEXP_STAGE & XrdPssSys::XPList.Find(_x_))
89 
90 #define isREADONLY(_x_) (XRDEXP_NOTRW & XrdPssSys::XPList.Find(_x_))
91 
92 /******************************************************************************/
93 /* G l o b a l s */
94 /******************************************************************************/
95 
96 class XrdScheduler;
97 
98 namespace XrdProxy
99 {
100 thread_local XrdOucECMsg ecMsg("[pss]");
101 
103 
104  XrdSysError eDest(0, "pss_");
105 
107 
109 
111 
113 
114  XrdSecsssID *idMapper = 0; // -> Auth ID mapper
115 
116 static const char *ofslclCGI = "ofs.lcl=1";
117 
118 static const char *osslclCGI = "oss.lcl=1";
119 
120 static const int PBsz = 4096;
121 
122  int rpFD = -1;
123 
124  bool idMapAll = false;
125 
126  bool outProxy = false; // True means outgoing proxy
127 
128  bool xrdProxy = false; // True means dest using xroot protocol
129 
130  XrdSysTrace SysTrace("Pss",0);
131 }
132 using namespace XrdProxy;
133 
134 /******************************************************************************/
135 /* XrdOssGetSS (a.k.a. XrdOssGetStorageSystem) */
136 /******************************************************************************/
137 
139 
140 // This function is called by the OFS layer to retrieve the Storage System
141 // object. We return our proxy storage system object if configuration succeeded.
142 //
143 extern "C"
144 {
147  const char *cFN,
148  const char *parms,
149  XrdOucEnv *envp)
150 {
151 
152 // Ignore the parms (we accept none for now) and call the init routine
153 //
154  envP = envp;
155  return (XrdProxySS.Init(Logger, cFN, envP) ? 0 : (XrdOss *)&XrdProxySS);
156 }
157 }
158 
159 /******************************************************************************/
160 /* o o s s _ S y s M e t h o d s */
161 /******************************************************************************/
162 /******************************************************************************/
163 /* C o n s t r u c t o r */
164 /******************************************************************************/
165 
166 XrdPssSys::XrdPssSys() : HostArena(0), LocalRoot(0), theN2N(0), DirFlags(0),
167  myVersion(&XrdVERSIONINFOVAR(XrdOssGetStorageSystem2)),
168  myFeatures(XRDOSS_HASPRXY|XRDOSS_HASPGRW|
170  {}
171 
172 /******************************************************************************/
173 /* i n i t */
174 /******************************************************************************/
175 
176 /*
177  Function: Initialize proxy subsystem
178 
179  Input: None
180 
181  Output: Returns zero upon success otherwise (-errno).
182 */
183 int XrdPssSys::Init(XrdSysLogger *lp, const char *cFN, XrdOucEnv *envP)
184 {
185  int NoGo;
186  const char *tmp;
187 
188 // Do the herald thing
189 //
190  SysTrace.SetLogger(lp);
191  eDest.logger(lp);
192  eDest.Say("Copr. 2019, Stanford University, Pss Version " XrdVSTRING);
193 
194 // Initialize the subsystems
195 //
196  tmp = ((NoGo = Configure(cFN, envP)) ? "failed." : "completed.");
197  eDest.Say("------ Proxy storage system initialization ", tmp);
198 
199 // Extract Pfc control, if it is there.
200 //
201  if (!NoGo)
202  cacheFSctl = (XrdOfsFSctl_PI*)envP->GetPtr("XrdFSCtl_PC*");
203 
204 
205 // All done.
206 //
207  return NoGo;
208 }
209 
210 /******************************************************************************/
211 /* C h m o d */
212 /******************************************************************************/
213 /*
214  Function: Change file mode.
215 
216  Input: path - Is the fully qualified name of the target file.
217  mode - The new mode that the file is to have.
218  envP - Environmental information.
219 
220  Output: Returns XrdOssOK upon success and -errno upon failure.
221 
222  Notes: This function is currently unsupported.
223 */
224 
225 int XrdPssSys::Chmod(const char *path, mode_t mode, XrdOucEnv *eP)
226 {
227 // We currently do not support chmod()
228 //
229  return -ENOTSUP;
230 }
231 
232 /******************************************************************************/
233 /* C o n n e c t */
234 /******************************************************************************/
235 
237 {
238  EPNAME("Connect");
239  const XrdSecEntity *client = theEnv.secEnv();
240 
241 // If we need to personify the client, set it up
242 //
243  if (idMapper && client)
244  {const char *fmt = (client->ueid & 0xf0000000 ? "%x" : "U%x");
245  char uName[32];
246  snprintf(uName, sizeof(uName), fmt, client->ueid);
247  DEBUG(client->tident,"Registering as ID "<<uName);
248  idMapper->Register(uName, client, deferID);
249  }
250 }
251 
252 /******************************************************************************/
253 /* c r e a t e */
254 /******************************************************************************/
255 
256 /*
257  Function: Create a file named `path' with 'file_mode' access mode bits set.
258 
259  Input: path - The fully qualified name of the file to create.
260  access_mode - The Posix access mode bits to be assigned to the file.
261  These bits correspond to the standard Unix permission
262  bits (e.g., 744 == "rwxr--r--").
263  env - Environmental information.
264  opts - Set as follows:
265  XRDOSS_mkpath - create dir path if it does not exist.
266  XRDOSS_new - the file must not already exist.
267  x00000000 - x are standard open flags (<<8)
268 
269  Output: Returns XrdOssOK upon success; (-errno) otherwise.
270 
271  Notes: We always return ENOTSUP as we really want the create options to be
272  promoted to the subsequent open().
273 */
274 int XrdPssSys::Create(const char *tident, const char *path, mode_t Mode,
275  XrdOucEnv &env, int Opts)
276 {
277 
278  return -ENOTSUP;
279 }
280 
281 /******************************************************************************/
282 /* D i s c */
283 /******************************************************************************/
284 
286 {
287  EPNAME("Disc");
288  const XrdSecEntity *client = theEnv.secEnv();
289 
290 // If we personified a client, remove that persona.
291 //
292  if (idMapper && client)
293  {const char *fmt = (client->ueid & 0xf0000000 ? "%x" : "U%x");
294  char uName[32];
295  snprintf(uName, sizeof(uName), fmt, client->ueid);
296  DEBUG(client->tident,"Unregistering as ID "<<uName);
297  idMapper->Register(uName, 0);
298  }
299 }
300 
301 /******************************************************************************/
302 /* E n v I n f o */
303 /******************************************************************************/
304 
306 {
307 // We only need to extract the scheduler pointer from the environment. Propogate
308 // the information to the POSIX layer.
309 //
310  if (envP)
311  {schedP = (XrdScheduler *)envP->GetPtr("XrdScheduler*");
313  }
314 }
315 
316 /******************************************************************************/
317 /* F S c t l */
318 /******************************************************************************/
319 
320 int XrdPssSys::FSctl(int cmd, int alen, const char *args, char **resp)
321 {
322  EPNAME("FSctl");
324  int rc;
325 
326 // Get correct argument to use
327 //
328  switch(cmd)
329  {case XRDOSS_FSCTLFS: opc = XrdOucCacheOp::Code::QFSinfo;
330  break;
331  default:
332  *resp = 0;
333  return -ENOTSUP;
334  break;
335  }
336 
337 // Perform setup
338 //
339  std::string thePath(args, alen); // Gaurd against missing null byte
340  std::string theResp;
341  XrdPssUrlInfo uInfo(0, args); // CGI is already appended
342  char pbuff[PBsz];
343 
344 // Convert path to URL
345 //
346  if ((rc = P2URL(pbuff, PBsz, uInfo, xLfn2Pfn))) return rc;
347  thePath = pbuff;
348 
349 // Some tracing
350 //
351  if(DEBUGON) {
352  auto urlObf = obfuscateAuth(pbuff);
353  DEBUG(uInfo.Tident(),"url="<<urlObf);
354  }
355 
356 // Invoke the file control. Make sure it goes through the cache if it exists.
357 //
358  if (XrdPosixExtra::FSctl(opc, thePath, theResp, true) < 0) return -errno;
359 
360 // Convert the response
361 //
362  if (resp)
363  {int n = theResp.size() + 1;
364  *resp = new char[n];
365  strcpy(*resp, theResp.c_str());
366  }
367  return XrdOssOK;
368 }
369 
370 /******************************************************************************/
371 /* g e t E r r M s g */
372 /******************************************************************************/
373 
374 bool XrdPssSys::getErrMsg(std::string& eText)
375 {
376 // Return what we have but make sure to reset whatever we have
377 //
378  if (XrdProxy::ecMsg.Get() <= 0 || !XrdProxy::ecMsg.hasMsg()) return false;
379  XrdProxy::ecMsg.Get(eText);
380  return true;
381 }
382 
383 /******************************************************************************/
384 /* L f n 2 P f n */
385 /******************************************************************************/
386 
387 int XrdPssSys::Lfn2Pfn(const char *oldp, char *newp, int blen)
388 {
389  if (theN2N) return -(theN2N->lfn2pfn(oldp, newp, blen));
390  if ((int)strlen(oldp) >= blen) return -ENAMETOOLONG;
391  strcpy(newp, oldp);
392  return 0;
393 }
394 
395 const char *XrdPssSys::Lfn2Pfn(const char *oldp, char *newp, int blen, int &rc)
396 {
397  if (!theN2N) {rc = 0; return oldp;}
398  if ((rc = -(theN2N->lfn2pfn(oldp, newp, blen)))) return 0;
399  return newp;
400 }
401 
402 /******************************************************************************/
403 /* M k d i r */
404 /******************************************************************************/
405 /*
406  Function: Create a directory
407 
408  Input: path - Is the fully qualified name of the new directory.
409  mode - The new mode that the directory is to have.
410  mkpath - If true, makes the full path.
411  envP - Environmental information.
412 
413  Output: Returns XrdOssOK upon success and -errno upon failure.
414 
415  Notes: Directories are only created in the local disk cache.
416  Currently, we do not propogate the mkpath option.
417 */
418 
419 int XrdPssSys::Mkdir(const char *path, mode_t mode, int mkpath, XrdOucEnv *eP)
420 {
421  EPNAME("Mkdir");
422  XrdPssUrlInfo uInfo(eP, path);
423  int rc;
424  char pbuff[PBsz];
425 
426 // Verify we can write here
427 //
428  if (isREADONLY(path)) return -EROFS;
429 
430 // Convert path to URL
431 //
432  if ((rc = P2URL(pbuff, PBsz, uInfo, xLfn2Pfn))) return rc;
433 
434 // Some tracing
435 //
436  if(DEBUGON) {
437  auto urlObf = obfuscateAuth(pbuff);
438  DEBUG(uInfo.Tident(),"url="<<urlObf);
439  }
440 
441 // Simply return the proxied result here
442 //
443  return (XrdPosixXrootd::Mkdir(pbuff, mode) ? Info(errno) : XrdOssOK);
444 }
445 
446 /******************************************************************************/
447 /* R e m d i r */
448 /******************************************************************************/
449 
450 /*
451  Function: Removes the directory 'path'
452 
453  Input: path - Is the fully qualified name of the directory to remove.
454  envP - Environmental information.
455 
456  Output: Returns XrdOssOK upon success and -errno upon failure.
457 */
458 int XrdPssSys::Remdir(const char *path, int Opts, XrdOucEnv *eP)
459 {
460  EPNAME("Remdir");
461  const char *Cgi = "";
462  int rc;
463  char pbuff[PBsz];
464 
465 // Verify we can write here
466 //
467  if (isREADONLY(path)) return -EROFS;
468 
469 // Setup any required cgi information
470 //
471  if (*path == '/' && !outProxy && (Opts & XRDOSS_Online)) Cgi = ofslclCGI;
472 
473 // Setup url information
474 //
475  XrdPssUrlInfo uInfo(eP, path, Cgi);
476 
477 // Convert path to URL
478 //
479  if ((rc = P2URL(pbuff, PBsz, uInfo, xLfn2Pfn))) return rc;
480 
481 // Do some tracing
482 //
483  if(DEBUGON) {
484  auto urlObf = obfuscateAuth(pbuff);
485  DEBUG(uInfo.Tident(),"url="<<urlObf);
486  }
487 // Issue unlink and return result
488 //
489  return (XrdPosixXrootd::Rmdir(pbuff) ? Info(errno) : XrdOssOK);
490 }
491 
492 /******************************************************************************/
493 /* R e n a m e */
494 /******************************************************************************/
495 
496 /*
497  Function: Renames a file with name 'old_name' to 'new_name'.
498 
499  Input: old_name - Is the fully qualified name of the file to be renamed.
500  new_name - Is the fully qualified name that the file is to have.
501  old_envP - Environmental information for old_name.
502  new_envP - Environmental information for new_name.
503 
504  Output: Returns XrdOssOK upon success and -errno upon failure.
505 */
506 int XrdPssSys::Rename(const char *oldname, const char *newname,
507  XrdOucEnv *oldenvP, XrdOucEnv *newenvP)
508 {
509  EPNAME("Rename");
510  int rc;
511  char oldName[PBsz], newName[PBsz];
512 
513 // Verify we can write in the source and target
514 //
515  if (isREADONLY(oldname) || isREADONLY(newname)) return -EROFS;
516 
517 // Setup url info
518 //
519  XrdPssUrlInfo uInfoOld(oldenvP, oldname);
520  XrdPssUrlInfo uInfoNew(newenvP, newname, "", true, false);
521 
522 // Convert path to URL
523 //
524  if ((rc = P2URL(oldName, PBsz, uInfoOld, xLfn2Pfn))
525  || (rc = P2URL(newName, PBsz, uInfoNew, xLfn2Pfn))) return rc;
526 
527 // Do some tracing
528 //
529  if(DEBUGON) {
530  auto oldNameObf = obfuscateAuth(oldName);
531  auto newNameObf = obfuscateAuth(newName);
532  DEBUG(uInfoOld.Tident(),"old url="<<oldNameObf <<" new url=" <<newNameObf);
533  }
534 
535 
536 // Execute the rename and return result
537 //
538  return (XrdPosixXrootd::Rename(oldName, newName) ? Info(errno) : XrdOssOK);
539 }
540 
541 /******************************************************************************/
542 /* s t a t */
543 /******************************************************************************/
544 
545 /*
546  Function: Determine if file 'path' actually exists.
547 
548  Input: path - Is the fully qualified name of the file to be tested.
549  buff - pointer to a 'stat' structure to hold the attributes
550  of the file.
551  Opts - stat() options.
552  envP - Environmental information.
553 
554  Output: Returns XrdOssOK upon success and -errno upon failure.
555 
556  Notes: The XRDOSS_resonly flag in Opts is not supported.
557 */
558 
559 int XrdPssSys::Stat(const char *path, struct stat *buff, int Opts, XrdOucEnv *eP)
560 {
561  EPNAME("Stat");
562  const char *Cgi = "";
563  int rc;
564  char pbuff[PBsz];
565 
566 // Setup any required special cgi information
567 //
568  if (*path == '/' && !outProxy && ((Opts & XRDOSS_resonly)||isNOSTAGE(path)))
569  Cgi = osslclCGI;
570 
571 // We can now establish the url information to be used
572 //
573  XrdPssUrlInfo uInfo(eP, path, Cgi);
574 
575 // Generate an ID if we need to. We can use the server's identity unless that
576 // has been prohibited because client ID mapping is taking place.
577 //
578  if (idMapAll) uInfo.setID();
579  else if (sidP) uInfo.setID(sidP);
580 
581 // Convert path to URL
582 //
583  if ((rc = P2URL(pbuff, PBsz, uInfo, xLfn2Pfn))) return rc;
584 
585 // Do some tracing
586 //
587  if(DEBUGON) {
588  auto urlObf = obfuscateAuth(pbuff);
589  DEBUG(uInfo.Tident(),"url="<<urlObf);
590  }
591 
592 // Return proxied stat
593 //
594  return (XrdPosixXrootd::Stat(pbuff, buff) ? Info(errno) : XrdOssOK);
595 }
596 
597 /******************************************************************************/
598 /* S t a t s */
599 /******************************************************************************/
600 
601 /* Function: Return statistics.
602 
603  Input: buff - Pointer to buffer for statistics data.
604  blen - The length of the buffer.
605 
606  Output: When blen is not zero, null terminated statistics are placed
607  in buff and the length is returned. When blen is zero, the
608  maximum length needed is returned.
609 */
610 int XrdPssSys::Stats(char *bp, int bl)
611 {
612  return XrdPosixConfig::Stats("pss", bp, bl);
613 }
614 
615 /******************************************************************************/
616 /* T r u n c a t e */
617 /******************************************************************************/
618 /*
619  Function: Truncate a file.
620 
621  Input: path - Is the fully qualified name of the target file.
622  flen - The new size that the file is to have.
623  envP - Environmental information.
624 
625  Output: Returns XrdOssOK upon success and -errno upon failure.
626 */
627 
628 int XrdPssSys::Truncate(const char *path, unsigned long long flen,
629  XrdOucEnv *envP)
630 {
631  EPNAME("Trunc");
632  XrdPssUrlInfo uInfo(envP, path);
633  int rc;
634  char pbuff[PBsz];
635 
636 // Make sure we can write here
637 //
638  if (isREADONLY(path)) return -EROFS;
639 
640 // Convert path to URL
641 //
642  if ((rc = P2URL(pbuff, PBsz, uInfo, xLfn2Pfn))) return rc;
643 
644 // Do some tracing
645 //
646  if(DEBUGON) {
647  auto urlObf = obfuscateAuth(pbuff);
648  DEBUG(uInfo.Tident(),"url="<<urlObf);
649  }
650 
651 // Return proxied truncate. We only do this on a single machine because the
652 // redirector will forbid the trunc() if multiple copies exist.
653 //
654  return (XrdPosixXrootd::Truncate(pbuff, flen) ? Info(errno) : XrdOssOK);
655 }
656 
657 /******************************************************************************/
658 /* U n l i n k */
659 /******************************************************************************/
660 
661 /*
662  Function: Delete a file from the namespace and release it's data storage.
663 
664  Input: path - Is the fully qualified name of the file to be removed.
665  envP - Environmental information.
666 
667  Output: Returns XrdOssOK upon success and -errno upon failure.
668 */
669 int XrdPssSys::Unlink(const char *path, int Opts, XrdOucEnv *envP)
670 {
671  EPNAME("Unlink");
672  const char *Cgi = "";
673  int rc;
674  char pbuff[PBsz];
675 
676 // Make sure we can write here
677 //
678  if (isREADONLY(path)) return -EROFS;
679 
680 // Setup any required cgi information
681 //
682  if (*path == '/' && !outProxy && (Opts & XRDOSS_Online)) Cgi = ofslclCGI;
683 
684 // Setup url info
685 //
686  XrdPssUrlInfo uInfo(envP, path, Cgi);
687 
688 // Convert path to URL
689 //
690  if ((rc = P2URL(pbuff, PBsz, uInfo, xLfn2Pfn))) return rc;
691 
692 // Do some tracing
693 //
694  if(DEBUGON) {
695  auto urlObf = obfuscateAuth(pbuff);
696  DEBUG(uInfo.Tident(),"url="<<urlObf);
697  }
698 
699 // Unlink the file and return result.
700 //
701  return (XrdPosixXrootd::Unlink(pbuff) ? Info(errno) : XrdOssOK);
702 }
703 
704 /******************************************************************************/
705 /* P s s D i r M e t h o d s */
706 /******************************************************************************/
707 /******************************************************************************/
708 /* o p e n d i r */
709 /******************************************************************************/
710 
711 /*
712  Function: Open the directory `path' and prepare for reading.
713 
714  Input: path - The fully qualified name of the directory to open.
715  envP - Environmental information.
716 
717  Output: Returns XrdOssOK upon success; (-errno) otherwise.
718 */
719 int XrdPssDir::Opendir(const char *dir_path, XrdOucEnv &Env)
720 {
721  EPNAME("Opendir");
722  int rc;
723  char pbuff[PBsz];
724 
725 // Return an error if this object is already open
726 //
727  if (myDir) return -XRDOSS_E8001;
728 
729 // Open directories are not supported for object id's
730 //
731  if (*dir_path != '/') return -ENOTSUP;
732 
733 // Setup url info
734 //
735  XrdPssUrlInfo uInfo(&Env, dir_path);
736  uInfo.setID();
737 
738 // Convert path to URL
739 //
740  if ((rc = XrdPssSys::P2URL(pbuff, PBsz, uInfo, XrdPssSys::xLfn2Pfn)))
741  return rc;
742 
743 // Do some tracing
744 //
745  if(DEBUGON) {
746  auto urlObf = obfuscateAuth(pbuff);
747  DEBUG(uInfo.Tident(),"url="<<urlObf);
748  }
749 
750 // Open the directory
751 //
752  myDir = XrdPosixXrootd::Opendir(pbuff);
753  if (!myDir)
754  {rc = -errno;
755  lastEtrc = XrdPosixXrootd::QueryError(lastEtext);
756  return rc;
757  }
758  return XrdOssOK;
759 }
760 
761 /******************************************************************************/
762 /* r e a d d i r */
763 /******************************************************************************/
764 
765 /*
766  Function: Read the next entry if directory associated with this object.
767 
768  Input: buff - Is the address of the buffer that is to hold the next
769  directory name.
770  blen - Size of the buffer.
771 
772  Output: Upon success, places the contents of the next directory entry
773  in buff. When the end of the directory is encountered buff
774  will be set to the null string.
775 
776  Upon failure, returns a (-errno).
777 
778  Warning: The caller must provide proper serialization.
779 */
780 int XrdPssDir::Readdir(char *buff, int blen)
781 {
782 // Check if we are directly reading the directory
783 //
784  if (myDir)
785  {dirent *entP, myEnt;
786  int rc = XrdPosixXrootd::Readdir_r(myDir, &myEnt, &entP);
787  if (rc)
788  {lastEtrc = XrdPosixXrootd::QueryError(lastEtext, myDir);
789  return -rc;
790  }
791  if (!entP) *buff = 0;
792  else strlcpy(buff, myEnt.d_name, blen);
793  return XrdOssOK;
794  }
795 
796 // The directory is not open
797 //
798  return -XRDOSS_E8002;
799 }
800 
801 /******************************************************************************/
802 /* S t a t R e t */
803 /******************************************************************************/
804 int XrdPssDir::StatRet(struct stat *buff)
805 {
806  if (!myDir) return -XRDOSS_E8002;
807 
808  auto rc = XrdPosixXrootd::StatRet(myDir, buff);
809  if (rc) return -rc;
810  return XrdOssOK;
811 }
812 
813 /******************************************************************************/
814 /* C l o s e */
815 /******************************************************************************/
816 
817 /*
818  Function: Close the directory associated with this object.
819 
820  Input: None.
821 
822  Output: Returns XrdOssOK upon success and (errno) upon failure.
823 */
824 int XrdPssDir::Close(long long *retsz)
825 {
826  DIR *theDir;
827 
828 // Close the directory proper if it exists. POSIX specified that directory
829 // stream is no longer available after closedir() regardless if return value.
830 //
831  if ((theDir = myDir))
832  {myDir = 0;
833  if (XrdPosixXrootd::Closedir(theDir))
834  {int rc = errno;
835  lastEtrc = XrdPosixXrootd::QueryError(lastEtext);
836  return -rc;
837  }
838  return XrdOssOK;
839  }
840 
841 // Directory is not open
842 //
843  return -XRDOSS_E8002;
844 }
845 
846 /******************************************************************************/
847 /* g e t E r r M s g */
848 /******************************************************************************/
849 
850 bool XrdPssDir::getErrMsg(std::string& eText)
851 {
852 // Return what we have but make sure to reset whatever we have
853 //
854  if (lastEtrc <= 0 || lastEtext.empty()) return false;
855  eText = lastEtext;
856  lastEtext.clear();
857  lastEtrc = 0;
858  return true;
859 }
860 
861 /******************************************************************************/
862 /* o o s s _ F i l e M e t h o d s */
863 /******************************************************************************/
864 /******************************************************************************/
865 /* o p e n */
866 /******************************************************************************/
867 
868 /*
869  Function: Open the file `path' in the mode indicated by `Mode'.
870 
871  Input: path - The fully qualified name of the file to open.
872  Oflag - Standard open flags.
873  Mode - Create mode (i.e., rwx).
874  env - Environmental information.
875 
876  Output: XrdOssOK upon success; -errno otherwise.
877 */
878 int XrdPssFile::Open(const char *path, int Oflag, mode_t Mode, XrdOucEnv &Env)
879 {
880  EPNAME("Open");
881  unsigned long long popts = XrdPssSys::XPList.Find(path);
882  const char *Cgi = "";
883  char pbuff[PBsz];
884  int rc;
885  bool tpcMode = (Oflag & O_NOFOLLOW) != 0;
886  bool rwMode = (Oflag & O_ACCMODE) != O_RDONLY;
887  bool ucgiOK = true;
888  bool ioCache = (Oflag & O_DIRECT);
889 
890 // Record the security environment
891 //
892  entity = Env.secEnv();
893 
894 // Turn off direct flag if set (we record it separately
895 //
896  if (ioCache) Oflag &= ~O_DIRECT;
897 
898 // Return an error if the object is already open
899 //
900  if (fd >= 0 || tpcPath) return -XRDOSS_E8003;
901 
902 // If we are opening this in r/w mode make sure we actually can
903 //
904  if (rwMode)
905  {if (XrdPssSys::fileOrgn) return -EROFS;
906  if (popts & XRDEXP_NOTRW)
907  {if (popts & XRDEXP_FORCERO && !tpcMode) Oflag = O_RDONLY;
908  else return -EROFS;
909  }
910  }
911 
912  // check CGI cache-control paramters
913  if (cacheFSctl)
914  {
915  int elen;
916  char *envcgi = (char *)Env.Env(elen);
917 
918  if (envcgi && strstr(envcgi, "only-if-cached"))
919  {
920  XrdOucErrInfo einfo;
921  XrdSfsFSctl myData;
922  myData.Arg1 = "cached";
923  myData.Arg1Len = 1;
924  myData.Arg2Len = 1;
925  const char *myArgs[1];
926  myArgs[0] = path;
927  myData.ArgP = myArgs;
928  int fsctlRes = cacheFSctl->FSctl(SFS_FSCTL_PLUGXC, myData, einfo);
929  if (fsctlRes == SFS_ERROR)
930  return -einfo.getErrInfo();
931  }
932  }
933 
934 // If this is a third party copy open, then strange rules apply. If this is an
935 // outgoing proxy we let everything pass through as this may be a TPC request
936 // elsewhere. Otherwise, if it's an open for reading, we open the file but
937 // strip off all CGI (technically, we should only remove the "tpc" tokens)
938 // because the source might not support direct TPC mode. If we are opening for
939 // writing, then we skip the open and mark this as a TPC handle which can only
940 // be used for fstat() and close(). Any other actions return an error.
941 //
942  if (tpcMode)
943  {Oflag &= ~O_NOFOLLOW;
944  if (!XrdProxy::outProxy || !IS_FWDPATH(path))
945  {if (rwMode)
946  {tpcPath = strdup(path);
947  if (XrdPssSys::reProxy)
948  {const char *rPath = Env.Get("tpc.reproxy");
949  if (!rPath || *rPath != '/') return -ENOATTR;
950  if (!(rPath = rindex(rPath, '/')) || *(rPath+1) == 0)
951  return -EFAULT;
952  rpInfo = new tprInfo(rPath+1);
953  }
954  return XrdOssOK;
955  }
956  ucgiOK = false;
957  }
958  }
959 
960 // Setup any required cgi information. Don't mess with it if it's an objectid
961 // or if the we are an outgoing proxy server.
962 //
963  if (!XrdProxy::outProxy && *path == '/' && !(XRDEXP_STAGE & popts))
964  Cgi = osslclCGI;
965 
966 // Construct the url info
967 //
968  XrdPssUrlInfo uInfo(&Env, path, Cgi, ucgiOK);
969  uInfo.setID();
970 
971 // Convert path to URL
972 //
973  if ((rc = XrdPssSys::P2URL(pbuff, PBsz, uInfo, XrdPssSys::xLfn2Pfn)))
974  return rc;
975 
976 // Do some tracing
977 //
978  if(DEBUGON) {
979  auto urlObf = obfuscateAuth(pbuff);
980  DEBUG(uInfo.Tident(),"url="<<urlObf);
981  }
982 
983 // Try to open and if we failed, return an error
984 //
985  if (!XrdPssSys::dcaCheck || !ioCache)
986  {if ((fd = XrdPosixXrootd::Open(pbuff,Oflag,Mode)) < 0)
987  {rc = -errno;
988  lastEtrc = XrdPosixXrootd::QueryError(lastEtext);
989  return rc;
990  }
991  } else {
993  Info.ffReady = XrdPssSys::dcaWorld;
994  if (XrdPosixConfig::OpenFC(pbuff,Oflag,Mode,Info))
995  {Env.Put("FileURL", Info.cacheURL);
996  return -EDESTADDRREQ;
997  }
998  fd = Info.fileFD;
999  if (fd < 0)
1000  {rc = -errno;
1001  lastEtrc = XrdPosixXrootd::QueryError(lastEtext);
1002  return rc;
1003  }
1004  }
1005 
1006 // All done
1007 //
1008  return XrdOssOK;
1009 }
1010 
1011 /******************************************************************************/
1012 /* c l o s e */
1013 /******************************************************************************/
1014 
1015 /*
1016  Function: Close the file associated with this object.
1017 
1018  Input: None.
1019 
1020  Output: Returns XrdOssOK upon success aud -errno upon failure.
1021 */
1022 int XrdPssFile::Close(long long *retsz)
1023 { int rc;
1024 
1025 // We don't support returning the size (we really should fix this)
1026 //
1027  if (retsz) *retsz = 0;
1028 
1029 // If the file is not open, then this may be OK if it is a 3rd party copy
1030 //
1031  if (fd < 0)
1032  {if (!tpcPath) return -XRDOSS_E8004;
1033  free(tpcPath);
1034  tpcPath = 0;
1035  return XrdOssOK;
1036  }
1037 
1038 // Close the file
1039 //
1040  rc = XrdPosixXrootd::Close(fd);
1041  fd = -1;
1042  if (rc == 0) return XrdOssOK;
1043  rc = -errno;
1044  lastEtrc = XrdPosixXrootd::QueryError(lastEtext);
1045  return rc;
1046 }
1047 
1048 /******************************************************************************/
1049 /* g e t E r r M s g */
1050 /******************************************************************************/
1051 
1052 bool XrdPssFile::getErrMsg(std::string& eText)
1053 {
1054 // Return what we have but make sure to reset whatever we have
1055 //
1056  if (lastEtrc <= 0 || lastEtext.empty()) return false;
1057  eText = lastEtext;
1058  lastEtext.clear();
1059  lastEtrc = 0;
1060  return true;
1061 }
1062 
1063 /******************************************************************************/
1064 /* p g R e a d */
1065 /******************************************************************************/
1066 
1067 /*
1068  Function: Read file pages into a buffer and return corresponding checksums.
1069 
1070  Input: buffer - pointer to buffer where the bytes are to be placed.
1071  offset - The offset where the read is to start.
1072  rdlen - The number of bytes to read.
1073  csvec - A vector to be filled with the corresponding CRC32C
1074  checksums for each page or page segment, if available.
1075  opts - Options as noted (see inherited class).
1076 
1077  Output: returns Number of bytes that placed in buffer upon success and
1078  -errno upon failure.
1079 */
1080 
1081 ssize_t XrdPssFile::pgRead(void *buffer,
1082  off_t offset,
1083  size_t rdlen,
1084  uint32_t *csvec,
1085  uint64_t opts)
1086 {
1087  std::vector<uint32_t> vecCS;
1088  uint64_t psxOpts;
1089  ssize_t bytes;
1090 
1091 // Make sure file is open
1092 //
1093  if (fd < 0) return (ssize_t)-XRDOSS_E8004;
1094 
1095 // Set options as needed
1096 //
1097  psxOpts = (csvec ? XrdPosixExtra::forceCS : 0);
1098 
1099 // Issue the pgread
1100 //
1101  if ((bytes = XrdPosixExtra::pgRead(fd,buffer,offset,rdlen,vecCS,psxOpts)) < 0)
1102  {int rc = -errno;
1103  lastEtrc = XrdPosixXrootd::QueryError(lastEtext, fd);
1104  return (ssize_t)rc;
1105  }
1106 
1107 // Copy out the checksum vector
1108 //
1109  if (vecCS.size() && csvec)
1110  memcpy(csvec, vecCS.data(), vecCS.size()*sizeof(uint32_t));
1111 
1112 // All done
1113 //
1114  return bytes;
1115 }
1116 
1117 /******************************************************************************/
1118 /* p g W r i t e */
1119 /******************************************************************************/
1120 /*
1121  Function: Write file pages into a file with corresponding checksums.
1122 
1123  Input: buffer - pointer to buffer containing the bytes to write.
1124  offset - The offset where the write is to start.
1125  wrlen - The number of bytes to write.
1126  be the last write to the file at or above the offset.
1127  csvec - A vector which contains the corresponding CRC32 checksum
1128  for each page or page segment. If size is 0, then
1129  checksums are calculated. If not zero, the size must
1130  equal the required number of checksums for offset/wrlen.
1131  opts - Options as noted.
1132 
1133  Output: Returns the number of bytes written upon success and -errno
1134  upon failure.
1135 */
1136 
1137 ssize_t XrdPssFile::pgWrite(void *buffer,
1138  off_t offset,
1139  size_t wrlen,
1140  uint32_t *csvec,
1141  uint64_t opts)
1142 {
1143  std::vector<uint32_t> vecCS;
1144  ssize_t bytes;
1145 
1146 // Make sure we have an open file
1147 //
1148  if (fd < 0) return (ssize_t)-XRDOSS_E8004;
1149 
1150 // Check if caller wants to verify the checksums before writing
1151 //
1152  if (csvec && (opts & XrdOssDF::Verify))
1153  {XrdOucPgrwUtils::dataInfo dInfo((const char*)buffer,csvec,offset,wrlen);
1154  off_t bado;
1155  int badc;
1156  if (!XrdOucPgrwUtils::csVer(dInfo, bado, badc))
1157  {lastEtext = "pgWrite checksum verification failed.";
1158  lastEtrc = EDOM;
1159  return -EDOM;
1160  }
1161  }
1162 
1163 // Check if caller want checksum generated and possibly returned
1164 //
1165  if ((opts & XrdOssDF::doCalc) || csvec == 0)
1166  {XrdOucPgrwUtils::csCalc((const char *)buffer, offset, wrlen, vecCS);
1167  if (csvec) memcpy(csvec, vecCS.data(), vecCS.size()*sizeof(uint32_t));
1168  } else {
1169  int n = XrdOucPgrwUtils::csNum(offset, wrlen);
1170  vecCS.resize(n);
1171  vecCS.assign(n, 0);
1172  memcpy(vecCS.data(), csvec, n*sizeof(uint32_t));
1173  }
1174 
1175 // Issue the pgwrite
1176 //
1177  bytes = XrdPosixExtra::pgWrite(fd, buffer, offset, wrlen, vecCS);
1178 
1179 // Return result
1180 //
1181  if (bytes < 0)
1182  {int rc = -errno;
1183  lastEtrc = XrdPosixXrootd::QueryError(lastEtext, fd);
1184  return (ssize_t)rc;
1185  }
1186  return bytes;
1187 }
1188 
1189 /******************************************************************************/
1190 /* r e a d */
1191 /******************************************************************************/
1192 
1193 /*
1194  Function: Preread `blen' bytes from the associated file.
1195 
1196  Input: offset - The absolute 64-bit byte offset at which to read.
1197  blen - The size to preread.
1198 
1199  Output: Returns zero read upon success and -errno upon failure.
1200 */
1201 
1202 ssize_t XrdPssFile::Read(off_t offset, size_t blen)
1203 {
1204  if (fd < 0) return (ssize_t)-XRDOSS_E8004;
1205 
1206  return 0; // We haven't implemented this yet!
1207 }
1208 
1209 
1210 /******************************************************************************/
1211 /* r e a d */
1212 /******************************************************************************/
1213 
1214 /*
1215  Function: Read `blen' bytes from the associated file, placing in 'buff'
1216  the data and returning the actual number of bytes read.
1217 
1218  Input: buff - Address of the buffer in which to place the data.
1219  offset - The absolute 64-bit byte offset at which to read.
1220  blen - The size of the buffer. This is the maximum number
1221  of bytes that will be read.
1222 
1223  Output: Returns the number bytes read upon success and -errno upon failure.
1224 */
1225 
1226 ssize_t XrdPssFile::Read(void *buff, off_t offset, size_t blen)
1227 {
1228  ssize_t retval;
1229 
1230  if (fd < 0) return (ssize_t)-XRDOSS_E8004;
1231 
1232  if ((retval = XrdPosixXrootd::Pread(fd, buff, blen, offset)) < 0)
1233  {int rc = -errno;
1234  lastEtrc = XrdPosixXrootd::QueryError(lastEtext, fd);
1235  return (ssize_t)rc;
1236  }
1237  return retval;
1238 }
1239 
1240 /******************************************************************************/
1241 /* r e a d v */
1242 /******************************************************************************/
1243 
1244 ssize_t XrdPssFile::ReadV(XrdOucIOVec *readV, // In
1245  int readCount) // In
1246 /*
1247  Function: Perform all the reads specified in the readV vector.
1248 
1249  Input: readV - A description of the reads to perform; includes the
1250  absolute offset, the size of the read, and the buffer
1251  to place the data into.
1252  readCount - The size of the readV vector.
1253 
1254  Output: Returns the number of bytes read upon success and -errno upon failure.
1255  If the number of bytes read is less than requested, it is considered
1256  an error.
1257 */
1258 {
1259  ssize_t retval;
1260 
1261  if (fd < 0) return (ssize_t)-XRDOSS_E8004;
1262 
1263  if ((retval = XrdPosixXrootd::VRead(fd, readV, readCount)) < 0)
1264  {int rc = -errno;
1265  lastEtrc = XrdPosixXrootd::QueryError(lastEtext, fd);
1266  return (ssize_t)rc;
1267  }
1268  return (ssize_t)retval;;
1269 }
1270 
1271 /******************************************************************************/
1272 /* R e a d R a w */
1273 /******************************************************************************/
1274 
1275 /*
1276  Function: Read `blen' bytes from the associated file, placing in 'buff'
1277  the data and returning the actual number of bytes read.
1278 
1279  Input: buff - Address of the buffer in which to place the data.
1280  offset - The absolute 64-bit byte offset at which to read.
1281  blen - The size of the buffer. This is the maximum number
1282  of bytes that will be read.
1283 
1284  Output: Returns the number bytes read upon success and -errno upon failure.
1285 */
1286 
1287 ssize_t XrdPssFile::ReadRaw(void *buff, off_t offset, size_t blen)
1288 {
1289  return Read(buff, offset, blen);
1290 }
1291 
1292 /******************************************************************************/
1293 /* w r i t e */
1294 /******************************************************************************/
1295 
1296 /*
1297  Function: Write `blen' bytes to the associated file, from 'buff'
1298  and return the actual number of bytes written.
1299 
1300  Input: buff - Address of the buffer from which to get the data.
1301  offset - The absolute 64-bit byte offset at which to write.
1302  blen - The number of bytes to write from the buffer.
1303 
1304  Output: Returns the number of bytes written upon success and -errno o/w.
1305 */
1306 
1307 ssize_t XrdPssFile::Write(const void *buff, off_t offset, size_t blen)
1308 {
1309  ssize_t retval;
1310 
1311  if (fd < 0) return (ssize_t)-XRDOSS_E8004;
1312 
1313  if ((retval = XrdPosixXrootd::Pwrite(fd, buff, blen, offset)) < 0)
1314  {int rc = -errno;
1315  lastEtrc = XrdPosixXrootd::QueryError(lastEtext, fd);
1316  return (ssize_t)rc;
1317  }
1318  return (ssize_t)retval;
1319 }
1320 
1321 /******************************************************************************/
1322 /* F c t l */
1323 /******************************************************************************/
1324 
1325 int XrdPssFile::Fctl(int cmd, int alen, const char *args, char **resp)
1326 {
1327  XrdOucCacheOp::Code opc;
1328 
1329 // Made sure the file is open
1330 //
1331  if (fd < 0) return -XRDOSS_E8004;
1332 
1333 // Get correct argument to use
1334 //
1335  switch(cmd)
1336  {case XrdOssDF::Fctl_QFinfo: opc = XrdOucCacheOp::Code::QFinfo;
1337  break;
1338  default:
1339  *resp = 0;
1340  return -ENOTSUP;
1341  break;
1342  }
1343 
1344 // Convert argument to a string and prepare for the reponse
1345 //
1346  std::string theArgs(args, alen);
1347  std::string theResp;
1348 
1349 // Invoke the file control
1350 //
1351 
1352  if (XrdPosixExtra::Fctl(fd, opc, theArgs, theResp) < 0)
1353  {int rc = -errno;
1354  lastEtrc = XrdPosixXrootd::QueryError(lastEtext, fd);
1355  return rc;
1356  }
1357 
1358 // Convert the response
1359 //
1360  if (resp)
1361  {int n = theResp.size() + 1;
1362  *resp = new char[n];
1363  strcpy(*resp, theResp.c_str());
1364  }
1365  return XrdOssOK;
1366 }
1367 
1368 /******************************************************************************/
1369 /* f s t a t */
1370 /******************************************************************************/
1371 
1372 /*
1373  Function: Return file status for the associated file.
1374 
1375  Input: buff - Pointer to buffer to hold file status.
1376 
1377  Output: Returns XrdOssOK upon success and -errno upon failure.
1378 */
1379 
1380 int XrdPssFile::Fstat(struct stat *buff)
1381 {
1382  EPNAME("fstat");
1383 
1384 // If we have a file descriptor then return a stat for it
1385 //
1386  if (fd >= 0)
1387  {if (XrdPosixXrootd::Fstat(fd, buff) == 0) return XrdOssOK;
1388  int rc = -errno;
1389  lastEtrc = XrdPosixXrootd::QueryError(lastEtext, fd);
1390  return (ssize_t)rc;
1391  }
1392 
1393 // Otherwise, if this is not a tpc of any kind, return an error
1394 //
1395  if (!tpcPath) return -XRDOSS_E8004;
1396 
1397 // If this is a normal tpc then simply issue the stat against the origin
1398 //
1399  if (!rpInfo)
1400  {XrdOucEnv fstatEnv(0, 0, entity);
1401  return XrdProxySS.Stat(tpcPath, buff, 0, &fstatEnv);
1402  }
1403 
1404 // This is a reproxy tpc, if we have not yet dertermined the true dest, do so.
1405 //
1406  struct stat Stat;
1407 
1408  if (rpInfo->dstURL == 0
1409  || !fstatat(rpFD, rpInfo->tprPath, &Stat, AT_SYMLINK_NOFOLLOW))
1410  {char lnkbuff[2048]; int lnklen;
1411  lnklen = readlinkat(rpFD, rpInfo->tprPath, lnkbuff, sizeof(lnkbuff)-1);
1412  if (lnklen <= 0)
1413  {int rc = 0;
1414  if (lnklen < 0) {if (errno != ENOENT) rc = -errno;}
1415  else rc = -EFAULT;
1416  if (rc)
1417  {unlinkat(rpFD, rpInfo->tprPath, 0);
1418  return rc;
1419  }
1420  } else {
1421  unlinkat(rpFD, rpInfo->tprPath, 0);
1422  lnkbuff[lnklen] = 0;
1423  if (rpInfo->dstURL) free(rpInfo->dstURL);
1424  rpInfo->dstURL = strdup(lnkbuff);
1425  rpInfo->fSize = 1;
1426  DEBUG(tident,rpInfo->tprPath<<" maps "<<tpcPath<<" -> "<<lnkbuff);
1427  }
1428  }
1429 
1430 // At this point we may or may not have the final endpoint. An error here could
1431 // be due to write error recovery, so make allowance for that.
1432 //
1433  if (rpInfo->dstURL)
1434  {if (!XrdPosixXrootd::Stat(rpInfo->dstURL, buff))
1435  {if (!(rpInfo->fSize = buff->st_size)) rpInfo->fSize = 1;
1436  return XrdOssOK;
1437  }
1438  free(rpInfo->dstURL);
1439  rpInfo->dstURL = 0;
1440  }
1441 
1442 // We don't have the final endpoint. If we ever had it before, then punt.
1443 //
1444  if (rpInfo->fSize)
1445  {memset(buff, 0, sizeof(struct stat));
1446  buff->st_size = rpInfo->fSize;
1447  return XrdOssOK;
1448  }
1449 
1450 // If we are here then maybe the reproxy option was the wrong config setting.
1451 // Give stat a try on the origin we'll retry resolution on the next stat.
1452 //
1453  XrdOucEnv fstatEnv(0, 0, entity);
1454 
1455  if (XrdProxySS.Stat(tpcPath, buff, 0, &fstatEnv))
1456  memset(buff, 0, sizeof(struct stat));
1457  return XrdOssOK;
1458 }
1459 
1460 /******************************************************************************/
1461 /* f s y n c */
1462 /******************************************************************************/
1463 
1464 /*
1465  Function: Synchronize associated file.
1466 
1467  Input: None.
1468 
1469  Output: Returns XrdOssOK upon success and -errno upon failure.
1470 */
1472 {
1473  if (fd < 0) return -XRDOSS_E8004;
1474 
1475  if (XrdPosixXrootd::Fsync(fd) == 0) return XrdOssOK;
1476  int rc = -errno;
1477  lastEtrc = XrdPosixXrootd::QueryError(lastEtext, fd);
1478  return (ssize_t)rc;
1479 }
1480 
1481 /******************************************************************************/
1482 /* f t r u n c a t e */
1483 /******************************************************************************/
1484 
1485 /*
1486  Function: Set the length of associated file to 'flen'.
1487 
1488  Input: flen - The new size of the file.
1489 
1490  Output: Returns XrdOssOK upon success and -errno upon failure.
1491 
1492  Notes: If 'flen' is smaller than the current size of the file, the file
1493  is made smaller and the data past 'flen' is discarded. If 'flen'
1494  is larger than the current size of the file, a hole is created
1495  (i.e., the file is logically extended by filling the extra bytes
1496  with zeroes).
1497 
1498  If compiled w/o large file support, only lower 32 bits are used.
1499  used.
1500 
1501  Currently not supported for proxies.
1502 */
1503 int XrdPssFile::Ftruncate(unsigned long long flen)
1504 {
1505  if (fd < 0) return -XRDOSS_E8004;
1506 
1507  if (XrdPosixXrootd::Ftruncate(fd, flen) == 0) return XrdOssOK;
1508  int rc = -errno;
1509  lastEtrc = XrdPosixXrootd::QueryError(lastEtext, fd);
1510  return (ssize_t)rc;
1511 }
1512 
1513 /******************************************************************************/
1514 /* I n t e r n a l M e t h o d s */
1515 /******************************************************************************/
1516 
1517 int XrdPssSys::Info(int rc)
1518 {
1519  std::string psxMsg;
1520  int n = XrdPosixXrootd::QueryError(psxMsg);
1521 
1522  XrdProxy::ecMsg.Set(n, psxMsg);
1523  return -rc;
1524 }
1525 
1526 /******************************************************************************/
1527 /* P 2 D S T */
1528 /******************************************************************************/
1529 
1530 int XrdPssSys::P2DST(int &retc, char *hBuff, int hBlen, XrdPssSys::PolAct pEnt,
1531  const char *path)
1532 {
1533  const char *Slash;
1534  int n;
1535 
1536 // Extract out the destination
1537 //
1538  Slash = index(path, '/');
1539  if (!Slash || (n = (Slash - path)) == 0) {retc = -EINVAL; return 0;}
1540  if (n >= hBlen) {retc = -ENAMETOOLONG; return 0;}
1541  strncpy(hBuff, path, n); hBuff[n] = 0;
1542 
1543 // Check if we need to authorize the outgoing connection
1544 //
1545  if (Police[pEnt] && !Police[pEnt]->Authorize(hBuff))
1546  {retc = -EACCES; return 0;}
1547 
1548 // All is well
1549 //
1550  return n;
1551 }
1552 
1553 /******************************************************************************/
1554 /* P 2 O U T */
1555 /******************************************************************************/
1556 
1557 int XrdPssSys::P2OUT(char *pbuff, int pblen, XrdPssUrlInfo &uInfo)
1558 { const char *theID = uInfo.getID();
1559  const char *pname, *path, *thePath;
1560  char hBuff[288];
1561  int retc, n;
1562 
1563 // Setup the path
1564 //
1565  thePath = path = uInfo.thePath();
1566 
1567 // Make sure the path is valid for an outgoing proxy
1568 //
1569  if (*path == '/') path++;
1570  if ((pname = XrdPssUtils::valProt(path, n, 1))) path += n;
1571  else {if (!hdrLen) return -ENOTSUP;
1572  n = snprintf(pbuff, pblen, hdrData, theID, thePath);
1573  if (n >= pblen || !uInfo.addCGI(pbuff, pbuff+n, pblen-n))
1574  return -ENAMETOOLONG;
1575  return 0;
1576  }
1577 
1578 // Objectid must be handled differently as they have not been refalgomized
1579 //
1580  if (*thePath != '/')
1581  {if (*path == '/')
1582  {path++;
1583  if (*path == '/') theID = "";
1584  }
1585  if (Police[PolObj] && !P2DST(retc, hBuff, sizeof(hBuff), PolObj,
1586  path+(*path == '/' ? 1:0))) return 0;
1587  n = snprintf(pbuff, pblen, "%s%s%s", pname, theID, path);
1588  if (n >= pblen || !uInfo.addCGI(pbuff, pbuff+n, pblen-n))
1589  return -ENAMETOOLONG;
1590  return 0;
1591  }
1592 
1593 // Extract out the destination. We need to do this because the front end
1594 // will have extracted out double slashes and we need to add them back. We
1595 // also authorize the outgoing connection if we need to in the process.
1596 //
1597  if (!(n = P2DST(retc, hBuff, sizeof(hBuff), PolPath, path))) return 0;
1598  path += n;
1599 
1600 // Create the new path. If the url already contains a userid then use it
1601 // instead or our internally generated one. We may need an option for this
1602 // as it may result in unintended side-effects but for now we do that.
1603 //
1604  if (index(hBuff, '@')) theID= "";
1605  n = snprintf(pbuff,pblen,"%s%s%s/%s",pname,theID,hBuff,path);
1606 
1607 // Make sure the path will fit
1608 //
1609  if (n >= pblen || !uInfo.addCGI(pbuff, pbuff+n, pblen-n))
1610  return -ENAMETOOLONG;
1611 
1612 // All done
1613 //
1614  return 0;
1615 }
1616 
1617 /******************************************************************************/
1618 /* P 2 U R L */
1619 /******************************************************************************/
1620 
1621 int XrdPssSys::P2URL(char *pbuff, int pblen, XrdPssUrlInfo &uInfo, bool doN2N)
1622 {
1623 
1624 // If this is an outgoing proxy then we need to do someother work
1625 //
1626  if (outProxy) return P2OUT(pbuff, pblen, uInfo);
1627 
1628 // Do url generation for actual known origin
1629 //
1630  const char *path = uInfo.thePath();
1631  int retc, pfxLen;
1632  char Apath[MAXPATHLEN+1];
1633 
1634 // Setup to process url generation
1635 //
1636  path = uInfo.thePath();
1637 
1638 // First, apply the N2N mapping if necessary. If N2N fails then the whole
1639 // mapping fails and ENAMETOOLONG will be returned.
1640 //
1641  if (doN2N && XrdProxySS.theN2N)
1642  {if ((retc = XrdProxySS.theN2N->lfn2pfn(path, Apath, sizeof(Apath))))
1643  {if (retc > 0) return -retc;}
1644  path = Apath;
1645  }
1646 
1647 // Format the header into the buffer and check if we overflowed. Note that we
1648 // defer substitution of the path as we need to know where the path is.
1649 //
1650  if (fileOrgn) pfxLen = snprintf(pbuff, pblen, hdrData, path);
1651  else pfxLen = snprintf(pbuff, pblen, hdrData, uInfo.getID(), path);
1652  if (pfxLen >= pblen) return -ENAMETOOLONG;
1653 
1654 // Add any cgi information
1655 //
1656  if (!fileOrgn && uInfo.hasCGI())
1657  {if (!uInfo.addCGI(pbuff, pbuff+pfxLen, pblen-pfxLen))
1658  return -ENAMETOOLONG;
1659  }
1660 
1661 // All done
1662 //
1663  return 0;
1664 }
XrdAccAuthorize * Authorize
Definition: XrdAccTest.cc:61
#define tident
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
struct stat Stat
Definition: XrdCks.cc:49
XrdSysError eDest(0, "HttpMon")
#define XRDOSS_E8002
Definition: XrdOssError.hh:36
#define XRDOSS_E8003
Definition: XrdOssError.hh:37
#define XRDOSS_E8004
Definition: XrdOssError.hh:38
#define XRDOSS_E8001
Definition: XrdOssError.hh:35
#define XRDOSS_HASPRXY
Definition: XrdOss.hh:538
#define XRDOSS_HASXERT
Definition: XrdOss.hh:543
#define XRDOSS_FSCTLFS
Definition: XrdOss.hh:555
#define XRDOSS_Online
Definition: XrdOss.hh:528
#define XrdOssOK
Definition: XrdOss.hh:54
#define XRDOSS_HASNOSF
Definition: XrdOss.hh:539
#define XRDOSS_HASPGRW
Definition: XrdOss.hh:536
#define XRDOSS_resonly
Definition: XrdOss.hh:548
#define XRDEXP_NOTRW
Definition: XrdOucExport.hh:45
#define XRDEXP_FORCERO
Definition: XrdOucExport.hh:43
#define XRDEXP_STAGE
Definition: XrdOucExport.hh:52
std::string obfuscateAuth(const std::string &input)
#define DEBUGON
#define fstatat(a, b, c, d)
Definition: XrdPosix.hh:64
#define stat(a, b)
Definition: XrdPosix.hh:105
#define IS_FWDPATH(x)
Definition: XrdPssUtils.hh:64
#define ENOATTR
Definition: XrdPss.cc:81
XrdVERSIONINFO(XrdOssGetStorageSystem2, XrdPss)
#define isNOSTAGE(_x_)
Definition: XrdPss.cc:88
XrdOss * XrdOssGetStorageSystem2(XrdOss *native_oss, XrdSysLogger *Logger, const char *cFN, const char *parms, XrdOucEnv *envp)
Definition: XrdPss.cc:145
#define O_DIRECT
Definition: XrdPss.cc:77
#define isREADONLY(_x_)
Definition: XrdPss.cc:90
int Mode
struct myOpts opts
const char * Arg1
PLUGFS, PLUGIN, PLUGIO, PLUGXC.
int Arg2Len
Length or -count of args in extension.
#define SFS_ERROR
int Arg1Len
Length.
#define SFS_FSCTL_PLUGXC
< SFS_FSCTL_PLUGIN/PLUGIO/PLUGXC/PLUGFS parms
size_t strlcpy(char *dst, const char *src, size_t sz)
virtual int FSctl(const int cmd, int alen, const char *args, XrdSfsFile &file, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)=0
static const uint64_t doCalc
pgw: Calculate checksums
Definition: XrdOss.hh:253
const char * tident
Definition: XrdOss.hh:513
int fd
Definition: XrdOss.hh:515
static const uint64_t Verify
all: Verify checksums
Definition: XrdOss.hh:251
static const int Fctl_QFinfo
Definition: XrdOss.hh:461
void Set(int ecc, const char *ecm="")
Definition: XrdOucECMsg.hh:146
int Get(std::string &ecm, bool rst=true)
Definition: XrdOucECMsg.cc:41
void * GetPtr(const char *varname)
Definition: XrdOucEnv.cc:281
char * Get(const char *varname)
Definition: XrdOucEnv.hh:69
const XrdSecEntity * secEnv() const
Definition: XrdOucEnv.hh:107
char * Env(int &envlen)
Definition: XrdOucEnv.hh:48
void Put(const char *varname, const char *value)
Definition: XrdOucEnv.hh:85
virtual int lfn2pfn(const char *lfn, char *buff, int blen)=0
unsigned long long Find(const char *pathname)
Definition: XrdOucPList.hh:112
static void csCalc(const char *data, off_t offs, size_t count, uint32_t *csval)
static bool csVer(dataInfo &dInfo, off_t &bado, int &badc)
static int csNum(off_t offs, int count)
Compute the required size of a checksum vector based on offset & length.
static bool OpenFC(const char *path, int oflag, mode_t mode, XrdPosixInfo &Info)
static int Stats(const char *theID, char *buff, int blen)
static void EnvInfo(XrdOucEnv &theEnv)
static int FSctl(XrdOucCacheOp::Code opc, const std::string &args, std::string &resp, bool viaCache=false, bool viaRedir=false)
static ssize_t pgWrite(int fildes, void *buffer, off_t offset, size_t wrlen, std::vector< uint32_t > &csvec, uint64_t opts=0, XrdPosixCallBackIO *cbp=0)
static const uint64_t forceCS
static ssize_t pgRead(int fildes, void *buffer, off_t offset, size_t rdlen, std::vector< uint32_t > &csvec, uint64_t opts=0, XrdPosixCallBackIO *cbp=0)
static int Fctl(int fildes, XrdOucCacheOp::Code opc, const std::string &args, std::string &resp)
static ssize_t Pread(int fildes, void *buf, size_t nbyte, off_t offset)
Pread() conforms to POSIX.1-2001 pread()
static int Closedir(DIR *dirp)
Closedir() conforms to POSIX.1-2001 closedir()
static int Stat(const char *path, struct stat *buf)
Stat() conforms to POSIX.1-2001 stat()
static int Mkdir(const char *path, mode_t mode)
Mkdir() conforms to POSIX.1-2001 mkdir()
static int Unlink(const char *path)
Unlink() conforms to POSIX.1-2001 unlink()
static int Rmdir(const char *path)
Rmdir() conforms to POSIX.1-2001 rmdir()
static void VRead(int fildes, const XrdOucIOVec *readV, int n, XrdPosixCallBackIO *cbp)
static int Rename(const char *oldpath, const char *newpath)
Rename() conforms to POSIX.1-2001 rename()
static int Close(int fildes)
Close() conforms to POSIX.1-2001 close()
static int Readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
static int QueryError(std::string &emsg, int fd=-1, bool reset=true)
static int Ftruncate(int fildes, off_t offset)
Ftruncate() conforms to POSIX.1-2001 ftruncate()
static DIR * Opendir(const char *path)
Opendir() conforms to POSIX.1-2001 opendir()
static int Fsync(int fildes)
Fsync() conforms to POSIX.1-2001 fsync()
static int StatRet(DIR *dirp, struct stat *buf)
static int Fstat(int fildes, struct stat *buf)
Fstat() conforms to POSIX.1-2001 fstat()
static int Open(const char *path, int oflag, mode_t mode=0, XrdPosixCallBack *cbP=0)
static ssize_t Pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
Pwrite() conforms to POSIX.1-2001 pwrite()
static int Truncate(const char *path, off_t offset)
Telldir() conforms to POSIX.1-2001 telldir()
int Readdir(char *buff, int blen) override
Definition: XrdPss.cc:780
int Close(long long *retsz=0) override
Definition: XrdPss.cc:824
int Opendir(const char *, XrdOucEnv &) override
Definition: XrdPss.cc:719
int StatRet(struct stat *buf) override
Definition: XrdPss.cc:804
bool getErrMsg(std::string &eText) override
Definition: XrdPss.cc:850
ssize_t Read(off_t, size_t) override
Definition: XrdPss.cc:1202
virtual int Open(const char *, int, mode_t, XrdOucEnv &) override
Definition: XrdPss.cc:878
ssize_t pgWrite(void *buffer, off_t offset, size_t wrlen, uint32_t *csvec, uint64_t opts) override
Definition: XrdPss.cc:1137
ssize_t Write(const void *, off_t, size_t) override
Definition: XrdPss.cc:1307
virtual int Close(long long *retsz=0) override
Definition: XrdPss.cc:1022
int Fstat(struct stat *) override
Definition: XrdPss.cc:1380
ssize_t ReadV(XrdOucIOVec *readV, int n) override
Definition: XrdPss.cc:1244
int Ftruncate(unsigned long long) override
Definition: XrdPss.cc:1503
bool getErrMsg(std::string &eText) override
Definition: XrdPss.cc:1052
int Fsync() override
Definition: XrdPss.cc:1471
ssize_t pgRead(void *buffer, off_t offset, size_t rdlen, uint32_t *csvec, uint64_t opts) override
Definition: XrdPss.cc:1081
ssize_t ReadRaw(void *, off_t, size_t) override
Definition: XrdPss.cc:1287
int Fctl(int cmd, int alen, const char *args, char **resp=0) override
Definition: XrdPss.cc:1325
int Mkdir(const char *, mode_t mode, int mkpath=0, XrdOucEnv *eP=0) override
Definition: XrdPss.cc:419
static int P2OUT(char *pbuff, int pblen, XrdPssUrlInfo &uInfo)
Definition: XrdPss.cc:1557
int Unlink(const char *, int Opts=0, XrdOucEnv *eP=0) override
Definition: XrdPss.cc:669
XrdPssSys()
Definition: XrdPss.cc:166
virtual void Connect(XrdOucEnv &) override
Definition: XrdPss.cc:236
int Truncate(const char *, unsigned long long, XrdOucEnv *eP=0) override
Definition: XrdPss.cc:628
int Stats(char *bp, int bl) override
Definition: XrdPss.cc:610
static int Info(int rc)
Definition: XrdPss.cc:1517
static bool deferID
Definition: XrdPss.hh:225
static int hdrLen
Definition: XrdPss.hh:216
static const char * hdrData
Definition: XrdPss.hh:215
int Stat(const char *, struct stat *, int opts=0, XrdOucEnv *eP=0) override
Definition: XrdPss.cc:559
int Init(XrdSysLogger *, const char *) override
Definition: XrdPss.hh:181
static char * fileOrgn
Definition: XrdPss.hh:213
static int P2DST(int &retc, char *hBuff, int hBlen, PolAct pType, const char *path)
Definition: XrdPss.cc:1530
static bool dcaCheck
Definition: XrdPss.hh:223
static bool reProxy
Definition: XrdPss.hh:226
int Chmod(const char *, mode_t mode, XrdOucEnv *eP=0) override
Definition: XrdPss.cc:225
@ PolObj
Definition: XrdPss.hh:196
@ PolPath
Definition: XrdPss.hh:196
void EnvInfo(XrdOucEnv *envP) override
Definition: XrdPss.cc:305
static XrdNetSecurity * Police[PolNum]
Definition: XrdPss.hh:211
static XrdOucPListAnchor XPList
Definition: XrdPss.hh:209
static int P2URL(char *pbuff, int pblen, XrdPssUrlInfo &uInfo, bool doN2N=true)
Definition: XrdPss.cc:1621
int Remdir(const char *, int Opts=0, XrdOucEnv *eP=0) override
Definition: XrdPss.cc:458
int Lfn2Pfn(const char *Path, char *buff, int blen) override
Definition: XrdPss.cc:387
static bool xLfn2Pfn
Definition: XrdPss.hh:222
int FSctl(int cmd, int alen, const char *args, char **resp=0) override
Definition: XrdPss.cc:320
virtual int Create(const char *, const char *, mode_t, XrdOucEnv &, int opts=0) override
Definition: XrdPss.cc:274
virtual void Disc(XrdOucEnv &) override
Definition: XrdPss.cc:285
int Rename(const char *, const char *, XrdOucEnv *eP1=0, XrdOucEnv *eP2=0) override
Definition: XrdPss.cc:506
static bool dcaWorld
Definition: XrdPss.hh:224
bool getErrMsg(std::string &eText) override
Definition: XrdPss.cc:374
const char * thePath()
const char * Tident()
void setID(const char *tid=0)
const char * getID()
bool addCGI(const char *prot, char *buff, int blen)
static const char * valProt(const char *pname, int &plen, int adj=0)
Definition: XrdPssUtils.cc:82
const char * tident
Trace identifier always preset.
Definition: XrdSecEntity.hh:81
unsigned int ueid
Unique ID of entity instance.
Definition: XrdSecEntity.hh:79
bool Register(const char *lgnid, const XrdSecEntity *Ident, bool doReplace=false, bool defer=false)
Definition: XrdSecsssID.cc:224
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
Definition: XrdSysError.cc:162
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition: XrdSysError.hh:175
void SetLogger(XrdSysLogger *logp)
Definition: XrdSysTrace.cc:65
XrdVersionInfo myVersion
XrdOucEnv theEnv
XrdSysLogger Logger
Definition: XrdGlobals.cc:47
int Opts
Definition: XrdMpxStats.cc:58
XrdOucName2Name * theN2N
Definition: XrdPosixFile.cc:62
XrdSecsssID * idMapper
Definition: XrdPss.cc:114
XrdOfsFSctl_PI * cacheFSctl
Definition: XrdPss.cc:112
XrdSysTrace SysTrace("Pss", 0)
Definition: XrdPssCks.cc:55
XrdScheduler * schedP
Definition: XrdPss.cc:106
bool xrdProxy
Definition: XrdPss.cc:128
XrdOucSid * sidP
Definition: XrdPss.cc:108
static const int PBsz
Definition: XrdPss.cc:120
XrdSysError eDest(0, "pss_")
static const char * osslclCGI
Definition: XrdPss.cc:118
bool outProxy
Definition: XrdPss.cc:126
bool idMapAll
Definition: XrdPss.cc:124
thread_local XrdOucECMsg ecMsg("[pss]")
int rpFD
Definition: XrdPss.cc:122
static XrdPssSys XrdProxySS
Definition: XrdPss.cc:102
static const char * ofslclCGI
Definition: XrdPss.cc:116
XrdOucEnv * envP
Definition: XrdPss.cc:110