From: teodor Date: Wed, 22 Sep 2004 16:23:41 +0000 (+0000) Subject: Initial revision X-Git-Tag: start~1 X-Git-Url: http://sigaev.ru/git/gitweb.cgi?a=commitdiff_plain;h=3847745d793d35eca05b9bd1d5f5d5980f7fda8c;p=remotetop.git Initial revision --- 3847745d793d35eca05b9bd1d5f5d5980f7fda8c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e531efd --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +CC=gcc +AR=ar rcv +RANLIB=ranlib +LD=ld -x -shared + +INCLUDE=-I. -I../tedtools +CFLAGS=-Wall -g -O2 -pedantic -ansi -DASSERT_CORE -D_GNU_SOURCE -DHAVE_POLL_H -DHAVE_SYS_POLL_H -DHAVE_HSTRERROR +LIB=-L../tedtools -ltedtools + +PROGS=sendtop topd rtop + +.SUFFIXES: .o.c + +all: $(PROGS) + +rtop: rtop.o + $(CC) -o $@ $< $(LIB) + +sendtop: sendtop.o + $(CC) -o $@ $< $(LIB) + +topd: topd.o td_unit.o td_smsg.o td_lmsg.o + $(CC) -o $@ topd.o td_unit.o td_smsg.o td_lmsg.o $(LIB) + +.c.o: + $(CC) $(CFLAGS) $(INCLUDE) -c $< + + +clean: + rm -rf $(PROGS) *.o + rm -rf *core *gmon* nohup.out + diff --git a/rtop.c b/rtop.c new file mode 100644 index 0000000..c204aaf --- /dev/null +++ b/rtop.c @@ -0,0 +1,105 @@ +/* + * 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 +#include +#include +#include +#include + +#include "tlog.h" +#include "connection.h" +#include "tmalloc.h" +#include "top.h" + +int +main( int argc, char *argv[] ) { + int ch; + int debug=0; + char *host="127.0.0.1"; + int port=TOPD_SERVER_DEFAULT_PORT; + int i; + + MassiveUnit *mu; + TCMsg *pmsg = (TCMsg*)malloc( TCMSGHDRSZ ); + TC_Connection cs; + + pmsg->type = TOPGETTYPE; + pmsg->len = TCMSGHDRSZ; + + while( (ch=getopt(argc, argv, "Dh:p:"))!=-1) { + switch(ch) { + case 'D': + debug=1; + break; + case 'h': + host=strdup(optarg); + break; + case 'p': + port=atoi(optarg); + break; + default: + return 1; + } + } + + if ( debug ) + opentlog( TL_OPEN_STDERR, TL_DEBUG, NULL); + else + opentlog( TL_OPEN_SYSLOG, TL_INFO, NULL); + + TC_fillConnection(&cs, host, port); + cs.buf = (char*)pmsg; + cs.len = pmsg->len; + if ( TC_Talk(&cs) == CS_OK ) { + pmsg = (TCMsg*) cs.buf; + mu = (MassiveUnit*)pmsg->data; + + printf("\tIP\tLoad\tFree\tTotal\tData\n"); + for(i=0; inumber; i++) + printf("%s\t%.2f\t%.1fM\t%.1fM\t%s", + inet_ntoa(mu->units[i].ip), + mu->units[i].top.load, + ((float) mu->units[i].top.freemem)/( 1024*1024.0 ), + ((float) mu->units[i].top.usermem)/( 1024*1024.0 ), + ctime( &(mu->units[i].stamp) ) + ); + } + + TC_FreeConnection(&cs); + + return 0; +} + diff --git a/sendtop.c b/sendtop.c new file mode 100644 index 0000000..8ab3269 --- /dev/null +++ b/sendtop.c @@ -0,0 +1,171 @@ +/* + * 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); +} diff --git a/td_lmsg.c b/td_lmsg.c new file mode 100644 index 0000000..7f27280 --- /dev/null +++ b/td_lmsg.c @@ -0,0 +1,132 @@ +/* + * 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 "tlog.h" +#include "connection.h" +#include "top.h" +#include "tmalloc.h" + +static void +getTopData(TC_Connection *conn) { + TCMsg *pmsg; + conn->len = TCMSGHDRSZ + MUHDRSZ + cfg.mu->number * sizeof(UnitInfo); + conn->buf = trealloc( conn->buf, conn->len ); + pmsg = (TCMsg*) conn->buf; + + pmsg->len = conn->len; + pmsg->type = TOPGETTYPE; + memcpy( pmsg->data, cfg.mu, pmsg->len - TCMSGHDRSZ ); + ((MassiveUnit*)pmsg->data)->maxnumber = cfg.mu->number; + TC_Send(conn); +} + +static void +gotLongMessage( TC_Connection *conn ) { + TCMsg *pmsg = (TCMsg*) conn->buf; + + if ( conn->ptr - conn->buf < TCMSGHDRSZ ) { + tlog(TL_ALARM,"Wrong size of long message (%d bytes)", conn->ptr - conn->buf); + conn->state = CS_ERROR; + return; + } + + switch(pmsg->type) { + case TOPGETTYPE: + getTopData(conn); + break; + default: + tlog(TL_ALARM,"Got unknown packet type: %d", pmsg->type); + conn->state = CS_ERROR; + } +} + +static void +sendedLongMessage( TC_Connection *conn ) { + TCMsg *pmsg = (TCMsg*) conn->buf; + switch(pmsg->type) { + case TOPGETTYPE: + conn->state = CS_FINISH; + break; + default: + tlog(TL_ALARM,"Send unknown packet type: %d", pmsg->type); + conn->state = CS_ERROR; + } +} + +void +ConnectionWorks() { + int i; + TC_Connection *conn; + for(i=TC_SERVER_CONN_START; istate ) { + case CS_INPROCESS: + TC_ServerConnect( conn ); + break; + case CS_CONNECTED: /* we have connected to remote host */ + TC_Send( conn ); + break; + case CS_FINISHSEND: + sendedLongMessage( conn ); + break; + case CS_FINISHREAD: + gotLongMessage( conn ); + break; + case CS_READ: + if ( conn->readyio ) { + TC_Read( conn ); + if ( conn->state != CS_READ ) i--; /* check it one more time */ + } + break; + case CS_SEND: + if ( conn->readyio ) { + TC_Send( conn ); + if ( conn->state != CS_SEND ) i--; /* check it one more time */ + } + break; + /* ignore */ + case CS_OK: + case CS_AGAIN: + case CS_WAIT: /* ??? */ + break; + /* out */ + case CS_TIMEOUT: + case CS_CLOSED: + case CS_NOTINITED: + case CS_FINISH: + case CS_ERROR: + default: + tlog(TL_DEBUG, "Clear N%d connection", i); + TC_deleteConnectionByN(&cfg.pool,i); + i--; + } + } +} diff --git a/td_smsg.c b/td_smsg.c new file mode 100644 index 0000000..3bfded6 --- /dev/null +++ b/td_smsg.c @@ -0,0 +1,76 @@ +/* + * 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 "tlog.h" +#include "connection.h" +#include "top.h" +#include "tmalloc.h" + + +static void +addMsgTop( MassiveUnit *mu, TCMsgTop *tmsg, struct in_addr *client ) { + UnitInfo unit; + + memcpy( &(unit.top), tmsg, sizeof( TCMsgTop )); + unit.stamp=time(NULL); + memcpy( &(unit.ip), client, sizeof(struct in_addr) ); + unit.flag = 0; + + fillUnit(mu, &unit); +} + + +void +gotMsg(TC_Connection *msgconn) { + Msg gmsg; + TCMsg *pmsg; + + if ( TC_getMsg( msgconn->fd, &gmsg ) ) + return; + + pmsg = gmsg.msg; + + if ( cfg.debug ) + tlog(TL_DEBUG, "Got %d bytes %08x type from %s:%d", + pmsg->len, + pmsg->type, + inet_ntoa(gmsg.host_addr.sin_addr), + ntohs(gmsg.host_addr.sin_port) + ); + + switch( pmsg->type ) { + case TOPMSGTYPE: + addMsgTop( cfg.mu, (TCMsgTop*)(pmsg->data), &(gmsg.host_addr.sin_addr) ); + break; + default: + tlog(TL_ALARM, "Unknown message type: %d from %s", + pmsg->type, inet_ntoa(gmsg.host_addr.sin_addr)); + } +} diff --git a/td_unit.c b/td_unit.c new file mode 100644 index 0000000..c736284 --- /dev/null +++ b/td_unit.c @@ -0,0 +1,80 @@ +/* + * 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 "tlog.h" +#include "connection.h" +#include "top.h" +#include "tmalloc.h" + + +MassiveUnit* +allocUnits(int n ) { + MassiveUnit *ptr = NULL; + + ptr = (MassiveUnit*)malloc( MUHDRSZ + n * sizeof(UnitInfo) ); + if ( !ptr ) + tlog(TL_CRIT|TL_EXIT, "allocUnits: no memoru for %d units", n); + ptr->maxnumber = n; + ptr->number=0; + + return ptr; +} + +static int +cmpUnit(const void *a, const void *b) { + if ( ((UnitInfo*)a)->ip.s_addr == ((UnitInfo*)b)->ip.s_addr ) + return 0; + return ( ((UnitInfo*)a)->ip.s_addr > ((UnitInfo*)b)->ip.s_addr ) ? 1 : -1; +} + +void +fillUnit( MassiveUnit* mu, UnitInfo *unit ) { + if ( mu->number==0 || ( mu->number==1 && unit->ip.s_addr == mu->units->ip.s_addr ) ) { + memcpy( mu->units, unit, sizeof(UnitInfo) ); + mu->number=1; + } else { + UnitInfo *ptr = bsearch(unit, mu->units, mu->number, sizeof(UnitInfo), cmpUnit); + if ( ptr ) + memcpy( ptr, unit, sizeof(UnitInfo) ); + else { + if ( mu->number == mu->maxnumber ) + tlog(TL_ALARM, "Can't add new unit"); + else { + ptr = mu->units + mu->number; + memcpy( ptr, unit, sizeof(UnitInfo) ); + mu->number++; + qsort(mu->units, mu->number, sizeof(UnitInfo), cmpUnit); + } + } + } +} + + diff --git a/top.h b/top.h new file mode 100644 index 0000000..ca89a59 --- /dev/null +++ b/top.h @@ -0,0 +1,79 @@ +/* + * 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. + */ + +#ifndef __TOP_H__ +#define __TOP_H__ + +#include +#include "connection.h" + +#define TOPD_SERVER_DEFAULT_PORT 6543 +#define TOPMSGTYPE 0x10AD10AD +#define TOPGETTYPE 0x06ED10AD + +typedef struct { + double load; + int freemem; + int usermem; +} TCMsgTop; + +typedef struct { + TCMsgTop top; + time_t stamp; + struct in_addr ip; + u_int32_t flag; +} UnitInfo; + +typedef struct { + u_int32_t maxnumber; + u_int32_t number; + UnitInfo units[1]; +} MassiveUnit; + +#define MUHDRSZ (2*sizeof(u_int32_t)) + +MassiveUnit *allocUnits(int n); +void fillUnit( MassiveUnit* mu, UnitInfo *unit ); + +void gotMsg(TC_Connection *msgconn); +void ConnectionWorks(); + +typedef struct { + MassiveUnit *mu; + u_int32_t + debug:1, + unused:31; + PoolConnection pool; +} TCServer; + +extern TCServer cfg; + +#define TC_SERVER_CONN_START 2 + +#endif diff --git a/topd.c b/topd.c new file mode 100644 index 0000000..56a7e03 --- /dev/null +++ b/topd.c @@ -0,0 +1,138 @@ +/* + * 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 "connection.h" +#include "top.h" +#include "tmalloc.h" + +TCServer cfg; +static int continueWork=1; + +static void +inquireExit(int s) { + continueWork=0; +} + +extern char *optarg; +extern int optind; + +int +main( int argc, char *argv[] ) { + int ch; + int child=0, listenport = TOPD_SERVER_DEFAULT_PORT; + int n=1024; + char *host="127.0.0.1"; + + memset( &cfg, 0, sizeof(TCServer) ); + + while( (ch=getopt(argc, argv, "h:p:c:s:D"))!=-1) { + switch(ch) { + case 'D': + cfg.debug=1; + break; + case 'h': + host=strdup(optarg); + break; + case 'p': + listenport=atoi(optarg); + break; + case 'n': + n=atoi(optarg); + break; + default: + return 1; + } + } + + signal(SIGCHLD, SIG_IGN); + + if ( cfg.debug ) + opentlog( TL_OPEN_STDERR, TL_DEBUG, NULL); + else + opentlog( TL_OPEN_SYSLOG, TL_INFO, NULL); + + if ( cfg.debug || (child = fork()) == 0 ) { + /* child */ + if ( cfg.debug || (child = fork()) == 0 ) { + /*child*/ + TC_Connection *newconn; + int i; + + signal(SIGINT, inquireExit); + signal(SIGHUP, inquireExit); + + if ( n <= 0 ) + n=1024; + + cfg.mu = allocUnits(n); + + TC_addConnection( &cfg.pool, TC_fillConnection(NULL, NULL, listenport) ); + TC_ClientInitConnection( cfg.pool.conn[0], NULL, listenport); + cfg.pool.conn[0]->state = CS_READ; + + TC_addConnection( &cfg.pool, TC_fillConnection(NULL, NULL, listenport) ); + cfg.pool.conn[1]->fd = TC_AcceptUdp( host, listenport ); + cfg.pool.conn[1]->state = CS_READ; + + while(continueWork) { + if ( TC_ReadyIO(cfg.pool.conn, cfg.pool.number, 100 ) ) { + if ( cfg.pool.conn[1]->readyio ) + gotMsg( cfg.pool.conn[1] ); + else + tlog(TL_DEBUG,"Ready connection..."); + } + ConnectionWorks(); + if ( cfg.pool.conn[0]->readyio && (newconn=TC_AcceptTcp( cfg.pool.conn[0] )) != NULL ) { + if ( newconn->state == CS_CONNECTED ) { + tlog(TL_DEBUG,"Accept new connection..."); + newconn->state = CS_READ; + TC_addConnection( &cfg.pool, newconn ); + } + } + } + TC_deleteConnectionByN(&cfg.pool, 0); + close( cfg.pool.conn[1]->fd ); + for(i=TC_SERVER_CONN_START; i