예제 #1
0
void	count_memory(aClient *cptr, char *nick, int debug)
{
	extern	aChannel	*channel;
	extern	aClass		*classes;
	extern	aConfItem	*conf;
	extern	int		_HASHSIZE, _CHANNELHASHSIZE;

	Reg	aClient		*acptr;
	Reg	Link		*link;
	Reg	aChannel	*chptr;
	Reg	aConfItem	*aconf;
	Reg	aClass		*cltmp;

	int	lc = 0, d_lc = 0,	/* local clients */
		ch = 0, d_ch = 0,	/* channels */
		lcc = 0, d_lcc = 0,	/* local client conf links */
		rc = 0, d_rc = 0,	/* remote clients */
		us = 0, d_us = 0,	/* user structs */
		chu = 0, d_chu = 0,	/* channel users */
		chi = 0, d_chi = 0,	/* channel invites */
		chb = 0, d_chb = 0,	/* channel bans */
		chh = 0, d_chh = 0,	/* channel in history */
		wwu = 0, d_wwu = 0,	/* whowas users */
		cl = 0, d_cl = 0,	/* classes */
		co = 0, d_co = 0;	/* conf lines */

	int	usi = 0, d_usi = 0,	/* users invited */
		usc = 0, d_usc = 0,	/* users in channels */
		aw = 0, d_aw = 0,	/* aways set */
		wwa = 0, d_wwa = 0,	/* whowas aways */
		wwuw = 0, d_wwuw = 0;   /* whowas uwas */

	u_long	chm = 0, d_chm = 0,	/* memory used by channels */
		chhm = 0, d_chhm = 0,	/* memory used by channel in history */
		chbm = 0, d_chbm = 0,	/* memory used by channel bans */
		lcm = 0, d_lcm = 0,	/* memory used by local clients */
		rcm = 0, d_rcm = 0,	/* memory used by remote clients */
		awm = 0, d_awm = 0,	/* memory used by aways */
		wwam = 0, d_wwam = 0,	/* whowas away memory used */
		wwm = 0, d_wwm = 0,	/* whowas array memory used */
		dm = 0, d_dm = 0,	/* delay array memory used */
		com = 0, d_com = 0,	/* memory used by conf lines */
		db = 0, d_db = 0,	/* memory used by dbufs */
		rm = 0, d_rm = 0,	/* res memory used */
		totcl = 0, d_totcl = 0,
		totch = 0, d_totch = 0,
		totww = 0, d_totww = 0,
		tot = 0, d_tot = 0;
	time_t	start = 0;

	if (debug)
	    {
		start = time(NULL);
		count_whowas_memory(&d_wwu, &d_wwa, &d_wwam, &d_wwuw);
		d_wwm = sizeof(aName) * ww_size;
		d_dm = sizeof(aLock) * lk_size;
	    }
	wwu = istat.is_wwusers;
	wwa = istat.is_wwaways;
	wwam = istat.is_wwawaysmem;
	wwuw = istat.is_wwuwas;
	wwm = sizeof(aName) * ww_size;
	dm = sizeof(aLock) * lk_size;

	/*lc = istat.is_unknown + istat.is_myclnt + istat.is_serv;*/
	lc = istat.is_localc;
	lcc = istat.is_conflink;
	rc = istat.is_remc;
	us = istat.is_users;
	usi = istat.is_useri;
	usc = istat.is_userc;
	aw = istat.is_away;
	awm = istat.is_awaymem;

	if (debug)
	{
		for (acptr = client; acptr; acptr = acptr->next)
		{
			if (MyConnect(acptr))
			{
				d_lc++;
				for (link = acptr->confs; link; link=link->next)
				{
					d_lcc++;
				}
			}
			else
			{
				d_rc++;
			}
			if (acptr->user)
			{
				invLink	*ilink;

				d_us++;
				for (ilink = acptr->user->invited; ilink;
				     ilink = ilink->next)
				{
					d_usi++;
				}
				d_usc += acptr->user->joined;
				if (acptr->user->away)
				{
					d_aw++;
					d_awm += (strlen(acptr->user->away)+1);
				}
			}
		}
	}

	lcm = lc * CLIENT_LOCAL_SIZE;
	rcm = rc * CLIENT_REMOTE_SIZE;

	d_lcm = d_lc * CLIENT_LOCAL_SIZE;
	d_rcm = d_rc * CLIENT_REMOTE_SIZE;

	ch = istat.is_chan;
	chm = istat.is_chanmem;
	chh = istat.is_hchan;
	chhm = istat.is_hchanmem;
	chi = istat.is_invite;
	chb = istat.is_bans;
	chbm = istat.is_banmem + chb * sizeof(Link);
	chu = istat.is_chanusers;

	if (debug)
	{
		for (chptr = channel; chptr; chptr = chptr->nextch)
		{
			if (chptr->users == 0)
			{
				d_chh++;
				d_chhm+=strlen(chptr->chname)+sizeof(aChannel);
			}
			else
			{
				d_ch++;
				d_chm += (strlen(chptr->chname) +
					  sizeof(aChannel));
			}
			for (link = chptr->members; link; link = link->next)
			{
				d_chu++;
			}
			for (link = chptr->invites; link; link = link->next)
			{
				d_chi++;
			}
			for (link = chptr->mlist; link; link = link->next)
			{
				d_chb++;
				d_chbm += strlen(link->value.cp) + 1;
			}
		}
		d_chbm += d_chb * sizeof(Link);
	}

	co = istat.is_conf;
	com = istat.is_confmem;
	cl = istat.is_class;

	if (debug)
	{
		for (aconf = conf; aconf; aconf = aconf->next)
		{
			d_co++;
			d_com += aconf->host ? strlen(aconf->host)+1 : 0;
			d_com += aconf->passwd ? strlen(aconf->passwd)+1 : 0;
			d_com += aconf->name ? strlen(aconf->name)+1 : 0;
			d_com += aconf->ping ? sizeof(*aconf->ping) : 0;
			d_com += sizeof(aConfItem);
		}
		for (cltmp = classes; cltmp; cltmp = cltmp->next)
		{
			d_cl++;
		}
	}

	if (debug)
		sendto_one(cptr, ":%s %d %s :Request processed in %u seconds",
			   me.name, RPL_STATSDEBUG, nick, time(NULL) - start);

	sendto_one(cptr,
		   ":%s %d %s :Client Local %d(%lu) Remote %d(%lu) Auth %d(%lu)",
		   me.name, RPL_STATSDEBUG, nick, lc, lcm, rc, rcm,
		   istat.is_auth, istat.is_authmem);
	if (debug
	    && (lc != d_lc || lcm != d_lcm || rc != d_rc || rcm != d_rcm))
	{
		sendto_one(cptr,
			":%s %d %s :Client Local %d(%lu) Remote %d(%lu) [REAL]",
			me.name, RPL_STATSDEBUG, nick, d_lc, d_lcm, d_rc,
			d_rcm);
	}
	sendto_one(cptr,
		   ":%s %d %s :Users %d in/visible %d/%d(%lu) Invites %d(%lu)",
		   me.name, RPL_STATSDEBUG, nick, us, istat.is_user[1],
		   istat.is_user[0], us*sizeof(anUser), usi,
		   usi*sizeof(Link));
	if (debug && (us != d_us || usi != d_usi))
	{
		sendto_one(cptr,
			   ":%s %d %s :Users %d(%lu) Invites %d(%lu) [REAL]",
			   me.name, RPL_STATSDEBUG, nick, d_us,
			   d_us*sizeof(anUser), d_usi, d_usi * sizeof(Link));
	}
	sendto_one(cptr, ":%s %d %s :User channels %d(%lu) Aways %d(%lu)",
		   me.name, RPL_STATSDEBUG, nick, usc, usc*sizeof(Link),
		   aw, awm);
	if (debug && (usc != d_usc || aw != d_aw || awm != d_awm))
	{
		sendto_one(cptr,
			":%s %d %s :User channels %d(%lu) Aways %d(%lu) [REAL]",
			   me.name, RPL_STATSDEBUG, nick, d_usc,
			   d_usc*sizeof(Link), d_aw, d_awm);
	}
	sendto_one(cptr, ":%s %d %s :Attached confs %d(%lu)",
		   me.name, RPL_STATSDEBUG, nick, lcc, lcc*sizeof(Link));
	if (debug && lcc != d_lcc)
	{
		sendto_one(cptr, ":%s %d %s :Attached confs %d(%lu) [REAL]",
			   me.name, RPL_STATSDEBUG, nick, d_lcc,
			   d_lcc*sizeof(Link));
	}

	totcl = lcm + rcm + us*sizeof(anUser) + usc*sizeof(Link) + awm;
	totcl += lcc*sizeof(Link) + usi*sizeof(Link);
	d_totcl = d_lcm + d_rcm + d_us*sizeof(anUser) + d_usc*sizeof(Link);
	d_totcl += d_awm + d_lcc*sizeof(Link) + d_usi*sizeof(Link);

	sendto_one(cptr, ":%s %d %s :Conflines %d(%lu)",
		   me.name, RPL_STATSDEBUG, nick, co, com);
	if (debug && (co != d_co || com != d_com))
	{
		sendto_one(cptr, ":%s %d %s :Conflines %d(%lu) [REAL]",
			   me.name, RPL_STATSDEBUG, nick, d_co, d_com);
	}

	sendto_one(cptr, ":%s %d %s :Classes %d(%lu)",
		   me.name, RPL_STATSDEBUG, nick, cl, cl*sizeof(aClass));
	if (debug && cl != d_cl)
	{
		sendto_one(cptr, ":%s %d %s :Classes %d(%lu) [REAL]",
			   me.name, RPL_STATSDEBUG, nick, d_cl,
			   d_cl*sizeof(aClass));
	}

	sendto_one(cptr,
   ":%s %d %s :Channels %d(%lu) Modes %d(%lu) History %d(%lu) Cache %d(%lu)",
		   me.name, RPL_STATSDEBUG, nick, ch, chm, chb, chbm, chh,
		   chhm, istat.is_cchan, istat.is_cchanmem);
	if (debug && (ch != d_ch || chm != d_chm || chb != d_chb
		      || chbm != d_chbm || chh != d_chh || chhm != d_chhm))
	{
		sendto_one(cptr,
	       ":%s %d %s :Channels %d(%lu) Modes %d(%lu) History %d(%lu) [REAL]",
			   me.name, RPL_STATSDEBUG, nick, d_ch, d_chm, d_chb,
			   d_chbm, d_chh, d_chhm);
	}
	sendto_one(cptr, ":%s %d %s :Channel members %d(%lu) invite %d(%lu)",
		   me.name, RPL_STATSDEBUG, nick, chu, chu*sizeof(Link),
		   chi, chi*sizeof(Link));
	if (debug && (chu != d_chu || chi != d_chi))
	{
		sendto_one(cptr,
			":%s %d %s :Channel members %d(%lu) invite %d(%lu) "
			"[REAL]", me.name, RPL_STATSDEBUG, nick, d_chu, 
			d_chu*sizeof(Link), d_chi, d_chi*sizeof(Link));
	}
	totch = chm + chhm + chbm + chu*sizeof(Link) + chi*sizeof(Link);
	d_totch = d_chm + d_chhm + d_chbm + d_chu*sizeof(Link)
		  + d_chi*sizeof(Link);

	sendto_one(cptr,
		   ":%s %d %s :Whowas users %d(%lu) away %d(%lu) links %d(%lu)",
		   me.name, RPL_STATSDEBUG, nick, wwu, wwu*sizeof(anUser),
		   wwa, wwam, wwuw, wwuw*sizeof(Link));
	if (debug && (wwu != d_wwu || wwa != d_wwa || wwam != d_wwam
		      || wwuw != d_wwuw))
	{
		sendto_one(cptr,
			":%s %d %s :Whowas users %d(%lu) away %d(%lu) "
			"links %d(%lu) [REAL]", me.name, RPL_STATSDEBUG,
			nick, d_wwu, d_wwu*sizeof(anUser),
			d_wwa, d_wwam, d_wwuw, d_wwuw*sizeof(Link));
	}
	sendto_one(cptr, ":%s %d %s :Whowas array %d(%lu) Delay array %d(%lu)",
		   me.name, RPL_STATSDEBUG, nick, ww_size, wwm, lk_size, dm);
	if (debug && (wwm != d_wwm || dm != d_dm))
	{
		sendto_one(cptr,
			":%s %d %s :Whowas array %d(%lu) Delay array %d(%lu) "
			"[REAL]", me.name, RPL_STATSDEBUG, nick, ww_size,
			d_wwm, lk_size, d_dm);
	}

	totww = wwu*sizeof(anUser) + wwam + wwm;
	d_totww = d_wwu*sizeof(anUser) + d_wwam + d_wwm;

	sendto_one(cptr, ":%s %d %s :Hash: client %d(%lu) chan %d(%lu)",
		me.name, RPL_STATSDEBUG, nick, _HASHSIZE,
		sizeof(aHashEntry) * _HASHSIZE,
		_CHANNELHASHSIZE, sizeof(aHashEntry) * _CHANNELHASHSIZE);
	d_db = db = istat.is_dbufnow * sizeof(dbufbuf);
	db = istat.is_dbufnow * sizeof(dbufbuf);
	sendto_one(cptr,
		":%s %d %s :Dbuf blocks %lu(%lu) (> %lu [%lu]) (%lu < %lu) "
		"[%lu]", me.name, RPL_STATSDEBUG, nick, istat.is_dbufnow, db,
		istat.is_dbuf,
		(u_int) (((u_int)BUFFERPOOL) / ((u_int)sizeof(dbufbuf))),
		istat.is_dbufuse, istat.is_dbufmax, istat.is_dbufmore);

	d_rm = rm = cres_mem(cptr, nick);

	tot = totww + totch + totcl + com + cl*sizeof(aClass) + db + rm;
	tot += sizeof(aHashEntry) * _HASHSIZE;
	tot += sizeof(aHashEntry) * _CHANNELHASHSIZE;
	d_tot = d_totww + d_totch + d_totcl + d_com + d_cl*sizeof(aClass);
	d_tot += d_db + d_rm;
	d_tot += sizeof(aHashEntry) * _HASHSIZE;
	d_tot += sizeof(aHashEntry) * _CHANNELHASHSIZE;

	sendto_one(cptr, ":%s %d %s :Total: ww %lu ch %lu cl %lu co %lu db %lu",
		   me.name, RPL_STATSDEBUG, nick, totww, totch, totcl, com,db);
	if (debug && tot != d_tot)
	{
		sendto_one(cptr,
			":%s %d %s :Total: ww %lu ch %lu cl %lu co %lu "
			"db %lu [REAL]", me.name, RPL_STATSDEBUG, nick,
			d_totww, d_totch, d_totcl, d_com, d_db);
		sendto_one(cptr, ":%s %d %s :TOTAL: %lu [REAL]",
			me.name, RPL_STATSDEBUG, nick, d_tot);
	}
	sendto_one(cptr, ":%s %d %s :TOTAL: %d sbrk(0)-etext: %u",
		   me.name, RPL_STATSDEBUG, nick, tot,
		   (u_long)sbrk((size_t)0)-(u_long)sbrk0);
	return;
}
예제 #2
0
파일: s_debug.c 프로젝트: mojadita/ircd
/** Report memory usage statistics to a client.
 * @param cptr Client to send data to.
 * @param sd StatDesc that generated the stats request (ignored).
 * @param param Extra parameter from user (ignored).
 */
