XrdXrootdConfig.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                    X r d X r o o t d C o n f i g . c c                     */
00004 /*                                                                            */
00005 /* (c) 2010 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*       All Rights Reserved. See XrdInfo.cc for complete License Terms       */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*                DE-AC03-76-SFO0515 with the Deprtment of Energy             */
00009 /******************************************************************************/
00010  
00011 #include <unistd.h>
00012 #include <ctype.h>
00013 #include <fcntl.h>
00014 #include <string.h>
00015 #include <stdio.h>
00016 #include <sys/param.h>
00017 #include <sys/stat.h>
00018 #include <sys/types.h>
00019 #include <sys/un.h>
00020 
00021 #include "XrdVersion.hh"
00022 
00023 #include "XrdSfs/XrdSfsInterface.hh"
00024 #include "XrdNet/XrdNetDNS.hh"
00025 #include "XrdNet/XrdNetOpts.hh"
00026 #include "XrdNet/XrdNetSocket.hh"
00027 #include "XrdOuc/XrdOuca2x.hh"
00028 #include "XrdOuc/XrdOucEnv.hh"
00029 #include "XrdOuc/XrdOucProg.hh"
00030 #include "XrdOuc/XrdOucReqID.hh"
00031 #include "XrdOuc/XrdOucStream.hh"
00032 #include "XrdOuc/XrdOucTrace.hh"
00033 #include "XrdOuc/XrdOucUtils.hh"
00034 #include "XrdSys/XrdSysError.hh"
00035 #include "XrdSys/XrdSysHeaders.hh"
00036 #include "XrdSys/XrdSysLogger.hh"
00037 
00038 #include "XrdXrootd/XrdXrootdAdmin.hh"
00039 #include "XrdXrootd/XrdXrootdAio.hh"
00040 #include "XrdXrootd/XrdXrootdCallBack.hh"
00041 #include "XrdXrootd/XrdXrootdFile.hh"
00042 #include "XrdXrootd/XrdXrootdFileLock.hh"
00043 #include "XrdXrootd/XrdXrootdFileLock1.hh"
00044 #include "XrdXrootd/XrdXrootdJob.hh"
00045 #include "XrdXrootd/XrdXrootdMonitor.hh"
00046 #include "XrdXrootd/XrdXrootdPrepare.hh"
00047 #include "XrdXrootd/XrdXrootdProtocol.hh"
00048 #include "XrdXrootd/XrdXrootdStats.hh"
00049 #include "XrdXrootd/XrdXrootdTrace.hh"
00050 #include "XrdXrootd/XrdXrootdXPath.hh"
00051 
00052 #include "Xrd/XrdBuffer.hh"
00053 
00054 /******************************************************************************/
00055 /*         P r o t o c o l   C o m m a n d   L i n e   O p t i o n s          */
00056 /******************************************************************************/
00057   
00058 /* This is the XRootd server. The syntax is:
00059 
00060    xrootd [options]
00061 
00062    options: [<xopt>] [-r] [-t] [-y] [path]
00063 
00064 Where:
00065    xopt   are xrd specified options that are screened out.
00066 
00067    -r     This is a redirecting server.
00068 
00069    -t     This server is a redirection target.
00070 
00071    -y     This server is a proxy server.
00072 
00073     path  Export path. Any number of paths may be specified.
00074           By default, only '/tmp' is exported.
00075 
00076 */
00077 /******************************************************************************/
00078 /*                               G l o b a l s                                */
00079 /******************************************************************************/
00080   
00081 extern          XrdOucTrace       *XrdXrootdTrace;
00082 
00083                 XrdXrootdPrepare  *XrdXrootdPrepQ;
00084 
00085                 XrdOucReqID       *XrdXrootdReqID;
00086 
00087                 const char        *XrdXrootdInstance;
00088 
00089                 XrdInet           *XrdXrootdNetwork;
00090 
00091                 int                XrdXrootdPort;
00092 
00093 /******************************************************************************/
00094 /*                             C o n f i g u r e                              */
00095 /******************************************************************************/
00096   
00097 int XrdXrootdProtocol::Configure(char *parms, XrdProtocol_Config *pi)
00098 {
00099 /*
00100   Function: Establish configuration at load time.
00101 
00102   Input:    None.
00103 
00104   Output:   0 upon success or !0 otherwise.
00105 */
00106    extern XrdSfsFileSystem *XrdSfsGetDefaultFileSystem
00107                             (XrdSfsFileSystem *nativeFS,
00108                              XrdSysLogger     *Logger,
00109                              const char       *configFn);
00110    extern XrdSecService    *XrdXrootdloadSecurity(XrdSysError *, char *, char *);
00111    extern XrdSfsFileSystem *XrdXrootdloadFileSystem(XrdSysError *, char *, 
00112                                                     const char *);
00113    extern int optind, opterr;
00114 
00115    XrdXrootdXPath *xp;
00116    char *adminp, *fsver, *rdf, *bP, *tmp, c, buff[1024];
00117    int i, n, deper = 0;
00118 
00119 // Copy out the special info we want to use at top level
00120 //
00121    eDest.logger(pi->eDest->logger());
00122    XrdXrootdTrace = new XrdOucTrace(&eDest);
00123    SI           = new XrdXrootdStats(pi->Stats);
00124    Sched        = pi->Sched;
00125    BPool        = pi->BPool;
00126    hailWait     = pi->hailWait;
00127    readWait     = pi->readWait;
00128    Port         = pi->Port;
00129    myInst       = pi->myInst;
00130    Window       = pi->WSize;
00131    WANPort      = pi->WANPort;
00132    WANWindow    = pi->WANWSize;
00133 
00134 // Record globally accessible values
00135 //
00136    XrdXrootdInstance = pi->myInst;
00137    XrdXrootdNetwork  = pi->NetTCP;
00138    XrdXrootdPort     = pi->Port;
00139 
00140 // Set the callback object static areas now!
00141 //
00142    XrdXrootdCallBack::setVals(&eDest, SI, Sched, Port);
00143 
00144 // Prohibit this program from executing as superuser
00145 //
00146    if (geteuid() == 0)
00147       {eDest.Emsg("Config", "Security reasons prohibit xrootd running as "
00148                   "superuser; xrootd is terminating.");
00149        _exit(8);
00150       }
00151 
00152 // Process any command line options
00153 //
00154    opterr = 0; optind = 1;
00155    if (pi->argc > 1 && '-' == *(pi->argv[1]))
00156       while ((c=getopt(pi->argc,pi->argv,"mrst")) && ((unsigned char)c != 0xff))
00157      { switch(c)
00158        {
00159        case 'r': deper = 1;
00160        case 'm': XrdOucEnv::Export("XRDREDIRECT", "R");
00161                  break;
00162        case 't': deper = 1;
00163        case 's': XrdOucEnv::Export("XRDRETARGET", "1");
00164                  break;
00165        case 'y': XrdOucEnv::Export("XRDREDPROXY", "1");
00166                  break;
00167        default:  eDest.Say("Config warning: ignoring invalid option '",pi->argv[optind-1],"'.");
00168        }
00169      }
00170 
00171 // Check for deprecated options
00172 //
00173    if (deper) eDest.Say("Config warning: '-r -t' are deprecated; use '-m -s' instead.");
00174 
00175 // Pick up exported paths
00176 //
00177    for ( ; optind < pi->argc; optind++) xexpdo(pi->argv[optind]);
00178 
00179 // Pre-initialize some i/o values. Note that we now set maximum readv element
00180 // transfer size to the buffer size (before it was a reasonable 256K).
00181 //
00182    if (!(as_miniosz = as_segsize/2)) as_miniosz = as_segsize;
00183    maxTransz = maxBuffsz = BPool->MaxSize();
00184 
00185 // Now process and configuration parameters
00186 //
00187    rdf = (parms && *parms ? parms : pi->ConfigFN);
00188    if (rdf && Config(rdf)) return 0;
00189    if (pi->DebugON) XrdXrootdTrace->What = TRACE_ALL;
00190 
00191 // Check if we are exporting anything
00192 //
00193    if (!(xp = XPList.Next()))
00194       {XPList.Insert("/tmp"); n = 8;
00195        eDest.Say("Config warning: only '/tmp' will be exported.");
00196       } else {
00197        n = 0;
00198        while(xp) {eDest.Say("Config exporting ", xp->Path(i));
00199                   n += i+2; xp = xp->Next();
00200                  }
00201       }
00202 
00203 // Export the exports
00204 //
00205    bP = tmp = (char *)malloc(n);
00206    xp = XPList.Next();
00207    while(xp) {strcpy(bP, xp->Path(i)); bP += i; *bP++ = ' '; xp = xp->Next();}
00208    *(bP-1) = '\0';
00209    XrdOucEnv::Export("XRDEXPORTS", tmp); free(tmp);
00210 
00211 // Initialiaze for AIO
00212 //
00213    if (!as_noaio) XrdXrootdAioReq::Init(as_segsize, as_maxperreq, as_maxpersrv);
00214       else eDest.Say("Config warning: asynchronous I/O has been disabled!");
00215 
00216 // Initialize the security system if this is wanted
00217 //
00218    if (!SecLib) eDest.Say("Config warning: 'xrootd.seclib' not specified;"
00219                           " strong authentication disabled!");
00220       else {TRACE(DEBUG, "Loading security library " <<SecLib);
00221             if (!(CIA = XrdXrootdloadSecurity(&eDest, SecLib, pi->ConfigFN)))
00222                {eDest.Emsg("Config", "Unable to load security system.");
00223                 return 0;
00224                }
00225            }
00226 
00227 // Get the filesystem to be used
00228 //
00229    if (FSLib)
00230       {TRACE(DEBUG, "Loading filesystem library " <<FSLib);
00231        osFS = XrdXrootdloadFileSystem(&eDest, FSLib, pi->ConfigFN);
00232       } else osFS = XrdSfsGetDefaultFileSystem(0, eDest.logger(), pi->ConfigFN);
00233    if (!osFS)
00234       {eDest.Emsg("Config", "Unable to load file system.");
00235        return 0;
00236       } else SI->setFS(osFS);
00237 
00238 // Check if the file system version matches our version
00239 //
00240    if (chkfsV)
00241       {fsver = (char *)osFS->getVersion();
00242        if (strcmp(XrdVERSION, fsver))
00243           eDest.Emsg("Config", "Warning! xrootd build version " XrdVERSION
00244                                "differs from file system version ", fsver);
00245       }
00246 
00247 // Create the file lock manager
00248 //
00249    Locker = (XrdXrootdFileLock *)new XrdXrootdFileLock1();
00250    XrdXrootdFile::Init(Locker, as_nosf == 0);
00251    if (as_nosf) eDest.Say("Config warning: sendfile I/O has been disabled!");
00252 
00253 // Schedule protocol object cleanup
00254 //
00255    ProtStack.Set(pi->Sched, XrdXrootdTrace, TRACE_MEM);
00256    ProtStack.Set((pi->ConnMax/3 ? pi->ConnMax/3 : 30), 60*60);
00257 
00258 // Initialize the request ID generation object
00259 //
00260    XrdXrootdReqID = new XrdOucReqID((int)Port, pi->myName,
00261                                     XrdNetDNS::IPAddr(pi->myAddr));
00262 
00263 // Initialize for prepare processing
00264 //
00265    XrdXrootdPrepQ = new XrdXrootdPrepare(&eDest, pi->Sched);
00266    sprintf(buff, "udp://%s:%d/&L=%%d&U=%%s", pi->myName, pi->Port);
00267    Notify = strdup(buff);
00268 
00269 // Check if we are redirecting anything
00270 //
00271    if ((xp = RPList.Next()))
00272       {int k;
00273        char buff[512];
00274        do {k = xp->Opts();
00275            sprintf(buff, " to %s:%d", Route[k].Host, Route[k].Port);
00276            eDest.Say("Config redirecting ", xp->Path(), buff);
00277            xp = xp->Next();
00278           } while(xp);
00279       }
00280 
00281 // Set the redirect flag if we are a pure redirector
00282 //
00283    if ((rdf = getenv("XRDREDIRECT"))
00284    && (!strcmp(rdf, "R") || !strcmp(rdf, "M"))) isRedir = *rdf;
00285 
00286 // Check if monitoring should be enabled
00287 //
00288    if (!isRedir && !XrdXrootdMonitor::Init(Sched,&eDest)) return 0;
00289 
00290 // Add all jobs that we can run to the admin object
00291 //
00292    if (JobCKS) XrdXrootdAdmin::addJob("chksum", JobCKS);
00293 
00294 // Establish the path to be used for admin functions. We will loose this
00295 // storage upon an error but we don't care because we'll just exit.
00296 //
00297    adminp = XrdOucUtils::genPath(pi->AdmPath, 0, ".xrootd");
00298 
00299 // Setup the admin path (used in all roles).
00300 //
00301    if (!(AdminSock = XrdNetSocket::Create(&eDest, adminp, "admin", pi->AdmMode))
00302    ||  !XrdXrootdAdmin::Init(&eDest, AdminSock)) return 0;
00303 
00304 // Setup pid file
00305 //
00306    PidFile();
00307 
00308 // Return success
00309 //
00310    free(adminp);
00311    return 1;
00312 }
00313 
00314 /******************************************************************************/
00315 /*                                C o n f i g                                 */
00316 /******************************************************************************/
00317   
00318 #define TS_Xeq(x,m) (!strcmp(x,var)) GoNo = m(Config)
00319 
00320 int XrdXrootdProtocol::Config(const char *ConfigFN)
00321 {
00322    XrdOucEnv myEnv;
00323    XrdOucStream Config(&eDest, getenv("XRDINSTANCE"), &myEnv, "=====> ");
00324    char *var;
00325    int cfgFD, GoNo, NoGo = 0, ismine;
00326 
00327    // Open and attach the config file
00328    //
00329    if ((cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
00330        return eDest.Emsg("Config", errno, "open config file", ConfigFN);
00331    Config.Attach(cfgFD);
00332 
00333    // Process items
00334    //
00335    while((var = Config.GetMyFirstWord()))
00336         {     if ((ismine = !strncmp("xrootd.", var, 7)) && var[7]) var += 7;
00337          else if ((ismine = !strcmp("all.export", var)))    var += 4;
00338          else if ((ismine = !strcmp("all.pidpath",var)))    var += 4;
00339          else if ((ismine = !strcmp("all.seclib", var)))    var += 4;
00340 
00341          if (ismine)
00342             {     if TS_Xeq("async",         xasync);
00343              else if TS_Xeq("chksum",        xcksum);
00344              else if TS_Xeq("export",        xexp);
00345              else if TS_Xeq("fslib",         xfsl);
00346              else if TS_Xeq("log",           xlog);
00347              else if TS_Xeq("monitor",       xmon);
00348              else if TS_Xeq("pidpath",       xpidf);
00349              else if TS_Xeq("prep",          xprep);
00350              else if TS_Xeq("redirect",      xred);
00351              else if TS_Xeq("seclib",        xsecl);
00352              else if TS_Xeq("trace",         xtrace);
00353              else {eDest.Say("Config warning: ignoring unknown directive '",var,"'.");
00354                    Config.Echo();
00355                    continue;
00356                   }
00357              if (GoNo) {Config.Echo(); NoGo = 1;}
00358             }
00359         }
00360    return NoGo;
00361 }
00362 
00363 /******************************************************************************/
00364 /*                     P r i v a t e   F u n c t i o n s                      */
00365 /******************************************************************************/
00366 /******************************************************************************/
00367 /*                               P i d F i l e                                */
00368 /******************************************************************************/
00369   
00370 void XrdXrootdProtocol::PidFile()
00371 {
00372     int rc, xfd;
00373     char buff[32], pidFN[1200];
00374     char *ppath=XrdOucUtils::genPath(pidPath,XrdOucUtils::InstName(-1));
00375     const char *xop = 0;
00376 
00377     if ((rc = XrdOucUtils::makePath(ppath,XrdOucUtils::pathMode)))
00378        {xop = "create"; errno = rc;}
00379        else {snprintf(pidFN, sizeof(pidFN), "%s/xrootd.pid", ppath);
00380 
00381             if ((xfd = open(pidFN, O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0)
00382                xop = "open";
00383                else {if (write(xfd,buff,snprintf(buff,sizeof(buff),"%d",
00384                          static_cast<int>(getpid()))) < 0) xop = "write";
00385                      close(xfd);
00386                     }
00387             }
00388 
00389     free(ppath);
00390     if (xop) eDest.Emsg("Config", errno, xop, pidFN);
00391 }
00392 
00393 /******************************************************************************/
00394 /*                                x a s y n c                                 */
00395 /******************************************************************************/
00396 
00397 /* Function: xasync
00398 
00399    Purpose:  To parse directive: async [limit <aiopl>] [maxsegs <msegs>]
00400                                        [maxtot <mtot>] [segsize <segsz>]
00401                                        [minsize <iosz>] [maxstalls <cnt>]
00402                                        [force] [syncw] [off] [nosf]
00403 
00404              <aiopl>  maximum number of async ops per link. Default 8.
00405              <msegs>  maximum number of async ops per request. Default 8.
00406              <mtot>   maximum number of async ops per server. Default is 20%
00407                       of maximum connection times aiopl divided by two.
00408              <segsz>  The aio segment size. This is the maximum size that data
00409                       will be read or written. The defaults to 64K but is
00410                       adjusted for each request to minimize latency.
00411              <iosz>   the minimum number of bytes that must be read or written
00412                       to allow async processing to occur (default is maxbsz/2
00413                       typically 1M).
00414              <cnt>    Maximum number of client stalls before synchronous i/o is
00415                       used. Async mode is tried after <cnt> requests.
00416              force    Uses async i/o for all requests, even when not explicitly
00417                       requested (this is compatible with synchronous clients).
00418              syncw    Use synchronous i/o for write requests.
00419              off      Disables async i/o
00420              nosf     Disables use of sendfile to send data to the client.
00421 
00422    Output: 0 upon success or 1 upon failure.
00423 */
00424 
00425 int XrdXrootdProtocol::xasync(XrdOucStream &Config)
00426 {
00427     char *val;
00428     int  i, ppp;
00429     int  V_force=-1, V_syncw = -1, V_off = -1, V_mstall = -1, V_nosf = -1;
00430     int  V_limit=-1, V_msegs=-1, V_mtot=-1, V_minsz=-1, V_segsz=-1;
00431     int  V_minsf=-1;
00432     long long llp;
00433     static struct asyncopts {const char *opname; int minv; int *oploc;
00434                              const char *opmsg;} asopts[] =
00435        {
00436         {"force",     -1, &V_force, ""},
00437         {"off",       -1, &V_off,   ""},
00438         {"nosf",      -1, &V_nosf,  ""},
00439         {"syncw",     -1, &V_syncw, ""},
00440         {"limit",      0, &V_limit, "async limit"},
00441         {"segsize", 4096, &V_segsz, "async segsize"},
00442         {"maxsegs",    0, &V_msegs, "async maxsegs"},
00443         {"maxstalls",  0, &V_mstall,"async maxstalls"},
00444         {"maxtot",     0, &V_mtot,  "async maxtot"},
00445         {"minsfsz",    1, &V_minsf, "async minsfsz"},
00446         {"minsize", 4096, &V_minsz, "async minsize"}};
00447     int numopts = sizeof(asopts)/sizeof(struct asyncopts);
00448 
00449     if (!(val = Config.GetWord()))
00450        {eDest.Emsg("Config", "async option not specified"); return 1;}
00451 
00452     while (val)
00453          {for (i = 0; i < numopts; i++)
00454               if (!strcmp(val, asopts[i].opname))
00455                  {if (asopts[i].minv >=  0 && !(val = Config.GetWord()))
00456                      {eDest.Emsg("Config","async",(char *)asopts[i].opname,
00457                                  "value not specified");
00458                       return 1;
00459                      }
00460                        if (asopts[i].minv >  0)
00461                           if (XrdOuca2x::a2sz(eDest,asopts[i].opmsg, val, &llp,
00462                                          (long long)asopts[i].minv)) return 1;
00463                              else *asopts[i].oploc = (int)llp;
00464                   else if (asopts[i].minv == 0)
00465                           if (XrdOuca2x::a2i(eDest,asopts[i].opmsg,val,&ppp,1))
00466                                             return 1;
00467                              else *asopts[i].oploc = ppp;
00468                   else *asopts[i].oploc = 1;
00469                   break;
00470                  }
00471           if (i >= numopts)
00472              eDest.Emsg("Config", "Warning, invalid async option", val);
00473           val = Config.GetWord();
00474          }
00475 
00476 // Make sure max values are consistent
00477 //
00478    if (V_limit > 0 && V_mtot > 0 && V_limit > V_mtot)
00479            {eDest.Emsg("Config", "async limit may not be greater than maxtot");
00480             return 1;
00481            }
00482 
00483 // Calculate the actual segment size
00484 //
00485    if (V_segsz > 0)
00486       {i = BPool->Recalc(V_segsz);
00487        if (!i) {eDest.Emsg("Config", "async segsize is too large"); return 1;}
00488        if (i != V_segsz)
00489           {char buff[64];
00490            sprintf(buff, "%d readjusted to %d", V_segsz, i);
00491            eDest.Emsg("Config", "async segsize", buff);
00492            V_segsz = i;
00493           }
00494       }
00495 
00496 // Establish async options
00497 //
00498    if (V_limit > 0) as_maxperlnk = V_limit;
00499    if (V_msegs > 0) as_maxperreq = V_msegs;
00500    if (V_mtot  > 0) as_maxpersrv = V_mtot;
00501    if (V_minsz > 0) as_miniosz   = V_minsz;
00502    if (V_segsz > 0) as_segsize   = V_segsz;
00503    if (V_mstall> 0) as_maxstalls = V_mstall;
00504    if (V_force > 0) as_force     = 1;
00505    if (V_off   > 0) as_noaio     = 1;
00506    if (V_syncw > 0) as_syncw     = 1;
00507    if (V_nosf  > 0) as_nosf      = 1;
00508    if (V_minsf > 0) as_minsfsz   = V_minsf;
00509 
00510    return 0;
00511 }
00512 
00513 /******************************************************************************/
00514 /*                                x c k s u m                                 */
00515 /******************************************************************************/
00516 
00517 /* Function: xcksum
00518 
00519    Purpose:  To parse the directive: chksum [max <n>] <type> <path>
00520 
00521              max       maximum number of simultaneous jobs
00522              <type>    algorithm of checksum (e.g., md5)
00523              <path>    the path of the program performing the checksum
00524 
00525   Output: 0 upon success or !0 upon failure.
00526 */
00527 
00528 int XrdXrootdProtocol::xcksum(XrdOucStream &Config)
00529 {
00530    static XrdOucProg *theProg = 0;
00531    char *palg, prog[2048];
00532    int jmax = 4;
00533 
00534 // Get the algorithm name and the program implementing it
00535 //
00536    while ((palg = Config.GetWord()) && *palg != '/')
00537          {if (strcmp(palg, "max")) break;
00538           if (!(palg = Config.GetWord()))
00539              {eDest.Emsg("Config", "chksum max not specified"); return 1;}
00540           if (XrdOuca2x::a2i(eDest, "chksum max", palg, &jmax, 1)) return 1;
00541          }
00542 
00543 // Verify we have an algoritm
00544 //
00545    if (!palg || *palg == '/')
00546       {eDest.Emsg("Config", "chksum algorithm not specified"); return 1;}
00547    if (JobCKT) free(JobCKT);
00548    JobCKT = strdup(palg);
00549 
00550 // Verify that we have a program
00551 //
00552    if (!Config.GetRest(prog, sizeof(prog)))
00553       {eDest.Emsg("Config", "cksum parameters too long"); return 1;}
00554    if (*prog == '\0')
00555       {eDest.Emsg("Config", "chksum program not specified"); return 1;}
00556 
00557 // Set up the program and job
00558 //
00559    if (!theProg) theProg = new XrdOucProg(0);
00560    if (theProg->Setup(prog, &eDest)) return 1;
00561    if (JobCKS) delete JobCKS;
00562    JobCKS = new XrdXrootdJob(Sched, theProg, "chksum", jmax);
00563    return 0;
00564 }
00565   
00566 /******************************************************************************/
00567 /*                                  x e x p                                   */
00568 /******************************************************************************/
00569 
00570 /* Function: xexp
00571 
00572    Purpose:  To parse the directive: export <path> [lock|nolock]
00573 
00574              <path>    the path to be exported.
00575 
00576   Output: 0 upon success or !0 upon failure.
00577 */
00578 
00579 int XrdXrootdProtocol::xexp(XrdOucStream &Config)
00580 {
00581     char *val, pbuff[1024];
00582     int   popt = 0;
00583 
00584 // Get the path
00585 //
00586    val = Config.GetWord();
00587    if (!val || !val[0])
00588       {eDest.Emsg("Config", "export path not specified"); return 1;}
00589    strlcpy(pbuff, val, sizeof(pbuff));
00590 
00591 // Get export lock option
00592 //
00593    if ((val = Config.GetWord()))
00594       {if (!strcmp("nolock", val)) popt = XROOTDXP_NOLK;
00595           else if (strcmp("lock", val)) Config.RetToken();
00596       }
00597 
00598 // Add path to configuration
00599 //
00600    return xexpdo(pbuff, popt);
00601 }
00602 
00603 /******************************************************************************/
00604 
00605 int XrdXrootdProtocol::xexpdo(char *path, int popt)
00606 {
00607    const char *opaque;
00608 
00609 // Make sure path start with a slash
00610 //
00611    if (rpCheck(path, &opaque))
00612       {eDest.Emsg("Config", "non-absolute export path -", path); return 1;}
00613 
00614 // Record the path
00615 //
00616    if (!Squash(path)) XPList.Insert(path, popt);
00617    return 0;
00618 }
00619   
00620 /******************************************************************************/
00621 /*                                  x f s l                                   */
00622 /******************************************************************************/
00623 
00624 /* Function: xfsl
00625 
00626    Purpose:  To parse the directive: fslib [?] <path>
00627 
00628              ?         check if fslib build version matches our version
00629              <path>    the path of the filesystem library to be used.
00630 
00631   Output: 0 upon success or !0 upon failure.
00632 */
00633 
00634 int XrdXrootdProtocol::xfsl(XrdOucStream &Config)
00635 {
00636     char *val, *Slash;
00637 
00638 // Get the path
00639 //
00640    chkfsV = 0;
00641    if ((val = Config.GetWord()) && *val == '?' && !val[1])
00642       {chkfsV = '?'; val = Config.GetWord();}
00643 
00644    if (!val || !val[0])
00645       {eDest.Emsg("Config", "fslib not specified"); return 1;}
00646 
00647 // If this is the "standard" name tell the user that we are ignoring this lib.
00648 // Otherwise, record the path and return.
00649 //
00650    if (!(Slash = rindex(val, '/'))) Slash = val;
00651    if (!strcmp(Slash, "/libXrdOfs.so"))
00652       eDest.Say("Config warning: ignoring fslib; libXrdOfs.so is built-in.");
00653       else {if (FSLib) free(FSLib);
00654             FSLib = strdup(val);
00655            }
00656    return 0;
00657 }
00658 
00659 /******************************************************************************/
00660 /*                                  x l o g                                   */
00661 /******************************************************************************/
00662 
00663 /* Function: xlog
00664 
00665    Purpose:  To parse the directive: log <events>
00666 
00667              <events> the blank separated list of events to log.
00668 
00669    Output: 0 upon success or 1 upon failure.
00670 */
00671 
00672 int XrdXrootdProtocol::xlog(XrdOucStream &Config)
00673 {
00674     char *val;
00675     static struct logopts {const char *opname; int opval;} lgopts[] =
00676        {
00677         {"all",     -1},
00678         {"disc",    SYS_LOG_02},
00679         {"login",   SYS_LOG_01}
00680        };
00681     int i, neg, lgval = -1, numopts = sizeof(lgopts)/sizeof(struct logopts);
00682 
00683     if (!(val = Config.GetWord()))
00684        {eDest.Emsg("config", "log option not specified"); return 1;}
00685     while (val)
00686           {if ((neg = (val[0] == '-' && val[1]))) val++;
00687            for (i = 0; i < numopts; i++)
00688                {if (!strcmp(val, lgopts[i].opname))
00689                    {if (neg) lgval &= ~lgopts[i].opval;
00690                        else  lgval |=  lgopts[i].opval;
00691                     break;
00692                    }
00693                }
00694            if (i >= numopts) eDest.Emsg("config","invalid log option",val);
00695            val = Config.GetWord();
00696           }
00697     eDest.setMsgMask(lgval);
00698     return 0;
00699 }
00700 
00701 /******************************************************************************/
00702 /*                                  x m o n                                   */
00703 /******************************************************************************/
00704 
00705 /* Function: xmon
00706 
00707    Purpose:  Parse directive: monitor [all] [mbuff <sz>] 
00708                                       [flush <sec>] [window <sec>]
00709                                       dest [Events] <host:port>
00710 
00711    Events: [files] [info] [io] [stage] [user] <host:port>
00712 
00713          all                enables monitoring for all connections.
00714          mbuff  <sz>        size of message buffer.
00715          flush  <sec>       time (seconds, M, H) between auto flushes.
00716          window <sec>       time (seconds, M, H) between timing marks.
00717          dest               specified routing information. Up to two dests
00718                             may be specified.
00719          files              only monitors file open/close events.
00720          info               monitors client appid and info requests.
00721          io                 monitors I/O requests, and files open/close events.
00722          stage              monitors file stage operations
00723          user               monitors user login and disconnect events.
00724          <host:port>        where monitor records are to be sentvia UDP.
00725 
00726    Output: 0 upon success or !0 upon failure. Ignored by master.
00727 */
00728 int XrdXrootdProtocol::xmon(XrdOucStream &Config)
00729 {   char  *val, *cp, *monDest[2] = {0, 0};
00730     long long tempval;
00731     int i, monFlush=0, monMBval=0, monWWval=0, xmode=0, monMode[2] = {0, 0};
00732 
00733     while((val = Config.GetWord()))
00734 
00735          {     if (!strcmp("all",  val)) xmode = XROOTD_MON_ALL;
00736           else if (!strcmp("flush", val))
00737                 {if (!(val = Config.GetWord()))
00738                     {eDest.Emsg("Config", "monitor flush value not specified");
00739                      return 1;
00740                     }
00741                  if (XrdOuca2x::a2tm(eDest,"monitor flush",val,
00742                                            &monFlush,1)) return 1;
00743                 }
00744           else if (!strcmp("mbuff",val))
00745                   {if (!(val = Config.GetWord()))
00746                       {eDest.Emsg("Config", "monitor mbuff value not specified");
00747                        return 1;
00748                       }
00749                    if (XrdOuca2x::a2sz(eDest,"monitor mbuff", val,
00750                                              &tempval, 1024, 65536)) return 1;
00751                     monMBval = static_cast<int>(tempval);
00752                   }
00753           else if (!strcmp("window", val))
00754                 {if (!(val = Config.GetWord()))
00755                     {eDest.Emsg("Config", "monitor window value not specified");
00756                      return 1;
00757                     }
00758                  if (XrdOuca2x::a2tm(eDest,"monitor window",val,
00759                                            &monWWval,1)) return 1;
00760                 }
00761           else break;
00762          }
00763 
00764     if (!val) {eDest.Emsg("Config", "monitor dest not specified"); return 1;}
00765 
00766     for (i = 0; i < 2; i++)
00767         {if (strcmp("dest", val)) break;
00768          while((val = Config.GetWord()))
00769                    if (!strcmp("files",val)) monMode[i] |=  XROOTD_MON_FILE;
00770               else if (!strcmp("info", val)) monMode[i] |=  XROOTD_MON_INFO;
00771               else if (!strcmp("io",   val)) monMode[i] |=  XROOTD_MON_IO;
00772               else if (!strcmp("stage",val)) monMode[i] |=  XROOTD_MON_STAGE;
00773               else if (!strcmp("user", val)) monMode[i] |=  XROOTD_MON_USER;
00774               else break;
00775           if (!val) {eDest.Emsg("Config","monitor dest value not specified");
00776                      return 1;
00777                     }
00778           if (!(cp = index(val, (int)':')) || !atoi(cp+1))
00779              {eDest.Emsg("Config","monitor dest port missing or invalid in",val);
00780               return 1;
00781              }
00782           monDest[i] = strdup(val);
00783          if (!(val = Config.GetWord())) break;
00784         }
00785 
00786     if (val)
00787        {if (!strcmp("dest", val))
00788            eDest.Emsg("Config", "Warning, a maximum of two dest values allowed.");
00789            else eDest.Emsg("Config", "Warning, invalid monitor option", val);
00790        }
00791 
00792 // Make sure dests differ
00793 //
00794    if (monDest[0] && monDest[1] && !strcmp(monDest[0], monDest[1]))
00795       {eDest.Emsg("Config", "Warning, monitor dests are identical.");
00796        monMode[0] |= monMode[1]; monMode[1] = 0;
00797        free(monDest[1]); monDest[1] = 0;
00798       }
00799 
00800 // Screen out requests that only want to stage
00801 //
00802    if (monDest[0] && monMode[0] == XROOTD_MON_STAGE)
00803       {monMode[0] = 0; free(monDest[0]); monDest[0] = 0;}
00804    if (monDest[1] && monMode[1] == XROOTD_MON_STAGE)
00805       {monMode[1] = 0; free(monDest[1]); monDest[1] = 0;}
00806 
00807 // Add files option if I/O is enabled
00808 //
00809    if (monMode[0] & XROOTD_MON_IO) monMode[0] |= XROOTD_MON_FILE;
00810    if (monMode[1] & XROOTD_MON_IO) monMode[1] |= XROOTD_MON_FILE;
00811 
00812 // Set the monitor defaults
00813 //
00814    XrdXrootdMonitor::Defaults(monMBval, monWWval, monFlush);
00815    if (monDest[0]) monMode[0] |= (monMode[0] ? xmode : XROOTD_MON_FILE|xmode);
00816    if (monDest[1]) monMode[1] |= (monMode[1] ? xmode : XROOTD_MON_FILE|xmode);
00817    XrdXrootdMonitor::Defaults(monDest[0],monMode[0],monDest[1],monMode[1]);
00818    return 0;
00819 }
00820   
00821 /******************************************************************************/
00822 /*                                 x p i d f                                  */
00823 /******************************************************************************/
00824 
00825 /* Function: xpidf
00826 
00827    Purpose:  To parse the directive: pidpath <path>
00828 
00829              <path>    the path where the pid file is to be created.
00830 
00831   Output: 0 upon success or !0 upon failure.
00832 */
00833 
00834 int XrdXrootdProtocol::xpidf(XrdOucStream &Config)
00835 {
00836     char *val;
00837 
00838 // Get the path
00839 //
00840    val = Config.GetWord();
00841    if (!val || !val[0])
00842       {eDest.Emsg("Config", "pidpath not specified"); return 1;}
00843 
00844 // Record the path
00845 //
00846    if (pidPath) free(pidPath);
00847    pidPath = strdup(val);
00848    return 0;
00849 }
00850 
00851 /******************************************************************************/
00852 /*                                 x p r e p                                  */
00853 /******************************************************************************/
00854 
00855 /* Function: xprep
00856 
00857    Purpose:  To parse the directive: prep [keep <sec>] [scrub <sec>]
00858                                           [logdir <path>]
00859          keep   <sec>  time (seconds, M, H) to keep logdir entries.
00860          scrub  <sec>  time (seconds, M, H) between logdir scrubs.
00861          logdir <path> the absolute path to the prepare log directory.
00862 
00863    Output: 0 upon success or !0 upon failure. Ignored by master.
00864 */
00865 int XrdXrootdProtocol::xprep(XrdOucStream &Config)
00866 {   int   rc, keep = 0, scrub=0;
00867     char  *ldir=0,*val,buff[1024];
00868 
00869     if (!(val = Config.GetWord()))
00870        {eDest.Emsg("Config", "prep options not specified"); return 1;}
00871 
00872         do { if (!strcmp("keep", val))
00873                 {if (!(val = Config.GetWord()))
00874                     {eDest.Emsg("Config", "prep keep value not specified");
00875                      return 1;
00876                     }
00877                  if (XrdOuca2x::a2tm(eDest,"prep keep int",val,&keep,1)) return 1;
00878                 }
00879         else if (!strcmp("scrub", val))
00880                 {if (!(val = Config.GetWord()))
00881                     {eDest.Emsg("Config", "prep scrub value not specified");
00882                      return 1;
00883                     }
00884                  if (XrdOuca2x::a2tm(eDest,"prep scrub",val,&scrub,0)) return 1;
00885                 }
00886         else if (!strcmp("logdir", val))
00887                 {if (!(ldir = Config.GetWord()))
00888                    {eDest.Emsg("Config", "prep logdir value not specified");
00889                     return 1;
00890                    }
00891                 }
00892         else eDest.Emsg("Config", "Warning, invalid prep option", val);
00893        } while((val = Config.GetWord()));
00894 
00895 // Set the values
00896 //
00897    if (scrub || keep) XrdXrootdPrepare::setParms(scrub, keep);
00898    if (ldir) 
00899        if ((rc = XrdOucUtils::genPath(buff, sizeof(buff), ldir, myInst)) < 0
00900        ||  (rc = XrdOucUtils::makePath(buff, XrdOucUtils::pathMode)) < 0
00901        ||  (rc = XrdXrootdPrepare::setParms(buff)) < 0)
00902           {eDest.Emsg("Config", rc, "process logdir", ldir);
00903            return 1;
00904           }
00905    return 0;
00906 }
00907 
00908 /******************************************************************************/
00909 /*                                  x r e d                                   */
00910 /******************************************************************************/
00911   
00912 /* Function: xred
00913 
00914    Purpose:  To parse the directive: redirect <host>:<port> {<funcs>|<path>}
00915 
00916              <funcs>   are one or more of the following functions that will
00917                        be immediately redirected to <host>:<port>. Each function
00918                        may be prefixed by a minus sign to disable redirection.
00919 
00920                        chmod dirlist locate mkdir mv prepare rm rmdir stat
00921 
00922              <paths>   redirects the client when an attempt is made to open
00923                        one of absolute <paths>. Up to 4 different redirect
00924                        combinations may be specified.
00925 
00926   Output: 0 upon success or !0 upon failure.
00927 */
00928 
00929 int XrdXrootdProtocol::xred(XrdOucStream &Config)
00930 {
00931     static struct rediropts {const char *opname; RD_func opval;} rdopts[] =
00932        {
00933         {"chmod",    RD_chmod},
00934         {"dirlist",  RD_dirlist},
00935         {"locate",   RD_locate},
00936         {"mkdir",    RD_mkdir},
00937         {"mv",       RD_mv},
00938         {"prepare",  RD_prepare},
00939         {"prepstage",RD_prepstg},
00940         {"rm",       RD_rm},
00941         {"rmdir",    RD_rmdir},
00942         {"stat",     RD_stat}
00943        };
00944     char rHost[512], *val, *pp;
00945     int i, k, neg, rPort, numopts = sizeof(rdopts)/sizeof(struct rediropts);
00946 
00947 // Get the host and port
00948 //
00949    val = Config.GetWord();
00950    if (!val || !val[0] || val[0] == ':')
00951       {eDest.Emsg("Config", "redirect host not specified"); return 1;}
00952    if (!(pp = index(val, ':')))
00953       {eDest.Emsg("Config", "redirect port not specified"); return 1;}
00954    if (!(rPort = atoi(pp+1)))
00955       {eDest.Emsg("Config", "redirect port is invalid");    return 1;}
00956    *pp = '\0';
00957    strlcpy(rHost, val, sizeof(rHost));
00958 
00959 // Set all redirect target functions
00960 //
00961     if (!(val = Config.GetWord()))
00962        {eDest.Emsg("config", "redirect option not specified"); return 1;}
00963 
00964     if (*val == '/')
00965        {for (k = static_cast<int>(RD_open1); k < RD_Num; k++)
00966             if (!Route[k].Host
00967             || (strcmp(Route[k].Host, rHost) && Route[k].Port == rPort)) break;
00968         if (k >= RD_Num)
00969            {eDest.Emsg("Config", "too many diffrent path redirects"); return 1;}
00970         xred_set(RD_func(k), rHost, rPort);
00971         do {RPList.Insert(val, k, 0);
00972             if ((val = Config.GetWord()) && *val != '/')
00973                {eDest.Emsg("Config", "non-absolute redirect path -", val);
00974                 return 1;
00975                }
00976            } while(val);
00977         return 0;
00978        }
00979 
00980     while (val)
00981           {if (!strcmp(val, "all"))
00982               {for (i = 0; i < numopts; i++)
00983                    xred_set(rdopts[i].opval, rHost, rPort);
00984               }
00985               else {if ((neg = (val[0] == '-' && val[1]))) val++;
00986                     for (i = 0; i < numopts; i++)
00987                        {if (!strcmp(val, rdopts[i].opname))
00988                            {if (neg) xred_set(rdopts[i].opval, 0, 0);
00989                                else  xred_set(rdopts[i].opval, rHost, rPort);
00990                             break;
00991                            }
00992                        }
00993                    if (i >= numopts)
00994                       eDest.Emsg("config", "invalid redirect option", val);
00995                   }
00996           val = Config.GetWord();
00997          }
00998    return 0;
00999 }
01000 
01001 void XrdXrootdProtocol::xred_set(RD_func func, const char *rHost, int rPort)
01002 {
01003 // Reset static redirection
01004 //
01005    if (Route[func].Host) free(Route[func].Host);
01006    Route[func].Host = (rHost ? strdup(rHost) : 0);
01007    Route[func].Port = rPort;
01008 }
01009 
01010 /******************************************************************************/
01011 /*                                 x s e c l                                  */
01012 /******************************************************************************/
01013 
01014 /* Function: xsecl
01015 
01016    Purpose:  To parse the directive: seclib <path>
01017 
01018              <path>    the path of the security library to be used.
01019 
01020   Output: 0 upon success or !0 upon failure.
01021 */
01022 
01023 int XrdXrootdProtocol::xsecl(XrdOucStream &Config)
01024 {
01025     char *val;
01026 
01027 // Get the path
01028 //
01029    val = Config.GetWord();
01030    if (!val || !val[0])
01031       {eDest.Emsg("Config", "XRootd seclib not specified"); return 1;}
01032 
01033 // Record the path
01034 //
01035    if (SecLib) free(SecLib);
01036    SecLib = strdup(val);
01037    return 0;
01038 }
01039   
01040 /******************************************************************************/
01041 /*                                x t r a c e                                 */
01042 /******************************************************************************/
01043 
01044 /* Function: xtrace
01045 
01046    Purpose:  To parse the directive: trace <events>
01047 
01048              <events> the blank separated list of events to trace. Trace
01049                       directives are cummalative.
01050 
01051    Output: 0 upon success or 1 upon failure.
01052 */
01053 
01054 int XrdXrootdProtocol::xtrace(XrdOucStream &Config)
01055 {
01056     char *val;
01057     static struct traceopts {const char *opname; int opval;} tropts[] =
01058        {
01059         {"all",      TRACE_ALL},
01060         {"emsg",     TRACE_EMSG},
01061         {"debug",    TRACE_DEBUG},
01062         {"fs",       TRACE_FS},
01063         {"login",    TRACE_LOGIN},
01064         {"mem",      TRACE_MEM},
01065         {"stall",    TRACE_STALL},
01066         {"redirect", TRACE_REDIR},
01067         {"request",  TRACE_REQ},
01068         {"response", TRACE_RSP}
01069        };
01070     int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
01071 
01072     if (!(val = Config.GetWord()))
01073        {eDest.Emsg("config", "trace option not specified"); return 1;}
01074     while (val)
01075          {if (!strcmp(val, "off")) trval = 0;
01076              else {if ((neg = (val[0] == '-' && val[1]))) val++;
01077                    for (i = 0; i < numopts; i++)
01078                        {if (!strcmp(val, tropts[i].opname))
01079                            {if (neg) trval &= ~tropts[i].opval;
01080                                else  trval |=  tropts[i].opval;
01081                             break;
01082                            }
01083                        }
01084                    if (i >= numopts)
01085                       eDest.Emsg("config", "invalid trace option", val);
01086                   }
01087           val = Config.GetWord();
01088          }
01089     XrdXrootdTrace->What = trval;
01090     return 0;
01091 }

Generated on Tue Jul 5 14:47:04 2011 for ROOT_528-00b_version by  doxygen 1.5.1