XRootD
XrdOssArcFile.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d O s s A r c F i l e . c c */
4 /* */
5 /* (c) 2024 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 
43 
44 #include "XrdOuc/XrdOucEnv.hh"
45 #include "XrdOuc/XrdOucECMsg.hh"
46 
47 #include "XrdSys/XrdSysError.hh"
48 #include "XrdSys/XrdSysFD.hh"
49 #include "XrdSys/XrdSysPlatform.hh"
50 
51 /******************************************************************************/
52 /* G l o b a l O b j e c t s */
53 /******************************************************************************/
54 
55 namespace XrdOssArcGlobals
56 {
57 extern XrdOss* ossP;
58 
59 extern XrdOssArcConfig Config;
60 
61 extern XrdSysError Elog;
62 
63 extern XrdSysTrace ArcTrace;
64 
65 extern thread_local XrdOucECMsg ecMsg;
66 }
67 using namespace XrdOssArcGlobals;
68 
69 #define Neg(x) (x > 0 ? -x : x)
70 
71 /******************************************************************************/
72 /* D e s t r u c t o r */
73 /******************************************************************************/
74 
76 { delete ossDF;
77  if (zFile) delete zFile;
78 }
79 
80 /******************************************************************************/
81 /* C l o s e */
82 /******************************************************************************/
83 
84 int XrdOssArcFile::Close(long long *retsz)
85 {
86  int rc;
87 
88 // Issue close to possible zipfile appendage and delete it. The underlying
89 // oss did not open the file, so we do not issue a close to that.
90 //
91  if (zFile)
92  {rc = zFile->Close();
93  if (retsz) *retsz = 0;
94  delete zFile;
95  zFile = 0;
96  } else rc = ossDF->Close(retsz);
97 
98 // All done
99 //
100  return rc;
101 }
102 
103 /******************************************************************************/
104 /* f s t a t */
105 /******************************************************************************/
106 
107 int XrdOssArcFile::Fstat(struct stat* buf)
108 {
109 // Check if we should forward this call
110 //
111  if (zFile == 0) return ossDF->Fstat(buf);
112 
113 // Obtain stat for the archive file member
114 //
115  return zFile->Stat(*buf);
116 }
117 
118 /******************************************************************************/
119 /* g e t E r r M s g */
120 /******************************************************************************/
121 
122 bool XrdOssArcFile::getErrMsg(std::string& eText)
123 {
124 // Return any extened error mesage associated with this thread
125 //
126  if (ecMsg.hasMsg())
127  {std::string xMsg;
128  if (ossDF->getErrMsg(xMsg))
129  {ecMsg.Append();
130  ecMsg.Msg("oss", xMsg.c_str());
131  }
132  ecMsg.Get(eText);
133  return true;
134  }
135  return ossDF->getErrMsg(eText);
136 }
137 
138 /******************************************************************************/
139 /* O p e n */
140 /******************************************************************************/
141 
142 int XrdOssArcFile::Open(const char *path,int Oflag,mode_t Mode,XrdOucEnv &env)
143 {
144  int rc, arcFD;
145  bool isRW = (Oflag & (O_APPEND|O_CREAT|O_TRUNC|O_WRONLY|O_RDWR)) != 0;
146 
147 // Check what we should be doing here. Options are:
148 // a) Forward open to underlying storage system (not our path),
149 // b) Handle and error,
150 // c) Open an actual arvhive, or
151 // d) Open a file inside an archive.
152 //
153  XrdOssArcCompose dsInfo(path, &env, rc, isRW);
154 
155  if (rc == EDOM) return ossDF->Open(path, Oflag, Mode, env);
156  if (rc != 0) return -rc;
157 
158 // We will be doing a MSS orinted restore. This is subject to pausing.
159 // So, we must run under the control of the stop monitor.
160 //
162 
163 // Whether this is a request for an archve or a file in the archive, we
164 // need to bring the archive file online. We do this first.
165 //
166  char arcPath[MAXPATHLEN];
167  if ((rc = dsInfo.ArcPath(arcPath, sizeof(arcPath), true))) return -rc;
168  if ((rc = XrdOssArcStage::Stage(arcPath, arcPath+Config.tapePathLEN)))
169  {if (rc == EINPROGRESS) return Config.wtpStage;
170  return -rc;
171  }
172 
173 // If this was a request for the actual archive file, then open it and promote
174 // the open to the underlying file system as it will handle all I/O.
175 //
176  if (dsInfo.didType == XrdOssArcCompose::isARC)
177  {if ((arcFD = XrdSysFD_Open(arcPath, O_RDONLY, Mode)) < 0)
178  {rc = errno;
179  Elog.Emsg("open", rc, "open", arcPath);
180  return -rc;
181  }
182  rc = ossDF->Fctl(XrdOssDF::Fctl_setFD,sizeof(int),(const char*)&arcFD);
183  if (rc)
184  {Elog.Emsg("open", rc, "promote open", arcPath);
185  close(arcFD);
186  return Neg(rc);
187  }
188  return XrdOssOK;
189  }
190 
191 // Create the name of the archive member in the archive file
192 //
193  char arcMember[MAXPATHLEN];
194  if ((rc = dsInfo.ArcMember(arcMember, sizeof(arcMember)))) return -rc;
195 
196 // This is a request for a particular file. Get a zip file object and open it.
197 //
198  zFile = new XrdOssArcZipFile(arcPath, rc);
199 
200 // Open the member in the archive if possibe
201 //
202  if (!rc) rc = zFile->Open(arcMember);
203 
204 // Diagnose any errors
205 //
206  if (rc)
207  {Elog.Emsg("open", rc, "open archive", path);
208  ecMsg.Msg("open", "Unable to access member", arcMember, "in archive",
209  arcPath);
210  delete zFile; zFile = 0;
211  return Neg(rc);
212  }
213  return 0;
214 }
215 
216 /******************************************************************************/
217 /* R e a d */
218 /******************************************************************************/
219 
220 ssize_t XrdOssArcFile::Read(void *buffer, off_t offset, size_t size)
221 {
222 // Execute read based on what kind of file we currently have
223 //
224  if (zFile) return zFile->Read(buffer, offset, size);
225  return ossDF->Read(buffer, offset, size);
226 }
227 
228 /******************************************************************************/
229 /* W r i t e */
230 /******************************************************************************/
231 
232 // Write calls are valid for regular files but not for archive files
233 //
234 ssize_t XrdOssArcFile::Write(const void *buffer, off_t offset, size_t size)
235 {
236 // Execute read based on what kind of file we currently have
237 //
238  if (zFile) return -EBADF;
239  return ossDF->Write(buffer, offset, size);
240 }
#define Neg(x)
#define XrdOssOK
Definition: XrdOss.hh:54
#define close(a)
Definition: XrdPosix.hh:48
#define stat(a, b)
Definition: XrdPosix.hh:105
int Mode
int ArcMember(char *buff, int blen)
int ArcPath(char *buff, int blen, bool addafn=false)
XrdOssArcStopMon * stopMon
virtual ~XrdOssArcFile()
int Open(const char *path, int Oflag, mode_t Mode, XrdOucEnv &env) override
int Close(long long *retsz=0) override
bool getErrMsg(std::string &eText) override
ssize_t Write(const void *buffer, off_t offset, size_t size) override
ssize_t Read(off_t offset, size_t size) override
int Fstat(struct stat *buf) override
static int Stage(const char *path, const char *mssPath)
static const int Fctl_setFD
Definition: XrdOss.hh:460
bool hasMsg() const
Definition: XrdOucECMsg.hh:73
std::string Msg()
Definition: XrdOucECMsg.hh:83
int Get(std::string &ecm, bool rst=true)
Definition: XrdOucECMsg.cc:41
XrdOucECMsg & Append(char dlm='\n')
Definition: XrdOucECMsg.hh:52
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:116
thread_local XrdOucECMsg ecMsg
XrdOssArcConfig Config
Definition: XrdOssArc.cc:68
XrdOss * ossP
Definition: XrdOssArc.cc:64
XrdSysTrace ArcTrace("OssArc")
XrdSysError Elog(0, "OssArc_")