/* * Copyright (c) 2004 Teodor Sigaev * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "tlog.h" #include "tmalloc.h" #include "connection.h" #include "top.h" #define NITEM 0 static int getsysctl(char *name, void *ptr, size_t len) { size_t nlen = len; if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) { tlog(TL_ALARM, "sysctl(%s...) failed: %s\n", name, strerror(errno)); return 1; } if (nlen != len) { tlog(TL_ALARM, "sysctl(%s...) expected %lu, got %lu\n", name, (unsigned long)len, (unsigned long)nlen); return 1; } return 0; } #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var)) static void fillMsgTop(TCMsgTop *m) { double lll[3]; int memory_tmp; memset(m,0,sizeof(TCMsgTop)); if ( getloadavg(lll,3) >= NITEM+1 ) m->load=lll[NITEM]; else m->load=-1.0; m->freemem = 0; if ( GETSYSCTL("vm.stats.vm.v_inactive_count", memory_tmp) == 0 ) m->freemem += memory_tmp; else m->freemem = -1; if ( m->freemem>=0 && GETSYSCTL("vm.stats.vm.v_cache_count", memory_tmp) == 0 ) m->freemem += memory_tmp; else m->freemem = -1; if ( m->freemem>=0 && GETSYSCTL("vm.stats.vm.v_free_count", memory_tmp) == 0 ) m->freemem += memory_tmp; else m->freemem = -1; if ( m->freemem>=0 ) m->freemem *= getpagesize(); m->usermem =-1; if ( GETSYSCTL("hw.usermem", memory_tmp) == 0 ) m->usermem = memory_tmp; tlog( TL_DEBUG, "Sended topdata: %.2f load, %d free, %d total", m->load, m->freemem, m->usermem); } static int sendTop(Msg *msg) { TCMsg *pmsg; if ( !msg->msg ) { int msglen = TCMSGHDRSZ + sizeof(TCMsgTop); pmsg = (TCMsg*)tmalloc(msglen); pmsg->len = msglen; pmsg->type=TOPMSGTYPE; msg->msg = pmsg; } else { pmsg = msg->msg; } fillMsgTop( (TCMsgTop*)(pmsg->data) ); return TC_sendMsg(msg); } extern char *optarg; int main( int argc, char *argv[] ) { int ch; Msg msg; int debug=0, child=0; int period=30; msg.port = TOPD_SERVER_DEFAULT_PORT; msg.host = "127.0.0.1"; msg.msg = NULL; msg.sockfd =-1; while( (ch=getopt(argc, argv, "h:p:s:D"))!=-1) { switch(ch) { case 'h': msg.host = strdup(optarg); break; case 'p': msg.port = atoi(optarg); break; case 's': period = atoi(optarg); break; case 'D': debug=1; break; default: return 1; } } signal(SIGCHLD, SIG_IGN); if ( debug ) opentlog( TL_OPEN_STDERR, TL_DEBUG, NULL); else opentlog( TL_OPEN_SYSLOG, TL_INFO, NULL); if ( debug || (child = fork()) == 0 ) { while(1) { sendTop(&msg); sleep(period); } TC_closefd(&msg); } if (child == -1) tlog(TL_CRIT|TL_EXIT, "Can't start child process: %s", strerror(errno)); return (0); }