XRootD
Loading...
Searching...
No Matches
XrdOfsConfigCP.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d O f s C o n f i g C P . c c */
4/* */
5/* (c) 2020 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 <cstdio>
32#include <cstring>
33
36#include "XrdOss/XrdOss.hh"
37#include "XrdOuc/XrdOuca2x.hh"
41#include "XrdOuc/XrdOucUtils.hh"
42#include "XrdSys/XrdSysError.hh"
43
44/******************************************************************************/
45/* G l o b a l O b j e c t s */
46/******************************************************************************/
47
48extern XrdOss *XrdOfsOss;
50
51/******************************************************************************/
52/* S t a t i c M e m b e r s */
53/******************************************************************************/
54
55char *XrdOfsConfigCP::Path = 0;
56long long XrdOfsConfigCP::MaxSZ = 1024*1024;
58bool XrdOfsConfigCP::cprErrNA = true;
59bool XrdOfsConfigCP::Enabled = true;
60bool XrdOfsConfigCP::isProxy = false;
61bool XrdOfsConfigCP::EnForce = false;
62
63/******************************************************************************/
64/* I n i t */
65/******************************************************************************/
66
68{
69 const int AMode = S_IRWXU|S_IRGRP|S_IXGRP;
70 const char *endMsg = "completed.";
71 char *aPath;
72 int rc;
73 bool autoDis = false;
74
75// If we are not enabled then do nothing
76//
77 if (!Enabled || isProxy) return true;
78
79// Print warm-up message
80//
81 OfsEroute.Say("++++++ Checkpoint initialization started.");
82
83// If there is no path then generate the default path
84//
85 if (Path)
86 {aPath = XrdOucUtils::genPath(Path, XrdOucUtils::InstName(-1), "chkpnt/");
87 free(Path);
88 Path = aPath;
89 } else {
90 if (!(aPath = getenv("XRDADMINPATH")))
91 {OfsEroute.Emsg("Config",
92 "Unable to determine adminpath for chkpnt files.");
93 return false;
94 }
95 Path = XrdOucUtils::genPath(aPath, (char *)0, "chkpnt/");
96 }
97
98// Make sure directory path exists
99//
100 if ((rc = XrdOucUtils::makePath(Path, AMode)))
101 {OfsEroute.Emsg("Config", rc, "create path for", Path);
102 return false;
103 }
104
105// We generally prohibit placing the checkpoint directory in /tmp unless
106// "enable" has been specified.
107//
108 if (!strncmp(Path, "/tmp/", 5))
109 {if (EnForce) OfsEroute.Say("Config warning: rooting the checkpoint "
110 "directory in '/tmp' is ill-advised!");
111 else autoDis = true;
112 }
113
114// Prepare to list contents of the directory
115//
117 XrdOucNSWalk::NSEnt *nsX, *nsP = nsWalk.Index(rc);
118 if (rc)
119 {OfsEroute.Emsg("Config", rc, "list CKP path", Path);
120 return false;
121 }
122
123// Process all files
124//
125 Stats stats;
126 while((nsX = nsP))
127 {Recover(nsX->Path, stats);
128 nsP = nsP->Next;
129 delete nsX;
130 }
131
132// Print message if we found anything
133//
134 if (stats.numFiles)
135 {char mBuff[256];
136 snprintf(mBuff, sizeof(mBuff),
137 "%d of %d checkpoints restored, %d failed, and %d skipped.",
138 stats.numRecov, stats.numFiles, stats.numError, stats.numSkipd);
139 OfsEroute.Say("Config ", mBuff);
140 if (stats.numUnres)
141 {snprintf(mBuff, sizeof(mBuff), "%d", stats.numUnres);
142 OfsEroute.Say("Config warning: ", mBuff, " unresolved checkpoint "
143 "restore failures found!");
144 endMsg = "requires attention!";
145 }
146 }
147
148// Check if we need to disable checkpoint processing at this point
149//
150 if (autoDis)
151 {OfsEroute.Say("Config warning: checkpoints disabled because the "
152 "checkpoint directory is rooted in '/tmp'!");
153 Enabled = false;
154 }
155
156// Print final mesage
157//
158 OfsEroute.Say("++++++ Checkpoint initialization ", endMsg);
159 return true;
160}
161
162/******************************************************************************/
163/* P a r s e */
164/******************************************************************************/
165
166/* Function: Parse
167
168 Purpose: To parse the directive: chkpnt [disable|enable]
169 [cprerr <opt>]
170 [maxsz <sz>] [path <path>]
171
172 disable Disables checkpointing.
173 enable Enables checkpointing.
174 <opt> Checkpoint restore error option:
175 makero - make the source file read/only and
176 rename checkpoint file.
177 stopio - make file neither readable nor writable and
178 rename checkpoint file.
179 <sz> the maximum size of a checkpoint. The minimum and default
180 value is 1m.
181 <path> path to where checkpoint files are to be placed.
182 The default is <adminpath>/.ofs/chkpnt
183*/
184
186{
187 static const int minSZ = 1024*1024;
188 char *val;
189
190// Get the size
191//
192 if (!(val = Config.GetWord()) || !val[0])
193 {OfsEroute.Emsg("Config", "chkpnt parameters not specified");
194 return false;
195 }
196
197// Process options
198//
199do{ if (!strcmp(val, "disable")) Enabled = EnForce = false;
200 else if (!strcmp(val, "enable")) Enabled = EnForce = true;
201 else if (!strcmp(val, "cprerr"))
202 { if (!strcmp(val, "makero")) cprErrNA = false;
203 else if (!strcmp(val, "stopio")) cprErrNA = true;
204 else {OfsEroute.Emsg("Config","invalid chkpnt cperr option -",val);
205 return false;
206 }
207 }
208 else if (!strcmp(val, "maxsz"))
209 {if (!(val = Config.GetWord()) || !val[0])
210 {OfsEroute.Emsg("Config", "chkpnt maxsz value not specified");
211 return false;
212 }
213 if (XrdOuca2x::a2sz(OfsEroute,"chkpnt maxsz", val, &MaxSZ, minSZ))
214 return false;
215 }
216 else if (!strcmp(val, "path"))
217 {if (!(val = Config.GetWord()) || !val[0])
218 {OfsEroute.Emsg("Config", "chkpnt path value not specified");
219 return false;
220 }
221 if (*val != '/')
222 {OfsEroute.Emsg("Config", "chkpnt path is not absolute");
223 return false;
224 }
225 if (Path) free(Path);
226 int n = strlen(val);
227 if (val[n-1] == '/') Path = strdup(val);
228 else {XrdOucString pstr(n+1);
229 pstr = val; pstr.append('/');
230 Path = strdup(pstr.c_str());
231 }
232 }
233 else {OfsEroute.Emsg("Config", "invalid chkpnt parameter -", val);
234 return false;
235 }
236
237 } while((val = Config.GetWord()));
238
239// All done
240//
241 return true;
242}
243
244/******************************************************************************/
245/* R e c o v e r */
246/******************************************************************************/
247
248void XrdOfsConfigCP::Recover(const char *ckpPath, struct Stats &stats)
249{
250 const char *sfx = rindex(ckpPath, '.');
251
252// Count of files we have seen
253//
254 stats.numFiles++;
255
256// Check if this is an unresolved error
257//
258 if ( sfx && !strcmp(sfx, ".ckperr"))
259 {char *fName = XrdOfsCPFile::Target(ckpPath);
260 OfsEroute.Say("Config warning: unresolved checkpoint error in '",
261 ckpPath, "' for file '", fName, "'!");
262 free(fName);
263 stats.numUnres++;
264 return;
265 }
266
267// Make sure this file end with '.ckp')
268//
269 if (!sfx || strcmp(sfx, ".ckp"))
270 {OfsEroute.Say("Config warning: unrecognized checkpoint file '",
271 ckpPath, "' skipped!");
272 stats.numSkipd++;
273 return;
274 }
275
276// Get a new oss file, create a checkpoint object and try to restore the file
277//
278 XrdOssDF *ossFP = XrdOfsOss->newFile("checkpoint");
279 XrdOfsChkPnt chkPnt(*ossFP, 0, ckpPath);
280 if (chkPnt.Restore()) stats.numError++;
281 else stats.numRecov++;
282 delete ossFP;
283}
XrdOss * XrdOfsOss
Definition XrdOfs.cc:163
XrdSysError OfsEroute
XrdSysError OfsEroute(0)
XrdOss * XrdOfsOss
Definition XrdOfs.cc:163
static char * Target(const char *ckpfn)
static bool Init()
static bool Parse(XrdOucStream &Config)
static bool isProxy
static bool EnForce
static long long MaxSZ
static bool Enabled
static bool cprErrNA
static char * Path
virtual XrdOssDF * newFile(const char *tident)=0
static const int retFile
NSEnt * Index(int &rc, const char **dPath=0)
void append(const int i)
const char * c_str() const
static char * genPath(const char *path, const char *inst, const char *psfx=0)
static const char * InstName(int TranOpt=0)
static int makePath(char *path, mode_t mode, bool reset=false)
static int a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
Definition XrdOuca2x.cc:257
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
struct NSEnt * Next