void count_memory(struct Client *cptr, const struct StatDesc *sd,
                  char *param)
{
  struct Client *acptr;
  struct Invite *inv;
  struct SLink *link;
  struct Ban *ban;
  struct Channel *chptr;
  struct ConfItem *aconf;
  const struct ConnectionClass* cltmp;
  struct Membership* member;

  int acc = 0,                  /* accounts */
      c = 0,                    /* clients */
      cn = 0,                   /* connections */
      ch = 0,                   /* channels */
      lcc = 0,                  /* local client conf links */
      chb = 0,                  /* channel bans */
      wwu = 0,                  /* whowas users */
      cl = 0,                   /* classes */
      co = 0,                   /* conf lines */
      listeners = 0,            /* listeners */
      memberships = 0;          /* channel memberships */

  int usi = 0,                  /* users invited */
      aw = 0,                   /* aways set */
      wwa = 0,                  /* whowas aways */
      gl = 0,                   /* glines */
      ju = 0;                   /* jupes */

  size_t chm = 0,               /* memory used by channels */
      chbm = 0,                 /* memory used by channel bans */
      cm = 0,                   /* memory used by clients */
      cnm = 0,                  /* memory used by connections */
      us = 0,                   /* user structs */
      usm = 0,                  /* memory used by user structs */
      awm = 0,                  /* memory used by aways */
      wwam = 0,                 /* whowas away memory used */
      wwm = 0,                  /* whowas array memory used */
      wt = 0,                   /* watch entrys */
      wtm = 0,                  /* memory used by watchs */
#if defined(DDB)
      dbs = 0,                  /* keys of database */
      dbm = 0,                  /* memory used by DDB */
#endif
      glm = 0,                  /* memory used by glines */
      jum = 0,                  /* memory used by jupes */
      com = 0,                  /* memory used by conf lines */
      dbufs_allocated = 0,      /* memory used by dbufs */
      dbufs_used = 0,           /* memory used by dbufs */
      msg_allocated = 0,	/* memory used by struct Msg */
      msgbuf_allocated = 0,	/* memory used by struct MsgBuf */
      listenersm = 0,           /* memory used by listetners */
      rm = 0,                   /* res memory used */
      totcl = 0, totch = 0, totww = 0, tot = 0;

  count_whowas_memory(&wwu, &wwm, &wwa, &wwam);
  wwm += sizeof(struct Whowas) * feature_uint(FEAT_NICKNAMEHISTORYLENGTH);
  wwm += sizeof(struct Whowas *) * WW_MAX;

  for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr))
  {
    c++;
    if (MyConnect(acptr))
    {
      cn++;
      for (link = cli_confs(acptr); link; link = link->next)
        lcc++;
    }
    if (cli_user(acptr))
    {
      for (inv = cli_user(acptr)->invited; inv; inv = inv->next_user)
        usi++;
      for (member = cli_user(acptr)->channel; member; member = member->next_channel)
        ++memberships;
      if (cli_user(acptr)->away)
      {
        aw++;
        awm += (strlen(cli_user(acptr)->away) + 1);
      }
    }
#if defined(UNDERNET)
    if (IsAccount(acptr))
      acc++;
#endif
  }
  cm = c * sizeof(struct Client);
  cnm = cn * sizeof(struct Connection);
  user_count_memory(&us, &usm);

  for (chptr = GlobalChannelList; chptr; chptr = chptr->next)
  {
    ch++;
    chm += (strlen(chptr->chname) + sizeof(struct Channel));
    for (ban = chptr->banlist; ban; ban = ban->next)
    {
      chb++;
      chbm += strlen(ban->who) + strlen(ban->banstr) + 2 + sizeof(*ban);
    }
  }

  for (aconf = GlobalConfList; 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(struct ConfItem);
  }

  for (cltmp = get_class_list(); cltmp; cltmp = cltmp->next)
    cl++;

