Home | History | Annotate | Line # | Download | only in h_client
h_stresscli.c revision 1.8
      1  1.8  pooka /*	$NetBSD: h_stresscli.c,v 1.8 2011/01/12 12:32:53 pooka Exp $	*/
      2  1.1  pooka 
      3  1.1  pooka #include <sys/types.h>
      4  1.1  pooka #include <sys/atomic.h>
      5  1.1  pooka #include <sys/sysctl.h>
      6  1.1  pooka #include <sys/wait.h>
      7  1.8  pooka #include <sys/socket.h>
      8  1.8  pooka 
      9  1.8  pooka #include <netinet/in.h>
     10  1.1  pooka 
     11  1.1  pooka #include <err.h>
     12  1.8  pooka #include <fcntl.h>
     13  1.1  pooka #include <pthread.h>
     14  1.1  pooka #include <stdio.h>
     15  1.1  pooka #include <stdlib.h>
     16  1.1  pooka #include <string.h>
     17  1.1  pooka #include <unistd.h>
     18  1.1  pooka 
     19  1.1  pooka #include <rump/rump_syscalls.h>
     20  1.1  pooka #include <rump/rumpclient.h>
     21  1.1  pooka 
     22  1.8  pooka static unsigned int syscalls, bindcalls;
     23  1.1  pooka static pid_t mypid;
     24  1.4  pooka static volatile sig_atomic_t doquit;
     25  1.1  pooka 
     26  1.1  pooka static void
     27  1.1  pooka signaali(int sig)
     28  1.1  pooka {
     29  1.1  pooka 
     30  1.4  pooka 	doquit = 1;
     31  1.1  pooka }
     32  1.1  pooka 
     33  1.1  pooka static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME };
     34  1.1  pooka static char hostnamebuf[128];
     35  1.1  pooka #define HOSTNAMEBASE "rumpclient"
     36  1.1  pooka 
     37  1.8  pooka static int iskiller;
     38  1.8  pooka 
     39  1.1  pooka static void *
     40  1.1  pooka client(void *arg)
     41  1.1  pooka {
     42  1.1  pooka 	char buf[256];
     43  1.8  pooka 	struct sockaddr_in sin;
     44  1.1  pooka 	size_t blen;
     45  1.8  pooka 	int port = (int)(uintptr_t)arg;
     46  1.8  pooka 	int s, fd, x;
     47  1.8  pooka 
     48  1.8  pooka 	memset(&sin, 0, sizeof(sin));
     49  1.8  pooka 	sin.sin_family = AF_INET;
     50  1.8  pooka 	sin.sin_len = sizeof(sin);
     51  1.8  pooka 	sin.sin_port = htons(port);
     52  1.1  pooka 
     53  1.4  pooka 	while (!doquit) {
     54  1.1  pooka 		pid_t pidi;
     55  1.1  pooka 		blen = sizeof(buf);
     56  1.8  pooka 		s = rump_sys_socket(PF_INET, SOCK_STREAM, 0);
     57  1.8  pooka 		if (s == -1)
     58  1.8  pooka 			err(1, "socket");
     59  1.8  pooka 		atomic_inc_uint(&syscalls);
     60  1.8  pooka 
     61  1.8  pooka 		fd = rump_sys_open("/dev/null", O_RDWR);
     62  1.8  pooka 		atomic_inc_uint(&syscalls);
     63  1.8  pooka 
     64  1.8  pooka 		if (doquit)
     65  1.8  pooka 			goto out;
     66  1.8  pooka 
     67  1.8  pooka 		x = 1;
     68  1.8  pooka 		if (rump_sys_setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
     69  1.8  pooka 		    &x, sizeof(x)) == -1)
     70  1.8  pooka 			err(1, "reuseaddr");
     71  1.8  pooka 
     72  1.8  pooka 		/*
     73  1.8  pooka 		 * we don't really know when the kernel handles our disconnect,
     74  1.8  pooka 		 * so be soft about about the failure in case of a killer client
     75  1.8  pooka 		 */
     76  1.8  pooka 		if (rump_sys_bind(s, (struct sockaddr*)&sin, sizeof(sin))==-1) {
     77  1.8  pooka 			if (!iskiller)
     78  1.8  pooka 				err(1, "bind to port %d failed",
     79  1.8  pooka 				    ntohs(sin.sin_port));
     80  1.8  pooka 		} else {
     81  1.8  pooka 			atomic_inc_uint(&bindcalls);
     82  1.8  pooka 		}
     83  1.8  pooka 		atomic_inc_uint(&syscalls);
     84  1.8  pooka 
     85  1.8  pooka 		if (doquit)
     86  1.8  pooka 			goto out;
     87  1.8  pooka 
     88  1.1  pooka 		if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
     89  1.1  pooka 		    buf, &blen, NULL, 0) == -1)
     90  1.1  pooka 			err(1, "sysctl");
     91  1.1  pooka 		if (strncmp(buf, hostnamebuf, sizeof(HOSTNAMEBASE)-1) != 0)
     92  1.1  pooka 			errx(1, "hostname (%s/%s) mismatch", buf, hostnamebuf);
     93  1.1  pooka 		atomic_inc_uint(&syscalls);
     94  1.1  pooka 
     95  1.8  pooka 		if (doquit)
     96  1.8  pooka 			goto out;
     97  1.8  pooka 
     98  1.1  pooka 		pidi = rump_sys_getpid();
     99  1.1  pooka 		if (pidi == -1)
    100  1.1  pooka 			err(1, "getpid");
    101  1.1  pooka 		if (pidi != mypid)
    102  1.1  pooka 			errx(1, "mypid mismatch");
    103  1.1  pooka 		atomic_inc_uint(&syscalls);
    104  1.8  pooka 
    105  1.8  pooka 		if (doquit)
    106  1.8  pooka 			goto out;
    107  1.8  pooka 
    108  1.8  pooka 		if (rump_sys_write(fd, buf, 16) != 16)
    109  1.8  pooka 			err(1, "write /dev/null");
    110  1.8  pooka 		atomic_inc_uint(&syscalls);
    111  1.8  pooka 
    112  1.8  pooka  out:
    113  1.8  pooka 		rump_sys_close(fd);
    114  1.8  pooka 		atomic_inc_uint(&syscalls);
    115  1.8  pooka 		rump_sys_close(s);
    116  1.8  pooka 		atomic_inc_uint(&syscalls);
    117  1.1  pooka 	}
    118  1.1  pooka 
    119  1.1  pooka 	return NULL;
    120  1.1  pooka }
    121  1.1  pooka 
    122  1.1  pooka /* Stress with max 32 clients, 8 threads each (256 concurrent threads) */
    123  1.1  pooka #define NCLI 32
    124  1.1  pooka #define NTHR 8
    125  1.1  pooka 
    126  1.1  pooka int
    127  1.1  pooka main(int argc, char *argv[])
    128  1.1  pooka {
    129  1.4  pooka 	pthread_t pt[NTHR-1];
    130  1.1  pooka 	pid_t clis[NCLI];
    131  1.1  pooka 	pid_t apid;
    132  1.1  pooka 	int ncli = 0;
    133  1.1  pooka 	int i = 0, j;
    134  1.7  pooka 	int status, thesig;
    135  1.8  pooka 	int rounds, myport;
    136  1.1  pooka 
    137  1.7  pooka 	if (argc != 2 && argc != 3)
    138  1.1  pooka 		errx(1, "need roundcount");
    139  1.1  pooka 
    140  1.7  pooka 	if (argc == 3) {
    141  1.7  pooka 		if (strcmp(argv[2], "kill") != 0)
    142  1.7  pooka 			errx(1, "optional 3rd param must be kill");
    143  1.7  pooka 		thesig = SIGKILL;
    144  1.8  pooka 		iskiller = 1;
    145  1.7  pooka 	} else {
    146  1.7  pooka 		thesig = SIGUSR1;
    147  1.7  pooka 	}
    148  1.7  pooka 
    149  1.6  pooka 	signal(SIGUSR1, signaali);
    150  1.6  pooka 
    151  1.1  pooka 	memset(clis, 0, sizeof(clis));
    152  1.1  pooka 	for (rounds = 1; rounds < atoi(argv[1])*10; rounds++) {
    153  1.1  pooka 		while (ncli < NCLI) {
    154  1.1  pooka 			switch ((apid = fork())) {
    155  1.1  pooka 			case -1:
    156  1.1  pooka 				err(1, "fork failed");
    157  1.1  pooka 			case 0:
    158  1.1  pooka 				if (rumpclient_init() == -1)
    159  1.1  pooka 					err(1, "rumpclient init");
    160  1.1  pooka 
    161  1.1  pooka 				mypid = rump_sys_getpid();
    162  1.1  pooka 				sprintf(hostnamebuf, HOSTNAMEBASE "%d", mypid);
    163  1.1  pooka 				if (rump_sys___sysctl(hostnamemib,
    164  1.1  pooka 				    __arraycount(hostnamemib), NULL, NULL,
    165  1.1  pooka 				    hostnamebuf, strlen(hostnamebuf)+1) == -1)
    166  1.1  pooka 					err(1, "sethostname");
    167  1.1  pooka 
    168  1.8  pooka 				for (j = 0; j < NTHR-1; j++) {
    169  1.8  pooka 					myport = i*NCLI + j+2;
    170  1.4  pooka 					if (pthread_create(&pt[j], NULL,
    171  1.8  pooka 					    client,
    172  1.8  pooka 					    (void*)(uintptr_t)myport) !=0 )
    173  1.1  pooka 						err(1, "pthread create");
    174  1.8  pooka 				}
    175  1.8  pooka 				myport = i*NCLI+1;
    176  1.8  pooka 				client((void *)(uintptr_t)myport);
    177  1.4  pooka 				for (j = 0; j < NTHR-1; j++)
    178  1.4  pooka 					pthread_join(pt[j], NULL);
    179  1.4  pooka 				membar_consumer();
    180  1.4  pooka 				fprintf(stderr, "done %d\n", syscalls);
    181  1.4  pooka 				exit(0);
    182  1.1  pooka 				/* NOTREACHED */
    183  1.1  pooka 			default:
    184  1.1  pooka 				ncli++;
    185  1.1  pooka 				clis[i] = apid;
    186  1.1  pooka 				break;
    187  1.1  pooka 			}
    188  1.1  pooka 
    189  1.1  pooka 			i = (i + 1) % NCLI;
    190  1.1  pooka 		}
    191  1.1  pooka 
    192  1.1  pooka 		usleep(100000);
    193  1.7  pooka 		kill(clis[i], thesig);
    194  1.1  pooka 
    195  1.1  pooka 		apid = wait(&status);
    196  1.1  pooka 		if (apid != clis[i])
    197  1.1  pooka 			errx(1, "wanted pid %d, got %d\n", clis[i], apid);
    198  1.1  pooka 		clis[i] = 0;
    199  1.1  pooka 		ncli--;
    200  1.7  pooka 		if (thesig == SIGUSR1) {
    201  1.7  pooka 			if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
    202  1.7  pooka 				fprintf(stderr, "child died with 0x%x\n",
    203  1.7  pooka 				    status);
    204  1.7  pooka 				exit(1);
    205  1.7  pooka 			}
    206  1.7  pooka 		} else {
    207  1.7  pooka 			if (!WIFSIGNALED(status) || WTERMSIG(status) != thesig){
    208  1.7  pooka 				fprintf(stderr, "child died with 0x%x\n",
    209  1.7  pooka 				    status);
    210  1.7  pooka 				exit(1);
    211  1.7  pooka 			}
    212  1.5  pooka 		}
    213  1.1  pooka 	}
    214  1.1  pooka 
    215  1.1  pooka 	for (i = 0; i < NCLI; i++)
    216  1.1  pooka 		if (clis[i])
    217  1.1  pooka 			kill(clis[i], SIGKILL);
    218  1.1  pooka }
    219