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