XRootD
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 
34 #include "XrdOfs/XrdOfsChkPnt.hh"
35 #include "XrdOfs/XrdOfsConfigCP.hh"
36 #include "XrdOss/XrdOss.hh"
37 #include "XrdOuc/XrdOuca2x.hh"
38 #include "XrdOuc/XrdOucNSWalk.hh"
39 #include "XrdOuc/XrdOucStream.hh"
40 #include "XrdOuc/XrdOucString.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 
48 extern XrdOss *XrdOfsOss;
49 extern XrdSysError OfsEroute;
50 
51 /******************************************************************************/
52 /* S t a t i c M e m b e r s */
53 /******************************************************************************/
54 
55 char *XrdOfsConfigCP::Path = 0;
56 long long XrdOfsConfigCP::MaxSZ = 1024*1024;
57 int XrdOfsConfigCP::MaxVZ = 16;
58 bool XrdOfsConfigCP::cprErrNA = true;
59 bool XrdOfsConfigCP::Enabled = true;
60 bool XrdOfsConfigCP::isProxy = false;
61 bool 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 //
199 do{ 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 
248 void 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
static char * Target(const char *ckpfn)
static int MaxVZ
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)
Definition: XrdOucNSWalk.cc:93
const char * c_str() const
void append(const int i)
static char * genPath(const char *path, const char *inst, const char *psfx=0)
Definition: XrdOucUtils.cc:417
static const char * InstName(int TranOpt=0)
Definition: XrdOucUtils.cc:732
static int makePath(char *path, mode_t mode, bool reset=false)
Definition: XrdOucUtils.cc:917
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)
Definition: XrdSysError.cc:95
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)
Definition: XrdSysError.cc:141
XrdCmsConfig Config
XrdPosixStats Stats
Definition: XrdPosixFile.cc:64
struct NSEnt * Next
Definition: XrdOucNSWalk.hh:48