XRootD
XrdOssReloc.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d O s s R e l o c . c c */
4 /* */
5 /* (c) 2009 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 /******************************************************************************/
32 /* i n c l u d e s */
33 /******************************************************************************/
34 
35 #include <unistd.h>
36 #include <cerrno>
37 #include <fcntl.h>
38 #include <strings.h>
39 #include <cstdio>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 #include <sys/param.h>
43 
44 #include "XrdOss/XrdOssApi.hh"
45 #include "XrdOss/XrdOssCache.hh"
46 #include "XrdOss/XrdOssConfig.hh"
47 #include "XrdOss/XrdOssCopy.hh"
48 #include "XrdOss/XrdOssError.hh"
49 #include "XrdOss/XrdOssPath.hh"
50 #include "XrdOss/XrdOssSpace.hh"
51 #include "XrdOss/XrdOssTrace.hh"
52 #include "XrdOuc/XrdOucUtils.hh"
53 #include "XrdSys/XrdSysError.hh"
54 #include "XrdSys/XrdSysHeaders.hh"
55 #include "XrdSys/XrdSysPlatform.hh"
56 
57 /******************************************************************************/
58 /* E r r o r R o u t i n g O b j e c t */
59 /******************************************************************************/
60 
61 extern XrdSysError OssEroute;
62 
63 extern XrdSysTrace OssTrace;
64 
65 extern XrdOssSys *XrdOssSS;
66 
67 /******************************************************************************/
68 /* R e l o c */
69 /******************************************************************************/
70 
71 /*
72  Function: Relocate/Copy the file at `path' to a new location.
73 
74  Input: path - The fully qualified name of the file to relocate.
75  cgName - Target space name[:path]
76  anchor - The base path where a symlink to the copied file is
77  to be created. If present, the original file is kept.
78  If anchor is "." then path is taken as pfn (not lfn)
79  and a pure relocation is performed.
80 
81  Output: Returns XrdOssOK upon success; (-errno) otherwise.
82 */
83 int XrdOssSys::Reloc(const char *tident, const char *path,
84  const char *cgName, const char *anchor)
85 {
86  EPNAME("Reloc")
87  const int AMode = S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH; // 775
88  class pendFiles
89  {public:
90  char *pbuff;
91  char *tbuff;
92  int datfd;
93  pendFiles(char *pb, char *tb) : datfd(-1)
94  {pbuff = pb; *pb = '\0';
95  tbuff = tb; *tb = '\0';
96  }
97  ~pendFiles() {if (datfd >= 0) close(datfd);
98  if (pbuff && *pbuff) unlink(pbuff);
99  if (tbuff && *tbuff) unlink(tbuff);
100  }
101  };
102  char cgNow[XrdOssSpace::minSNbsz], cgbuff[XrdOssSpace::minSNbsz];
103  char lbuff[MAXPATHLEN+8];
104  char pbuff[MAXPATHLEN+8];
105  char tbuff[MAXPATHLEN+8];
106  char local_path[MAXPATHLEN+8];
107  pendFiles PF(pbuff, tbuff);
108  XrdOssCache::allocInfo aInfo(path, pbuff, sizeof(pbuff));
109  int rc, lblen, datfd, Pure = (anchor && !strcmp(anchor, "."));
110  off_t rc_c;
111  struct stat buf;
112 
113 // Generate the actual local path for this file.
114 //
115  if (Pure) {strcpy(local_path, path); anchor = 0;}
116  else if ((rc = GenLocalPath(path, local_path))) return rc;
117 
118 // Determine the state of the file.
119 //
120  if (stat(local_path, &buf)) return -errno;
121  if ((buf.st_mode & S_IFMT) == S_IFDIR) return -EISDIR;
122  if ((buf.st_mode & S_IFMT) != S_IFREG) return -ENOTBLK;
123 
124 // Get the correct cache group and partition path
125 //
126  if ((aInfo.cgPath = XrdOssCache::Parse(cgName, cgbuff, sizeof(cgbuff))))
127  aInfo.cgPlen = strlen(aInfo.cgPath);
128 
129 // Verify that this file will go someplace other than where it is now
130 //
131  lblen = XrdOssPath::getCname(local_path, cgNow, lbuff, sizeof(lbuff)-7);
132  lbuff[lblen] = '\0';
133  if (!Pure && !strcmp(cgbuff, cgNow)
134  && (!aInfo.cgPath || !strncmp(aInfo.cgPath, lbuff, aInfo.cgPlen)))
135  return -EEXIST;
136 
137 // Allocate space in the cache. Note that the target must be an xa cache
138 //
139  aInfo.aMode = buf.st_mode & S_IAMB;
140  aInfo.cgSize = (Pure ? 0 : buf.st_size);
141  aInfo.cgName = cgbuff;
142  if ((PF.datfd = datfd = XrdOssCache::Alloc(aInfo)) < 0) return datfd;
143  if (!aInfo.cgPsfx) return -ENOTSUP;
144 
145 // Copy the original file to the new location. Copy() always closes the fd.
146 //
147  PF.datfd = -1;
148  if ((rc_c = XrdOssCopy::Copy(local_path, pbuff, datfd)) < 0) return (int)rc_c;
149 
150 // If the file is to be merely copied, substitute the desired destination
151 //
152  if (!anchor) {strcpy(tbuff, local_path); strcat(tbuff, ".anew");}
153  else {struct stat sbuf;
154  char *Slash;
155  if (strlen(anchor)+strlen(path) >= sizeof(local_path))
156  return -ENAMETOOLONG;
157  strcpy(local_path, anchor); strcat(local_path, path);
158  if (!(Slash = rindex(local_path, '/'))) return -ENOTDIR;
159  *Slash = '\0'; rc = stat(local_path, &sbuf); *Slash = '/';
160  if (rc && (rc = XrdOucUtils::makePath(local_path, AMode)))
161  return rc;
162  strcpy(tbuff, local_path);
163  }
164 
165 // Now create a symbolic link to the target
166 //
167  if ((symlink(pbuff, tbuff) && errno != EEXIST)
168  || unlink(tbuff) || symlink(pbuff, tbuff)) return -errno;
169 
170 // Rename the link atomically over the existing name
171 //
172  if (!anchor && rename(tbuff, local_path) < 0) return -errno;
173  PF.tbuff = 0; PF.pbuff = 0; rc = 0;
174 
175 // Issue warning if the pfn file could not be created (very very rare).
176 // At this point we can't do much about it.
177 //
178  if (rc) OssEroute.Emsg("Reloc", rc, "create symlink", pbuff);
179  *(aInfo.cgPsfx) = '\0';
180 
181 // If this was a copy operation, we are done
182 //
183  DEBUG(cgNow <<':' <<local_path <<" -> " <<aInfo.cgName <<':' <<pbuff);
184  if (anchor) return XrdOssOK;
185 
186 // Check if the original file was a symlink and that has to be deleted
187 // Adjust the space usage numbers at this point as well.
188 //
189  if (*lbuff)
190  {if (unlink(lbuff)) OssEroute.Emsg("Reloc",errno,"removing",lbuff);
191  XrdOssCache::Adjust(XrdOssCache::Find(lbuff, lblen), -buf.st_size);
192  } else XrdOssCache::Adjust(buf.st_dev, -buf.st_size);
193 
194 // All done (permanently adjust usage for the target)
195 //
196  XrdOssCache::Adjust(aInfo.cgFSp, buf.st_size);
197  return XrdOssOK;
198 }
#define tident
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
#define S_IAMB
Definition: XrdConfig.cc:159
XrdSysTrace OssTrace
XrdOssSys * XrdOssSS
Definition: XrdOssApi.cc:77
XrdSysError OssEroute
#define XrdOssOK
Definition: XrdOss.hh:50
int stat(const char *path, struct stat *buf)
int unlink(const char *path)
int rename(const char *oldpath, const char *newpath)
#define close(a)
Definition: XrdPosix.hh:43
static int Alloc(allocInfo &aInfo)
Definition: XrdOssCache.cc:492
static char * Parse(const char *token, char *cbuff, int cblen)
Definition: XrdOssCache.cc:814
static XrdOssCache_FS * Find(const char *Path, int lklen=0)
Definition: XrdOssCache.cc:611
static void Adjust(dev_t devid, off_t size)
Definition: XrdOssCache.cc:397
static off_t Copy(const char *inFn, const char *outFn, int outFD)
Definition: XrdOssCopy.cc:59
static int getCname(const char *path, char *Cache, char *lbuf=0, int lbsz=0)
Definition: XrdOssPath.cc:241
static const int minSNbsz
Definition: XrdOssSpace.hh:45
int GenLocalPath(const char *, char *)
Definition: XrdOssApi.cc:232
int Reloc(const char *tident, const char *path, const char *cgName, const char *anchor=0)
Definition: XrdOssReloc.cc:83
static int makePath(char *path, mode_t mode, bool reset=false)
Definition: XrdOucUtils.cc:917
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
XrdOssCache_FS * cgFSp
Definition: XrdOssCache.hh:231