XRootD
XrdFfsFsinfo.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* XrdFfsFsinfo.cc filesystem/xrootd oss space usage info cache */
3 /* */
4 /* (c) 2010 by the Board of Trustees of the Leland Stanford, Jr., University */
5 /* All Rights Reserved */
6 /* Author: Wei Yang (SLAC National Accelerator Laboratory, 2010) */
7 /* Contract DE-AC02-76-SFO0515 with the Department of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include <cstdio>
31 #include <cstring>
32 #include <cstdlib>
33 #include <ctime>
34 #include <pthread.h>
35 
36 #ifndef _GNU_SOURCE
37 #define _GNU_SOURCE
38 #endif
39 #include <sys/statvfs.h>
40 #include "XrdOuc/XrdOucHash.hh"
41 
42 #ifdef __cplusplus
43  extern "C" {
44 #endif
45 
46 struct XrdFfsFsInfo {
47  time_t t;
48 // unsigned long f_blocks, f_bavail, f_bfree;
49  fsblkcnt_t f_blocks, f_bavail, f_bfree;
50 };
51 
52 pthread_mutex_t XrdFfsFsinfo_cache_mutex_wr = PTHREAD_MUTEX_INITIALIZER;
53 pthread_mutex_t XrdFfsFsinfo_cache_mutex_rd = PTHREAD_MUTEX_INITIALIZER;
54 
56 
57 int XrdFfsFsinfo_cache_search(int (*func)(const char*, const char*, struct statvfs*, uid_t), const char* rdrurl, const char* path, struct statvfs *stbuf, uid_t user_uid)
58 {
59  struct XrdFfsFsInfo *s;
60  int wlock, rc = 0, dofree = 0;
61  const char *p;
62  char* sname;
63 
64  wlock = pthread_mutex_trylock(&XrdFfsFsinfo_cache_mutex_wr);
65  pthread_mutex_lock(&XrdFfsFsinfo_cache_mutex_rd);
66 
67  p=strstr(path, "oss.cgroup=");
68  if (p != NULL && p[11] != '\0')
69  sname = strdup(p+11);
70  else
71  sname = strdup(" ");
72  s = XrdFfsFsinfoHtab.Find(sname);
73  if (s != NULL)
74  {
75  stbuf->f_blocks = s->f_blocks;
76  stbuf->f_bavail = s->f_bavail;
77  stbuf->f_bfree = s->f_bfree;
78  }
79  else
80  {
81  rc = (*func)(rdrurl, path, stbuf, user_uid);
82  s = (struct XrdFfsFsInfo*) malloc(sizeof(struct XrdFfsFsInfo));
83  s->t = 0;
84  dofree = 1;
85  }
86 
87  pthread_mutex_unlock(&XrdFfsFsinfo_cache_mutex_rd);
88  if (wlock == 0) // did get a lock for update
89  {
90  time_t curr_time = time(NULL);
91  if (curr_time - s->t > 120)
92  {
93  if (s->t != 0)
94  rc = (*func)(rdrurl, path, stbuf, user_uid);
95 
96  pthread_mutex_lock(&XrdFfsFsinfo_cache_mutex_rd);
97  s->t = curr_time;
98  s->f_blocks = stbuf->f_blocks;
99  s->f_bavail = stbuf->f_bavail;
100  s->f_bfree = stbuf->f_bfree;
101 
102  if (s->f_blocks != 0) // if s->f_blocks is zero, then this space token probably does not exist
104  else if (dofree) free(s);
105  pthread_mutex_unlock(&XrdFfsFsinfo_cache_mutex_rd);
106  }
107  pthread_mutex_unlock(&XrdFfsFsinfo_cache_mutex_wr);
108  }
109  free(sname);
110  return rc;
111 }
112 
113 
114 /* for testing
115 
116 void junkfunc(const char *rdrurl, const char *path, struct statvfs *stbuf, uid_t user_uid)
117 {
118  stbuf->f_blocks = rand();
119  stbuf->f_bavail = stbuf->f_blocks;
120  stbuf->f_bfree = stbuf->f_blocks;
121 }
122 
123 main() {
124  char name[100];
125  struct statvfs stbuf;
126 
127  void XrdFfsFsinfo_cache_init()
128  while (1) {
129  printf("name = "); // name should be /oss.cgroup=xyz
130  scanf("%s", name);
131  XrdFfsFsinfo_cache_search(&junkfunc, "rdr", name, &stbuf, 10);
132  printf("name %s space %lld\n", name, stbuf.f_blocks);
133  }
134  hdestroy_r(&XrdFfsFsinfoHtab);
135 }
136 
137 */
138 #ifdef __cplusplus
139  }
140 #endif
fsblkcnt_t f_bavail
Definition: XrdFfsFsinfo.cc:49
pthread_mutex_t XrdFfsFsinfo_cache_mutex_rd
Definition: XrdFfsFsinfo.cc:53
XrdOucHash< struct XrdFfsFsInfo > XrdFfsFsinfoHtab
Definition: XrdFfsFsinfo.cc:55
fsblkcnt_t f_bfree
Definition: XrdFfsFsinfo.cc:49
int XrdFfsFsinfo_cache_search(int(*func)(const char *, const char *, struct statvfs *, uid_t), const char *rdrurl, const char *path, struct statvfs *stbuf, uid_t user_uid)
Definition: XrdFfsFsinfo.cc:57
fsblkcnt_t f_blocks
Definition: XrdFfsFsinfo.cc:49
pthread_mutex_t XrdFfsFsinfo_cache_mutex_wr
Definition: XrdFfsFsinfo.cc:52
XrdOucHash_Options
Definition: XrdOucHash.hh:51
@ Hash_keepdata
Definition: XrdOucHash.hh:57
@ Hash_default
Definition: XrdOucHash.hh:51
int statvfs(const char *path, struct statvfs *buf)