#if defined(USE_SSL)
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":Clients %d(%zu) Connections %d(%zu) SSL %d", c, cm, cn, cnm, ssl_count());
#else
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":Clients %d(%zu) Connections %d(%zu)", c, cm, cn, cnm);
#endif
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":Users %zu(%zu) Accounts %d(%zu) Invites %d(%zu)",
             us, usm, acc, acc * (ACCOUNTLEN + 1),
	     usi, usi * sizeof(struct Invite));
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":User channels %d(%zu) Aways %d(%zu)", memberships,
	     memberships * sizeof(struct Membership), aw, awm);

  totcl = cm + cnm + us * sizeof(struct User) + memberships * sizeof(struct Membership) + awm;
  totcl += lcc * sizeof(struct SLink) + usi * sizeof(struct SLink);

  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Conflines %d(%zu) Attached %d(%zu) Classes %d(%zu)",
             co, com, lcc, lcc * sizeof(struct SLink),
             cl, cl * sizeof(struct ConnectionClass));

  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":Channels %d(%zu) Bans %d(%zu)", ch, chm, chb, chbm);
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":Channel Members %d(%zu)", memberships,
	     memberships * sizeof(struct Membership));

  totch = chm + chbm;

  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":Whowas Users %d(%zu) Away %d(%zu) Array %u(%zu)",
             wwu, wwu * sizeof(struct User), wwa, wwam,
             feature_uint(FEAT_NICKNAMEHISTORYLENGTH), wwm);

  totww = wwu * sizeof(struct User) + wwam + wwm;

  watch_count_memory(&wt, &wtm);
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
             ":Watchs %d(%zu)", wt, wtm);

  motd_memory_count(cptr);

  gl = gline_memory_count(&glm);
  ju = jupe_memory_count(&jum);
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":Glines %d(%zu) Jupes %d(%zu)", gl, glm, ju, jum);

  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":Hash: client %d(%zu), chan is the same", HASHSIZE,
	     sizeof(void *) * HASHSIZE);

  count_listener_memory(&listeners, &listenersm);
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
             ":Listeners allocated %d(%zu)", listeners, listenersm);

