#ifndef __XRDCnsLogRec_H_ #define __XRDCnsLogRec_H_ /******************************************************************************/ /* */ /* X r d C n s L o g R e c . h h */ /* */ /* (c) 2009 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 Department 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 "XrdSys/XrdSysPlatform.hh" #include "XrdSys/XrdSysPthread.hh" class XrdCnsLogRec { public: static const int maxClients = 4; struct Ctl {short dataLen; // Length of data in Arg (eof when 0) short lfn1Len; // strlen(lfn1) short lfn2Len; // strlen(lfn2) short Mode; // File mode (create and mkdir) char Done[maxClients]; // 1->Record processed int Rsvd; // Reserved field long long Size; // Valid when Closew }; struct Arg {char Type; // Event code char Mode[3]; // Mode (create, inv, mkdir) char SorT[12]; // Size (closew, inv) | TOD (eol) char Mount; // Mount Index char Space; // Space Index char Rsvd[6]; // Reserved (blank filled) char lfn[MAXPATHLEN*2+3]; // lfn1 [lfn2] \n }; struct LogRec {struct Ctl Hdr; struct Arg Data; }; static const int OffDone = offsetof(LogRec, Hdr.Done); static const int FixDLen = offsetof(Arg, lfn); static const int MinSize = sizeof(Ctl); // Header static const int MaxSize = sizeof(Arg); // Data static const long tBase = 1248126834L; static const char lrClosew = 't'; static const char lrCreate = 'c'; static const char lrEOL = 'E'; // Internal static const char lrInvD = 'I'; // Internal dir inventory static const char lrInvF = 'i'; // Internal file inventory static const char lrMkdir = 'd'; static const char lrMount = 'M'; // Internal Mount inventory static const char lrMv = 'm'; static const char lrRm = 'r'; static const char lrRmdir = 'D'; static const char lrSpace = 'S'; // Internal Space inventory static const char lrTOD = 'T'; // Internal TOD static const char *IArg; static const char *iArg; static XrdCnsLogRec *Alloc(); inline const char *Data() {return (const char *)&Rec.Data;} inline int DLen() {return Rec.Hdr.dataLen;} inline int Done(int iPos) {return Rec.Hdr.Done[iPos];} static XrdCnsLogRec *Get(char &lrType); inline const char *Lfn1() {return Rec.Data.lfn;} inline const char *Lfn1(int &Len) {Len=Rec.Hdr.lfn1Len; return Rec.Data.lfn;} inline const char *Lfn2() {return Rec.Data.lfn+Rec.Hdr.lfn1Len+1;} inline mode_t Mode() {return static_cast(Rec.Hdr.Mode);} void Queue(); void Recycle(); inline char *Record() {return (char *)&Rec;} // setLfn1() must be called prior to calling setLfn2() or setData() // int setData(const char *dP1, const char *dP2=0); void setDone(int iPos, char Val=1) {Rec.Hdr.Done[iPos] = Val;} int setLen() {if (Rec.Hdr.lfn1Len) {Rec.Hdr.dataLen = FixDLen+Rec.Hdr.lfn1Len+1; if (Rec.Hdr.lfn2Len) Rec.Hdr.dataLen += Rec.Hdr.lfn2Len+1; } else Rec.Hdr.dataLen = 0; return static_cast(Rec.Hdr.dataLen); } inline int setLfn1(const char *lfn) {int n; n = strlcpy(Rec.Data.lfn, lfn, MAXPATHLEN+1); if (n > MAXPATHLEN) return 0; Rec.Hdr.lfn1Len = n; return n; } inline int setLfn2(const char *lfn) {int n; setSize(static_cast(Rec.Hdr.lfn1Len)); n = strlcpy(Rec.Data.lfn + Rec.Hdr.lfn1Len + 1, lfn, MAXPATHLEN+1); if (n > MAXPATHLEN) return 0; Rec.Hdr.lfn2Len = n; return n; } inline void setMode(mode_t Mode) {char mBuff[8]; Rec.Hdr.Mode = Mode; snprintf(mBuff,sizeof(mBuff),"%03o", 511 & static_cast(Mode)); memcpy(Rec.Data.Mode, mBuff, sizeof(Rec.Data.Mode)); } inline void setMount(char mCode) {Rec.Data.Mount = mCode;} inline void setSize(long long Size) {char tBuff[24]; Rec.Hdr.Size = Size; snprintf(tBuff, sizeof(tBuff), "%12lld", (Size > 0 ? Size & 0x7fffffffffLL : Size)); memcpy(Rec.Data.SorT, tBuff, sizeof(Rec.Data.SorT)); } inline void setSpace(char sCode) {Rec.Data.Space = sCode;} inline void setTime(long TOD=time(0)){char tBuff[24]; snprintf(tBuff, sizeof(tBuff), "%12ld", TOD-tBase); memcpy(Rec.Data.SorT, tBuff, sizeof(Rec.Data.SorT)); } inline void setType(const char evt) {Rec.Data.Type = evt;} int setType(const char *evt); inline long long Size() {return Rec.Hdr.Size;} inline char Space(){return Rec.Data.Space;} inline int L1sz() {return Rec.Hdr.lfn1Len;} inline int L2sz() {return Rec.Hdr.lfn2Len;} char Type() {return Rec.Data.Type;} XrdCnsLogRec(const char rType=0) : Next(0) {memset(&Rec, 0, sizeof(Rec.Hdr)); memset(&Rec.Data,' ', FixDLen); Rec.Data.Type = rType; if (rType == lrEOL || rType == lrTOD) {setTime(); Rec.Hdr.dataLen=FixDLen; if (rType == lrTOD) {Rec.Data.lfn[0] = ' '; Rec.Data.lfn[1] = '\0'; Rec.Hdr.lfn1Len = 1; } } } ~XrdCnsLogRec() {} private: static XrdSysSemaphore qSem; static XrdSysMutex qMutex; static XrdSysMutex fMutex; static XrdCnsLogRec *freeRec; static XrdCnsLogRec *frstRec; static XrdCnsLogRec *lastRec; static int Running; XrdCnsLogRec *Next; LogRec Rec; }; #endif