#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