XRootD
XrdFrmAdminFiles.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d F r m A d m i n F i l e s . c c */
4 /* */
5 /* (c) 2010 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 <cctype>
32 #include <cerrno>
33 #include <fcntl.h>
34 #include <cstdio>
35 #include <cstring>
36 #include <ctime>
37 #include <unistd.h>
38 #include <sys/param.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 
42 #include "XrdFrc/XrdFrcUtils.hh"
43 #include "XrdFrc/XrdFrcXAttr.hh"
44 #include "XrdFrm/XrdFrmAdmin.hh"
45 #include "XrdFrm/XrdFrmConfig.hh"
46 #include "XrdFrm/XrdFrmFiles.hh"
47 
48 #include "XrdOuc/XrdOucXAttr.hh"
49 
50 using namespace XrdFrm;
51 
52 /******************************************************************************/
53 /* c k A t t r */
54 /******************************************************************************/
55 
56 char XrdFrmAdmin::ckAttr(int What, const char *Lfn, char *Pfn, int Pfnsz)
57 {
58  struct stat Stat;
59  const char *Msg = (What & mkLF ? "mark " : (What & mkMF ? "mmap " : "pin "));
60  char Buff[80], Resp;
61 
62 // Get the actual pfn for the base file
63 //
64  if (!Config.LocalPath(Lfn, Pfn, Pfnsz)) {finalRC = 4; return 0;}
65 
66 // Get file state
67 //
68  if (stat(Pfn, &Stat))
69  {Emsg(errno, "ckAttr ", Msg, Lfn); return 0;}
70 
71 // If this is not a directory, then all is well
72 //
73  if ((Stat.st_mode & S_IFMT) != S_IFDIR)
74  {if (!Opt.All) return 'f';
75  Emsg(ENOTDIR, "ckAttr ", Msg, "files in ", Lfn);
76  return 0;
77  }
78 
79 // Make sure the whole directory is being considered
80 //
81  if (Opt.All || Opt.Recurse) return 'd';
82 
83 // Ask what we should do
84 //
85  sprintf(Buff, "%s ALL files in directory ", Msg);
86  Buff[0] = toupper(*Buff);
87  if ((Resp = XrdFrcUtils::Ask('n', Buff, Lfn)) == 'y') return 'd';
88  return (Resp == 'a' ? 'a' : 0);
89 }
90 
91 /******************************************************************************/
92 /* m k M a r k */
93 /******************************************************************************/
94 
95 int XrdFrmAdmin::mkMark(const char *Lfn)
96 {
97  XrdFrmFileset *sP;
98  XrdFrmFiles *fP;
99  char Pfn[MAXPATHLEN+8], Resp;
100  int opts = (Opt.Recurse ? XrdFrmFiles::Recursive : 0);
101  int ec = 0, Adj = (Opt.MPType == 'p' ? 0 : -113);
102 
103 // Check what we are dealing with
104 //
105  if (!(Resp = ckAttr(mkLF, Lfn, Pfn, sizeof(Pfn)-8))) return 1;
106  if (Resp == 'a') return 0;
107 
108 // If this is a file then do one file
109 //
110  if (Resp == 'f')
111  {if (XrdFrcUtils::updtCpy(Pfn, Adj)) numFiles++;
112  return 1;
113  }
114 
115 // Process the directory
116 //
117  fP = new XrdFrmFiles(Pfn, opts | XrdFrmFiles::NoAutoDel);
118  while((sP = fP->Get(ec,1)))
119  {if (sP->baseFile()
120  && XrdFrcUtils::updtCpy(sP->basePath(), Adj)) numFiles++;
121  delete sP;
122  }
123 
124 // All done
125 //
126  if (ec) finalRC = 4;
127  delete fP;
128  return 1;
129 }
130 
131 /******************************************************************************/
132 /* m k M m a p */
133 /******************************************************************************/
134 
135 int XrdFrmAdmin::mkMmap(const char *Lfn)
136 {
138  XrdFrmFileset *sP;
139  XrdFrmFiles *fP;
140  const char *bFn;
141  char Pfn[MAXPATHLEN+8], Resp;
142  int opts = (Opt.Recurse ? XrdFrmFiles::Recursive : 0);
143  int ec, doSet = 0;
144 
145 // Check what we are dealing with
146 //
147  if (!(Resp = ckAttr(mkMF, Lfn, Pfn, sizeof(Pfn)-8))) return 1;
148  if (Resp == 'a') return 0;
149 
150 // Construct the proper mmap attribute
151 //
152  if (!Opt.Local)
153  { doSet = memInfo.Attr.Flags = XrdFrcXAttrMem::memMap;
154  if (Opt.Fix) memInfo.Attr.Flags |= XrdFrcXAttrMem::memLock;
155  if (Opt.Keep) memInfo.Attr.Flags |= XrdFrcXAttrMem::memKeep;
156  }
157 
158 // If this is a file then do one file
159 //
160  if (Resp == 'f')
161  {if ((doSet ? !memInfo.Set(Pfn) : !memInfo.Del(Pfn))) numFiles++;
162  return 1;
163  }
164 
165 // Process the directory
166 //
167  fP = new XrdFrmFiles(Pfn, opts | XrdFrmFiles::NoAutoDel);
168  while((sP = fP->Get(ec,1)))
169  {if (sP->baseFile() && (bFn = sP->basePath())
170  && (doSet ? !memInfo.Set(bFn) : !memInfo.Del(bFn))) numFiles++;
171  delete sP;
172  }
173 
174 
175 // All done
176 //
177  if (ec) finalRC = 4;
178  delete fP;
179  return 1;
180 }
181 
182 /******************************************************************************/
183 /* m k P i n */
184 /******************************************************************************/
185 
186 int XrdFrmAdmin::mkPin(const char *Lfn)
187 {
189  XrdFrmFileset *sP;
190  XrdFrmFiles *fP;
191  const char *bFn;
192  char Pfn[MAXPATHLEN+8], Resp;
193  int opts = (Opt.Recurse ? XrdFrmFiles::Recursive : 0);
194  int ec, doSet;
195 
196 // Check what we are dealing with
197 //
198  if (!(Resp = ckAttr(mkPF, Lfn, Pfn, sizeof(Pfn)-8))) return 1;
199  if (Resp == 'a') return 0;
200 
201 // Construct the proper pin attribute
202 //
203  if (Opt.ktAlways) pinInfo.Attr.Flags = XrdFrcXAttrPin::pinPerm;
204  else if (Opt.KeepTime)
205  {pinInfo.Attr.pinTime = static_cast<long long>(Opt.KeepTime);
206  if (Opt.ktIdle) pinInfo.Attr.Flags = XrdFrcXAttrPin::pinIdle;
207  else pinInfo.Attr.Flags = XrdFrcXAttrPin::pinKeep;
208  }
209  doSet = (Opt.ktAlways || Opt.KeepTime ? 1 : 0);
210 
211 // If this is a file then do one file
212 //
213  if (Resp == 'f')
214  {if ((doSet ? !pinInfo.Set(Pfn) : !pinInfo.Del(Pfn))) numFiles++;
215  return 1;
216  }
217 
218 // Process the directory
219 //
220  fP = new XrdFrmFiles(Pfn, opts | XrdFrmFiles::NoAutoDel);
221  while((sP = fP->Get(ec,1)))
222  {if (sP->baseFile() && (bFn = sP->basePath())
223  && (doSet ? !pinInfo.Set(bFn) : !pinInfo.Del(bFn))) numFiles++;
224  delete sP;
225  }
226 
227 // All done
228 //
229  if (ec) finalRC = 4;
230  delete fP;
231  return 1;
232 }
233 
234 /******************************************************************************/
235 /* O b s o l e t e M e t h o d s */
236 /******************************************************************************/
237 /******************************************************************************/
238 /* m k F i l e */
239 /******************************************************************************/
240 
241 int XrdFrmAdmin::mkFile(int What, const char *Path, const char *Data, int DLen)
242 {
243  static const mode_t Mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
244  struct stat Stat;
245  time_t Tid;
246  uid_t Uid;
247  gid_t Gid;
248  char *pfn, baseFN[1038], tempFN[1038];
249  int rc, theFD;
250 
251 // Check if we are handling hidden files
252 //
253  if (!Config.lockFN || *Config.lockFN != '.') pfn = baseFN;
254  else {*baseFN = '.'; pfn = baseFN+1;}
255 
256 // Get the actual pfn for the base file
257 //
258  if (What & isPFN) strcpy(pfn, Path);
259  else if (!Config.LocalPath(Path, pfn, sizeof(baseFN)-6)) return 0;
260 
261 // Make sure the base file exists
262 //
263  if (stat(pfn, &Stat)) {Emsg(errno,"stat pfn ",pfn); return 0;}
264 
265 // Add the appropriate suffix
266 //
267  strcat(baseFN, (What & mkLF ? ".lock" : ".pin"));
268  strcpy(tempFN, baseFN);
269  strcat(tempFN, ".TEMP");
270 
271 // Check if we need to merely delete the pin file
272 //
273  if ((What & mkPF) && !Opt.ktAlways && !Opt.KeepTime)
274  {if (unlink(baseFN)) {Emsg(errno, "remove pfn ", tempFN); return 0;}
275  return 1;
276  }
277 
278 // Open the file, possibly creating it
279 //
280  if ((theFD = open(tempFN, O_RDWR | O_CREAT | O_TRUNC, Mode)) < 0)
281  {Emsg(errno, "open pfn ", tempFN); return 0;}
282 
283 // If we need to write some data into the file
284 //
285  if (Data && DLen)
286  {do {rc = write(theFD, Data, DLen);
287  if (rc < 0) {if (errno != EINTR) break;}
288  else {Data += rc; DLen -= rc;}
289  } while(DLen > 0);
290  if (rc< 0) {Emsg(errno, "write pfn ", tempFN);
291  close(theFD); unlink(tempFN); return 0;
292  }
293  }
294 
295 // Set correct ownership
296 //
297  Uid = (int(Opt.Uid) < 0 ? Stat.st_uid : Opt.Uid);
298  Gid = (int(Opt.Gid) < 0 ? Stat.st_gid : Opt.Gid);
299  if (Stat.st_uid != Uid || Stat.st_gid != Gid)
300  {do {rc = fchown(theFD, Uid, Gid);} while(rc && errno == EINTR);
301  if (rc) {Emsg(errno, "set uid/gid for pfn ", tempFN);
302  close(theFD); unlink(tempFN); return 0;
303  }
304  }
305 
306 // Set the file time (mig -> lock < file; prg -> lock > file)
307 //
308  if (What & mkLF) {Tid = Stat.st_mtime + (Opt.MPType == 'p' ? +113 : -113);}
309  else {Tid = (DLen || Opt.ktAlways ? time(0) : Opt.KeepTime);
310  if (Opt.ktAlways)
311  {do {rc = fchmod(theFD, Mode);} while(rc && errno == EINTR);
312  if (rc) {Emsg(errno, "set mode for pfn ", tempFN);
313  close(theFD); unlink(tempFN); return 0;
314  }
315  }
316  }
317  close(theFD);
318  if (!XrdFrcUtils::Utime(tempFN,Tid)) {unlink(tempFN); return 0;}
319 
320 // Finish up
321 //
322  if (rename(tempFN, baseFN))
323  {Emsg(errno, "rename pfn ", tempFN);
324  unlink(tempFN);
325  return 0;
326  }
327  return 1;
328 }
329 
330 /******************************************************************************/
331 /* m k L o c k */
332 /******************************************************************************/
333 
334 int XrdFrmAdmin::mkLock(const char *Lfn)
335 {
336  XrdFrmFileset *sP;
337  XrdFrmFiles *fP;
338  char Pfn[MAXPATHLEN+8], Resp;
339  int opts = (Opt.Recurse ? XrdFrmFiles::Recursive : 0);
340  int ec = 0;
341 
342 // Check what we are dealing with
343 //
344  if (!(Resp = mkStat(mkLF, Lfn, Pfn, sizeof(Pfn)-8))) return 1;
345  if (Resp == 'a') return 0;
346 
347 // If this is a file then do one file
348 //
349  if (Resp == 'f')
350  {if (mkFile(mkLF|isPFN, Pfn)) numFiles++;
351  return 1;
352  }
353 
354 // Process the directory
355 //
356  fP = new XrdFrmFiles(Pfn, opts | XrdFrmFiles::NoAutoDel);
357  while((sP = fP->Get(ec,1)))
358  {if (sP->baseFile() && mkFile(mkLF|isPFN, sP->basePath())) numFiles++;
359  delete sP;
360  }
361 
362 // All done
363 //
364  if (ec) finalRC = 4;
365  delete fP;
366  return 1;
367 }
368 
369 /******************************************************************************/
370 /* m k S t a t */
371 /******************************************************************************/
372 
373 char XrdFrmAdmin::mkStat(int What, const char *Lfn, char *Pfn, int Pfnsz)
374 {
375  struct stat Stat;
376  const char *Msg = (What & mkLF ? "create lock file for "
377  : "create pin file for ");
378  const char *Msh = (What & mkLF ? "create lock files in "
379  : "create pin files in ");
380  char Resp;
381 
382 // Get the actual pfn for the base file
383 //
384  if (!Config.LocalPath(Lfn, Pfn, Pfnsz)) {finalRC = 4; return 0;}
385 
386 // Get file state
387 //
388  if (stat(Pfn, &Stat))
389  {Emsg(errno, "create ", Msg, Lfn); return 0;}
390 
391 // If this is not a directory, then all is well
392 //
393  if ((Stat.st_mode & S_IFMT) != S_IFDIR)
394  {if (!Opt.All) return 'f';
395  Emsg(ENOTDIR, "create ", Msh, Lfn);
396  return 0;
397  }
398 
399 // Make sure the whole directory is being considered
400 //
401  if (Opt.All || Opt.Recurse) return 'd';
402 
403 // Ask what we should do
404 //
405  Msg = (What & mkLF ? "Apply makelf to ALL files in directory "
406  : "Apply pin to ALL files in directory ");
407  if ((Resp = XrdFrcUtils::Ask('n', Msg, Lfn)) == 'y') return 'd';
408  return (Resp == 'a' ? 'a' : 0);
409 }
struct stat Stat
Definition: XrdCks.cc:49
int stat(const char *path, struct stat *buf)
int open(const char *path, int oflag,...)
int unlink(const char *path)
int rename(const char *oldpath, const char *newpath)
ssize_t write(int fildes, const void *buf, size_t nbyte)
#define close(a)
Definition: XrdPosix.hh:43
int Mode
XrdOucString Path
struct myOpts opts
static char Ask(char dflt, const char *Msg1, const char *Msg2="", const char *Msg3="")
Definition: XrdFrcUtils.cc:56
static int Utime(const char *Path, time_t tVal)
Definition: XrdFrcUtils.cc:296
static int updtCpy(const char *Pfn, int Adj)
Definition: XrdFrcUtils.cc:277
static const char memKeep
Definition: XrdFrcXAttr.hh:98
static const char memLock
Definition: XrdFrcXAttr.hh:99
static const char memMap
Definition: XrdFrcXAttr.hh:97
static const char pinKeep
Definition: XrdFrcXAttr.hh:135
static const char pinPerm
Definition: XrdFrcXAttr.hh:133
static const char pinIdle
Definition: XrdFrcXAttr.hh:134
long long pinTime
Definition: XrdFrcXAttr.hh:127
int LocalPath(const char *oldp, char *newp, int newpsz)
const char * lockFN
Definition: XrdFrmConfig.hh:63
static const int NoAutoDel
Definition: XrdFrmFiles.hh:123
XrdFrmFileset * Get(int &rc, int noBase=0)
Definition: XrdFrmFiles.cc:340
static const int Recursive
Definition: XrdFrmFiles.hh:121
XrdOucNSWalk::NSEnt * baseFile()
Definition: XrdFrmFiles.hh:60
const char * basePath()
Definition: XrdFrmFiles.hh:61
int Del(const char *Path, int fd=-1)
Definition: XrdOucXAttr.hh:119
int Set(const char *Path, int fd=-1)
Definition: XrdOucXAttr.hh:139
XrdFrmConfig Config