/************************************************************************ * IRC - Internet Relay Chat, server/s_debug.c * * Copyright (C) 2000-2003 TR-IRCD Development * * Copyright (C) 1990 Jarkko Oikarinen and * University of Oulu, Co Center * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * $Id: s_debug.c,v 1.4 2003/06/14 13:55:52 tr-ircd Exp $ */ #include "struct.h" #include "common.h" #include "sys.h" #include "blalloc.h" #include "h.h" #include "msg.h" #include "s_conf.h" #include "zlink.h" #include "numeric.h" /* * This is part of the STATS replies. There is no offical numeric for * this since this isnt an official command, in much the same way as * HASH isnt. It is also possible that some systems wont support this * call or have different field names for "struct rusage". -avalon */ void send_usage(aClient *cptr, char *nick) { #if defined( HAVE_GETRUSAGE ) struct rusage rus; time_t secs, rup; #ifdef hz #define hzz hz #else #ifdef HZ #define hzz HZ #else int hzz = 1; #endif #endif if (getrusage(RUSAGE_SELF, &rus) == -1) { send_me_notice(cptr, ":Getrusage error"); return; } secs = rus.ru_utime.tv_sec + rus.ru_stime.tv_sec; rup = timeofday - me.since; if (secs == 0) secs = 1; send_me_debug(cptr, "CPU Secs %d:%d User %d:%d System %d:%d", secs / 60, secs % 60, rus.ru_utime.tv_sec / 60, rus.ru_utime.tv_sec % 60, rus.ru_stime.tv_sec / 60, rus.ru_stime.tv_sec % 60); send_me_debug(cptr, "RSS %d ShMem %d Data %d Stack %d", rus.ru_maxrss, rus.ru_ixrss / (rup * hzz), rus.ru_idrss / (rup * hzz), rus.ru_isrss / (rup * hzz)); send_me_debug(cptr, "Swaps %d Reclaims %d Faults %d", rus.ru_nswap, rus.ru_minflt, rus.ru_majflt); send_me_debug(cptr, "Block in %d out %d", rus.ru_inblock, rus.ru_oublock); send_me_debug(cptr, "Msg Rcv %d Send %d", rus.ru_msgrcv, rus.ru_msgsnd); send_me_debug(cptr, "Signals %d Context Vol. %d Invol %d", rus.ru_nsignals, rus.ru_nvcsw, rus.ru_nivcsw); #endif return; } void count_memory(aClient *cptr, char *nick) { aClient *acptr; dlink_node *links; aNUH *ap; aChannel *chptr; aConfItem *aconf; aClass *cltmp; aMotdItem *amo; int lc = 0; /* local clients */ int ch = 0; /* channels */ int lcc = 0; /* local client conf links */ int rc = 0; /* remote clients */ int us = 0; /* user structs */ int chi = 0; /* channel invites */ int chb = 0; /* channel bans */ int ce = 0; /* channel ban exceptions */ int chci = 0; /* channel chaninvites */ int chsm = 0; /* channel moderated hosts */ int chcb = 0; /* channel channel bans */ int chu = 0; /* channel member */ int wwu = 0; /* whowas users */ int cl = 0; /* classes */ int co = 0; /* conf lines */ int usi = 0; /* users invited */ int usc = 0; /* users in channels */ int usdm = 0; /* dccallow local */ int usdr = 0; /* dccallow remote */ int uss = 0; /* silenced users */ int aw = 0; /* aways set */ int linebuf_count = 0; u_long linebuf_memory_used = 0; u_long chbm = 0; /* memory used by channel bans */ u_long chep = 0; /* memory used by ban exceptions */ u_long chim = 0; /* memory used by channel invites */ u_long chmh = 0; /* memory used by channel mhosts */ u_long chcm = 0; /* memory used by channel channel bans */ u_long lcm = 0; /* memory used by local clients */ u_long rcm = 0; /* memory used by remote clients */ u_long awm = 0; /* memory used by aways */ u_long wwm = 0; /* whowas array memory used */ u_long com = 0; /* memory used by conf lines */ u_long totcl = 0; u_long totch = 0; u_long totww = 0; u_long totmisc = 0; u_long tothash = 0; u_long tot = 0; int wlh = 0, wle = 0; /* watch headers/entries */ u_long wlhm = 0; /* memory used by watch */ int lcalloc = 0; /* local clients allocated */ int rcalloc = 0; /* remote clients allocated */ int useralloc = 0; /* allocated users */ int linkalloc = 0; /* allocated links */ int totallinks = 0; /* total links used */ int chanalloc = 0; /* total channels alloc'd */ u_long lcallocsz = 0, rcallocsz = 0; /* size for stuff above */ u_long userallocsz = 0, linkallocsz = 0, chanallocsz = 0, cmemballocsz = 0; int motdlen = 0; int servn = 0; count_whowas_memory(&wwu, &wwm); count_watch_memory(&wlh, &wlhm); count_linebuf_memory(&linebuf_count, &linebuf_memory_used); lcm = lc * CLIENT_LOCAL_SIZE; rcm = rc * CLIENT_REMOTE_SIZE; for (acptr = GlobalClientList; acptr; acptr = acptr->next) { if (MyConnect(acptr)) { lc++; wle += acptr->watches; } else rc++; if (acptr->serv) { servn++; } if (acptr->user) { us++; for (links = acptr->user->invited.head; links; links = links->next) usi++; for (links = acptr->user->channel.head; links; links = links->next) usc++; for (links = acptr->user->dccallow.head; links; links = links->next) { usdm++; usdr++; } for (links = acptr->user->silence.head; links; links = links->next) uss++; if (acptr->user->away) { aw++; awm += (strlen(acptr->user->away) + 1); } } } for (chptr = channel; chptr; chptr = chptr->nextch) { ch++; chu = chptr->users; for (links = chptr->invites.head; links; links = links->next) chi++; for (links = chptr->banlist.head; links; links = links->next) { ap = links->data; chb++; if (ap) chbm += (strlen(ap->who) + strlen(ap->nuhstr) + 2 + sizeof(aNUH)); } for (links = chptr->invitelist.head; links; links = links->next) { ap = links->data; chci++; if (ap) chim += (strlen(ap->who) + strlen(ap->nuhstr) + 2 + sizeof(aNUH)); } for (links = chptr->banexlist.head; links; links = links->next) { ap = links->data; ce++; if (ap) chep += (strlen(ap->who) + strlen(ap->nuhstr) + 2 + sizeof(aNUH)); } for (links = chptr->stoplist.head; links; links = links->next) { ap = links->data; chsm++; if (ap) chmh += (strlen(ap->who) + strlen(ap->nuhstr) + 2 + sizeof(aNUH)); } for (links = chptr->chanbanlist.head; links; links = links->next) { ap = links->data; chcb++; if (ap) chcm += (strlen(ap->who) + strlen(ap->nuhstr) + 2 + sizeof(aNUH)); } } for (aconf = GlobalConfItemList; aconf; aconf = aconf->next) { co++; com += aconf->host ? strlen(aconf->host) + 1 : 0; com += aconf->passwd ? strlen(aconf->passwd) + 1 : 0; com += aconf->name ? strlen(aconf->name) + 1 : 0; com += sizeof(aConfItem); } for (cltmp = ConnectionClasses; cltmp; cltmp = cltmp->next) cl++; for (amo = (&(GeneralOpts.motd))->content; amo; amo = amo->next) motdlen++; for (amo = (&(GeneralOpts.shortmotd))->content; amo; amo = amo->next) motdlen++; for (amo = (&(GeneralOpts.linksfile))->content; amo; amo = amo->next) motdlen++; for (amo = (&(GeneralOpts.conffile))->content; amo; amo = amo->next) motdlen++; #ifndef NOBALLOC lcalloc = free_local_aClients->blocksAllocated * free_local_aClients->elemsPerBlock; lcallocsz = lcalloc * free_local_aClients->elemSize; rcalloc = free_remote_aClients->blocksAllocated * free_remote_aClients->elemsPerBlock; rcallocsz = rcalloc * free_remote_aClients->elemSize; chanalloc = free_channels->blocksAllocated * free_channels->elemsPerBlock; chanallocsz = chanalloc * free_channels->elemSize; #endif totallinks = lcc + usi + uss + usc + chi + wle + usdm + usdr; send_me_debug(cptr, "Memory Use Summary"); send_me_debug(cptr, "Client usage %d(%d) ALLOC %d(%d)", lc + rc, lcm + rcm, lcalloc + rcalloc, lcallocsz + rcallocsz); send_me_debug(cptr, " Local %d(%d) ALLOC %d(%d)", lc, lcm, lcalloc, lcallocsz); send_me_debug(cptr, " Remote %d(%d) ALLOC %d(%d)", rc, rcm, rcalloc, rcallocsz); send_me_debug(cptr, "Users %d(%d) ALLOC %d(%d)", us, us * sizeof(anUser), useralloc, userallocsz); totcl = lcallocsz + rcallocsz + userallocsz; send_me_debug(cptr, "Links %d(%d) ALLOC %d(%d)", totallinks, totallinks * sizeof(dlink_list), linkalloc, linkallocsz); send_me_debug(cptr, " UserInvites %d(%d) ChanInvites %d(%d)", usi, usi * sizeof(dlink_list), chi, chi * sizeof(dlink_list)); send_me_debug(cptr, " UserChannels %d(%d)", usc, usc * sizeof(dlink_list)); send_me_debug(cptr, " DCCAllow Local %d(%d) Remote %d(%d)", usdm, usdm * sizeof(dlink_list), usdr, usdr * sizeof(dlink_list)); send_me_debug(cptr, " WATCH entries %d(%d)", wle, wle * sizeof(dlink_list)); send_me_debug(cptr, " Attached confs %d(%d)", lcc, lcc * sizeof(dlink_list)); send_me_debug(cptr, "WATCH headers %d(%d)", wlh, wlhm); send_me_debug(cptr, "Conflines %d(%d)", co, com); send_me_debug(cptr, "Classes %d(%d)", cl, cl * sizeof(aClass)); send_me_debug(cptr, "Away Messages %d(%d)", aw, awm); send_me_debug(cptr, "MOTD structs %d(%d)", motdlen, motdlen * sizeof(aMotd)); send_me_debug(cptr, "Servers %d(%d)", servn, servn * sizeof(aServer)); send_me_debug(cptr, "Channels %d(%d) ALLOC %d(%d) Bans %d(%d)", ch, ch * sizeof(aChannel), chanalloc, chanallocsz, chb, chbm); totch = chanallocsz + cmemballocsz + chbm; send_me_debug(cptr, "Whowas users %d(%d)", wwu, wwu * sizeof(anUser)); send_me_debug(cptr, "Whowas array %d(%d)", NICKNAMEHISTORYLENGTH, wwm); totww = wwu * sizeof(anUser) + wwm; send_me_debug(cptr, "Hash: client %d(%d) chan %d(%d) whowas %d(%d) watch %d(%d)", U_MAX, sizeof(aHashEntry) * U_MAX, CH_MAX, sizeof(aHashEntry) * CH_MAX, WW_MAX, sizeof(aWhowas *) * WW_MAX, WATCHHASHSIZE, sizeof(aWatch *) * WATCHHASHSIZE); send_me_debug(cptr, "Linebuf %d(%d)", linebuf_count, (int) linebuf_memory_used); tothash = (sizeof(aHashEntry) * U_MAX) + (sizeof(aHashEntry) * CH_MAX) + (sizeof(aWatch *) * WATCHHASHSIZE) + (sizeof(aWhowas *) * WW_MAX); tot = totww + totch + totcl + totmisc + tothash + linkallocsz; send_me_debug(cptr, "whowas %d chan %d client/user %d misc %d hash %d link %d", totww, totch, totcl, totmisc, tothash, linkallocsz); return; }