XrdOssStat.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                         X r d O s s S t a t . c c                          */
00004 /*                                                                            */
00005 /* (c) 2008 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: XrdOssStat.cc 34000 2010-06-21 06:49:56Z ganis $
00012 
00013 const char *XrdOssStatCVSID = "$Id: XrdOssStat.cc 34000 2010-06-21 06:49:56Z ganis $";
00014 
00015 #include <unistd.h>
00016 #include <errno.h>
00017 #include <fcntl.h>
00018 #include <stdio.h>
00019 #include <strings.h>
00020 #include <time.h>
00021 #include <utime.h>
00022 #include <sys/param.h>
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 
00026 #include "XrdSys/XrdSysHeaders.hh"
00027 #include "XrdOss/XrdOssApi.hh"
00028 #include "XrdOss/XrdOssCache.hh"
00029 #include "XrdOss/XrdOssConfig.hh"
00030 #include "XrdOss/XrdOssOpaque.hh"
00031 #include "XrdOss/XrdOssPath.hh"
00032 #include "XrdOss/XrdOssSpace.hh"
00033 #include "XrdOuc/XrdOucEnv.hh"
00034 #include "XrdOuc/XrdOucName2Name.hh"
00035 #include "XrdOuc/XrdOucPList.hh"
00036 
00037 /******************************************************************************/
00038 /*                                 s t a t                                    */
00039 /******************************************************************************/
00040 
00041 /*
00042   Function: Determine if file 'path' actually exists.
00043 
00044   Input:    path        - Is the fully qualified name of the file to be tested.
00045             buff        - pointer to a 'stat' structure to hold the attributes
00046                           of the file.
00047 
00048   Output:   Returns XrdOssOK upon success and -errno upon failure.
00049 */
00050 
00051 int XrdOssSys::Stat(const char *path, struct stat *buff, int opts)
00052 {
00053     const int ro_Mode = ~(S_IWUSR | S_IWGRP | S_IWOTH);
00054     char actual_path[MAXPATHLEN+1], *local_path, *remote_path;
00055     unsigned long long popts;
00056     int retc;
00057 
00058 // Construct the processing options for this path
00059 //
00060    popts = PathOpts(path);
00061 
00062 // Generate local path
00063 //
00064    if (lcl_N2N)
00065       if ((retc = lcl_N2N->lfn2pfn(path, actual_path, sizeof(actual_path)))) 
00066          return retc;
00067          else local_path = actual_path;
00068       else local_path = (char *)path;
00069 
00070 // Stat the file in the local filesystem first. If there. make sure the mode
00071 // bits correspond to our reality and update access time if so requested.
00072 //
00073    if (!stat(local_path, buff)) 
00074       {if (popts & XRDEXP_NOTRW) buff->st_mode &= ro_Mode;
00075        if (opts & XRDOSS_updtatm && (buff->st_mode & S_IFMT) == S_IFREG)
00076           {struct utimbuf times;
00077            times.actime  = time(0);
00078            times.modtime = buff->st_mtime;
00079            utime(local_path, &times);
00080           }
00081        return XrdOssOK;
00082       }
00083 
00084 // The file may be offline in a mass storage system, check if this is possible
00085 //
00086    if (!IsRemote(path) || opts & XRDOSS_resonly) return -errno;
00087    if (!RSSCmd) return (popts & XRDEXP_NOCHECK ? -ENOENT : -ENOMSG);
00088 
00089 // Generate remote path
00090 //
00091    if (rmt_N2N)
00092       if ((retc = rmt_N2N->lfn2rfn(path, actual_path, sizeof(actual_path))))
00093          return retc;
00094          else remote_path = actual_path;
00095       else remote_path = (char *)path;
00096 
00097 // Now stat the file in the remote system (it doesn't exist locally)
00098 //
00099    if ((retc = MSS_Stat(remote_path, buff))) return retc;
00100    if (popts & XRDEXP_NOTRW) buff->st_mode &= ro_Mode;
00101    buff->st_mode |= S_IFBLK;
00102    return XrdOssOK;
00103 }
00104 
00105 /******************************************************************************/
00106 /*                                S t a t F S                                 */
00107 /******************************************************************************/
00108 
00109 /*
00110   Function: Return free space information based on a path
00111 
00112   Input:    path        - Is the fully qualified name of the file to be tested.
00113             buff        - pointer to a buffer to hold the information.
00114             blen        - the length of the buffer
00115 
00116   Output:   Returns XrdOssOK upon success and -errno upon failure.
00117             blen is updated with the actual length of the buff data.
00118 */
00119 
00120 int XrdOssSys::StatFS(const char *path, char *buff, int &blen)
00121 {
00122    int sVal, wVal, Util;
00123    long long fSpace, fSize;
00124    unsigned long long Opt;
00125 
00126 // Get the values for this file system
00127 //
00128    StatFS(path, Opt, fSize, fSpace);
00129    sVal = (Opt & XRDEXP_STAGE ? 1 : 0);
00130    wVal = (Opt & XRDEXP_NOTRW ? 0 : 1);
00131 
00132 // Size the value to fit in an int
00133 //
00134    if (fSpace <= 0) {fSize = fSpace = 0; Util = 0;}
00135       else {Util = (fSize ? (fSize - fSpace)*100LL/fSize : 0);
00136             fSpace = fSpace >> 20LL;
00137             if ((fSpace >> 31LL)) fSpace = 0x7fffffff;
00138            }
00139 
00140 // Return the result
00141 //
00142    blen = snprintf(buff, blen, "%d %lld %d %d %lld %d",
00143                                wVal, (wVal ? fSpace : 0LL), (wVal ? Util : 0),
00144                                sVal, (sVal ? fSpace : 0LL), (sVal ? Util : 0));
00145    return XrdOssOK;
00146 }
00147 
00148 /******************************************************************************/
00149 
00150 /*
00151   Function: Return free space information based on a path
00152 
00153   Input:    path        - Is the fully qualified name of the file to be tested.
00154             opt         - Options associated with the path
00155             fSize       - total bytes in the filesystem.
00156             fSpace      - total free bytes in the filesystem. It is set to
00157                           -1 if the path is not convertable.
00158 
00159   Output:   Returns XrdOssOK upon success and -errno upon failure.
00160 */
00161 
00162 int XrdOssSys::StatFS(const char *path, unsigned long long &Opt,
00163                       long long &fSize, long long &fSpace)
00164 {
00165 // Establish the path options
00166 //
00167    Opt = PathOpts(path);
00168 
00169 // For in-place paths we just get the free space in that partition, otherwise
00170 // get the maximum available in any partition.
00171 //
00172    if ((Opt & XRDEXP_STAGE) || !(Opt & XRDEXP_NOTRW))
00173       if ((Opt & XRDEXP_INPLACE) || !XrdOssCache_Group::fsgroups)
00174          {char lcl_path[MAXPATHLEN+1];
00175           if (lcl_N2N)
00176              if (lcl_N2N->lfn2pfn(path, lcl_path, sizeof(lcl_path)))
00177                 fSpace = -1;
00178                 else fSpace = XrdOssCache_FS::freeSpace(fSize, lcl_path);
00179              else    fSpace = XrdOssCache_FS::freeSpace(fSize, path);
00180          } else     {fSpace = XrdOssCache_FS::freeSpace(fSize);}
00181       else          {fSpace = 0;      fSize = 0;}
00182    return XrdOssOK;
00183 }
00184 
00185 /******************************************************************************/
00186 /*                                S t a t L S                                 */
00187 /******************************************************************************/
00188 
00189 /*
00190   Function: Return free space information based on a cahe group name.
00191 
00192   Input:    Env         - Is the environment for cgi info.
00193             path        - Is the path name.
00194             buff        - pointer to a buffer to hold the information.
00195             blen        - the length of the buffer
00196 
00197   Output:   Returns XrdOssOK upon success and -errno upon failure.
00198 */
00199 
00200 int XrdOssSys::StatLS(XrdOucEnv &env, const char *path, char *buff, int &blen)
00201 {
00202    static const char *Resp="oss.cgroup=%s&oss.space=%lld&oss.free=%lld"
00203                            "&oss.maxf=%lld&oss.used=%lld&oss.quota=%lld";
00204    struct stat sbuff;
00205    XrdOssCache_Space   CSpace;
00206    char *cgrp, cgbuff[XrdOssSpace::minSNbsz];
00207    int retc;
00208 
00209 // We provide psuedo support whould be not have a cache
00210 //
00211    if (!XrdOssCache_Group::fsgroups)
00212       {unsigned long long Opt;
00213        long long fSpace, fSize;
00214        StatFS(path, Opt, fSize, fSpace);
00215        if (fSpace < 0) fSpace = 0;
00216        blen = snprintf(buff, blen, Resp, "public", fSize, fSpace, fSpace,
00217                                    fSize-fSpace, XrdOssCache_Group::PubQuota);
00218        return XrdOssOK;
00219       }
00220 
00221 // Find the cache group. We provide psuedo support should we not have a cache
00222 //
00223    if (!(cgrp = env.Get(OSS_CGROUP)))
00224       {if ((retc = getCname(path, &sbuff, cgbuff))) return retc;
00225           else cgrp = cgbuff;
00226       }
00227 
00228 // Accumulate the stats and format the result
00229 //
00230    blen = (XrdOssCache_FS::getSpace(CSpace, cgrp)
00231         ? snprintf(buff,blen,Resp,cgrp,CSpace.Total,CSpace.Free,CSpace.Maxfree,
00232                                        CSpace.Usage,CSpace.Quota)
00233         : snprintf(buff, blen, Resp, cgrp, 0LL, 0LL, 0LL, 0LL, -1LL));
00234    return XrdOssOK;
00235 }
00236 
00237 /******************************************************************************/
00238 /*                                S t a t V S                                 */
00239 /******************************************************************************/
00240   
00241 /*
00242   Function: Return space information for space name "sname".
00243 
00244   Input:    sname       - The name of the same, null if all space wanted.
00245             sP          - pointer to XrdOssVSInfo to hold information.
00246 
00247   Output:   Returns XrdOssOK upon success and -errno upon failure.
00248             Note that quota is zero when sname is null.
00249 */
00250 
00251 int XrdOssSys::StatVS(XrdOssVSInfo *sP, const char *sname, int updt)
00252 {
00253    XrdOssCache_Space   CSpace;
00254 
00255 // Check if we should update the statistics
00256 //
00257    if (updt) XrdOssCache::Scan(0);
00258 
00259 // If no space name present or no spaces defined and the space is public then
00260 // return information on all spaces.
00261 //
00262    if (!sname || (!XrdOssCache_Group::fsgroups && !strcmp("public", sname)))
00263       {XrdOssCache::Mutex.Lock();
00264        sP->Total  = XrdOssCache::fsTotal;
00265        sP->Free   = XrdOssCache::fsTotFr;
00266        sP->LFree  = XrdOssCache::fsFree;
00267        sP->Large  = XrdOssCache::fsLarge;
00268        sP->Extents= XrdOssCache::fsCount;
00269        XrdOssCache::Mutex.UnLock();
00270        return XrdOssOK;
00271       }
00272 
00273 // Get the space stats
00274 //
00275    if (!(sP->Extents=XrdOssCache_FS::getSpace(CSpace,sname))) return -ENOENT;
00276 
00277 // Return the result
00278 //
00279    sP->Total = CSpace.Total;
00280    sP->Free  = CSpace.Free;
00281    sP->LFree = CSpace.Maxfree;
00282    sP->Large = CSpace.Largest;
00283    sP->Usage = CSpace.Usage;
00284    sP->Quota = CSpace.Quota;
00285    return XrdOssOK;
00286 }
00287 
00288 /******************************************************************************/
00289 /*                                S t a t X A                                 */
00290 /******************************************************************************/
00291   
00292 /*
00293   Function: Return extended attributes for "path".
00294 
00295   Input:    path        - Is the fully qualified name of the target file.
00296             buff        - pointer to a buffer to hold the information.
00297             blen        - the length of the buffer
00298 
00299   Output:   Returns XrdOssOK upon success and -errno upon failure.
00300             blen is updated with the actual length of the buff data.
00301 */
00302 
00303 int XrdOssSys::StatXA(const char *path, char *buff, int &blen)
00304 {
00305    struct stat sbuff;
00306    char cgbuff[XrdOssSpace::minSNbsz], fType;
00307    long long Size, Mtime, Ctime, Atime;
00308    int retc;
00309 
00310 // Get the cache group and stat info for the file
00311 //
00312    if ((retc = getCname(path, &sbuff, cgbuff))) return retc;
00313         if (S_ISREG(sbuff.st_mode)) fType = 'f';
00314    else if (S_ISDIR(sbuff.st_mode)) fType = 'd';
00315    else                             fType = 'o';
00316 
00317 // Format the result
00318 //
00319    Size = sbuff.st_size;
00320    Mtime = sbuff.st_mtime; Ctime = sbuff.st_ctime; Atime = sbuff.st_atime;
00321    blen = snprintf(buff, blen, 
00322           "oss.cgroup=%s&oss.type=%c&oss.used=%lld&oss.mt=%lld"
00323           "&oss.ct=%lld&oss.at=%lld&oss.u=*&oss.g=*&oss.fs=%c",
00324           cgbuff, fType, Size, Mtime, Ctime, Atime,
00325           (sbuff.st_mode & S_IWUSR ? 'w':'r'));
00326    return XrdOssOK;
00327 }
00328 
00329 /******************************************************************************/
00330 /*                                S t a t X P                                 */
00331 /******************************************************************************/
00332 
00333 /*
00334   Function: Return export attributes for a path.
00335 
00336   Input:    path        - Is the path whose export attributes are wanted.
00337             attr        - reference to the are to receive the export attributes
00338 
00339   Output:   Returns XrdOssOK upon success and -errno upon failure.
00340 */
00341 
00342 int XrdOssSys::StatXP(const char *path, unsigned long long &attr)
00343 {
00344 
00345 // Construct the processing options for this path
00346 //
00347    attr = PathOpts(path);
00348    return XrdOssOK;
00349 }
00350   
00351 /******************************************************************************/
00352 /*                              g e t C n a m e                               */
00353 /******************************************************************************/
00354   
00355 int XrdOssSys::getCname(const char *path, struct stat *sbuff, char *cgbuff)
00356 {
00357    const char *thePath;
00358    char actual_path[MAXPATHLEN+1];
00359    int retc;
00360 
00361 // Get the pfn for this path
00362 //
00363    if (lcl_N2N)
00364       if ((retc = lcl_N2N->lfn2pfn(path, actual_path, sizeof(actual_path))))
00365          return retc;
00366          else thePath = actual_path;
00367       else thePath = path;
00368 
00369 // Get regular stat informtion for this file
00370 //
00371    if ((retc = stat(thePath, sbuff))) return retc;
00372 
00373 // Now determine if we should get the cache group name. There is none
00374 // for offline files and it's always public for directories.
00375 //
00376    if (S_ISDIR(sbuff->st_mode))          strcpy(cgbuff, "public");
00377       else if (sbuff->st_mode & S_IFBLK) strcpy(cgbuff, "*");
00378               else XrdOssPath::getCname(thePath, cgbuff);
00379 
00380 // All done
00381 //
00382    return 0;
00383 }
00384 
00385 /******************************************************************************/
00386 /*                              g e t S t a t s                               */
00387 /******************************************************************************/
00388   
00389 int XrdOssSys::getStats(char *buff, int blen)
00390 {
00391    static const char ptag1[] = "<paths>%d";
00392    static const char ptag2[] = "<stats id=\"%d\"><lp>\"%s\"</lp><rp>\"%s\"</rp>"
00393    "<tot>%lld</tot><free>%lld</free><ino>%lld</ino><ifr>%lld</ifr></stats>";
00394    static const char ptag3[] = "</paths>";
00395 
00396    static const int ptag1sz = sizeof(ptag1);
00397    static const int ptag2sz = sizeof(ptag2) + (16*4);
00398    static const int ptag3sz = sizeof(ptag3);
00399 
00400    static const char stag1[] = "<space>%d";
00401    static const char stag2[] = "<stats id=\"%d\"><name>%s</name>"
00402                 "<tot>%lld</tot><free>%lld</free><maxf>%lld</maxf>"
00403                 "<fsn>%d</fsn><usg>%lld</usg>";
00404    static const char stagq[] = "<qta>%lld</qta>";
00405    static const char stags[] = "</stats>";
00406    static const char stag3[] = "</space>";
00407 
00408    static const int stag1sz = sizeof(stag1);
00409    static const int stag2sz = sizeof(stag2) + XrdOssSpace::maxSNlen + (16*5);
00410    static const int stagqsz = sizeof(stagq) + 16;
00411    static const int stagssz = sizeof(stags);
00412    static const int stag3sz = sizeof(stag3);
00413 
00414    static const int stagsz  = ptag1sz + ptag2sz + ptag3sz + 1024 +
00415                             + stag1sz + stag2sz + stag3sz
00416                             + stagqsz + stagssz;
00417 
00418    XrdOssCache_Group  *fsg = XrdOssCache_Group::fsgroups;
00419    XrdOssCache_Space   CSpace;
00420    OssDPath           *dpP = DPList;
00421    char *bp = buff;
00422    int dpNum = 0, spNum = 0, n, flen;
00423 
00424 // If no buffer spupplied, return how much data we will generate. We also
00425 // do one-time initialization here.
00426 //
00427    if (!buff) return ptag1sz + (ptag2sz * numDP) + stag3sz + lenDP
00428                    + stag1sz + (stag2sz * numCG) + stag3sz
00429                    + stagqsz + stagssz;
00430 
00431 // Make sure we have enough space for one entry
00432 //
00433    if (blen <= stagsz) return 0;
00434 
00435 // Output first header (we know we have one path, at least)
00436 //
00437    flen = sprintf(bp, ptag1, numDP); bp += flen; blen -= flen;
00438 
00439 // Output individual entries
00440 //
00441    while(dpP && blen > 0)
00442         {XrdOssCache_FS::freeSpace(CSpace, dpP->Path2);
00443          flen = snprintf(bp, blen, ptag2, dpNum, dpP->Path1, dpP->Path2,
00444                                    CSpace.Total>>10, CSpace.Free>>10,
00445                                    CSpace.Inodes,    CSpace.Inleft);
00446          dpP = dpP->Next; bp += flen; blen -= flen; dpNum++;
00447         }
00448 
00449 // Output closing tag
00450 //
00451    if (blen <= ptag3sz) return 0;
00452    strcpy(bp, ptag3); bp += (ptag3sz-1); blen -= (ptag3sz-1);
00453    dpNum = bp - buff;
00454 
00455 // Output header
00456 //
00457    if (blen <= stag1sz) return (blen < 0 ? 0 : dpNum);
00458    flen = snprintf(bp, blen, stag1, numCG); bp += flen; blen -= flen;
00459    if (blen <= stag1sz) return dpNum;
00460 
00461 // Generate info for each path
00462 //
00463    while(fsg && blen > 0)
00464         {n = XrdOssCache_FS::getSpace(CSpace, fsg);
00465          flen = snprintf(bp, blen, stag2, spNum, fsg->group, CSpace.Total>>10,
00466                 CSpace.Free>>10, CSpace.Maxfree>>10, n, CSpace.Usage>>10);
00467          bp += flen; blen -= flen; spNum++;
00468          if (CSpace.Quota >= 0 && blen > stagqsz)
00469             {flen = sprintf(bp, stagq, CSpace.Quota); bp += flen; blen -= flen;}
00470          if (blen < stagssz) return dpNum;
00471          strcpy(bp, stags); bp += (stagssz-1); blen -= (stagssz-1);
00472          fsg = fsg->next;
00473         }
00474 
00475 // Insert trailer
00476 //
00477    if (blen >= stag3sz) {strcpy(bp, stag3); bp += (stag3sz-1);}
00478       else return dpNum;
00479 
00480 // All done
00481 //
00482    return bp - buff;
00483 }

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