XRootD
XrdBwmConfig.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d B w m C o n f i g . 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 Deprtment 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 <unistd.h>
32 #include <cctype>
33 #include <cerrno>
34 #include <fcntl.h>
35 #include <cstdlib>
36 #include <strings.h>
37 #include <cstdio>
38 #include <sys/param.h>
39 
40 #include "XrdBwm/XrdBwm.hh"
41 #include "XrdBwm/XrdBwmLogger.hh"
42 #include "XrdBwm/XrdBwmPolicy.hh"
43 #include "XrdBwm/XrdBwmPolicy1.hh"
44 #include "XrdBwm/XrdBwmTrace.hh"
45 
46 #include "XrdOuc/XrdOuca2x.hh"
47 #include "XrdOuc/XrdOucEnv.hh"
49 #include "XrdSys/XrdSysError.hh"
50 #include "XrdSys/XrdSysHeaders.hh"
51 #include "XrdOuc/XrdOucStream.hh"
52 #include "XrdOuc/XrdOucTrace.hh"
53 
55 
56 /******************************************************************************/
57 /* d e f i n e s */
58 /******************************************************************************/
59 
60 #define TS_Xeq(x,m) if (!strcmp(x,var)) return m(Config,Eroute);
61 
62 #define TS_Str(x,m) if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;}
63 
64 #define TS_PList(x,m) if (!strcmp(x,var)) \
65  {m.Insert(new XrdOucPList(val,1)); return 0;}
66 
67 #define TS_Chr(x,m) if (!strcmp(x,var)) {m = val[0]; return 0;}
68 
69 #define TS_Bit(x,m,v) if (!strcmp(x,var)) {m |= v; Config.Echo(); return 0;}
70 
71 #define Max(x,y) (x > y ? x : y)
72 
73 /******************************************************************************/
74 /* C o n f i g u r e */
75 /******************************************************************************/
76 
78 /*
79  Function: Establish default values using a configuration file.
80 
81  Input: None.
82 
83  Output: 0 upon success or !0 otherwise.
84 */
85  char *var;
86  int cfgFD, retc, NoGo = 0;
87  XrdOucEnv myEnv;
88  XrdOucStream Config(&Eroute, getenv("XRDINSTANCE"), &myEnv, "=====> ");
89 
90 // Print warm-up message
91 //
92  Eroute.Say("++++++ Bwm initialization started.");
93 
94 // Get the debug level from the command line
95 //
96  if (getenv("XRDDEBUG")) BwmTrace.What = TRACE_ALL;
97 
98 // If there is no config file, return with the defaults sets.
99 //
100  if( !ConfigFN || !*ConfigFN)
101  Eroute.Emsg("Config", "Configuration file not specified.");
102  else {
103  // Try to open the configuration file.
104  //
105  if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
106  return Eroute.Emsg("Config", errno, "open config file",
107  ConfigFN);
108  Config.Attach(cfgFD);
109  static const char *cvec[] = { "*** bwm ofs plugin config:", 0 };
110  Config.Capture(cvec);
111 
112  // Now start reading records until eof.
113  //
114  while((var = Config.GetMyFirstWord()))
115  {if (!strncmp(var, "bwm.", 4))
116  if (ConfigXeq(var+4,Config,Eroute)) {Config.Echo();NoGo=1;}
117  }
118 
119  // Now check if any errors occurred during file i/o
120  //
121  if ((retc = Config.LastError()))
122  NoGo = Eroute.Emsg("Config", -retc, "read config file",
123  ConfigFN);
124  Config.Close();
125  }
126 
127 // Determine whether we should initialize authorization
128 //
129  if (Authorize) NoGo |= setupAuth(Eroute);
130 
131 // Establish scheduling policy
132 //
133  if (PolLib) NoGo |= setupPolicy(Eroute);
134  else Policy = new XrdBwmPolicy1(PolSlotsIn, PolSlotsOut);
135 
136 // Start logger object
137 //
138  if (!NoGo && Logger) NoGo = Logger->Start(&Eroute);
139 
140 // Inform the handle of the policy and logger
141 //
142  if (!NoGo) XrdBwmHandle::setPolicy(Policy, Logger);
143 
144 // All done
145 //
146  Eroute.Say("------ Bwm initialization ", (NoGo ? "failed." : "completed."));
147  return NoGo;
148 }
149 
150 /******************************************************************************/
151 /* p r i v a t e f u n c t i o n s */
152 /******************************************************************************/
153 /******************************************************************************/
154 /* C o n f i g X e q */
155 /******************************************************************************/
156 
158  XrdSysError &Eroute)
159 {
160  TS_Bit("authorize", Authorize, 1);
161  TS_Xeq("authlib", xalib);
162  TS_Xeq("log", xlog);
163  TS_Xeq("policy", xpol);
164  TS_Xeq("trace", xtrace);
165 
166  // No match found, complain.
167  //
168  Eroute.Say("Config warning: ignoring unknown directive '",var,"'.");
169  Config.Echo();
170  return 0;
171 }
172 
173 /******************************************************************************/
174 /* x a l i b */
175 /******************************************************************************/
176 
177 /* Function: xalib
178 
179  Purpose: To parse the directive: authlib <path> [<parms>]
180 
181  <path> the path of the authorization library to be used.
182  <parms> optional parms to be passed
183 
184  Output: 0 upon success or !0 upon failure.
185 */
186 
187 int XrdBwm::xalib(XrdOucStream &Config, XrdSysError &Eroute)
188 {
189  char *val, parms[1024];
190 
191 // Get the path
192 //
193  if (!(val = Config.GetWord()) || !val[0])
194  {Eroute.Emsg("Config", "authlib not specified"); return 1;}
195 
196 // Record the path
197 //
198  if (AuthLib) free(AuthLib);
199  AuthLib = strdup(val);
200 
201 // Record any parms
202 //
203  if (!Config.GetRest(parms, sizeof(parms)))
204  {Eroute.Emsg("Config", "authlib parameters too long"); return 1;}
205  if (AuthParm) free(AuthParm);
206  AuthParm = (*parms ? strdup(parms) : 0);
207  return 0;
208 }
209 
210 /******************************************************************************/
211 /* x l o g */
212 /******************************************************************************/
213 
214 /* Function: xlog
215 
216  Purpose: Parse directive: log {* | <|prog> | <>path>}
217 
218  <prog> - is the program to execute and dynamically feed messages
219  about the indicated events. Messages are piped to prog.
220  <path> - is the udp named socket to receive the message. The
221  server creates the path if it's not present. If <path>
222  is an asterisk, then messages are written to standard
223  log file.
224 
225  Output: 0 upon success or !0 upon failure.
226 */
227 int XrdBwm::xlog(XrdOucStream &Config, XrdSysError &Eroute)
228 {
229  char *val, parms[1024];
230 
231  if (!(val = Config.GetWord()))
232  {Eroute.Emsg("Config", "log parameters not specified"); return 1;}
233 
234 // Get the remaining parameters
235 //
236  Config.RetToken();
237  if (!Config.GetRest(parms, sizeof(parms)))
238  {Eroute.Emsg("Config", "log parameters too long"); return 1;}
239  val = (*parms == '|' ? parms+1 : parms);
240 
241 // Create a log object
242 //
243  if (Logger) delete Logger;
244  Logger = new XrdBwmLogger(val);
245 
246 // All done
247 //
248  return 0;
249 }
250 
251 /******************************************************************************/
252 /* x p o l */
253 /******************************************************************************/
254 
255 /* Function: xpol
256 
257  Purpose: To parse the directive: policy args
258 
259  Args: {maxslots <innum> <outnum> | lib <path> [<parms>]}
260 
261  <num> maximum number of slots available.
262  <path> if preceeded by lib, the path of the policy library to
263  be used; otherwise, the file that describes policy.
264  <parms> optional parms to be passed
265 
266  Output: 0 upon success or !0 upon failure.
267 */
268 
269 int XrdBwm::xpol(XrdOucStream &Config, XrdSysError &Eroute)
270 {
271  char *val, parms[2048];
272  int pl;
273 
274 // Get next token
275 //
276  if (!(val = Config.GetWord()) || !val[0])
277  {Eroute.Emsg("Config", "policy not specified"); return 1;}
278 
279 // Start afresh
280 //
281  if (PolLib) {free(PolLib); PolLib = 0;}
282  if (PolParm) {free(PolParm); PolParm = 0;}
283  PolSlotsIn = PolSlotsOut = 0;
284 
285 // If the word maxslots then this is a simple policy
286 //
287  if (!strcmp("maxslots", val))
288  {if (!(val = Config.GetWord()) || !val[0])
289  {Eroute.Emsg("Config", "policy in slots not specified"); return 1;}
290  if (XrdOuca2x::a2i(Eroute,"policy in slots",val,&pl,0,32767)) return 1;
291  PolSlotsIn = pl;
292  if (!(val = Config.GetWord()) || !val[0])
293  {Eroute.Emsg("Config", "policy out slots not specified"); return 1;}
294  if (XrdOuca2x::a2i(Eroute,"policy out slots",val,&pl,0,32767)) return 1;
295  PolSlotsOut = pl;
296  return 0;
297  }
298 
299 // Make sure the word is lib
300 //
301  if (strcmp("lib", val))
302  {Eroute.Emsg("Config", "invalid policy keyword -", val); return 1;}
303  if (!(val = Config.GetWord()) || !val[0])
304  {Eroute.Emsg("Config", "policy library not specified"); return 1;}
305 
306 // Set the library
307 //
308  PolLib = strdup(val);
309 
310 // Get any parameters
311 //
312  if (!Config.GetRest(parms, sizeof(parms)))
313  {Eroute.Emsg("Config", "policy lib parameters too long"); return 1;}
314  PolParm = (*parms ? strdup(parms) : 0);
315 
316 // All done
317 //
318  return 0;
319 }
320 
321 /******************************************************************************/
322 /* x t r a c e */
323 /******************************************************************************/
324 
325 /* Function: xtrace
326 
327  Purpose: To parse the directive: trace <events>
328 
329  <events> the blank separated list of events to trace. Trace
330  directives are cummalative.
331 
332  Output: 0 upon success or !0 upon failure.
333 */
334 
335 int XrdBwm::xtrace(XrdOucStream &Config, XrdSysError &Eroute)
336 {
337  static struct traceopts {const char *opname; int opval;} tropts[] =
338  {
339  {"all", TRACE_ALL},
340  {"calls", TRACE_calls},
341  {"debug", TRACE_debug},
342  {"delay", TRACE_delay},
343  {"sched", TRACE_sched},
344  {"tokens", TRACE_tokens}
345  };
346  int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
347  char *val;
348 
349  if (!(val = Config.GetWord()))
350  {Eroute.Emsg("Config", "trace option not specified"); return 1;}
351  while (val)
352  {if (!strcmp(val, "off")) trval = 0;
353  else {if ((neg = (val[0] == '-' && val[1]))) val++;
354  for (i = 0; i < numopts; i++)
355  {if (!strcmp(val, tropts[i].opname))
356  {if (neg) trval &= ~tropts[i].opval;
357  else trval |= tropts[i].opval;
358  break;
359  }
360  }
361  if (i >= numopts)
362  Eroute.Say("Config warning: ignoring invalid trace option '",val,"'.");
363  }
364  val = Config.GetWord();
365  }
366  BwmTrace.What = trval;
367 
368 // All done
369 //
370  return 0;
371 }
372 
373 /******************************************************************************/
374 /* s e t u p A u t h */
375 /******************************************************************************/
376 
377 int XrdBwm::setupAuth(XrdSysError &Eroute)
378 {
380  const char *cfn,
381  const char *parm,
382  XrdVersionInfo &);
383  XrdOucPinLoader *myLib;
384  XrdAccAuthorize *(*ep)(XrdSysLogger *, const char *, const char *);
385 
386 // Authorization comes from the library or we use the default
387 //
388  if (!AuthLib) return 0 == (Authorization = XrdAccDefaultAuthorizeObject
389  (Eroute.logger(),ConfigFN,AuthParm,*myVersion));
390 
391 // Create a pluin object (we will throw this away without deletion because
392 // the library must stay open but we never want to reference it again).
393 //
394  if (!(myLib = new XrdOucPinLoader(&Eroute, myVersion, "authlib", AuthLib)))
395  return 1;
396 
397 // Now get the entry point of the object creator
398 //
399  ep = (XrdAccAuthorize *(*)(XrdSysLogger *, const char *, const char *))
400  (myLib->Resolve("XrdAccAuthorizeObject"));
401  if (!ep) return 1;
402 
403 // Get the Object now
404 //
405  if (!(Authorization = ep(Eroute.logger(), ConfigFN, AuthParm)))
406  myLib->Unload();
407  delete myLib;
408  return (Authorization == 0);
409 }
410 
411 /******************************************************************************/
412 /* s e t u p P o l i c y */
413 /******************************************************************************/
414 
415 int XrdBwm::setupPolicy(XrdSysError &Eroute)
416 {
417  XrdOucPinLoader myLib(&Eroute, myVersion, "policylib", PolLib);
418  XrdBwmPolicy *(*ep)(XrdSysLogger *, const char *, const char *);
419 
420 // Now get the entry point of the object creator
421 //
422  ep = (XrdBwmPolicy *(*)(XrdSysLogger *, const char *, const char *))
423  (myLib.Resolve("XrdBwmPolicyObject"));
424  if (!ep) {myLib.Unload(); return 1;}
425 
426 // Get the Object now
427 //
428  if (!(Policy = ep(Eroute.logger(), ConfigFN, PolParm))) myLib.Unload();
429  return (Policy == 0);
430 }
XrdAccAuthorize * XrdAccDefaultAuthorizeObject(XrdSysLogger *lp, const char *cfn, const char *parm, XrdVersionInfo &urVer)
Definition: XrdAccAccess.cc:64
#define TS_Bit(x, m, v)
Definition: XrdBwmConfig.cc:69
#define TS_Xeq(x, m)
Definition: XrdBwmConfig.cc:60
#define TRACE_sched
Definition: XrdBwmTrace.hh:76
#define TRACE_delay
Definition: XrdBwmTrace.hh:75
#define TRACE_debug
Definition: XrdBwmTrace.hh:78
#define TRACE_tokens
Definition: XrdBwmTrace.hh:77
XrdOucTrace BwmTrace
#define TRACE_calls
Definition: XrdBwmTrace.hh:74
int open(const char *path, int oflag,...)
#define TRACE_ALL
Definition: XrdTrace.hh:35
static int setPolicy(XrdBwmPolicy *pP, XrdBwmLogger *lP)
int Start(XrdSysError *eobj)
XrdVersionInfo * myVersion
Definition: XrdBwm.hh:244
char * ConfigFN
Definition: XrdBwm.hh:246
char Authorize
Definition: XrdBwm.hh:251
virtual int ConfigXeq(char *var, XrdOucStream &, XrdSysError &)
virtual int Configure(XrdSysError &)
Definition: XrdBwmConfig.cc:77
void * Resolve(const char *symbl, int mcnt=1)
void Unload(bool dodel=false)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition: XrdOuca2x.cc:45
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
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition: XrdSysError.hh:141
XrdCmsConfig Config