h_stresscli.c revision 1.9 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