XRootD
Loading...
Searching...
No Matches
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
54#include "XrdPss/XrdPss.hh"
55#include "XrdPss/XrdPssTrace.hh"
57#include "XrdPss/XrdPssUtils.hh"
63
64#include "XrdOss/XrdOssError.hh"
65#include "XrdOuc/XrdOucEnv.hh"
72#include "XrdSys/XrdSysError.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
96class XrdScheduler;
97
98namespace XrdProxy
99{
100thread_local XrdOucECMsg ecMsg("[pss]");
101
103
104 XrdSysError eDest(0, "pss_");
105
107
109
111
113
114 XrdSecsssID *idMapper = 0; // -> Auth ID mapper
115
116static const char *ofslclCGI = "ofs.lcl=1";
117
118static const char *osslclCGI = "oss.lcl=1";
119
120static 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}
132using 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//
143extern "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
166XrdPssSys::XrdPssSys() : HostArena(0), LocalRoot(0), theN2N(0), DirFlags(0),
167 myVersion(&XrdVERSIONINFOVAR(XrdOssGetStorageSystem2)),
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*/
183int 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
225int 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*/
274int 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
320int 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)
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
374bool 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
387int 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
395const 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
419int 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*/
458int 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*/
506int 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
559int 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*/
610int 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
628int XrdPssSys::Truncate(const char *path, unsigned long long flen,
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*/
669int 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*/
719int 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*/
780int 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/******************************************************************************/
804int 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*/
824int 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
850bool 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*/
878int 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);
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 {
992 XrdPosixInfo Info;
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*/
1022int 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//
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
1052bool 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
1081ssize_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
1137ssize_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
1202ssize_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
1226ssize_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
1244ssize_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
1287ssize_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
1307ssize_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
1325int XrdPssFile::Fctl(int cmd, int alen, const char *args, char **resp)
1326{
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)
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
1380int 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*/
1503int 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
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
1530int 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
1557int 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
1621int 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}
#define ENOATTR
XrdAccAuthorize * Authorize
Definition XrdAccTest.cc:61
#define tident
#define DEBUG(x)
#define EPNAME(x)
struct stat Stat
Definition XrdCks.cc:49
#define O_DIRECT
Definition XrdCrc32c.cc:51
static XrdSysLogger Logger
static XrdSysError eDest(0,"crypto_")
#define XRDOSS_E8002
#define XRDOSS_E8003
#define XRDOSS_E8004
#define XRDOSS_E8001
#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
#define XRDEXP_FORCERO
#define XRDEXP_STAGE
std::string obfuscateAuth(const std::string &input)
#define DEBUGON
#define stat(a, b)
Definition XrdPosix.hh:101
#define IS_FWDPATH(x)
XrdOss * XrdOssGetStorageSystem2(XrdOss *native_oss, XrdSysLogger *Logger, const char *cFN, const char *parms, XrdOucEnv *envp)
Definition XrdPss.cc:145
XrdVERSIONINFO(XrdOssGetStorageSystem2, XrdPss)
#define isNOSTAGE(_x_)
Definition XrdPss.cc:88
#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)
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
char * Env(int &envlen)
Definition XrdOucEnv.hh:48
const XrdSecEntity * secEnv() const
Definition XrdOucEnv.hh:107
char * Get(const char *varname)
Definition XrdOucEnv.hh:69
void Put(const char *varname, const char *value)
Definition XrdOucEnv.hh:85
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
void EnvInfo(XrdOucEnv *envP) override
Definition XrdPss.cc:305
static XrdNetSecurity * Police[PolNum]
Definition XrdPss.hh:101
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 * Tident()
const char * getID()
void setID(const char *tid=0)
const char * thePath()
bool addCGI(const char *prot, char *buff, int blen)
static const char * valProt(const char *pname, int &plen, int adj=0)
const char * tident
Trace identifier always preset.
unsigned int ueid
Unique ID of entity instance.
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_")
XrdOucECMsg ecMsg("[pss]")
static const char * osslclCGI
Definition XrdPss.cc:118
bool outProxy
Definition XrdPss.cc:126
bool idMapAll
Definition XrdPss.cc:124
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