/******************************************************************************/ /* */ /* X r d B w m C o n f i g . c c */ /* */ /* (C) 2010 by the Board of Trustees of the Leland Stanford, Jr., University */ /* All Rights Reserved */ /* Produced by Andrew Hanushevsky for Stanford University under contract */ /* DE-AC02-76-SFO0515 with the Deprtment of Energy */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ #include #include #include #include #include #include #include #include #include "XrdBwm/XrdBwm.hh" #include "XrdBwm/XrdBwmLogger.hh" #include "XrdBwm/XrdBwmPolicy.hh" #include "XrdBwm/XrdBwmPolicy1.hh" #include "XrdBwm/XrdBwmTrace.hh" #include "XrdOuc/XrdOuca2x.hh" #include "XrdOuc/XrdOucEnv.hh" #include "XrdOuc/XrdOucPinLoader.hh" #include "XrdSys/XrdSysError.hh" #include "XrdSys/XrdSysHeaders.hh" #include "XrdOuc/XrdOucStream.hh" #include "XrdOuc/XrdOucTrace.hh" #include "XrdAcc/XrdAccAuthorize.hh" /******************************************************************************/ /* d e f i n e s */ /******************************************************************************/ #define TS_Xeq(x,m) if (!strcmp(x,var)) return m(Config,Eroute); #define TS_Str(x,m) if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;} #define TS_PList(x,m) if (!strcmp(x,var)) \ {m.Insert(new XrdOucPList(val,1)); return 0;} #define TS_Chr(x,m) if (!strcmp(x,var)) {m = val[0]; return 0;} #define TS_Bit(x,m,v) if (!strcmp(x,var)) {m |= v; Config.Echo(); return 0;} #define Max(x,y) (x > y ? x : y) /******************************************************************************/ /* C o n f i g u r e */ /******************************************************************************/ int XrdBwm::Configure(XrdSysError &Eroute) { /* Function: Establish default values using a configuration file. Input: None. Output: 0 upon success or !0 otherwise. */ char *var; int cfgFD, retc, NoGo = 0; XrdOucEnv myEnv; XrdOucStream Config(&Eroute, getenv("XRDINSTANCE"), &myEnv, "=====> "); // Print warm-up message // Eroute.Say("++++++ Bwm initialization started."); // Get the debug level from the command line // if (getenv("XRDDEBUG")) BwmTrace.What = TRACE_ALL; // If there is no config file, return with the defaults sets. // if( !ConfigFN || !*ConfigFN) Eroute.Emsg("Config", "Configuration file not specified."); else { // Try to open the configuration file. // if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0) return Eroute.Emsg("Config", errno, "open config file", ConfigFN); Config.Attach(cfgFD); // Now start reading records until eof. // while((var = Config.GetMyFirstWord())) {if (!strncmp(var, "bwm.", 4)) if (ConfigXeq(var+4,Config,Eroute)) {Config.Echo();NoGo=1;} } // Now check if any errors occured during file i/o // if ((retc = Config.LastError())) NoGo = Eroute.Emsg("Config", -retc, "read config file", ConfigFN); Config.Close(); } // Determine whether we should initialize authorization // if (Authorize) NoGo |= setupAuth(Eroute); // Establish scheduling policy // if (PolLib) NoGo |= setupPolicy(Eroute); else Policy = new XrdBwmPolicy1(PolSlotsIn, PolSlotsOut); // Start logger object // if (!NoGo && Logger) NoGo = Logger->Start(&Eroute); // Inform the handle of the policy and logger // if (!NoGo) XrdBwmHandle::setPolicy(Policy, Logger); // All done // Eroute.Say("------ Bwm initialization ", (NoGo ? "failed." : "completed.")); return NoGo; } /******************************************************************************/ /* p r i v a t e f u n c t i o n s */ /******************************************************************************/ /******************************************************************************/ /* C o n f i g X e q */ /******************************************************************************/ int XrdBwm::ConfigXeq(char *var, XrdOucStream &Config, XrdSysError &Eroute) { TS_Bit("authorize", Authorize, 1); TS_Xeq("authlib", xalib); TS_Xeq("log", xlog); TS_Xeq("policy", xpol); TS_Xeq("trace", xtrace); // No match found, complain. // Eroute.Say("Config warning: ignoring unknown directive '",var,"'."); Config.Echo(); return 0; } /******************************************************************************/ /* x a l i b */ /******************************************************************************/ /* Function: xalib Purpose: To parse the directive: authlib [] the path of the authorization library to be used. optional parms to be passed Output: 0 upon success or !0 upon failure. */ int XrdBwm::xalib(XrdOucStream &Config, XrdSysError &Eroute) { char *val, parms[1024]; // Get the path // if (!(val = Config.GetWord()) || !val[0]) {Eroute.Emsg("Config", "authlib not specified"); return 1;} // Record the path // if (AuthLib) free(AuthLib); AuthLib = strdup(val); // Record any parms // if (!Config.GetRest(parms, sizeof(parms))) {Eroute.Emsg("Config", "authlib parameters too long"); return 1;} if (AuthParm) free(AuthParm); AuthParm = (*parms ? strdup(parms) : 0); return 0; } /******************************************************************************/ /* x l o g */ /******************************************************************************/ /* Function: xlog Purpose: Parse directive: log {* | <|prog> | <>path>} - is the program to execute and dynamically feed messages about the indicated events. Messages are piped to prog. - is the udp named socket to receive the message. The server creates the path if it's not present. If is an asterisk, then messages are written to standard log file. Output: 0 upon success or !0 upon failure. */ int XrdBwm::xlog(XrdOucStream &Config, XrdSysError &Eroute) { char *val, parms[1024]; if (!(val = Config.GetWord())) {Eroute.Emsg("Config", "log parameters not specified"); return 1;} // Get the remaining parameters // Config.RetToken(); if (!Config.GetRest(parms, sizeof(parms))) {Eroute.Emsg("Config", "log parameters too long"); return 1;} val = (*parms == '|' ? parms+1 : parms); // Create a log object // if (Logger) delete Logger; Logger = new XrdBwmLogger(val); // All done // return 0; } /******************************************************************************/ /* x p o l */ /******************************************************************************/ /* Function: xpol Purpose: To parse the directive: policy args Args: {maxslots | lib []} maximum number of slots available. if preceeded by lib, the path of the policy library to be used; otherwise, the file that describes policy. optional parms to be passed Output: 0 upon success or !0 upon failure. */ int XrdBwm::xpol(XrdOucStream &Config, XrdSysError &Eroute) { char *val, parms[2048]; int pl; // Get next token // if (!(val = Config.GetWord()) || !val[0]) {Eroute.Emsg("Config", "policy not specified"); return 1;} // Start afresh // if (PolLib) {free(PolLib); PolLib = 0;} if (PolParm) {free(PolParm); PolParm = 0;} PolSlotsIn = PolSlotsOut = 0; // If the word maxslots then this is a simple policy // if (!strcmp("maxslots", val)) {if (!(val = Config.GetWord()) || !val[0]) {Eroute.Emsg("Config", "policy in slots not specified"); return 1;} if (XrdOuca2x::a2i(Eroute,"policy in slots",val,&pl,0,32767)) return 1; PolSlotsIn = pl; if (!(val = Config.GetWord()) || !val[0]) {Eroute.Emsg("Config", "policy out slots not specified"); return 1;} if (XrdOuca2x::a2i(Eroute,"policy out slots",val,&pl,0,32767)) return 1; PolSlotsOut = pl; return 0; } // Make sure the word is lib // if (strcmp("lib", val)) {Eroute.Emsg("Config", "invalid policy keyword -", val); return 1;} if (!(val = Config.GetWord()) || !val[0]) {Eroute.Emsg("Config", "policy library not specified"); return 1;} // Set the library // PolLib = strdup(val); // Get any parameters // if (!Config.GetRest(parms, sizeof(parms))) {Eroute.Emsg("Config", "policy lib parameters too long"); return 1;} PolParm = (*parms ? strdup(parms) : 0); // All done // return 0; } /******************************************************************************/ /* x t r a c e */ /******************************************************************************/ /* Function: xtrace Purpose: To parse the directive: trace the blank separated list of events to trace. Trace directives are cummalative. Output: 0 upon success or !0 upon failure. */ int XrdBwm::xtrace(XrdOucStream &Config, XrdSysError &Eroute) { static struct traceopts {const char *opname; int opval;} tropts[] = { {"all", TRACE_ALL}, {"calls", TRACE_calls}, {"debug", TRACE_debug}, {"delay", TRACE_delay}, {"sched", TRACE_sched}, {"tokens", TRACE_tokens} }; int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts); char *val; if (!(val = Config.GetWord())) {Eroute.Emsg("Config", "trace option not specified"); return 1;} while (val) {if (!strcmp(val, "off")) trval = 0; else {if ((neg = (val[0] == '-' && val[1]))) val++; for (i = 0; i < numopts; i++) {if (!strcmp(val, tropts[i].opname)) {if (neg) trval &= ~tropts[i].opval; else trval |= tropts[i].opval; break; } } if (i >= numopts) Eroute.Say("Config warning: ignoring invalid trace option '",val,"'."); } val = Config.GetWord(); } BwmTrace.What = trval; // All done // return 0; } /******************************************************************************/ /* s e t u p A u t h */ /******************************************************************************/ int XrdBwm::setupAuth(XrdSysError &Eroute) { extern XrdAccAuthorize *XrdAccDefaultAuthorizeObject(XrdSysLogger *lp, const char *cfn, const char *parm, XrdVersionInfo &); XrdOucPinLoader *myLib; XrdAccAuthorize *(*ep)(XrdSysLogger *, const char *, const char *); // Authorization comes from the library or we use the default // if (!AuthLib) return 0 == (Authorization = XrdAccDefaultAuthorizeObject (Eroute.logger(),ConfigFN,AuthParm,*myVersion)); // Create a pluin object (we will throw this away without deletion because // the library must stay open but we never want to reference it again). // if (!(myLib = new XrdOucPinLoader(&Eroute, myVersion, "authlib", AuthLib))) return 1; // Now get the entry point of the object creator // ep = (XrdAccAuthorize *(*)(XrdSysLogger *, const char *, const char *)) (myLib->Resolve("XrdAccAuthorizeObject")); if (!ep) return 1; // Get the Object now // if (!(Authorization = ep(Eroute.logger(), ConfigFN, AuthParm))) myLib->Unload(); delete myLib; return (Authorization == 0); } /******************************************************************************/ /* s e t u p P o l i c y */ /******************************************************************************/ int XrdBwm::setupPolicy(XrdSysError &Eroute) { XrdOucPinLoader myLib(&Eroute, myVersion, "policylib", PolLib); XrdBwmPolicy *(*ep)(XrdSysLogger *, const char *, const char *); // Now get the entry point of the object creator // ep = (XrdBwmPolicy *(*)(XrdSysLogger *, const char *, const char *)) (myLib.Resolve("XrdBwmPolicyObject")); if (!ep) {myLib.Unload(); return 1;} // Get the Object now // if (!(Policy = ep(Eroute.logger(), ConfigFN, PolParm))) myLib.Unload(); return (Policy == 0); }