#if defined(DDB)
  ddb_count_memory(&dbs, &dbm);
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
             ":DDB keys allocated %d(%zu)", dbs, dbm);
#endif

  /*
   * NOTE: this count will be accurate only for the exact instant that this
   * message is being sent, so the count is affected by the dbufs that
   * are being used to send this message out. If this is not desired, move
   * the dbuf_count_memory call to a place before we start sending messages
   * and cache DBufAllocCount and DBufUsedCount in variables until they
   * are sent.
   */
  dbuf_count_memory(&dbufs_allocated, &dbufs_used);
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":DBufs allocated %u(%zu) used %u(%zu)", DBufAllocCount,
	     dbufs_allocated, DBufUsedCount, dbufs_used);

  /* The DBuf caveats now count for this, but this routine now sends
   * replies all on its own.
   */
  msgq_count_memory(cptr, &msg_allocated, &msgbuf_allocated);

  rm = cres_mem(cptr);

  tot =
      totww + totch + totcl + com + cl * sizeof(struct ConnectionClass) +
      dbufs_allocated + msg_allocated + msgbuf_allocated + rm;
  tot += sizeof(void *) * HASHSIZE * 3;

#if defined(MDEBUG)
  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Allocations: %zu(%zu)",
	     fda_get_block_count(), fda_get_byte_count());
#endif

  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
	     ":Total: ww %zu ch %zu cl %zu co %zu db %zu ms %zu mb %zu",
	     totww, totch, totcl, com, dbufs_allocated, msg_allocated,
	     msgbuf_allocated);
}