1 /*	$NetBSD: h_reconcli.c,v 1.2 2011/02/19 09:56:45 pooka Exp $	*/
2 
3 #include <sys/types.h>
4 #include <sys/sysctl.h>
5 
6 #include <rump/rumpclient.h>
7 #include <rump/rump_syscalls.h>
8 
9 #include <err.h>
10 #include <pthread.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 
16 static volatile int quit, riseandwhine;
17 
18 static pthread_mutex_t closermtx;
19 static pthread_cond_t closercv;
20 
21 static void *
22 closer(void *arg)
23 {
24 
25 	pthread_mutex_lock(&closermtx);
26 	while (!quit) {
27 		while (!riseandwhine)
28 			pthread_cond_wait(&closercv, &closermtx);
29 		riseandwhine = 0;
30 		pthread_mutex_unlock(&closermtx);
31 
32 		/* try to catch a random slot */
33 		usleep(random() % 100000);
34 
35 		/*
36 		 * wide-angle disintegration beam, but takes care
37 		 * of the client rumpkernel communication socket.
38 		 */
39 		closefrom(3);
40 
41 		pthread_mutex_lock(&closermtx);
42 	}
43 	pthread_mutex_unlock(&closermtx);
44 
45 	return NULL;
46 }
47 
48 static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME };
49 static char goodhostname[128];
50 
51 static void *
52 worker(void *arg)
53 {
54 	char hostnamebuf[128];
55 	size_t blen;
56 
57 	pthread_mutex_lock(&closermtx);
58 	while (!quit) {
59 		pthread_mutex_unlock(&closermtx);
60 		if (rump_sys_getpid() == -1)
61 			err(1, "getpid");
62 
63 		blen = sizeof(hostnamebuf);
64 		memset(hostnamebuf, 0, sizeof(hostnamebuf));
65 		if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
66 		    hostnamebuf, &blen, NULL, 0) == -1)
67 			err(1, "sysctl");
68 		if (strcmp(hostnamebuf, goodhostname) != 0)
69 			exit(1);
70 		pthread_mutex_lock(&closermtx);
71 		riseandwhine = 1;
72 		pthread_cond_signal(&closercv);
73 	}
74 	riseandwhine = 1;
75 	pthread_cond_signal(&closercv);
76 	pthread_mutex_unlock(&closermtx);
77 
78 	return NULL;
79 }
80 
81 int
82 main(int argc, char *argv[])
83 {
84 	pthread_t pt, w1, w2, w3, w4;
85 	size_t blen;
86 	int timecount;
87 
88 	if (argc != 2)
89 		errx(1, "need timecount");
90 	timecount = atoi(argv[1]);
91 	if (timecount <= 0)
92 		errx(1, "invalid timecount %d\n", timecount);
93 
94 	srandom(time(NULL));
95 
96 	rumpclient_setconnretry(RUMPCLIENT_RETRYCONN_INFTIME);
97 	if (rumpclient_init() == -1)
98 		err(1, "init");
99 
100 	blen = sizeof(goodhostname);
101 	if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
102 	    goodhostname, &blen, NULL, 0) == -1)
103 		err(1, "sysctl");
104 
105 	pthread_create(&pt, NULL, closer, NULL);
106 	pthread_create(&w1, NULL, worker, NULL);
107 	pthread_create(&w2, NULL, worker, NULL);
108 	pthread_create(&w3, NULL, worker, NULL);
109 	pthread_create(&w4, NULL, worker, NULL);
110 
111 	sleep(timecount);
112 	quit = 1;
113 
114 	pthread_join(pt, NULL);
115 	pthread_join(w1, NULL);
116 	pthread_join(w2, NULL);
117 	pthread_join(w3, NULL);
118 	pthread_join(w4, NULL);
119 
120 	exit(0);
121 }
122