commit 0c0486b1bdf45b1ce3e7f8e728f0777c379ee2ff Author: Jan Tluka jtluka@redhat.com Date: Fri Dec 6 15:47:33 2013 +0100
test_tools: make tcp_conn tools more robust and reliable
Major and minor fixes for tcp_conn suite,
* removed unused variables and code cleanup * server/client processes are terminated in graceful way using shared flag instead of sending SIGKILL that left connections in unfinished state * connection counters are now placed in shared memory instead of a variable available to controller only and incremented upon the signal delivery
Signed-off-by: Jan Tluka jtluka@redhat.com Signed-off-by: Jiri Pirko jiri@resnulli.us
test_tools/tcp_conn/Makefile | 4 +- test_tools/tcp_conn/tcp_connect.c | 73 +++++++++++++++++++++++++------ test_tools/tcp_conn/tcp_listen.c | 85 +++++++++++++++++++++++++++---------- 3 files changed, 123 insertions(+), 39 deletions(-) --- diff --git a/test_tools/tcp_conn/Makefile b/test_tools/tcp_conn/Makefile index 2e8f5e6..a570641 100644 --- a/test_tools/tcp_conn/Makefile +++ b/test_tools/tcp_conn/Makefile @@ -3,10 +3,10 @@ CC=gcc all: tcp_listen tcp_connect
tcp_listen: tcp_listen.c - $(CC) -o tcp_listen tcp_listen.c + $(CC) -o tcp_listen tcp_listen.c -pthread -lrt
tcp_connect: tcp_connect.c - $(CC) -o tcp_connect tcp_connect.c + $(CC) -o tcp_connect tcp_connect.c -pthread -lrt
clean: rm -f tcp_connect tcp_listen diff --git a/test_tools/tcp_conn/tcp_connect.c b/test_tools/tcp_conn/tcp_connect.c index cb6b8c4..fe351a6 100644 --- a/test_tools/tcp_conn/tcp_connect.c +++ b/test_tools/tcp_conn/tcp_connect.c @@ -1,21 +1,33 @@ #include <stdio.h> #include <unistd.h> #include <string.h> +#include <stdlib.h> +#include <sys/wait.h>
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> +#include <arpa/inet.h>
#include <errno.h> #include <signal.h> +#include <semaphore.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h>
+#define IPCKEY 5678
int connection_handlers[1024]; int handlers_count; +int *connection_count;
int debug_on = 0; int cont = 0; +int *term_flag; + +sem_t *mutex;
int usage() { @@ -26,7 +38,7 @@ int usage() #define MSG_MAX 256 char msg[MSG_MAX];
-int debug(char* msg) +void debug(char* msg) { if (debug_on) { @@ -36,24 +48,14 @@ int debug(char* msg)
void terminate_connections(int p) { - int cc; - debug("signalled"); - for (cc=0; cc < handlers_count; cc++) - { - snprintf(msg, MSG_MAX, "killing process %i", connection_handlers[cc]); - debug(msg); - kill(connection_handlers[cc], SIGKILL); - } + *term_flag = 1; }
int handle_connections(char* host, int port) { int conn_sock; - int remote_sock; struct sockaddr_in my_addr; - struct sockaddr remote; - int end_loop = 0; char data[] = "abcdefghijklmnopqrstuvwxyz0123456789"; char buf[21*10*strlen(data)+1];
@@ -83,6 +85,10 @@ int handle_connections(char* host, int port) return 1; }
+ sem_wait(mutex); + *connection_count += 1; + sem_post(mutex); + int bursts = 5*(random() % 10) + 1; int b; int sum = 0; @@ -98,7 +104,11 @@ int handle_connections(char* host, int port) strncpy(buf + (j*strlen(data)), data, strlen(data)); }
- int wr_rc = write(conn_sock, buf, parts * strlen(data)); + if (write(conn_sock, buf, parts * strlen(data)) == -1) + { + perror("failed to send data"); + return 1; + } usleep(100*(random()%100)); }
@@ -108,7 +118,7 @@ int handle_connections(char* host, int port) debug(msg);
close(conn_sock); - } while (cont); + } while (cont && (*term_flag) == 0);
return 0; } @@ -126,7 +136,40 @@ int main(int argc, char **argv) int opt; char *delimiter; struct sigaction sa; + int shm; + + term_flag = mmap(NULL, sizeof *term_flag, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + *term_flag = 0; + + connection_count = mmap(NULL, sizeof *connection_count, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + *connection_count = 0;
+ /* counter synchronization stuff - semaphore and shared memory */ + if ((shm = shm_open("myshm", O_RDWR | O_CREAT, S_IRWXU)) < 0) { + perror("shm_open"); + exit(1); + } + + if ( ftruncate(shm, sizeof(sem_t)) < 0 ) { + perror("ftruncate"); + exit(1); + } + + /* place shared mutex into shared memory */ + if ((mutex = (sem_t*) mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0)) == MAP_FAILED) { + perror("mmap"); + exit(1); + } + + if( sem_init(mutex,1,1) < 0) + { + perror("semaphore initilization"); + exit(0); + } + + /* signal handling */ memset(&sa, 0, sizeof(sa));
sa.sa_handler = &terminate_connections; @@ -200,5 +243,7 @@ int main(int argc, char **argv)
debug("tcp_connect finished");
+ printf("made %i connections\n", *connection_count); + return 0; } diff --git a/test_tools/tcp_conn/tcp_listen.c b/test_tools/tcp_conn/tcp_listen.c index ef5eeb2..2fc77f6 100644 --- a/test_tools/tcp_conn/tcp_listen.c +++ b/test_tools/tcp_conn/tcp_listen.c @@ -1,21 +1,33 @@ #include <stdio.h> #include <unistd.h> #include <string.h> +#include <stdlib.h> +#include <sys/wait.h>
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> +#include <arpa/inet.h>
#include <errno.h> #include <signal.h> +#include <semaphore.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define IPCKEY 5678
int listener_count; int listeners[1024]; +int *connection_count;
-int connection_count; int debug_on = 0; int cont = 0; +int *term_flag; + +sem_t *mutex;
int usage() { @@ -23,7 +35,7 @@ int usage() return 0; }
-int debug(char* msg) +void debug(char* msg) { if (debug_on) { @@ -36,21 +48,8 @@ char msg[MSG_MAX];
void terminate_connections(int p) { - int l; - debug("signal received, killing servers"); - for (l=0; l < listener_count; l++) - { - snprintf(msg, MSG_MAX, "killing process %i", listeners[l]); - debug(msg); - kill(listeners[l], SIGKILL); - } -} - -void connection_counter(int p) -{ - debug("increase counter"); - connection_count += 1; + *term_flag = 1; }
int handle_connections(char* host, int port) @@ -81,6 +80,13 @@ int handle_connections(char* host, int port) return 1; }
+ int on = 1; + if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (const char*) &on, sizeof(on)) == -1) + { + perror("fail on setsockopt"); + return 1; + } + if (bind(listen_sock, (struct sockaddr*) &my_addr, sizeof(struct sockaddr_in))) { perror("fail on bind"); @@ -109,6 +115,11 @@ int handle_connections(char* host, int port) return 1; }
+ sem_wait(mutex); + *connection_count += 1; + sem_post(mutex); + + inet_ntop(AF_INET, &ra, host_address_str, 255); snprintf(msg, MSG_MAX, "accepted connection from host %s port %i", host_address_str, port); debug(msg); @@ -122,8 +133,7 @@ int handle_connections(char* host, int port) snprintf(msg, MSG_MAX, "connection closed, read %d bytes (%i)", sum, port); debug(msg); close(remote_sock); - kill(getppid(), SIGUSR1); - } while (cont); + } while (cont && (*term_flag) == 0);
close(listen_sock);
@@ -144,7 +154,40 @@ int main(int argc, char **argv) char *delimiter; struct sigaction sa; struct sigaction sa2; + int shm; + + term_flag = mmap(NULL, sizeof *term_flag, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + *term_flag = 0; + + connection_count = mmap(NULL, sizeof *connection_count, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + *connection_count = 0; + + /* counter synchronization stuff - semaphore and shared memory */ + if ((shm = shm_open("myshm", O_RDWR | O_CREAT, S_IRWXU)) < 0) { + perror("shm_open"); + exit(1); + } + + if ( ftruncate(shm, sizeof(sem_t)) < 0 ) { + perror("ftruncate"); + exit(1); + }
+ /* place shared mutex into shared memory */ + if ((mutex = (sem_t*) mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0)) == MAP_FAILED) { + perror("mmap"); + exit(1); + } + + if( sem_init(mutex,1,1) < 0) + { + perror("semaphore initilization"); + exit(0); + } + + /* signal handling */ memset(&sa, 0, sizeof(sa)); memset(&sa2, 0, sizeof(sa2));
@@ -152,9 +195,6 @@ int main(int argc, char **argv) sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL);
- sa2.sa_handler = &connection_counter; - sigaction(SIGUSR1, &sa2, NULL); - /* collect program args */ while ((opt = getopt(argc, argv, "p:a:dc")) != -1) { switch (opt) { @@ -216,7 +256,6 @@ int main(int argc, char **argv) int i; for (i=0; i < listener_count; i++) { - int rc = -1; while (wait(&child_status) == -1 && errno == EINTR) { ; @@ -226,7 +265,7 @@ int main(int argc, char **argv)
debug("tcp_listener finished");
- printf("handled %i connections\n", connection_count); + printf("handled %i connections\n", *connection_count);
return 0; }
lnst-developers@lists.fedorahosted.org