XrdCnsLogServer.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                    X r d C n s L o g S e r v e r . c c                     */
00004 /*                                                                            */
00005 /* (c) 2009 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010   
00011 //          $Id: XrdCnsLogServer.cc 32231 2010-02-05 18:24:46Z ganis $
00012 
00013 const char *XrdCnsLogServerCVSID = "$Id: XrdCnsLogServer.cc 32231 2010-02-05 18:24:46Z ganis $";
00014   
00015 #include <fcntl.h>
00016 #include <unistd.h>
00017 #include <sys/types.h>
00018 #include <sys/stat.h>
00019 
00020 #include "Xrd/XrdTrace.hh"
00021 
00022 #include "XrdOss/XrdOssPath.hh"
00023 #include "XrdOuc/XrdOucTList.hh"
00024 #include "XrdCns/XrdCnsConfig.hh"
00025 #include "XrdCns/XrdCnsLogClient.hh"
00026 #include "XrdCns/XrdCnsLogFile.hh"
00027 #include "XrdCns/XrdCnsLogRec.hh"
00028 #include "XrdCns/XrdCnsLogServer.hh"
00029 #include "XrdSys/XrdSysError.hh"
00030 #include "XrdSys/XrdSysPthread.hh"
00031   
00032 /******************************************************************************/
00033 /*                        G l o b a l   O b j e c t s                         */
00034 /******************************************************************************/
00035   
00036 namespace XrdCns
00037 {
00038 extern XrdCnsConfig Config;
00039 
00040 extern XrdSysError  MLog;
00041 
00042 extern XrdOucTrace  XrdTrace;
00043 }
00044 
00045 using namespace XrdCns;
00046 
00047 
00048 /******************************************************************************/
00049 /*                     T h r e a d   I n t e r f a c e s                      */
00050 /******************************************************************************/
00051   
00052 namespace XrdCns
00053 {
00054 void *StartLogServer(void *parg)
00055 {
00056    XrdCnsLogServer *lsP = static_cast<XrdCnsLogServer *>(parg);
00057    lsP->Run();
00058    MLog.Emsg("Run", "Fatal log server error; terminating!");
00059    _exit(8);
00060    return (void *)0;
00061 }
00062 }
00063 
00064 /******************************************************************************/
00065 /*                           C o n s t r u c t o r                            */
00066 /******************************************************************************/
00067   
00068 XrdCnsLogServer::XrdCnsLogServer()
00069 {
00070 // Construct our logfile path
00071 //
00072    strcpy(logDir, Config.ePath);
00073    logFN = logDir + strlen(Config.ePath);
00074 }
00075 
00076 /******************************************************************************/
00077 /*                                  I n i t                                   */
00078 /******************************************************************************/
00079   
00080 int XrdCnsLogServer::Init(XrdOucTList *rList)
00081 {
00082    struct stat Stat;
00083    pthread_t tid;
00084    int rc, aOK = 1;
00085 
00086 // First, inform the log file the maximum true records we will add
00087 //
00088    XrdCnsLogFile::maxRecs(Config.qLim);
00089 
00090 // If this is a command line recreate then just serially do the recreates
00091 //
00092    if (Config.Opts & XrdCnsConfig::optRecr)
00093       {while(rList)
00094             {Client = new XrdCnsLogClient(rList, 0);
00095              if (!Client->Init()) aOK = 0;
00096              delete Client;
00097              rList = rList->next;
00098             }
00099         return aOK;
00100        }
00101 
00102 // First see if we have a pending log file
00103 //
00104    strcpy(logFN, "cns.log");
00105    if (stat(logDir, &Stat))
00106       {if (errno != ENOENT)
00107           {MLog.Emsg("Init", errno, "stat file", logDir); return 0;}
00108        Stat.st_size = 0;
00109       }
00110 
00111 // If this is an empty log file, then remove it, otherwise end file it
00112 //
00113    if (Stat.st_size != 0)
00114       {XrdCnsLogFile myLogFile(logDir);
00115        if (!myLogFile.Open(0, Stat.st_size) || !myLogFile.Eol()) return 0;
00116       }
00117    unlink(logDir);
00118 
00119 // We now can create required log clients and initialize them
00120 //
00121    *logFN = '\0';
00122    while(rList)
00123         {Client = new XrdCnsLogClient(rList, Client);
00124          if (!Client->Init())
00125             {MLog.Emsg("Init", "Initialization for",rList->text,"failed.");
00126              aOK = 0;
00127             }
00128          rList = rList->next;
00129         }
00130 
00131 // Now activate a new log and start the clients
00132 //
00133    if (aOK)
00134       {strcpy(logFN, "cns.log");
00135        logFile = new XrdCnsLogFile(logDir);
00136        if (!logFile->Open(0)) aOK = 0;
00137           else {if (!Client->Activate(logFile)) aOK = 0;
00138                    else Client->Start();
00139                }
00140       }
00141 
00142 // Now start the server
00143 //
00144    if ((rc = XrdSysThread::Run(&tid, StartLogServer, (void *)this,
00145                                  XRDSYSTHREAD_BIND, "Log server")))
00146       {MLog.Emsg("Start", rc, "create log server thread"); aOK = 0;}
00147 
00148 // All done
00149 //
00150    return aOK;
00151 }
00152 
00153 /******************************************************************************/
00154 /* Private                       M a s s a g e                                */
00155 /******************************************************************************/
00156   
00157 void XrdCnsLogServer::Massage(XrdCnsLogRec *lrP)
00158 {
00159    const char *cP;
00160    char lfnBuff[MAXPATHLEN+1], pfnBuff[MAXPATHLEN+1], lnkBuff[MAXPATHLEN+1];
00161    char *cgiP, *mP;
00162    int lnkbsz = sizeof(lnkBuff);
00163 
00164 // Get the pfn for the lfn
00165 //
00166    strcpy(lfnBuff, lrP->Lfn1());
00167    if ((cgiP = index(lfnBuff, '?'))) *cgiP = '\0';
00168    if (!Config.LocalPath(lfnBuff, pfnBuff, sizeof(pfnBuff))) return;
00169 
00170 // Now get space information
00171 //
00172    cP = XrdOssPath::Extract(pfnBuff, lnkBuff, lnkbsz);
00173 
00174 // Check if we actually have a true mount point
00175 //
00176    if (lnkBuff[1]) mP = lnkBuff;
00177       else {Config.MountPath(lfnBuff, pfnBuff, sizeof(pfnBuff));
00178             mP = pfnBuff;
00179            }
00180 
00181 // Set information in the create record
00182 //
00183    lrP->setData(cP, mP);
00184 }
00185 
00186 /******************************************************************************/
00187 /*                                   R u n                                    */
00188 /******************************************************************************/
00189   
00190 void XrdCnsLogServer::Run()
00191 {
00192    static const char *TraceID = "ServerRun";
00193    XrdCnsLogFile *lfP;
00194    XrdCnsLogRec  *lrP;
00195    char lrT;
00196    int  nRecs;
00197 
00198 // All we need to do is transfer log records from the queue to the log file
00199 // and periodically close out the log and start over. Timing marks are
00200 // periodically placed in the queue that cause a nil-pointer to be returned.
00201 // We honor them if we actually have something in the log file. In any case,
00202 // We must activate the new file before we close out the old file to make sure
00203 // log clients have a logfile that they can actually process.
00204 //
00205 do{nRecs = Config.qLim; lfP = logFile;
00206 
00207    while(nRecs && (lrP = XrdCnsLogRec::Get(lrT)))
00208         {if (lrP->Type() == XrdCnsLogRec::lrCreate) Massage(lrP);
00209          lfP->Add(lrP); lrP->Recycle();
00210          nRecs--;
00211         }
00212 
00213    if (nRecs != Config.qLim)
00214       {TRACE(DEBUG, "Closing out " <<(Config.qLim-nRecs) <<" log records.");
00215        lfP->Eol();
00216        if (!lfP->Unlink()) break;
00217        logFile = new XrdCnsLogFile(logDir);
00218        if (!logFile->Open() || !Client->Activate(logFile)) break;
00219        delete lfP;
00220       }
00221   } while(1);
00222 
00223 // At the moment we don't really have a recovery strategy
00224 //
00225    MLog.Emsg("Run", "Fatal error occurred; terminating. . .");
00226 }

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