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