XRootD
Loading...
Searching...
No Matches
XrdOssStat.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d O s s S t a t . c c */
4/* */
5/* (c) 2008 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#include <unistd.h>
32#include <cerrno>
33#include <fcntl.h>
34#include <cstdio>
35#include <strings.h>
36#include <ctime>
37#include <utime.h>
38#include <sys/param.h>
39#include <sys/types.h>
40#include <sys/stat.h>
41
44#include "XrdOss/XrdOssApi.hh"
45#include "XrdOss/XrdOssCache.hh"
48#include "XrdOss/XrdOssPath.hh"
49#include "XrdOss/XrdOssSpace.hh"
50#include "XrdOuc/XrdOucEnv.hh"
52#include "XrdOuc/XrdOucPList.hh"
53
54/******************************************************************************/
55/* s t a t */
56/******************************************************************************/
57
58/*
59 Function: Determine if file 'path' actually exists.
60
61 Input: path - Is the fully qualified name of the file to be tested.
62 buff - pointer to a 'stat' structure to hold the attributes
63 of the file.
64 opts - Options.
65 env - Environmental information.
66
67 Output: Returns XrdOssOK upon success and -errno upon failure.
68*/
69
70int XrdOssSys::Stat(const char *path, struct stat *buff, int opts,
71 XrdOucEnv *EnvP)
72{
73 const int ro_Mode = ~(S_IWUSR | S_IWGRP | S_IWOTH);
74 char actual_path[MAXPATHLEN+1], *local_path, *remote_path;
75 unsigned long long popts;
76 int retc;
77
78// Construct the processing options for this path
79//
80 popts = PathOpts(path);
81
82// Generate local path
83//
84 if (lcl_N2N && STT_DoN2N)
85 if ((retc = lcl_N2N->lfn2pfn(path, actual_path, sizeof(actual_path))))
86 return retc;
87 else local_path = actual_path;
88 else local_path = (char *)path;
89
90// Stat the file in the local filesystem first. If there. make sure the mode
91// bits correspond to our reality and update access time if so requested.
92//
93 if (STT_Func)
94 {retc = (STT_V2 ? (*STT_Fund)(local_path, buff, opts, EnvP, path)
95 : (*STT_Func)(local_path, buff, opts, EnvP));
96 } else retc = stat(local_path, buff);
97 if (!retc)
98 {if (popts & XRDEXP_NOTRW) buff->st_mode &= ro_Mode;
99 if (opts & XRDOSS_updtatm && (buff->st_mode & S_IFMT) == S_IFREG)
100 {struct utimbuf times;
101 times.actime = time(0);
102 times.modtime = buff->st_mtime;
103 utime(local_path, &times);
104 }
105 return XrdOssOK;
106 } else if (errno != ENOENT) return (errno ? -errno : -ENOMSG);
107
108// The file may be offline in a mass storage system, check if this is possible
109//
110 if (!IsRemote(path) || opts & XRDOSS_resonly
111 || (EnvP && EnvP->Get("oss.lcl"))) return -errno;
112 if (!RSSCmd) return (popts & XRDEXP_NOCHECK ? -ENOENT : -ENOMSG);
113
114// Generate remote path
115//
116 if (rmt_N2N)
117 if ((retc = rmt_N2N->lfn2rfn(path, actual_path, sizeof(actual_path))))
118 return retc;
119 else remote_path = actual_path;
120 else remote_path = (char *)path;
121
122// Now stat the file in the remote system (it doesn't exist locally)
123//
124 if ((retc = MSS_Stat(remote_path, buff))) return retc;
125 if (popts & XRDEXP_NOTRW) buff->st_mode &= ro_Mode;
126 return XrdOssOK;
127}
128
129/******************************************************************************/
130/* S t a t F S */
131/******************************************************************************/
132
133/*
134 Function: Return free space information based on a path
135
136 Input: path - Is the fully qualified name of the file to be tested.
137 buff - pointer to a buffer to hold the information.
138 blen - the length of the buffer
139 envP - Environmental Information.
140
141 Output: Returns XrdOssOK upon success and -errno upon failure.
142 blen is updated with the actual length of the buff data.
143*/
144
145int XrdOssSys::StatFS(const char *path, char *buff, int &blen, XrdOucEnv *envP)
146{
147 int sVal, wVal, Util;
148 long long fSpace, fSize;
149 unsigned long long Opt;
150
151// Get the values for this file system
152//
153 StatFS(path, Opt, fSize, fSpace);
154 sVal = (Opt & XRDEXP_STAGE ? 1 : 0);
155 wVal = (Opt & XRDEXP_NOTRW ? 0 : 1);
156
157// Size the value to fit in an int
158//
159 if (fSpace <= 0) {fSize = fSpace = 0; Util = 0;}
160 else {Util = (fSize ? (fSize - fSpace)*100LL/fSize : 0);
161 fSpace = fSpace >> 20LL; // Fdocumented as returning MB units
162 }
163
164// Return the result
165//
166 blen = snprintf(buff, blen, "%d %lld %d %d %lld %d",
167 wVal, (wVal ? fSpace : 0LL), (wVal ? Util : 0),
168 sVal, (sVal ? fSpace : 0LL), (sVal ? Util : 0));
169 return XrdOssOK;
170}
171
172/******************************************************************************/
173
174/*
175 Function: Return free space information based on a path
176
177 Input: path - Is the fully qualified name of the file to be tested.
178 opt - Options associated with the path
179 fSize - total bytes in the filesystem.
180 fSpace - total free bytes in the filesystem. It is set to
181 -1 if the path is not convertable.
182
183 Output: Returns XrdOssOK upon success and -errno upon failure.
184*/
185
186int XrdOssSys::StatFS(const char *path, unsigned long long &Opt,
187 long long &fSize, long long &fSpace)
188{
189// Establish the path options
190//
191 Opt = PathOpts(path);
192
193// For in-place paths we just get the free space in that partition, otherwise
194// get the maximum available in any partition.
195//
196 if ((Opt & XRDEXP_STAGE) || !(Opt & XRDEXP_NOTRW))
198 {char lcl_path[MAXPATHLEN+1];
199 if (lcl_N2N)
200 if (lcl_N2N->lfn2pfn(path, lcl_path, sizeof(lcl_path)))
201 fSpace = -1;
202 else fSpace = XrdOssCache_FS::freeSpace(fSize, lcl_path);
203 else fSpace = XrdOssCache_FS::freeSpace(fSize, path);
204 } else {fSpace = XrdOssCache_FS::freeSpace(fSize);}
205 else {fSpace = 0; fSize = 0;}
206 return XrdOssOK;
207}
208
209/******************************************************************************/
210/* S t a t L S */
211/******************************************************************************/
212
213/*
214 Function: Return free space information based on a cache group name.
215
216 Input: Env - Is the environment for cgi info.
217 path - Is the path name.
218 buff - pointer to a buffer to hold the information.
219 blen - the length of the buffer
220
221 Output: Returns XrdOssOK upon success and -errno upon failure.
222*/
223
224int XrdOssSys::StatLS(XrdOucEnv &env, const char *path, char *buff, int &blen)
225{
226 static const char *Resp="oss.cgroup=%s&oss.space=%lld&oss.free=%lld"
227 "&oss.maxf=%lld&oss.used=%lld&oss.quota=%lld";
228 struct stat sbuff;
229 XrdOssCache_Space CSpace;
230 char *cgrp, cgbuff[XrdOssSpace::minSNbsz];
231 int retc;
232
233// We provide pseudo support whould be not have a cache
234//
236 {unsigned long long Opt;
237 long long fSpace, fSize;
238 StatFS(path, Opt, fSize, fSpace);
239 if (fSpace < 0) fSpace = 0;
240 blen = snprintf(buff, blen, Resp, "public", fSize, fSpace, fSpace,
241 fSize-fSpace, XrdOssCache_Group::PubQuota);
242 return XrdOssOK;
243 }
244
245// Find the cache group. We provide pseudo support should we not have a cache
246//
247 if (!(cgrp = env.Get(OSS_CGROUP)))
248 {if ((retc = getCname(path, &sbuff, cgbuff))) return retc;
249 else cgrp = cgbuff;
250 }
251
252// Accumulate the stats and format the result
253//
254 blen = (XrdOssCache_FS::getSpace(CSpace, cgrp)
255 ? snprintf(buff,blen,Resp,cgrp,CSpace.Total,CSpace.Free,CSpace.Maxfree,
256 CSpace.Usage,CSpace.Quota)
257 : snprintf(buff, blen, Resp, cgrp, 0LL, 0LL, 0LL, 0LL, -1LL));
258 return XrdOssOK;
259}
260
261/******************************************************************************/
262/* S t a t P F */
263/******************************************************************************/
264
265/*
266 Function: Determine if physical file 'path' actually exists online.
267
268 Input: path - Is the fully qualified name of the file to be tested.
269 buff - pointer to a 'stat' structure to hold the attributes
270 of the file.
271
272 Output: Returns XrdOssOK upon success and -errno upon failure.
273*/
274
275int XrdOssSys::StatPF(const char *path, struct stat *buff, int opts)
276{
277 char lcl_path[MAXPATHLEN+1];
278 int retc;
279
280// If just the maximum values wanted then we can return these right away
281//
282 if (opts & PF_dNums)
283 {XrdOssCache::DevInfo(*buff, true);
284 return 0;
285 }
286
287// Check if path is nil and do he appropriate thing
288//
289 if (!path)
290 {if (opts & PF_dInfo) XrdOssCache::DevInfo(*buff, false);
291 else return -EINVAL;
292 return 0;
293 }
294
295// Check if we should do lfn2pfn conversion (previously we didn't allow it)
296//
297 if (lcl_N2N && (opts & PF_isLFN))
298 {if ((retc = lcl_N2N->lfn2pfn(path, lcl_path, sizeof(lcl_path))))
299 return retc;
300 path = lcl_path;
301 }
302
303// We no longer use the custom stat plug-in for this function. It never
304// worked in the first place, anyway.
305//
306 if (stat(path, buff)) return (errno ? -errno : -ENOMSG);
307
308// Check of general stat information is to be returned
309//
310 if (opts % PF_dStat)
311 {buff->st_rdev = 0;
312 return XrdOssOK;
313 }
314
315// Check if device info is to be returned
316//
317 if (opts & PF_dInfo) XrdOssCache::DevInfo(*buff);
318
319// All done
320//
321 return XrdOssOK;
322}
323
324/******************************************************************************/
325/* S t a t V S */
326/******************************************************************************/
327
328/*
329 Function: Return space information for space name "sname".
330
331 Input: sname - The name of the same, null if all space wanted.
332 sP - pointer to XrdOssVSInfo to hold information.
333
334 Output: Returns XrdOssOK upon success and -errno upon failure.
335 Note that quota is zero when sname is null.
336*/
337
338int XrdOssSys::StatVS(XrdOssVSInfo *sP, const char *sname, int updt)
339{
340 XrdOssCache_Space CSpace;
341 XrdOssVSPart **vsP;
342
343// Check if we should update the statistics
344//
345 if (updt) XrdOssCache::Scan(0);
346
347// If no space name present or no spaces defined and the space is public then
348// return information on all spaces.
349//
350 if (!sname || (!XrdOssCache_Group::fsgroups && !strcmp("public", sname)))
351 {XrdOssCache::Mutex.Lock();
357 XrdOssCache::Mutex.UnLock();
358 return XrdOssOK;
359 }
360
361// Check if partition table wanted
362//
363 if (*sname != '+') vsP = 0;
364 else {sname++;
365 vsP = &(sP->vsPart);
366 }
367
368// Get the space stats
369//
370 if (!(sP->Extents=XrdOssCache_FS::getSpace(CSpace, sname, vsP)))
371 return -ENOENT;
372
373// Return the result
374//
375 sP->Total = CSpace.Total;
376 sP->Free = CSpace.Free;
377 sP->LFree = CSpace.Maxfree;
378 sP->Large = CSpace.Largest;
379 sP->Usage = CSpace.Usage;
380 sP->Quota = CSpace.Quota;
381 return XrdOssOK;
382}
383
384/******************************************************************************/
385/* S t a t X A */
386/******************************************************************************/
387
388/*
389 Function: Return extended attributes for "path".
390
391 Input: path - Is the fully qualified name of the target file.
392 buff - pointer to a buffer to hold the information.
393 blen - the length of the buffer
394 envP - Environmental Information.
395
396 Output: Returns XrdOssOK upon success and -errno upon failure.
397 blen is updated with the actual length of the buff data.
398*/
399
400int XrdOssSys::StatXA(const char *path, char *buff, int &blen, XrdOucEnv *envP)
401{
402 struct stat sbuff;
403 char cgbuff[XrdOssSpace::minSNbsz], fType;
404 long long Size, Mtime, Ctime, Atime;
405 int retc;
406
407// Get the cache group and stat info for the file
408//
409 if ((retc = getCname(path, &sbuff, cgbuff))) return retc;
410 if (S_ISREG(sbuff.st_mode)) fType = 'f';
411 else if (S_ISDIR(sbuff.st_mode)) fType = 'd';
412 else fType = 'o';
413
414// Format the result
415//
416 Size = sbuff.st_size;
417 Mtime = sbuff.st_mtime; Ctime = sbuff.st_ctime; Atime = sbuff.st_atime;
418 blen = snprintf(buff, blen,
419 "oss.cgroup=%s&oss.type=%c&oss.used=%lld&oss.mt=%lld"
420 "&oss.ct=%lld&oss.at=%lld&oss.u=*&oss.g=*&oss.fs=%c",
421 cgbuff, fType, Size, Mtime, Ctime, Atime,
422 (sbuff.st_mode & S_IWUSR ? 'w':'r'));
423 return XrdOssOK;
424}
425
426/******************************************************************************/
427/* S t a t X P */
428/******************************************************************************/
429
430/*
431 Function: Return export attributes for a path.
432
433 Input: path - Is the path whose export attributes are wanted.
434 attr - reference to the are to receive the export attributes
435 envP - Environmental Information.
436
437 Output: Returns XrdOssOK upon success and -errno upon failure.
438*/
439
440int XrdOssSys::StatXP(const char *path, unsigned long long &attr,
441 XrdOucEnv *envP)
442{
443
444// Construct the processing options for this path
445//
446 attr = PathOpts(path);
447 return XrdOssOK;
448}
449
450/******************************************************************************/
451/* g e t C n a m e */
452/******************************************************************************/
453
454int XrdOssSys::getCname(const char *path, struct stat *sbuff, char *cgbuff)
455{
456 const char *thePath;
457 char actual_path[MAXPATHLEN+1];
458 int retc;
459
460// Get the pfn for this path
461//
462 if (lcl_N2N)
463 if ((retc = lcl_N2N->lfn2pfn(path, actual_path, sizeof(actual_path))))
464 return retc;
465 else thePath = actual_path;
466 else thePath = path;
467
468// Get regular stat informtion for this file
469//
470 if ((retc = stat(thePath, sbuff))) return -errno;
471
472// Now determine if we should get the cache group name. There is none
473// for offline files and it's always public for directories.
474//
475 if (S_ISDIR(sbuff->st_mode)) strcpy(cgbuff, "public");
476 else if (S_ISBLK(sbuff->st_mode)) strcpy(cgbuff, "*");
477 else XrdOssPath::getCname(thePath, cgbuff);
478
479// All done
480//
481 return 0;
482}
483
484/******************************************************************************/
485/* g e t S t a t s */
486/******************************************************************************/
487
488int XrdOssSys::getStats(char *buff, int blen)
489{
490 static const char ptag1[] = "<paths>%d";
491 static const char ptag2[] = "<stats id=\"%d\"><lp>\"%s\"</lp><rp>\"%s\"</rp>"
492 "<tot>%lld</tot><free>%lld</free><ino>%lld</ino><ifr>%lld</ifr></stats>";
493 static const char ptag3[] = "</paths>";
494
495 static const int ptag1sz = sizeof(ptag1);
496 static const int ptag2sz = sizeof(ptag2) + (16*4);
497 static const int ptag3sz = sizeof(ptag3);
498
499 static const char stag1[] = "<space>%d";
500 static const char stag2[] = "<stats id=\"%d\"><name>%s</name>"
501 "<tot>%lld</tot><free>%lld</free><maxf>%lld</maxf>"
502 "<fsn>%d</fsn><usg>%lld</usg>";
503 static const char stagq[] = "<qta>%lld</qta>";
504 static const char stags[] = "</stats>";
505 static const char stag3[] = "</space>";
506
507 static const int stag1sz = sizeof(stag1);
508 static const int stag2sz = sizeof(stag2) + XrdOssSpace::maxSNlen + (16*5);
509 static const int stagqsz = sizeof(stagq) + 16;
510 static const int stagssz = sizeof(stags);
511 static const int stag3sz = sizeof(stag3);
512
513 static const int stagsz = ptag1sz + ptag2sz + ptag3sz + 1024 +
514 + stag1sz + stag2sz + stag3sz
515 + stagqsz + stagssz;
516
518 OssDPath *dpP = DPList;
519 char *bp = buff;
520 int dpNum = 0, spNum = 0, n, flen;
521
522// If no buffer spupplied, return how much data we will generate. We also
523// do one-time initialization here.
524//
525 if (!buff) return ptag1sz + (ptag2sz * numDP) + stag3sz + lenDP
526 + stag1sz + (stag2sz * numCG) + stag3sz
527 + stagqsz + stagssz;
528
529// Make sure we have enough space for one entry
530//
531 if (blen <= stagsz) return 0;
532
533// Output first header (we know we have one path, at least)
534//
535 flen = sprintf(bp, ptag1, numDP); bp += flen; blen -= flen;
536
537// Output individual entries
538//
539 while(dpP && blen > 0)
540 {XrdOssCache_Space CSpace;
541 XrdOssCache_FS::freeSpace(CSpace, dpP->Path2);
542 flen = snprintf(bp, blen, ptag2, dpNum, dpP->Path1, dpP->Path2,
543 CSpace.Total>>10, CSpace.Free>>10,
544 CSpace.Inodes, CSpace.Inleft);
545 dpP = dpP->Next; bp += flen; blen -= flen; dpNum++;
546 }
547
548// Output closing tag
549//
550 if (blen <= ptag3sz) return 0;
551 strcpy(bp, ptag3); bp += (ptag3sz-1); blen -= (ptag3sz-1);
552 dpNum = bp - buff;
553
554// Output header
555//
556 if (blen <= stag1sz) return (blen < 0 ? 0 : dpNum);
557 flen = snprintf(bp, blen, stag1, numCG); bp += flen; blen -= flen;
558 if (blen <= stag1sz) return dpNum;
559
560// Generate info for each path
561//
562 while(fsg && blen > 0)
563 {XrdOssCache_Space CSpace;
564 n = XrdOssCache_FS::getSpace(CSpace, fsg);
565 flen = snprintf(bp, blen, stag2, spNum, fsg->group, CSpace.Total>>10,
566 CSpace.Free>>10, CSpace.Maxfree>>10, n, CSpace.Usage>>10);
567 bp += flen; blen -= flen; spNum++;
568 if (CSpace.Quota >= 0 && blen > stagqsz)
569 {flen = sprintf(bp, stagq, CSpace.Quota); bp += flen; blen -= flen;}
570 if (blen < stagssz) return dpNum;
571 strcpy(bp, stags); bp += (stagssz-1); blen -= (stagssz-1);
572 fsg = fsg->next;
573 }
574
575// Insert trailer
576//
577 if (blen >= stag3sz) {strcpy(bp, stag3); bp += (stag3sz-1);}
578 else return dpNum;
579
580// All done
581//
582 return bp - buff;
583}
#define OSS_CGROUP
#define XrdOssOK
Definition XrdOss.hh:54
#define XRDOSS_resonly
Definition XrdOss.hh:548
#define XRDOSS_updtatm
Definition XrdOss.hh:549
#define XRDEXP_NOTRW
#define XRDEXP_INPLACE
#define XRDEXP_NOCHECK
#define XRDEXP_STAGE
#define stat(a, b)
Definition XrdPosix.hh:105
struct myOpts opts
static int getSpace(XrdOssCache_Space &Space, const char *sname, XrdOssVSPart **vsPart=0)
static long long freeSpace(long long &Size, const char *path=0)
static long long PubQuota
static XrdOssCache_Group * fsgroups
XrdOssCache_Group * next
static void * Scan(int cscanint)
static long long fsLarge
static long long fsTotal
static void DevInfo(struct stat &buf, bool limits=false)
static long long fsTotFr
static int fsCount
static long long fsFree
static XrdSysMutex Mutex
static int getCname(const char *path, char *Cache, char *lbuf=0, int lbsz=0)
static const int minSNbsz
static const int maxSNlen
char STT_DoN2N
Definition XrdOssApi.hh:277
char STT_V2
Definition XrdOssApi.hh:278
OssDPath * DPList
Definition XrdOssApi.hh:265
int StatLS(XrdOucEnv &env, const char *path, char *buff, int &blen)
int StatVS(XrdOssVSInfo *sP, const char *sname=0, int updt=0)
short numCG
Definition XrdOssApi.hh:268
int IsRemote(const char *path)
Definition XrdOssApi.hh:178
int StatXP(const char *path, unsigned long long &attr, XrdOucEnv *Env=0)
int getStats(char *buff, int blen)
int getCname(const char *path, struct stat *sbuff, char *cgbuff)
int StatXA(const char *path, char *buff, int &blen, XrdOucEnv *Env=0)
int StatFS(const char *path, char *buff, int &blen, XrdOucEnv *Env=0)
unsigned long long PathOpts(const char *path)
Definition XrdOssApi.hh:184
XrdOucName2Name * lcl_N2N
Definition XrdOssApi.hh:261
int MSS_Stat(const char *, struct stat *buff=0)
Definition XrdOssMSS.cc:253
int Stat(const char *, struct stat *, int opts=0, XrdOucEnv *Env=0)
Definition XrdOssStat.cc:70
short numDP
Definition XrdOssApi.hh:267
int StatPF(const char *, struct stat *, int)
char * RSSCmd
Definition XrdOssApi.hh:245
XrdOucName2Name * rmt_N2N
Definition XrdOssApi.hh:262
long long LFree
Definition XrdOssVS.hh:93
long long Usage
Definition XrdOssVS.hh:94
long long Large
Definition XrdOssVS.hh:92
long long Total
Definition XrdOssVS.hh:90
long long Free
Definition XrdOssVS.hh:91
XrdOssVSPart * vsPart
Definition XrdOssVS.hh:98
long long Quota
Definition XrdOssVS.hh:95
static const int PF_dStat
Definition XrdOss.hh:854
static const int PF_dNums
Definition XrdOss.hh:852
static const int PF_dInfo
Definition XrdOss.hh:851
static const int PF_isLFN
Definition XrdOss.hh:853
char * Get(const char *varname)
Definition XrdOucEnv.hh:69
char * Path2
OssDPath * Next
char * Path1