XRootD
XrdOssArc.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d O s s A r c . c c */
4 /* */
5 /* (c) 2023 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 <fcntl.h>
35 #include <sys/stat.h>
36 
37 #include "XrdVersion.hh"
38 #include "Xrd/XrdScheduler.hh"
39 
40 #include "XrdOssArc/XrdOssArc.hh"
46 
47 #include "XrdOuc/XrdOucEnv.hh"
48 #include "XrdOuc/XrdOucECMsg.hh"
49 
50 #include "XrdSec/XrdSecEntity.hh"
51 
52 #include "XrdSys/XrdSysE2T.hh"
53 #include "XrdSys/XrdSysError.hh"
54 #include "XrdSys/XrdSysPlatform.hh"
55 
56 /******************************************************************************/
57 /* G l o b a l O b j e c t s */
58 /******************************************************************************/
59 
61 {
63 
64 XrdOss* ossP = 0;
65 
67 
69 
70 XrdSysError Elog(0, "OssArc_");
71 
72 XrdSysTrace ArcTrace("OssArc");
73 
74 extern thread_local XrdOucECMsg ecMsg;
75 }
76 using namespace XrdOssArcGlobals;
77 
78 #define Neg(x) (x > 0 ? -x : x)
79 
80 /******************************************************************************/
81 /* X r d O s s A d d S t o r a g e S y s t e m 2 */
82 /******************************************************************************/
83 
84 // This function is called by the OFS layer to retrieve the Storage System
85 // object that wraps the previously loaded storage system object. The object
86 // returned is a storage system wrapper providing archive functionality.
87 //
89 
90 extern "C"
91 {
94  const char *config_fn,
95  const char *parms,
96  XrdOucEnv *envP)
97 {
98 // Activate our error message object
99 //
100  Elog.logger(Logger);
101 
102 // Allocate an instance of the OssArc object
103 //
104  ArcSS = new XrdOssArc(*curr_oss);
105  ossP = curr_oss;
106 
107 // Initialize it
108 //
109  if (ArcSS->InitArc(config_fn, parms, envP) != XrdOssOK)
110  {delete ArcSS;
111  return NULL;
112  }
113 
114 // Upon success, return it.
115 //
116  return (XrdOss*)ArcSS;
117 }
118 }
119 
120 /******************************************************************************/
121 /* C h m o d */
122 /******************************************************************************/
123 
124 int XrdOssArc::Chmod(const char *path, mode_t mode, XrdOucEnv *envP)
125 {
126 
127 // chmod is only valid for non-archive paths
128 //
129  if (XrdOssArcCompose::isMine(path))
130  {Elog.Emsg("Chmod", EROFS, "chmod using", path);
131  return -EROFS;
132  }
133 
134 // Pass this through
135 //
136  return wrapPI.Chmod(path, mode, envP);
137 }
138 
139 /******************************************************************************/
140 /* C r e a t e */
141 /******************************************************************************/
142 
143 int XrdOssArc::Create(const char* tid, const char* path, mode_t mode,
144  XrdOucEnv& env, int opts)
145 {
146 
147 // Create is only valid for non-archive paths
148 //
149  if (XrdOssArcCompose::isMine(path))
150  {Elog.Emsg("create", EROFS, "create file using", path);
151  return -EROFS;
152  }
153 
154 // Pass this through
155 //
156  return wrapPI.Create(tid, path, mode, env, opts);
157 }
158 
159 /******************************************************************************/
160 /* F e a t u r e s */
161 /******************************************************************************/
162 
164 {
165  return XRDOSS_HASXERT | wrapPI.Features();
166 }
167 
168 /******************************************************************************/
169 /* F S c t l */
170 /******************************************************************************/
171 
172 int XrdOssArc:: FSctl(int cmd, int alen, const char *args, char **resp)
173 {
174 // Pass this through
175 //
176  return wrapPI.FSctl(cmd, alen, args, resp);
177 }
178 
179 /******************************************************************************/
180 /* g e t E r r M s g */
181 /******************************************************************************/
182 
183 bool XrdOssArc::getErrMsg(std::string& eText)
184 {
185 // Return any extened error mesage associated with this thread
186 //
187  if (ecMsg.hasMsg())
188  {ecMsg.Get(eText);
189  return true;
190  }
191  return false;
192 }
193 
194 /******************************************************************************/
195 /* I n i t A r c */
196 /******************************************************************************/
197 
198 /*
199  Function: Initialize staging subsystem
200 
201  Input: None
202 
203  Output: Returns zero upon success otherwise (-errno).
204 */
205 int XrdOssArc::InitArc(const char* configfn, const char* parms, XrdOucEnv* envP)
206 {
207  const char *ending = "completed.";
208  int retc = EINVAL;
209 
210 // Obtain pointer to the scheduler. If missing allocate one.
211 //
212  if (!envP || !(schedP = (XrdScheduler*)envP->GetPtr("XrdScheduler*")))
213  {schedP = new XrdScheduler;
214  schedP->Start();
215  }
216 
217 // Print herald
218 //
219  Elog.Say("++++++ Archive Storage System initialization started.");
220 
221 // Configure the subsystems
222 //
223  if ( (!Config.Configure(configfn, parms, envP)) ) ending = "failed!";
224  else retc = XrdOssOK;
225 
226 // Print closing herald
227 //
228  Elog.Say("------ Archive Storage System initialization ", ending);
229 
230 // All done.
231 //
232  return retc;
233 }
234 
235 /******************************************************************************/
236 /* L f n 2 P f n v 1 */
237 /******************************************************************************/
238 
239 int XrdOssArc::Lfn2Pfn(const char *Path, char *buff, int blen)
240 {
241  int rc = 0;
242 
243 // Use v2 version to generate the Pfn
244 //
245  if (Lfn2Pfn(Path, buff, blen, rc) == Path && !rc)
246  {if ((int)strlen(Path) >= blen) rc = -ENAMETOOLONG;
247  else strcpy(buff, Path);
248  }
249  return rc;
250 }
251 
252 /******************************************************************************/
253 /* L f n 2 P f n v 2 */
254 /******************************************************************************/
255 
256 const char *XrdOssArc::Lfn2Pfn(const char *Path, char *buff, int blen, int &rc)
257 {
258 
259 // The caller typically needs the LFN2PFN mapping to handle file attributes,
260 // checksums, and prepare requests. All of these are disallowed for our
261 // internal paths so we simply fail the mapping here.
262 //
264  {rc = -EPERM;
265  return 0;
266  }
267 
268 // Use the underlying mapping.
269 //
270  return wrapPI.Lfn2Pfn(Path, buff, blen, rc);
271 }
272 
273 /******************************************************************************/
274 /* M k d i r */
275 /******************************************************************************/
276 
277 int XrdOssArc::Mkdir(const char *path, mode_t mode, int mkpath, XrdOucEnv *envP)
278 {
279 
280 // mkdir is only valid for non-archive paths
281 //
282  if (XrdOssArcCompose::isMine(path))
283  {Elog.Emsg("Mkdir", EROFS, "create directory using", path);
284  return -EROFS;
285  }
286 
287 // Pass this through
288 //
289  return wrapPI.Mkdir(path, mode, mkpath, envP);
290 }
291 
292 /******************************************************************************/
293 /* R e m d i r */
294 /******************************************************************************/
295 
296 int XrdOssArc::Remdir(const char *path, int Opts, XrdOucEnv *envP)
297 {
298 
299 // Remdir is only valid for non-archive paths
300 //
301  if (XrdOssArcCompose::isMine(path))
302  {Elog.Emsg("Remdir", EROFS, "remove", path);
303  return -EROFS;
304  }
305 
306 // Pass this through
307 //
308  return wrapPI.Remdir(path, Opts, envP);
309 }
310 
311 /******************************************************************************/
312 /* R e n a m e */
313 /******************************************************************************/
314 
315 int XrdOssArc::Rename(const char *oldname, const char *newname,
316  XrdOucEnv *old_env, XrdOucEnv *new_env)
317 {
318 
319 // Rename is only valid for non-archive paths
320 //
321  if (XrdOssArcCompose::isMine(oldname) || (XrdOssArcCompose::isMine(newname)))
322  {Elog.Emsg("Rename", EROFS, "rename", newname);
323  return -EROFS;
324  }
325 
326 // Pass this through
327 //
328  return wrapPI.Rename(oldname, newname, old_env, new_env);
329 }
330 
331 /******************************************************************************/
332 /* S t a t */
333 /******************************************************************************/
334 
335 int XrdOssArc::Stat(const char *path, struct stat *Stat,
336  int opts, XrdOucEnv *envP)
337 {
338  TraceInfo("Stat", 0);
339  char buff[MAXPATHLEN];
340  int rc;
341 
342 // Prepare to process the archive/backup request
343 //
344  XrdOssArcCompose dsInfo(path, envP, rc, false, true);
345 
346 // Make sure all went well
347 //
348  if (rc)
349  {if (rc != EDOM)
350  {Elog.Emsg("Stat", rc, "locate", path);
351  return -rc;
352  }
353  return wrapPI.Stat(path, Stat, opts, envP);
354  }
355 
356 // If this is a stat for an archive, we can do this here
357 //
358  if (dsInfo.didType == dsInfo.isARC)
359  {if ((rc = dsInfo.ArcPath(buff, sizeof(buff), true))) return -rc;
360  if (stat(buff, Stat))
361  {rc = errno;
362  DEBUG("Stat archive "<<buff<<" failed; "<<XrdSysE2T(rc));
363  return -rc;
364  }
365  return XrdOssOK;
366  }
367 
368 // The person want to stat a particular file in an archive. The most sensible
369 // way to do this is to ask the DM system for than information.
370 //
371  if ((rc = dsInfo.Stat(dsInfo.flScope.c_str(), dsInfo.flName.c_str(), Stat)))
372  {DEBUG("Stat file "<<dsInfo.flScope.c_str()<<':'<<dsInfo.flName.c_str()
373  <<" failed; "<<XrdSysE2T(rc));
374  return -rc;
375  }
376  return XrdOssOK;
377 }
378 
379 /******************************************************************************/
380 /* T r u n c a t e */
381 /******************************************************************************/
382 
383 int XrdOssArc::Truncate(const char *path, unsigned long long size,
384  XrdOucEnv *envP)
385 {
386 
387 // Truncate is only valid for non-archive paths
388 //
389  if (XrdOssArcCompose::isMine(path))
390  {Elog.Emsg("Truncate", EROFS, "truncate", path);
391  return -EROFS;
392  }
393 
394 // Pass this through
395 //
396  return wrapPI.Truncate(path, size, envP);
397 }
398 
399 /******************************************************************************/
400 /* U n l i n k */
401 /******************************************************************************/
402 
403 int XrdOssArc::Unlink(const char* path, int Opts, XrdOucEnv* envP)
404 {
405 
406 // Unlink is only valid for non-archive paths
407 //
408  if (XrdOssArcCompose::isMine(path))
409  {Elog.Emsg("Rename", EROFS, "remove", path);
410  return -EROFS;
411  }
412 
413 // Pass this through
414 //
415  return wrapPI.Unlink(path, Opts, envP);
416 }
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
struct stat Stat
Definition: XrdCks.cc:49
#define TraceInfo(x, y)
XrdVERSIONINFO(XrdOssAddStorageSystem2, XrdOssArc) extern "C"
Definition: XrdOssArc.cc:88
XrdOss * XrdOssAddStorageSystem2(XrdOss *curr_oss, XrdSysLogger *Logger, const char *config_fn, const char *parms, XrdOucEnv *envP)
Definition: XrdOssCsi.cc:455
#define XRDOSS_HASXERT
Definition: XrdOss.hh:543
#define XrdOssOK
Definition: XrdOss.hh:54
#define stat(a, b)
Definition: XrdPosix.hh:105
XrdOucString Path
struct myOpts opts
const char * XrdSysE2T(int errcode)
Definition: XrdSysE2T.cc:104
static int Stat(const char *Scope, const char *Name, struct stat *Stat)
static bool isMine(const char *path)
int ArcPath(char *buff, int blen, bool addafn=false)
bool Configure(const char *cfn, const char *parms, XrdOucEnv *envP)
virtual int Chmod(const char *path, mode_t mode, XrdOucEnv *envP=0) override
Definition: XrdOssArc.cc:124
virtual int Remdir(const char *path, int Opts=0, XrdOucEnv *envP=0) override
Definition: XrdOssArc.cc:296
virtual int Rename(const char *oPath, const char *nPath, XrdOucEnv *oEnvP=0, XrdOucEnv *nEnvP=0) override
Definition: XrdOssArc.cc:315
virtual bool getErrMsg(std::string &eText) override
Definition: XrdOssArc.cc:183
virtual int Mkdir(const char *path, mode_t mode, int mkpath=0, XrdOucEnv *envP=0) override
Definition: XrdOssArc.cc:277
virtual int Truncate(const char *path, unsigned long long fsize, XrdOucEnv *envP=0) override
Definition: XrdOssArc.cc:383
virtual int Lfn2Pfn(const char *Path, char *buff, int blen) override
Definition: XrdOssArc.cc:239
virtual uint64_t Features() override
Definition: XrdOssArc.cc:163
virtual int FSctl(int cmd, int alen, const char *args, char **resp=0) override
Definition: XrdOssArc.cc:172
virtual int Stat(const char *path, struct stat *buff, int opts=0, XrdOucEnv *envP=0) override
Definition: XrdOssArc.cc:335
int InitArc(const char *, const char *parms, XrdOucEnv *envP)
Definition: XrdOssArc.cc:205
virtual int Unlink(const char *path, int Opts=0, XrdOucEnv *envP=0) override
Definition: XrdOssArc.cc:403
virtual int Create(const char *tid, const char *path, mode_t mode, XrdOucEnv &env, int opts=0) override
Definition: XrdOssArc.cc:143
bool hasMsg() const
Definition: XrdOucECMsg.hh:73
int Get(std::string &ecm, bool rst=true)
Definition: XrdOucECMsg.cc:41
void * GetPtr(const char *varname)
Definition: XrdOucEnv.cc:281
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:116
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
XrdSysLogger Logger
Definition: XrdGlobals.cc:47
int Opts
Definition: XrdMpxStats.cc:58
thread_local XrdOucECMsg ecMsg
XrdOssArcConfig Config
Definition: XrdOssArc.cc:68
XrdOssArc * ArcSS
Definition: XrdOssArc.cc:62
XrdOss * ossP
Definition: XrdOssArc.cc:64
XrdSysTrace ArcTrace("OssArc")
XrdScheduler * schedP
Definition: XrdOssArc.cc:66
XrdSysError Elog(0, "OssArc_")
XrdOucEnv * envP
Definition: XrdPss.cc:110