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
16static volatile int quit, riseandwhine;
17
18static pthread_mutex_t closermtx;
19static pthread_cond_t closercv;
20
21static void *
22closer(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
48static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME };
49static char goodhostname[128];
50
51static void *
52worker(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
81int
82main(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