#ifndef _BLURB_ #define _BLURB_ /* Coda: an Experimental Distributed File System Release 6 Copyright (c) 1987-2003 Carnegie Mellon University All Rights Reserved Permission to use, copy, modify and distribute this software and its documentation is hereby granted, provided that both the copyright notice and this permission notice appear in all copies of the software, derivative works or modified versions, and any portions thereof, and that both notices appear in supporting documentation, and that credit is given to Carnegie Mellon University in all documents and publicity pertaining to direct or indirect use of this code or its derivatives. CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS, SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF ANY DERIVATIVE WORK. Carnegie Mellon encourages users of this software to return any improvements or extensions that they make, and to grant Carnegie Mellon the rights to redistribute these changes without encumbrance. */ #endif /*_BLURB_*/ // // data.c // // implementation of the classes encapsulating the data types collected // by mond along with the buffer pool class. #ifdef __cplusplus extern "C" { #endif __cplusplus #include "coda_assert.h" #include #include "lock.h" #ifdef __cplusplus } #endif __cplusplus #include "mondgen.h" #include "mond.h" #include "report.h" #include "data.h" #include "util.h" extern int LogLevel; extern FILE *LogFile; /* ** global buffer pools -- one per data type */ bufpool session_pool(SESSION); bufpool comm_pool(COMM); bufpool clientCall_pool(CLNTCALL); bufpool clientMCall_pool(CLNTMCALL); bufpool clientRVM_pool(CLNTRVM); bufpool vcb_pool(VCB); bufpool advice_pool(ADVICE); bufpool miniCache_pool(MINICACHE); bufpool overflow_pool(OVERFLOW); bufpool srvrCall_pool(SRVCALL); bufpool resEvent_pool(SRVRES); bufpool rvmResEvent_pool(SRVRVMRES); bufpool srvOverflow_pool(SRVOVRFLW); bufpool iotInfo_pool(IOTINFO); bufpool iotStat_pool(IOTSTAT); bufpool subtree_pool(SUBTREE); bufpool repair_pool(REPAIR); bufpool rwsStat_pool(RWSSTAT); void callCountArray::set(long newSize, CallCountEntry *newArray) { if (size != newSize) { if (array != NULL) { for (int i=0; i", i, array[i].name, array[i].countent, array[i].countexit, array[i].tsec, array[i].tusec, array[i].counttime); } callCountArray::callCountArray(void) { size = 0; array = NULL; } callCountArray::~callCountArray(void) { if (array != NULL) { for (int i=0; iIPAddress; Venus.BirthTime = venus->BirthTime; Session = session; Volume = volume; User = user; for (i = 0; i < 8 ; i++) (&(AVSG.Member0))[i] = (&avsg->Member0)[i]; StartTime = starttime; EndTime = endtime; CETime = cetime; LogMsg(1000,LogLevel,LogFile,"Session Event init"); bzero((char *) &Events,(int)sizeof(VmonSessionEventArray)); for (i=0; iOpcode = se2.Opcode; se1->SuccessCount = se2.SuccessCount; se1->SigmaT = se2.SigmaT; se1->SigmaTSquared = se2.SigmaTSquared; se1->FailureCount = se2.FailureCount; } Stats = *stats; CacheStats = *cachestats; } void session_data::Release(void) { session_pool.putSlot((vmon_data *) this); } void comm_data::init(VmonVenusId *venus, unsigned long serveripaddress, long serial, unsigned long time, VmonCommEventType type) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; ServerIPAddress = serveripaddress; SerialNumber = serial; Time = time; EvType = type; } void comm_data::Release(void) { comm_pool.putSlot((vmon_data *) this); } void clientCall_data::init(VmonVenusId *venus, long time, long scsize, CallCountEntry *srvcount) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; Time = time; SrvCount.set(scsize,srvcount); } void clientCall_data::Release(void) { clientCall_pool.putSlot((vmon_data *) this); } void clientCall_data::Print(void) { LogMsg(0, LogLevel, LogFile, "clientCall_data::Print: this = %x; Venus = %x; Time = %d\n", this, Venus.IPAddress, Time); SrvCount.Print(); } void clientMCall_data::init(VmonVenusId *venus, long time, long mscsize, MultiCallEntry *msrvcount) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; Time = time; MSrvCount.set(mscsize,msrvcount); } void clientMCall_data::Release(void) { clientMCall_pool.putSlot((vmon_data *) this); } void clientRVM_data::init(VmonVenusId *venus, long time, RvmStatistics *stats) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; Time = time; Stats.Malloc = stats->Malloc; Stats.Free = stats->Free; Stats.FreeBytes = stats->FreeBytes; Stats.MallocBytes = stats->MallocBytes; } void clientRVM_data::Release(void) { clientRVM_pool.putSlot((vmon_data *) this); } void vcb_data::init(VmonVenusId *venus, long venusinit, long time, VolumeId volume, VCBStatistics *stats) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; VenusInit = venusinit; Time = time; Volume = volume; Stats = *stats; } void vcb_data::Release(void) { vcb_pool.putSlot((vmon_data *) this); } advice_data::advice_data() { Call_Size = 0L; Result_Size = 0L; Call_Stats = NULL; Result_Stats = NULL; } advice_data::~advice_data() { delete [] Call_Stats; delete [] Result_Stats; } void advice_data::init(VmonVenusId *venus, long time, UserId user, AdviceStatistics *stats, unsigned long call_size, AdviceCalls call_stats[], unsigned long result_size, AdviceResults result_stats[]) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; Time = time; User = user; Stats.NotEnabled = stats->NotEnabled; Stats.NotValid = stats->NotValid; Stats.Outstanding = stats->Outstanding; Stats.ASRnotAllowed = stats->ASRnotAllowed; Stats.ASRinterval = stats->ASRinterval; Stats.VolumeNull = stats->VolumeNull; Stats.TotalNumberAttempts = stats->TotalNumberAttempts; if (call_size != Call_Size) { delete Call_Stats; Call_Size = call_size; Call_Stats = new AdviceCalls[Call_Size]; } if (result_size != Result_Size) { delete Result_Stats; Result_Size = result_size; Result_Stats = new AdviceResults[Result_Size]; } for (int i=0; iIPAddress; Venus.BirthTime = venus->BirthTime; Time = time; if (vn_size != VN_Size) { delete VN_Stats; VN_Size = vn_size; VN_Stats = new VmonMiniCacheStat[VN_Size]; } if (vfs_size != VFS_Size) { delete VFS_Stats; VFS_Size = vfs_size; VFS_Stats = new VmonMiniCacheStat[VFS_Size]; } for (int i=0; iIPAddress; Venus.BirthTime = venus->BirthTime; VMStartTime = vmstarttime; VMEndTime = vmendtime; VMCount = vmcount; RVMStartTime = rvmstarttime; RVMEndTime = rvmendtime; RVMCount = rvmcount; } void overflow_data::Release(void) { overflow_pool.putSlot((vmon_data *) this); } void srvrCall_data::init(SmonViceId *vice ,unsigned long time, long cbcsize, CallCountEntry cbcount[], long rcsize, CallCountEntry rescount[], long scsize, CallCountEntry smoncount[], long vdcsize, CallCountEntry voldcount[], long mcsize, MultiCallEntry multicount[], SmonStatistics *stats) { Vice.IPAddress = vice->IPAddress; Vice.BirthTime = vice->BirthTime; Time = time; Stats.SystemCPU = stats->SystemCPU; Stats.UserCPU = stats->UserCPU; Stats.IdleCPU = stats->IdleCPU; Stats.BootTime = stats->BootTime; Stats.TotalIO = stats->TotalIO; CBCount.set(cbcsize,cbcount); ResCount.set(rcsize,rescount); SmonCount.set(scsize,smoncount); VolDCount.set(vdcsize,voldcount); MultiCount.set(mcsize,multicount); } void srvrCall_data::Release(void) { srvrCall_pool.putSlot((vmon_data *) this); } resEvent_data::resEvent_data(void) { // Uses the same array allocation/reallocation trick // seen in srvrCall_data::srvrCall_data() // only need to initialize resop_size and ResOp, the others // are covered by resevent::init ResOp_size = 0; ResOp = (ResOpEntry *)NULL; } void resEvent_data::init(SmonViceId *vice, RPC2_Unsigned time, VolumeId volid, RPC2_Integer highwatermark, RPC2_Integer allocnumber, RPC2_Integer deallocnumber, RPC2_Integer resop_size, ResOpEntry resop[]) { // this is somewhat simpler than the code in srvrCall_data::init, // because none of the fields of ResOpEntry require allocation if (resop_size != ResOp_size) { if (ResOp != NULL) delete [] ResOp; ResOp_size = resop_size; ResOp = new ResOpEntry[resop_size]; } Vice.IPAddress = vice->IPAddress; Vice.BirthTime = vice->BirthTime; Time = time; Volid = volid; HighWaterMark = highwatermark; AllocNumber = allocnumber; DeallocNumber = deallocnumber; for (int i=0;iIPAddress; Vice.BirthTime = vice->BirthTime; Time = time; StartTime = starttime; EndTime = endtime; Count = count; } void srvOverflow_data::Release(void) { srvOverflow_pool.putSlot((vmon_data *) this); } iotInfo_data::iotInfo_data(void) { AppNameLen = 0; AppName = NULL; } iotInfo_data::~iotInfo_data(void) { delete [] AppName; } void iotInfo_data::init(VmonVenusId *venus, IOT_INFO *info, RPC2_Integer appnamelen, RPC2_String appname) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; Info.Tid = info->Tid; Info.ResOpt = info->ResOpt; Info.ElapsedTime = info->ElapsedTime; Info.ReadSetSize = info->ReadSetSize; Info.WriteSetSize = info->WriteSetSize; Info.ReadVolNum = info->ReadVolNum; Info.WriteVolNum = info->WriteVolNum; Info.Validation = info->Validation; Info.InvalidSize = info->InvalidSize; Info.BackupObjNum = info->BackupObjNum; Info.LifeCycle = info->LifeCycle; Info.PredNum = info->PredNum; Info.SuccNum = info->SuccNum; AppNameLen = appnamelen; AppName = new unsigned char[appnamelen]; strcpy((char *)AppName, (char *)appname); } void iotInfo_data::Release(void) { iotInfo_pool.putSlot((vmon_data *) this); } void iotStat_data::init(VmonVenusId *venus, RPC2_Integer time, IOT_STAT *stats) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; Time = time; Stats.MaxElapsedTime = stats->MaxElapsedTime; Stats.AvgElapsedTime = stats->AvgElapsedTime; Stats.MaxReadSetSize = stats->MaxReadSetSize; Stats.AvgReadSetSize = stats->AvgReadSetSize; Stats.MaxWriteSetSize = stats->MaxWriteSetSize; Stats.AvgWriteSetSize = stats->AvgWriteSetSize; Stats.MaxReadVolNum = stats->MaxReadVolNum; Stats.AvgReadVolNum = stats->AvgReadVolNum; Stats.MaxWriteVolNum = stats->MaxWriteVolNum; Stats.AvgWriteVolNum = stats->AvgWriteVolNum; Stats.Committed = stats->Committed; Stats.Pending = stats->Pending; Stats.Resolved = stats->Resolved; Stats.Repaired = stats->Repaired; Stats.OCCRerun = stats->OCCRerun; } void iotStat_data::Release(void) { iotStat_pool.putSlot((vmon_data *) this); } void subtree_data::init(VmonVenusId *venus, RPC2_Integer time, LocalSubtreeStats *stats) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; Time = time; Stats.SubtreeNum = stats->SubtreeNum; Stats.MaxSubtreeSize = stats->MaxSubtreeSize; Stats.AvgSubtreeSize = stats->AvgSubtreeSize; Stats.MaxSubtreeHgt = stats->MaxSubtreeHgt; Stats.AvgSubtreeHgt = stats->AvgSubtreeHgt; Stats.MaxMutationNum = stats->MaxMutationNum; Stats.AvgMutationNum = stats->AvgMutationNum; } void subtree_data::Release(void) { subtree_pool.putSlot((vmon_data *) this); } void repair_data::init(VmonVenusId *venus, RPC2_Integer time, RepairSessionStats *stats) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; Time = time; Stats.SessionNum = stats->SessionNum; Stats.CommitNum = stats->CommitNum; Stats.AbortNum = stats->AbortNum; Stats.CheckNum = stats->CheckNum; Stats.PreserveNum = stats->PreserveNum; Stats.DiscardNum = stats->DiscardNum; Stats.RemoveNum = stats->RemoveNum; Stats.GlobalViewNum = stats->GlobalViewNum; Stats.LocalViewNum = stats->LocalViewNum; Stats.KeepLocalNum = stats->KeepLocalNum; Stats.ListLocalNum = stats->ListLocalNum; Stats.NewCommand1Num = stats->NewCommand1Num; Stats.NewCommand2Num = stats->NewCommand2Num; Stats.NewCommand3Num = stats->NewCommand3Num; Stats.NewCommand4Num = stats->NewCommand4Num; Stats.NewCommand5Num = stats->NewCommand5Num; Stats.NewCommand6Num = stats->NewCommand6Num; Stats.NewCommand7Num = stats->NewCommand7Num; Stats.NewCommand8Num = stats->NewCommand8Num; Stats.RepMutationNum = stats->RepMutationNum; Stats.MissTargetNum = stats->MissTargetNum; Stats.MissParentNum = stats->MissParentNum; Stats.AclDenyNum = stats->AclDenyNum; Stats.UpdateUpdateNum = stats->UpdateUpdateNum; Stats.NameNameNum = stats->NameNameNum; Stats.RemoveUpdateNum = stats->RemoveUpdateNum; } void repair_data::Release(void) { repair_pool.putSlot((vmon_data *) this); } void rwsStat_data::init(VmonVenusId *venus, RPC2_Integer time, ReadWriteSharingStats *stats) { Venus.IPAddress = venus->IPAddress; Venus.BirthTime = venus->BirthTime; Time = time; Stats.Vid = stats->Vid; Stats.RwSharingCount = stats->RwSharingCount; Stats.DiscReadCount = stats->DiscReadCount; Stats.DiscDuration = stats->DiscDuration; } void rwsStat_data::Release(void) { rwsStat_pool.putSlot((vmon_data *) this); } bufpool::bufpool(dataClass Type) { type = Type; Pool = NULL; Lock_Init(&lock); } vmon_data *bufpool::getSlot(void) { vmon_data *temp; ObtainWriteLock(&lock); if (Pool == NULL) { switch (type) { case SESSION: temp = (vmon_data*) new (session_data); break; case COMM: temp = (vmon_data*) new (comm_data); break; case CLNTCALL: temp = (vmon_data*) new (clientCall_data); break; case CLNTMCALL: temp = (vmon_data*) new (clientMCall_data); break; case CLNTRVM: temp = (vmon_data*) new (clientRVM_data); break; case VCB: temp = (vmon_data*) new (vcb_data); break; case ADVICE: temp = (vmon_data*) new (advice_data); break; case MINICACHE: temp = (vmon_data*) new (miniCache_data); break; case OVERFLOW: temp = (vmon_data*) new (overflow_data); break; case SRVCALL: temp = (vmon_data*) new (srvrCall_data); break; case SRVRES: temp = (vmon_data*) new (resEvent_data); break; case SRVRVMRES: temp = (vmon_data*) new (rvmResEvent_data); break; case SRVOVRFLW: temp = (vmon_data*) new (srvOverflow_data); break; case IOTINFO: temp = (vmon_data*) new (iotInfo_data); break; case IOTSTAT: temp = (vmon_data*) new (iotStat_data); break; case SUBTREE: temp = (vmon_data*) new (subtree_data); break; case REPAIR: temp = (vmon_data*) new (repair_data); break; case RWSSTAT: temp = (vmon_data*) new (rwsStat_data); break; case dataClass_last_tag: default: CODA_ASSERT(0); } } else { temp = (vmon_data*) Pool; Pool = Pool->Next(); temp->NotOnList(); } ReleaseWriteLock(&lock); return temp; } void bufpool::putSlot(vmon_data *slot) { ObtainWriteLock(&lock); slot->SetNext(Pool); Pool = slot; ReleaseWriteLock(&lock); }