XrdOssReloc.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                        X r d O s s R e l o c . c c                         */
00004 /*                                                                            */
00005 /* (c) 2009 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010   
00011 //         $Id: XrdOssReloc.cc 28902 2009-06-11 12:36:21Z ganis $
00012 
00013 const char *XrdOssRelocCVSID = "$Id: XrdOssReloc.cc 28902 2009-06-11 12:36:21Z ganis $";
00014 
00015 /******************************************************************************/
00016 /*                             i n c l u d e s                                */
00017 /******************************************************************************/
00018   
00019 #include <unistd.h>
00020 #include <errno.h>
00021 #include <fcntl.h>
00022 #include <strings.h>
00023 #include <stdio.h>
00024 #include <sys/stat.h>
00025 #include <sys/types.h>
00026 #include <sys/param.h>
00027 
00028 #include "XrdOss/XrdOssApi.hh"
00029 #include "XrdOss/XrdOssCache.hh"
00030 #include "XrdOss/XrdOssConfig.hh"
00031 #include "XrdOss/XrdOssCopy.hh"
00032 #include "XrdOss/XrdOssError.hh"
00033 #include "XrdOss/XrdOssPath.hh"
00034 #include "XrdOss/XrdOssSpace.hh"
00035 #include "XrdOss/XrdOssTrace.hh"
00036 #include "XrdOuc/XrdOucUtils.hh"
00037 #include "XrdSys/XrdSysError.hh"
00038 #include "XrdSys/XrdSysHeaders.hh"
00039 #include "XrdSys/XrdSysPlatform.hh"
00040 
00041 /******************************************************************************/
00042 /*                  E r r o r   R o u t i n g   O b j e c t                   */
00043 /******************************************************************************/
00044   
00045 extern XrdSysError OssEroute;
00046 
00047 extern XrdOucTrace OssTrace;
00048 
00049 extern XrdOssSys  *XrdOssSS;
00050 
00051 /******************************************************************************/
00052 /*                                 R e l o c                                  */
00053 /******************************************************************************/
00054 
00055 /*
00056   Function: Relocate/Copy the file at `path' to a new location.
00057 
00058   Input:    path        - The fully qualified name of the file to relocate.
00059             cgName      - Target space name[:path]
00060             anchor      - The base path where a symlink to the copied file is
00061                           to be created. If present, the original file is kept.
00062 
00063   Output:   Returns XrdOssOK upon success; (-errno) otherwise.
00064 */
00065 int XrdOssSys::Reloc(const char *tident, const char *path,
00066                      const char *cgName, const char *anchor)
00067 {
00068    EPNAME("Reloc")
00069    const int AMode = S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH; // 775
00070    class pendFiles
00071         {public:
00072          char *pbuff;
00073          char *tbuff;
00074          int   datfd;
00075                pendFiles(char *pb, char *tb) : datfd(-1)
00076                            {pbuff = pb; *pb = '\0';
00077                             tbuff = tb; *tb = '\0';
00078                            }
00079               ~pendFiles() {if (datfd >= 0) close(datfd);
00080                             if (pbuff && *pbuff) unlink(pbuff);
00081                             if (tbuff && *tbuff) unlink(tbuff);
00082                            }
00083         };
00084    char cgNow[XrdOssSpace::minSNbsz], cgbuff[XrdOssSpace::minSNbsz];
00085    char lbuff[MAXPATHLEN+8];
00086    char pbuff[MAXPATHLEN+8];
00087    char tbuff[MAXPATHLEN+8];
00088    char local_path[MAXPATHLEN+8];
00089    pendFiles PF(pbuff, tbuff);
00090    XrdOssCache::allocInfo aInfo(path, pbuff, sizeof(pbuff));
00091    int rc, lblen, datfd;
00092    struct stat buf;
00093 
00094 // Generate the actual local path for this file.
00095 //
00096    if ((rc = GenLocalPath(path, local_path))) return rc;
00097 
00098 // Determine the state of the file.
00099 //
00100    if (stat(local_path, &buf)) return -errno;
00101    if ((buf.st_mode & S_IFMT) == S_IFDIR) return -EISDIR;
00102    if ((buf.st_mode & S_IFMT) != S_IFREG) return -ENOTBLK;
00103 
00104 // Get the correct cache group and partition path
00105 //
00106    if ((aInfo.cgPath = XrdOssCache::Parse(cgName, cgbuff, sizeof(cgbuff))))
00107       aInfo.cgPlen = strlen(aInfo.cgPath);
00108 
00109 // Verify that this file will go someplace other than where it is now
00110 //
00111    lblen = XrdOssPath::getCname(local_path, cgNow, lbuff, sizeof(lbuff)-7);
00112    lbuff[lblen] = '\0';
00113    if (!strcmp(cgbuff, cgNow)
00114    && (!aInfo.cgPath || !strncmp(aInfo.cgPath, lbuff, aInfo.cgPlen)))
00115       return -EEXIST;
00116 
00117 // Allocate space in the cache. Note that the target must be an xa cache
00118 //
00119    aInfo.aMode  = buf.st_mode & S_IAMB;
00120    aInfo.cgSize = buf.st_size;
00121    aInfo.cgName = cgbuff;
00122    if ((PF.datfd = datfd = XrdOssCache::Alloc(aInfo)) < 0) return datfd;
00123    if (!aInfo.cgPsfx) return -ENOTSUP;
00124 
00125 // Copy the original file to the new location
00126 //
00127    if (XrdOssCopy::Copy(path, pbuff, datfd) < 0) return -EIO;
00128    close(datfd); PF.datfd = -1;
00129 
00130 // If the file is to be merely copied, substitute the desired destination
00131 //
00132    if (!anchor) {strcpy(tbuff, local_path); strcat(tbuff, ".anew");}
00133       else {struct stat sbuf;
00134             char *Slash;
00135             if (strlen(anchor)+strlen(path) >= sizeof(local_path))
00136                return -ENAMETOOLONG;
00137             strcpy(local_path, anchor); strcat(local_path, path);
00138             if (!(Slash = rindex(local_path, '/'))) return -ENOTDIR;
00139             *Slash = '\0'; rc = stat(local_path, &sbuf); *Slash = '/';
00140             if (rc && (rc = XrdOucUtils::makePath(local_path, AMode)))
00141                return rc;
00142             strcpy(tbuff, local_path);
00143            }
00144 
00145 // Now create a symbolic link to the target
00146 //
00147    if ((symlink(pbuff, tbuff) && errno != EEXIST)
00148    || unlink(tbuff) || symlink(pbuff, tbuff)) return -errno;
00149 
00150 // Rename the link atomically over the existing name
00151 //
00152    if (!anchor && rename(tbuff, local_path) < 0) return -errno;
00153    PF.tbuff = 0; PF.pbuff = 0;
00154 
00155 // Now create a symlink from the cache pfn to the actual path (xa only)
00156 //
00157    strcpy(aInfo.cgPsfx, ".pfn"); rc = 0;
00158    if ((symlink(local_path, pbuff) && errno != EEXIST)
00159    || unlink(pbuff) || symlink(local_path, pbuff)) rc = errno;
00160 
00161 // Issue warning if the pfn file could not be created (very very rare).
00162 // At this point we can't do much about it.
00163 //
00164    if (rc) OssEroute.Emsg("Reloc", rc, "create symlink", pbuff);
00165    *(aInfo.cgPsfx) = '\0';
00166 
00167 // If this was a copy operation, we are done
00168 //
00169    DEBUG(cgNow <<':' <<local_path <<" -> " <<aInfo.cgName <<':' <<pbuff);
00170    if (anchor) return XrdOssOK;
00171 
00172 // Check if the original file was a symlink and that has to be deleted
00173 // Adjust the space usage numbers at this point as well.
00174 //
00175    if (*lbuff)
00176       {if (unlink(lbuff))     OssEroute.Emsg("Reloc",errno,"removing",lbuff);
00177        if (XrdOssPath::isXA(lbuff))
00178           {strcat(lbuff, ".pfn");
00179            if (unlink(lbuff)) OssEroute.Emsg("Reloc",errno,"removing",lbuff);
00180           }
00181        XrdOssCache::Adjust(XrdOssCache::Find(lbuff, lblen), -buf.st_size);
00182        } else XrdOssCache::Adjust(buf.st_dev, -buf.st_size);
00183 
00184 // All done (permanently adjust usage for the target)
00185 //
00186    XrdOssCache::Adjust(aInfo.cgFSp, buf.st_size);
00187    return XrdOssOK;
00188 }

Generated on Tue Jul 5 14:46:48 2011 for ROOT_528-00b_version by  doxygen 1.5.1