XRootD
Loading...
Searching...
No Matches
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"
46#include "XrdFrm/XrdFrmFiles.hh"
47
48#include "XrdOuc/XrdOucXAttr.hh"
49
50using namespace XrdFrm;
51
52/******************************************************************************/
53/* c k A t t r */
54/******************************************************************************/
55
56char 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
95int 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
135int 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
186int 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
241int 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
334int 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
373char 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
#define close(a)
Definition XrdPosix.hh:43
#define write(a, b, c)
Definition XrdPosix.hh:110
#define open
Definition XrdPosix.hh:71
#define unlink(a)
Definition XrdPosix.hh:108
#define stat(a, b)
Definition XrdPosix.hh:96
#define rename(a, b)
Definition XrdPosix.hh:87
int Mode
XrdOucString Path
struct myOpts opts
if(ec< 0) ec
static char Ask(char dflt, const char *Msg1, const char *Msg2="", const char *Msg3="")
static int Utime(const char *Path, time_t tVal)
static int updtCpy(const char *Pfn, int Adj)
static const char memKeep
static const char memLock
static const char memMap
static const char pinKeep
static const char pinPerm
static const char pinIdle
int LocalPath(const char *oldp, char *newp, int newpsz)
const char * lockFN
static const int NoAutoDel
XrdFrmFileset * Get(int &rc, int noBase=0)
static const int Recursive
const char * basePath()
XrdOucNSWalk::NSEnt * baseFile()
int Del(const char *Path, int fd=-1)
int Set(const char *Path, int fd=-1)
XrdFrmConfig Config