/************************************************************************
* 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;
}
syntax highlighted by Code2HTML, v. 0.9.1