From: Michael J. Pounders Date: Mon, 17 Nov 2014 04:40:59 +0000 (-0500) Subject: Switch over to more modern unix sharedmemory API (requested by fatbob) X-Git-Url: http://git.code-monkey.de/?p=umurmur.git;a=commitdiff_plain;h=a738ff892738e239ad74f5aa686108298efa7cea Switch over to more modern unix sharedmemory API (requested by fatbob) --- diff --git a/shm_utils/mon-umurmurd/CHANGES b/shm_utils/mon-umurmurd/CHANGES index 606e46e..2432255 100644 --- a/shm_utils/mon-umurmurd/CHANGES +++ b/shm_utils/mon-umurmurd/CHANGES @@ -1,3 +1,10 @@ +* Using a more modern unix sharedmemory API. this requires linking with librt.so (requested by fatbob) +* Added away to know if umurmurd is not connected/updateing the shm_t struct. I use 8bit timer with + rollover protection see check_serverTick() and where I use the function near bottum of mon-umurmurd.c + for how to use this. + + * code clean up and some comments added -* 100% of the useful client data shown -* outputs a more meaningful idle and online time, both are reported in secs \ No newline at end of file +* ~95% of the useful client data shown +* outputs a more meaningful idle and online time, both are reported in secs (error reported by fatbob) + \ No newline at end of file diff --git a/shm_utils/mon-umurmurd/Makefile b/shm_utils/mon-umurmurd/Makefile index fbe9af7..9ecd325 100644 --- a/shm_utils/mon-umurmurd/Makefile +++ b/shm_utils/mon-umurmurd/Makefile @@ -4,8 +4,8 @@ # The recommended compiler flags for the Raspberry Pi -#CCFLAGS=-Wall -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -g -#CCFLAGS= +#CCFLAGS=-Wall -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -g -lrt +CCFLAGS= -lrt # define all programs PROGRAMS = mon-umurmurd diff --git a/shm_utils/mon-umurmurd/mon-umurmurd.c b/shm_utils/mon-umurmurd/mon-umurmurd.c index 444456c..7a1a5b2 100644 --- a/shm_utils/mon-umurmurd/mon-umurmurd.c +++ b/shm_utils/mon-umurmurd/mon-umurmurd.c @@ -1,51 +1,43 @@ -#include +#include /* For O_* constants */ #include -#include -#include -#include #include +#include #include #include -#include +#include +#include #include "../../src/sharedmemory.h" +#include "../../src/sharedmemory_global.h" - -struct shmid_ds buf; enum{ NOP_SHM, WAIT_ATTACH_SHM, TRY_ATTACH_SHM, MAT_SHM, CLEAN_UP_SHM, RUN_SHM }; - +int wait = 0, opt; +uint8_t last, shm_statem = TRY_ATTACH_SHM; void run_shm(void); - int main(int argc, char **argv) { - int wait = 0, opt; - unsigned int shm_statem = TRY_ATTACH_SHM; - - key_t key = 0x53021d79; - //key = ftok(".", 'S'); // using my own key for now. makes dev easier will fix - while ((opt = getopt(argc, argv, "w")) != -1) - { - switch (opt) - { + + while ( (opt = getopt(argc, argv, "w")) != -1 ) + { + switch(opt) + { case 'w': wait = 1; break; - default: /* '?' */ + default: fprintf(stderr, "Usage: %s [-w]\n", argv[0]); fprintf(stderr, "\t-w - Wait for umurmurd to create shm area. useful if you need to start from init.d script\n" ); - //My version of this talks to custom PIC18 hardware acting as a i2c slave to a RaspberryPI to - //sound buzzer and turn on a LED when my umurmurd server has users in it. I leave this in here - //in case you need it. exit(EXIT_FAILURE); } } - + shmptr = NULL; - + sprintf( shm_file_name, "/umurmurd:%i", 64738 ); + if( wait ) shm_statem = WAIT_ATTACH_SHM; @@ -57,88 +49,93 @@ int main(int argc, char **argv) run_shm(); break; case WAIT_ATTACH_SHM: - printf( "waiting on umurmurd to be run\n\r"); fflush(stdout); - while( ( shmid = shmget( key, 0, 0) ) == -1 ) + printf( "Waiting for umurmurd to be run\n\r"); fflush(stdout); + while( ( shm_fd = shm_open( shm_file_name, O_RDONLY, 0666 ) ) == -1 ) sleep( 1 ); shm_statem = MAT_SHM; break; case TRY_ATTACH_SHM: - if( ( shmid = shmget( key, 0, 0) ) == -1 ) + if( ( shm_fd = shm_open( shm_file_name, O_RDONLY, 0666 ) ) == -1 ) { - perror("shmget"); printf( "umurmurd doesn't seem to be running\n\r" ); exit(EXIT_FAILURE); } shm_statem = MAT_SHM; break; case MAT_SHM: - if( ( shmptr = shmat( shmid, 0, 0 ) ) == (void *) (-1) ) + if( ( shmptr = mmap(0, 1, PROT_READ, MAP_SHARED, shm_fd, 0) ) == (void *) (-1) ) //MJP BUG? { - perror("shmat"); + exit(EXIT_FAILURE); - } - printf( "shmid: %i\n\r", shmid ); - printf( "Connected to umumurd PID: %u\n\r", shmptr->umurmurd_pid ); - sleep( 1 ); + } + printf( "umumurd PID: %u\n\r", shmptr->umurmurd_pid ); shm_statem = RUN_SHM; break; case CLEAN_UP_SHM: - shmdt( shmptr ); - break; + + break; + } } - fflush(stdout); - return 0; + fflush(stdout); + return 0; } +uint8_t check_serverTick(void) +{ + last = shmptr->alive; + sleep( 1 ); // Sleep for 1 sec + return(shmptr->alive - last); +} void run_shm(void) { - int cc; - - shmctl( shmid, IPC_STAT, &buf ); //MJP BUG check for errors here - printf("\033[2J\033[H"); //clear screen VT100 +int cc; + + printf( "\033[2J\033[H" ); //clear screen VT100 - printf( "attach: %lu SCC: %i SMC: %i\n", (unsigned long int)buf.shm_nattch, shmptr->clientcount, shmptr->server_max_clients ); - - for( cc = 0 ; cc < shmptr->server_max_clients ; cc++ ) - { - if( !shmptr->client[cc].authenticated ) + + for( cc = 0 ; cc < shmptr->server_max_clients ; cc++ ) + { + + if( !shmptr->client[cc].authenticated ) continue; - printf( "%s@%s:%i in channel: %s\n\ - \tOnline(secs): %lu Idle(secs): %lu\n\ - \tusingUDP=%i\n\ - \tdeaf=%i, mute=%i\n\ - \tself_deaf=%i, self_mute=%i\n\ - \trecording=%i\n\ - \tbOpus=%i\n\ - \tUDP_Avg/Var: %3.2f/%3.2f \n\ - \tTCP_Avg/Var: %3.2f/%3.2f \n\ - \tUDP_C/TCP_C: %lu/%lu\n", - shmptr->client[cc].username, - shmptr->client[cc].ipaddress, - shmptr->client[cc].udp_port, - shmptr->client[cc].channel, - shmptr->client[cc].online_secs, - shmptr->client[cc].idle_secs, + printf( "%s@%s:%i in channel: %s\n\ + \tOnline(secs): %lu Idle(secs): %lu\n\ + \tusingUDP=%i\n\ + \tdeaf=%i, mute=%i\n\ + \tself_deaf=%i, self_mute=%i\n\ + \trecording=%i\n\ + \tbOpus=%i\n\ + \tUDP_Avg/Var: %3.2f/%3.2f \n\ + \tTCP_Avg/Var: %3.2f/%3.2f \n\ + \tUDP_C/TCP_C: %lu/%lu\n", + shmptr->client[cc].username, + shmptr->client[cc].ipaddress, + shmptr->client[cc].udp_port, + shmptr->client[cc].channel, + shmptr->client[cc].online_secs, + shmptr->client[cc].idle_secs, - shmptr->client[cc].bUDP, - shmptr->client[cc].deaf, - shmptr->client[cc].mute, - shmptr->client[cc].self_deaf, - shmptr->client[cc].self_mute, - shmptr->client[cc].recording, - shmptr->client[cc].bOpus, + shmptr->client[cc].bUDP, + shmptr->client[cc].deaf, + shmptr->client[cc].mute, + shmptr->client[cc].self_deaf, + shmptr->client[cc].self_mute, + shmptr->client[cc].recording, + shmptr->client[cc].bOpus, - shmptr->client[cc].UDPPingAvg, - shmptr->client[cc].UDPPingVar, - shmptr->client[cc].TCPPingAvg, - shmptr->client[cc].TCPPingVar, - shmptr->client[cc].UDPPackets, - shmptr->client[cc].TCPPackets - ); fflush(stdout); // fflush need because of sleep() call - } - sleep( 1 ); // Sleep for 1 sec + shmptr->client[cc].UDPPingAvg, + shmptr->client[cc].UDPPingVar, + shmptr->client[cc].TCPPingAvg, + shmptr->client[cc].TCPPingVar, + shmptr->client[cc].UDPPackets, + shmptr->client[cc].TCPPackets ); fflush(stdout); // fflush need because of sleep() call + } + if( !check_serverTick() ) + { + exit(EXIT_FAILURE); //You dont have to exit you could just report the fact that the data is not valid + } } \ No newline at end of file diff --git a/src/client.h b/src/client.h index a710f5c..9f17ddf 100644 --- a/src/client.h +++ b/src/client.h @@ -59,7 +59,7 @@ #define IS_AUTH(_a_) ((_a_)->authenticated) -typedef struct { +typedef struct { /* You can add new lines to this struct, any reordering of some of the lines will break the sharedmemory API */ int tcpfd; SSL_handle_t *ssl; bool_t SSLready; diff --git a/src/server.c b/src/server.c index a0ed7f5..74a736d 100644 --- a/src/server.c +++ b/src/server.c @@ -141,6 +141,10 @@ void Server_runLoop(struct pollfd* pollfds) while (!shutdown_server) { struct sockaddr_storage remote; int i; + +#ifdef USE_SHAREDMEMORY_API + Sharedmemory_alivetick(); +#endif for(i = 0; i < nofServerSocks; i++) { pollfds[i].revents = 0; diff --git a/src/sharedmemory.c b/src/sharedmemory.c index 4ede9d3..6af3f75 100644 --- a/src/sharedmemory.c +++ b/src/sharedmemory.c @@ -1,23 +1,42 @@ #include "sharedmemory.h" +#include "sharedmemory_global.h" void Sharedmemory_init(void) { - key_t key = 0x53021d79; - int server_max_clients = getIntConf(MAX_CLIENTS); + int bindport = getIntConf(BINDPORT); //MJP BUG commandline option for address and port dont work this way going to have + int server_max_clients = getIntConf(MAX_CLIENTS); //to bring them across as prameters to Sharedmemory_init(void) int shmptr_size = sizeof( shm_t ) + (sizeof( shmclient_t ) * server_max_clients); - //key = ftok( ".", 'S' ); //MJP BUG this needs fixing.. also how to handle multi copys of umurmur bound to diff ports or IPs option to pass key on cmdline? - shmid = shmget( key, shmptr_size, IPC_CREAT | 0666 ); - Log_info("SHM_KEY: 0x%x", key ); - if( ( shmptr = ( shm_t *) shmat( shmid, 0, 0 ) ) == (shm_t *) (-1) ) - { - perror("shmat"); - exit(1); //MJP BUG should report error and just not use shm dont exit - } - memset( shmptr, 0, shmptr_size ); + sprintf( shm_file_name, "umurmurd:%i", bindport ); + + Log_info("SHM_FD: %s", shm_file_name ); + +shm_fd = shm_open( shm_file_name, O_CREAT | O_RDWR, 0666 ); +if(shm_fd == -1) +{ + fprintf(stderr, "Open failed:%s\n", strerror(errno)); //MJP BUG make this Log_ calls once I get this working + exit(1); +} + +if( ftruncate( shm_fd, shmptr_size ) == -1 ) +{ + fprintf(stderr, "ftruncate : %s\n", strerror(errno)); //MJP BUG make this Log_ calls once I get this working + exit(1); +} + + shmptr = mmap(0, shmptr_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + if (shmptr == (void *) -1) + { + fprintf(stderr, "mmap failed : %s\n", strerror(errno)); //MJP BUG make this Log_ calls once I get this working + exit(1); + } + + + memset( shmptr, 0, shmptr_size ); + shmptr->umurmurd_pid = getpid(); shmptr->server_max_clients = server_max_clients; } @@ -25,47 +44,51 @@ void Sharedmemory_init(void) void Sharedmemory_update(void) { - static size_t bt_end = sizeof( bool_t ) * 8, //compute once - pa_end = sizeof( float ) * 4, - pc_end = sizeof( uint32_t ) * 2; + uint64_t now; + unsigned int cc = 0; + client_t *client_itr = NULL; + static size_t bt_end = sizeof( bool_t ) * 8, //compute once + pa_end = sizeof( float ) * 4, + pc_end = sizeof( uint32_t ) * 2; - unsigned int cc = 0; - client_t *client_itr = NULL; - uint64_t now; - memset( &shmptr->client[0], 0, sizeof( shmclient_t ) * shmptr->server_max_clients ); - shmptr->clientcount = Client_count(); - - if( shmptr->clientcount ) - { - Timer_init( &now ); - while( Client_iterate(&client_itr) != NULL ) { - - if( client_itr->authenticated ) - { - channel_t *channel = client_itr->channel; + memset( &shmptr->client[0], 0, sizeof( shmclient_t ) * shmptr->server_max_clients ); + shmptr->clientcount = Client_count(); + + if( shmptr->clientcount ) + { + Timer_init( &now ); + while( Client_iterate(&client_itr) != NULL ) + { + if( client_itr->authenticated ) + { + channel_t *channel = client_itr->channel; - strncpy( shmptr->client[cc].username, client_itr->username, 120 ); - strncpy( shmptr->client[cc].ipaddress, Util_clientAddressToString( client_itr ), 45 ); - shmptr->client[cc].tcp_port = Util_clientAddressToPortTCP( client_itr ); - shmptr->client[cc].udp_port = Util_clientAddressToPortUDP( client_itr ); - strncpy( shmptr->client[cc].channel, channel->name, 120 ); + strncpy( shmptr->client[cc].username, client_itr->username, 120 ); + strncpy( shmptr->client[cc].ipaddress, Util_clientAddressToString( client_itr ), 45 ); + shmptr->client[cc].tcp_port = Util_clientAddressToPortTCP( client_itr ); + shmptr->client[cc].udp_port = Util_clientAddressToPortUDP( client_itr ); + strncpy( shmptr->client[cc].channel, channel->name, 120 ); - shmptr->client[cc].online_secs = ( now - client_itr->connectTime ) / 1000000LL; - shmptr->client[cc].idle_secs = ( now - client_itr->idleTime ) / 1000000LL; + shmptr->client[cc].online_secs = ( now - client_itr->connectTime ) / 1000000LL; + shmptr->client[cc].idle_secs = ( now - client_itr->idleTime ) / 1000000LL; - memcpy( &shmptr->client[cc].bUDP, &client_itr->bUDP, bt_end ); - memcpy( &shmptr->client[cc].UDPPingAvg, &client_itr->UDPPingAvg, pa_end ); - memcpy( &shmptr->client[cc].UDPPackets, &client_itr->UDPPackets, pc_end ); - } - cc++; - } - -} + memcpy( &shmptr->client[cc].bUDP, &client_itr->bUDP, bt_end ); + memcpy( &shmptr->client[cc].UDPPingAvg, &client_itr->UDPPingAvg, pa_end ); + memcpy( &shmptr->client[cc].UDPPackets, &client_itr->UDPPackets, pc_end ); + } + cc++; + } + } +} +void Sharedmemory_alivetick(void) +{ + shmptr->alive++; } void Sharedmemory_deinit(void) { - shmctl( shmid, IPC_RMID, 0 ); //Mark shmid for removal. - shmdt( shmptr ); + close( shm_fd ); + unlink( shm_file_name ); + shmptr->umurmurd_pid = 0; } \ No newline at end of file diff --git a/src/sharedmemory.h b/src/sharedmemory.h index e4d4494..fd9c120 100644 --- a/src/sharedmemory.h +++ b/src/sharedmemory.h @@ -4,19 +4,19 @@ #include #include -#include +#include /* For O_* constants */ +#include +#include #include "util.h" #include "conf.h" #include "client.h" #include "channel.h" -#include "sharedmemory_struct.h" - -int shmid; -shm_t *shmptr; +#include "sharedmemory_struct.h" void Sharedmemory_init(void); void Sharedmemory_update(void); +void Sharedmemory_alivetick(void); void Sharedmemory_deinit(void); -#endif // SHAREDMEMORY_H_777736932196 \ No newline at end of file +#endif // SHAREDMEMORY_H_777736932196 \ No newline at end of file diff --git a/src/sharedmemory_global.h b/src/sharedmemory_global.h new file mode 100644 index 0000000..217ef9a --- /dev/null +++ b/src/sharedmemory_global.h @@ -0,0 +1,3 @@ +int shm_fd; +shm_t *shmptr = NULL; +char shm_file_name[128]; \ No newline at end of file diff --git a/src/sharedmemory_struct.h b/src/sharedmemory_struct.h index a4011b3..61d6488 100644 --- a/src/sharedmemory_struct.h +++ b/src/sharedmemory_struct.h @@ -1,5 +1,6 @@ typedef struct { + char username[121]; char ipaddress[46]; int tcp_port, udp_port; @@ -15,7 +16,8 @@ typedef struct { int clientcount, server_max_clients; - unsigned int umurmurd_pid; + unsigned int umurmurd_pid; + uint8_t alive; shmclient_t client[]; -}shm_t; \ No newline at end of file +}shm_t;