XRootD
Loading...
Searching...
No Matches
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"
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"
56
57/******************************************************************************/
58/* E r r o r R o u t i n g O b j e c t */
59/******************************************************************************/
60
62
64
65extern 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*/
83int 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)
#define EPNAME(x)
#define S_IAMB
Definition XrdConfig.cc:159
XrdSysError OssEroute
XrdSysTrace OssTrace
XrdOssSys * XrdOssSS
Definition XrdOssApi.cc:77
XrdSysError OssEroute
#define XrdOssOK
Definition XrdOss.hh:50
#define close(a)
Definition XrdPosix.hh:43
#define unlink(a)
Definition XrdPosix.hh:108
#define stat(a, b)
Definition XrdPosix.hh:96
#define rename(a, b)
Definition XrdPosix.hh:87
static int Alloc(allocInfo &aInfo)
static char * Parse(const char *token, char *cbuff, int cblen)
static XrdOssCache_FS * Find(const char *Path, int lklen=0)
static void Adjust(dev_t devid, off_t size)
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)
static const int minSNbsz
int GenLocalPath(const char *, char *)
Definition XrdOssApi.cc:232
int Reloc(const char *tident, const char *path, const char *cgName, const char *anchor=0)
static int makePath(char *path, mode_t mode, bool reset=false)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
XrdOssCache_FS * cgFSp