00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
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
00059
00060 popts = PathOpts(path);
00061
00062
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
00071
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, ×);
00080 }
00081 return XrdOssOK;
00082 }
00083
00084
00085
00086 if (!IsRemote(path) || opts & XRDOSS_resonly) return -errno;
00087 if (!RSSCmd) return (popts & XRDEXP_NOCHECK ? -ENOENT : -ENOMSG);
00088
00089
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
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
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
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
00127
00128 StatFS(path, Opt, fSize, fSpace);
00129 sVal = (Opt & XRDEXP_STAGE ? 1 : 0);
00130 wVal = (Opt & XRDEXP_NOTRW ? 0 : 1);
00131
00132
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
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
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 int XrdOssSys::StatFS(const char *path, unsigned long long &Opt,
00163 long long &fSize, long long &fSpace)
00164 {
00165
00166
00167 Opt = PathOpts(path);
00168
00169
00170
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
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
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
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
00222
00223 if (!(cgrp = env.Get(OSS_CGROUP)))
00224 {if ((retc = getCname(path, &sbuff, cgbuff))) return retc;
00225 else cgrp = cgbuff;
00226 }
00227
00228
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
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 int XrdOssSys::StatVS(XrdOssVSInfo *sP, const char *sname, int updt)
00252 {
00253 XrdOssCache_Space CSpace;
00254
00255
00256
00257 if (updt) XrdOssCache::Scan(0);
00258
00259
00260
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
00274
00275 if (!(sP->Extents=XrdOssCache_FS::getSpace(CSpace,sname))) return -ENOENT;
00276
00277
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
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
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
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
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
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 int XrdOssSys::StatXP(const char *path, unsigned long long &attr)
00343 {
00344
00345
00346
00347 attr = PathOpts(path);
00348 return XrdOssOK;
00349 }
00350
00351
00352
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
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
00370
00371 if ((retc = stat(thePath, sbuff))) return retc;
00372
00373
00374
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
00381
00382 return 0;
00383 }
00384
00385
00386
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
00425
00426
00427 if (!buff) return ptag1sz + (ptag2sz * numDP) + stag3sz + lenDP
00428 + stag1sz + (stag2sz * numCG) + stag3sz
00429 + stagqsz + stagssz;
00430
00431
00432
00433 if (blen <= stagsz) return 0;
00434
00435
00436
00437 flen = sprintf(bp, ptag1, numDP); bp += flen; blen -= flen;
00438
00439
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
00450
00451 if (blen <= ptag3sz) return 0;
00452 strcpy(bp, ptag3); bp += (ptag3sz-1); blen -= (ptag3sz-1);
00453 dpNum = bp - buff;
00454
00455
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
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
00476
00477 if (blen >= stag3sz) {strcpy(bp, stag3); bp += (stag3sz-1);}
00478 else return dpNum;
00479
00480
00481
00482 return bp - buff;
00483 }