commit 0c0486b1bdf45b1ce3e7f8e728f0777c379ee2ff
Author: Jan Tluka <jtluka(a)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(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)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;
}