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;
162 if ((fSpace >> 31LL)) fSpace = 0x7fffffff;
163 }
164
165// Return the result
166//
167 blen = snprintf(buff, blen, "%d %lld %d %d %lld %d",
168 wVal, (wVal ? fSpace : 0LL), (wVal ? Util : 0),
169 sVal, (sVal ? fSpace : 0LL), (sVal ? Util : 0));
170 return XrdOssOK;
171}
172
173/******************************************************************************/
174
175/*
176 Function: Return free space information based on a path
177
178 Input: path - Is the fully qualified name of the file to be tested.
179 opt - Options associated with the path
180 fSize - total bytes in the filesystem.
181 fSpace - total free bytes in the filesystem. It is set to
182 -1 if the path is not convertable.
183
184 Output: Returns XrdOssOK upon success and -errno upon failure.
185*/
186
187int XrdOssSys::StatFS(const char *path, unsigned long long &Opt,
188 long long &fSize, long long &fSpace)
189{
190// Establish the path options
191//
192 Opt = PathOpts(path);
193
194// For in-place paths we just get the free space in that partition, otherwise
195// get the maximum available in any partition.
196//
197 if ((Opt & XRDEXP_STAGE) || !(Opt & XRDEXP_NOTRW))
199 {char lcl_path[MAXPATHLEN+1];
200 if (lcl_N2N)
201 if (lcl_N2N->lfn2pfn(path, lcl_path, sizeof(lcl_path)))
202 fSpace = -1;
203 else fSpace = XrdOssCache_FS::freeSpace(fSize, lcl_path);
204 else fSpace = XrdOssCache_FS::freeSpace(fSize, path);
205 } else {fSpace = XrdOssCache_FS::freeSpace(fSize);}
206 else {fSpace = 0; fSize = 0;}
207 return XrdOssOK;
208}
209
210/******************************************************************************/
211/* S t a t L S */
212/******************************************************************************/
213
214/*
215 Function: Return free space information based on a cache group name.
216
217 Input: Env - Is the environment for cgi info.
218 path - Is the path name.
219 buff - pointer to a buffer to hold the information.
220 blen - the length of the buffer
221
222 Output: Returns XrdOssOK upon success and -errno upon failure.
223*/
224
225int XrdOssSys::StatLS(XrdOucEnv &env, const char *path, char *buff, int &blen)
226{
227 static const char *Resp="oss.cgroup=%s&oss.space=%lld&oss.free=%lld"
228 "&oss.maxf=%lld&oss.used=%lld&oss.quota=%lld";
229 struct stat sbuff;
230 XrdOssCache_Space CSpace;
231 char *cgrp, cgbuff[XrdOssSpace::minSNbsz];
232 int retc;
233
234// We provide pseudo support whould be not have a cache
235//
237 {unsigned long long Opt;
238 long long fSpace, fSize;
239 StatFS(path, Opt, fSize, fSpace);
240 if (fSpace < 0) fSpace = 0;
241 blen = snprintf(buff, blen, Resp, "public", fSize, fSpace, fSpace,
242 fSize-fSpace, XrdOssCache_Group::PubQuota);
243 return XrdOssOK;
244 }
245
246// Find the cache group. We provide pseudo support should we not have a cache
247//
248 if (!(cgrp = env.Get(OSS_CGROUP)))
249 {if ((retc = getCname(path, &sbuff, cgbuff))) return retc;
250 else cgrp = cgbuff;
251 }
252
253// Accumulate the stats and format the result
254//
255 blen = (XrdOssCache_FS::getSpace(CSpace, cgrp)
256 ? snprintf(buff,blen,Resp,cgrp,CSpace.Total,CSpace.Free,CSpace.Maxfree,
257 CSpace.Usage,CSpace.Quota)
258 : snprintf(buff, blen, Resp, cgrp, 0LL, 0LL, 0LL, 0LL, -1LL));
259 return XrdOssOK;
260}
261
262/******************************************************************************/
263/* S t a t P F */
264/******************************************************************************/
265
266/*
267 Function: Determine if physical file 'path' actually exists online.
268
269 Input: path - Is the fully qualified name of the file to be tested.
270 buff - pointer to a 'stat' structure to hold the attributes
271 of the file.
272
273 Output: Returns XrdOssOK upon success and -errno upon failure.
274*/
275
276int XrdOssSys::StatPF(const char *path, struct stat *buff, int opts)
277{
278 char lcl_path[MAXPATHLEN+1];
279 int retc;
280
281// If just the maximum values wanted then we can return these right away
282//
283 if (opts & PF_dNums)
284 {XrdOssCache::DevInfo(*buff, true);
285 return 0;
286 }
287
288// Check if path is nil and do he appropriate thing
289//
290 if (!path)
291 {if (opts & PF_dInfo) XrdOssCache::DevInfo(*buff, false);
292 else return -EINVAL;
293 return 0;
294 }
295
296// Check if we should do lfn2pfn conversion (previously we didn't allow it)
297//
298 if (lcl_N2N && (opts & PF_isLFN))
299 {if ((retc = lcl_N2N->lfn2pfn(path, lcl_path, sizeof(lcl_path))))
300 return retc;
301 path = lcl_path;
302 }
303
304// We no longer use the custom stat plug-in for this function. It never
305// worked in the first place, anyway.
306//
307 if (stat(path, buff)) return (errno ? -errno : -ENOMSG);
308
309// Check of general stat information is to be returned
310//
311 if (opts % PF_dStat)
312 {buff->st_rdev = 0;
313 return XrdOssOK;
314 }
315
316// Check if device info is to be returned
317//
318 if (opts & PF_dInfo) XrdOssCache::DevInfo(*buff);
319
320// All done
321//
322 return XrdOssOK;
323}
324
325/******************************************************************************/
326/* S t a t V S */
327/******************************************************************************/
328
329/*
330 Function: Return space information for space name "sname".
331
332 Input: sname - The name of the same, null if all space wanted.
333 sP - pointer to XrdOssVSInfo to hold information.
334
335 Output: Returns XrdOssOK upon success and -errno upon failure.
336 Note that quota is zero when sname is null.
337*/
338
339int XrdOssSys::StatVS(XrdOssVSInfo *sP, const char *sname, int updt)
340{
341 XrdOssCache_Space CSpace;
342 XrdOssVSPart **vsP;
343
344// Check if we should update the statistics
345//
346 if (updt) XrdOssCache::Scan(0);
347
348// If no space name present or no spaces defined and the space is public then
349// return information on all spaces.
350//
351 if (!sname || (!XrdOssCache_Group::fsgroups && !strcmp("public", sname)))
359 return XrdOssOK;
360 }
361
362// Check if partition table wanted
363//
364 if (*sname != '+') vsP = 0;
365 else {sname++;
366 vsP = &(sP->vsPart);
367 }
368
369// Get the space stats
370//
371 if (!(sP->Extents=XrdOssCache_FS::getSpace(CSpace, sname, vsP)))
372 return -ENOENT;
373
374// Return the result
375//
376 sP->Total = CSpace.Total;
377 sP->Free = CSpace.Free;
378 sP->LFree = CSpace.Maxfree;
379 sP->Large = CSpace.Largest;
380 sP->Usage = CSpace.Usage;
381 sP->Quota = CSpace.Quota;
382 return XrdOssOK;
383}
384
385/******************************************************************************/
386/* S t a t X A */
387/******************************************************************************/
388
389/*
390 Function: Return extended attributes for "path".
391
392 Input: path - Is the fully qualified name of the target file.
393 buff - pointer to a buffer to hold the information.
394 blen - the length of the buffer
395 envP - Environmental Information.
396
397 Output: Returns XrdOssOK upon success and -errno upon failure.
398 blen is updated with the actual length of the buff data.
399*/
400
401int XrdOssSys::StatXA(const char *path, char *buff, int &blen, XrdOucEnv *envP)
402{
403 struct stat sbuff;
404 char cgbuff[XrdOssSpace::minSNbsz], fType;
405 long long Size, Mtime, Ctime, Atime;
406 int retc;
407
408// Get the cache group and stat info for the file
409//
410 if ((retc = getCname(path, &sbuff, cgbuff))) return retc;
411 if (S_ISREG(sbuff.st_mode)) fType = 'f';
412 else if (S_ISDIR(sbuff.st_mode)) fType = 'd';
413 else fType = 'o';
414
415// Format the result
416//
417 Size = sbuff.st_size;
418 Mtime = sbuff.st_mtime; Ctime = sbuff.st_ctime; Atime = sbuff.st_atime;
419 blen = snprintf(buff, blen,
420 "oss.cgroup=%s&oss.type=%c&oss.used=%lld&oss.mt=%lld"
421 "&oss.ct=%lld&oss.at=%lld&oss.u=*&oss.g=*&oss.fs=%c",
422 cgbuff, fType, Size, Mtime, Ctime, Atime,
423 (sbuff.st_mode & S_IWUSR ? 'w':'r'));
424 return XrdOssOK;
425}
426
427/******************************************************************************/
428/* S t a t X P */
429/******************************************************************************/
430
431/*
432 Function: Return export attributes for a path.
433
434 Input: path - Is the path whose export attributes are wanted.
435 attr - reference to the are to receive the export attributes
436 envP - Environmental Information.
437
438 Output: Returns XrdOssOK upon success and -errno upon failure.
439*/
440
441int XrdOssSys::StatXP(const char *path, unsigned long long &attr,
442 XrdOucEnv *envP)
443{
444
445// Construct the processing options for this path
446//
447 attr = PathOpts(path);
448 return XrdOssOK;
449}
450
451/******************************************************************************/
452/* g e t C n a m e */
453/******************************************************************************/
454
455int XrdOssSys::getCname(const char *path, struct stat *sbuff, char *cgbuff)
456{
457 const char *thePath;
458 char actual_path[MAXPATHLEN+1];
459 int retc;
460
461// Get the pfn for this path
462//
463 if (lcl_N2N)
464 if ((retc = lcl_N2N->lfn2pfn(path, actual_path, sizeof(actual_path))))
465 return retc;
466 else thePath = actual_path;
467 else thePath = path;
468
469// Get regular stat informtion for this file
470//
471 if ((retc = stat(thePath, sbuff))) return -errno;
472
473// Now determine if we should get the cache group name. There is none
474// for offline files and it's always public for directories.
475//
476 if (S_ISDIR(sbuff->st_mode)) strcpy(cgbuff, "public");
477 else if (S_ISBLK(sbuff->st_mode)) strcpy(cgbuff, "*");
478 else XrdOssPath::getCname(thePath, cgbuff);
479
480// All done
481//
482 return 0;
483}
484
485/******************************************************************************/
486/* g e t S t a t s */
487/******************************************************************************/
488
489int XrdOssSys::getStats(char *buff, int blen)
490{
491 static const char ptag1[] = "<paths>%d";
492 static const char ptag2[] = "<stats id=\"%d\"><lp>\"%s\"</lp><rp>\"%s\"</rp>"
493 "<tot>%lld</tot><free>%lld</free><ino>%lld</ino><ifr>%lld</ifr></stats>";
494 static const char ptag3[] = "</paths>";
495
496 static const int ptag1sz = sizeof(ptag1);
497 static const int ptag2sz = sizeof(ptag2) + (16*4);
498 static const int ptag3sz = sizeof(ptag3);
499
500 static const char stag1[] = "<space>%d";
501 static const char stag2[] = "<stats id=\"%d\"><name>%s</name>"
502 "<tot>%lld</tot><free>%lld</free><maxf>%lld</maxf>"
503 "<fsn>%d</fsn><usg>%lld</usg>";
504 static const char stagq[] = "<qta>%lld</qta>";
505 static const char stags[] = "</stats>";
506 static const char stag3[] = "</space>";
507
508 static const int stag1sz = sizeof(stag1);
509 static const int stag2sz = sizeof(stag2) + XrdOssSpace::maxSNlen + (16*5);
510 static const int stagqsz = sizeof(stagq) + 16;
511 static const int stagssz = sizeof(stags);
512 static const int stag3sz = sizeof(stag3);
513
514 static const int stagsz = ptag1sz + ptag2sz + ptag3sz + 1024 +
515 + stag1sz + stag2sz + stag3sz
516 + stagqsz + stagssz;
517
519 OssDPath *dpP = DPList;
520 char *bp = buff;
521 int dpNum = 0, spNum = 0, n, flen;
522
523// If no buffer spupplied, return how much data we will generate. We also
524// do one-time initialization here.
525//
526 if (!buff) return ptag1sz + (ptag2sz * numDP) + stag3sz + lenDP
527 + stag1sz + (stag2sz * numCG) + stag3sz
528 + stagqsz + stagssz;
529
530// Make sure we have enough space for one entry
531//
532 if (blen <= stagsz) return 0;
533
534// Output first header (we know we have one path, at least)
535//
536 flen = sprintf(bp, ptag1, numDP); bp += flen; blen -= flen;
537
538// Output individual entries
539//
540 while(dpP && blen > 0)
541 {XrdOssCache_Space CSpace;
542 XrdOssCache_FS::freeSpace(CSpace, dpP->Path2);
543 flen = snprintf(bp, blen, ptag2, dpNum, dpP->Path1, dpP->Path2,
544 CSpace.Total>>10, CSpace.Free>>10,
545 CSpace.Inodes, CSpace.Inleft);
546 dpP = dpP->Next; bp += flen; blen -= flen; dpNum++;
547 }
548
549// Output closing tag
550//
551 if (blen <= ptag3sz) return 0;
552 strcpy(bp, ptag3); bp += (ptag3sz-1); blen -= (ptag3sz-1);
553 dpNum = bp - buff;
554
555// Output header
556//
557 if (blen <= stag1sz) return (blen < 0 ? 0 : dpNum);
558 flen = snprintf(bp, blen, stag1, numCG); bp += flen; blen -= flen;
559 if (blen <= stag1sz) return dpNum;
560
561// Generate info for each path
562//
563 while(fsg && blen > 0)
564 {XrdOssCache_Space CSpace;
565 n = XrdOssCache_FS::getSpace(CSpace, fsg);
566 flen = snprintf(bp, blen, stag2, spNum, fsg->group, CSpace.Total>>10,
567 CSpace.Free>>10, CSpace.Maxfree>>10, n, CSpace.Usage>>10);
568 bp += flen; blen -= flen; spNum++;
569 if (CSpace.Quota >= 0 && blen > stagqsz)
570 {flen = sprintf(bp, stagq, CSpace.Quota); bp += flen; blen -= flen;}
571 if (blen < stagssz) return dpNum;
572 strcpy(bp, stags); bp += (stagssz-1); blen -= (stagssz-1);
573 fsg = fsg->next;
574 }
575
576// Insert trailer
577//
578 if (blen >= stag3sz) {strcpy(bp, stag3); bp += (stag3sz-1);}
579 else return dpNum;
580
581// All done
582//
583 return bp - buff;
584}
#define OSS_CGROUP
#define XrdOssOK
Definition XrdOss.hh:50
#define XRDOSS_resonly
Definition XrdOss.hh:486
#define XRDOSS_updtatm
Definition XrdOss.hh:487
#define XRDEXP_NOTRW
#define XRDEXP_INPLACE
#define XRDEXP_NOCHECK
#define XRDEXP_STAGE
#define stat(a, b)
Definition XrdPosix.hh:96
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:270
char STT_V2
Definition XrdOssApi.hh:271
OssDPath * DPList
Definition XrdOssApi.hh:258
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:261
int IsRemote(const char *path)
Definition XrdOssApi.hh:171
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:177
XrdOucName2Name * lcl_N2N
Definition XrdOssApi.hh:254
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:260
int StatPF(const char *, struct stat *, int)
char * RSSCmd
Definition XrdOssApi.hh:238
XrdOucName2Name * rmt_N2N
Definition XrdOssApi.hh:255
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:773
static const int PF_dNums
Definition XrdOss.hh:771
static const int PF_dInfo
Definition XrdOss.hh:770
static const int PF_isLFN
Definition XrdOss.hh:772
char * Get(const char *varname)
Definition XrdOucEnv.hh:69
virtual int lfn2pfn(const char *lfn, char *buff, int blen)=0
virtual int lfn2rfn(const char *lfn, char *buff, int blen)=0
char * Path2
OssDPath * Next
char * Path1