xref: /freebsd/contrib/netbsd-tests/dev/md/h_mdserv.c (revision 9268022b74279434ed6300244e3f977e56a8ceb5)
1*57718be8SEnji Cooper /*	$NetBSD: h_mdserv.c,v 1.4 2011/02/10 13:29:02 pooka Exp $	*/
2*57718be8SEnji Cooper 
3*57718be8SEnji Cooper #include <sys/types.h>
4*57718be8SEnji Cooper #include <sys/mman.h>
5*57718be8SEnji Cooper #include <sys/ioctl.h>
6*57718be8SEnji Cooper 
7*57718be8SEnji Cooper #include <dev/md.h>
8*57718be8SEnji Cooper 
9*57718be8SEnji Cooper #include <err.h>
10*57718be8SEnji Cooper #include <errno.h>
11*57718be8SEnji Cooper #include <fcntl.h>
12*57718be8SEnji Cooper #include <pthread.h>
13*57718be8SEnji Cooper #include <stdio.h>
14*57718be8SEnji Cooper #include <stdlib.h>
15*57718be8SEnji Cooper #include <unistd.h>
16*57718be8SEnji Cooper 
17*57718be8SEnji Cooper #include <rump/rump.h>
18*57718be8SEnji Cooper #include <rump/rump_syscalls.h>
19*57718be8SEnji Cooper 
20*57718be8SEnji Cooper #define MDSIZE (1024*1024)
21*57718be8SEnji Cooper 
22*57718be8SEnji Cooper #define REQUIRE(a, msg) if ((a) != 0) err(1, msg);
23*57718be8SEnji Cooper 
24*57718be8SEnji Cooper static void *
prober(void * arg)25*57718be8SEnji Cooper prober(void *arg)
26*57718be8SEnji Cooper {
27*57718be8SEnji Cooper 	int fd, error;
28*57718be8SEnji Cooper 	char buf[4];
29*57718be8SEnji Cooper 	ssize_t n;
30*57718be8SEnji Cooper 
31*57718be8SEnji Cooper 	fd = rump_sys_open(arg, O_RDONLY);
32*57718be8SEnji Cooper 	for (;;) {
33*57718be8SEnji Cooper 		n = rump_sys_read(fd, buf, sizeof(buf));
34*57718be8SEnji Cooper 
35*57718be8SEnji Cooper 		switch (n) {
36*57718be8SEnji Cooper 		case 4:
37*57718be8SEnji Cooper 			error = 0;
38*57718be8SEnji Cooper 			goto out;
39*57718be8SEnji Cooper 
40*57718be8SEnji Cooper 		case -1:
41*57718be8SEnji Cooper 			if (errno == ENXIO) {
42*57718be8SEnji Cooper 				usleep(1000);
43*57718be8SEnji Cooper 				continue;
44*57718be8SEnji Cooper 			}
45*57718be8SEnji Cooper 
46*57718be8SEnji Cooper 			/* FALLTHROUGH */
47*57718be8SEnji Cooper 		default:
48*57718be8SEnji Cooper 			error = EPIPE;
49*57718be8SEnji Cooper 			goto out;
50*57718be8SEnji Cooper 		}
51*57718be8SEnji Cooper 	}
52*57718be8SEnji Cooper  out:
53*57718be8SEnji Cooper 
54*57718be8SEnji Cooper 	error = rump_daemonize_done(error);
55*57718be8SEnji Cooper 	REQUIRE(error, "rump_daemonize_done");
56*57718be8SEnji Cooper 
57*57718be8SEnji Cooper 	if (error)
58*57718be8SEnji Cooper 		exit(1);
59*57718be8SEnji Cooper 
60*57718be8SEnji Cooper 	return NULL;
61*57718be8SEnji Cooper }
62*57718be8SEnji Cooper 
63*57718be8SEnji Cooper int
main(int argc,char * argv[])64*57718be8SEnji Cooper main(int argc, char *argv[])
65*57718be8SEnji Cooper {
66*57718be8SEnji Cooper 	pthread_t pt;
67*57718be8SEnji Cooper 	struct md_conf md;
68*57718be8SEnji Cooper 	int fd, error;
69*57718be8SEnji Cooper 
70*57718be8SEnji Cooper 	if (argc != 2)
71*57718be8SEnji Cooper 		exit(1);
72*57718be8SEnji Cooper 
73*57718be8SEnji Cooper 	md.md_addr = calloc(1, MDSIZE);
74*57718be8SEnji Cooper 	md.md_size = MDSIZE;
75*57718be8SEnji Cooper 	md.md_type = MD_UMEM_SERVER;
76*57718be8SEnji Cooper 
77*57718be8SEnji Cooper 	error = rump_daemonize_begin();
78*57718be8SEnji Cooper 	REQUIRE(error, "rump_daemonize_begin");
79*57718be8SEnji Cooper 
80*57718be8SEnji Cooper 	error = rump_init();
81*57718be8SEnji Cooper 	REQUIRE(error, "rump_init");
82*57718be8SEnji Cooper 
83*57718be8SEnji Cooper 	error = rump_init_server("unix://commsock");
84*57718be8SEnji Cooper 	REQUIRE(error, "init server");
85*57718be8SEnji Cooper 
86*57718be8SEnji Cooper 	if ((fd = rump_sys_open(argv[1], O_RDWR)) == -1)
87*57718be8SEnji Cooper 		err(1, "open");
88*57718be8SEnji Cooper 
89*57718be8SEnji Cooper 	/*
90*57718be8SEnji Cooper 	 * Now, configuring the md driver also causes our process
91*57718be8SEnji Cooper 	 * to start acting as the worker for the md.  Splitting it
92*57718be8SEnji Cooper 	 * into two steps in the driver is not easy, since md is
93*57718be8SEnji Cooper 	 * supposed to be unconfigured when the process dies
94*57718be8SEnji Cooper 	 * (process may exit between calling ioctl1 and ioctl2).
95*57718be8SEnji Cooper 	 * So, start a probe thread which attempts to read the md
96*57718be8SEnji Cooper 	 * and declares the md as configured when the read is
97*57718be8SEnji Cooper 	 * succesful.
98*57718be8SEnji Cooper 	 */
99*57718be8SEnji Cooper 	error = pthread_create(&pt, NULL, prober, argv[1]);
100*57718be8SEnji Cooper 	REQUIRE(error, "pthread_create");
101*57718be8SEnji Cooper 	pthread_detach(pt);
102*57718be8SEnji Cooper 
103*57718be8SEnji Cooper 	if (rump_sys_ioctl(fd, MD_SETCONF, &md) == -1) {
104*57718be8SEnji Cooper 		rump_daemonize_done(errno);
105*57718be8SEnji Cooper 		exit(1);
106*57718be8SEnji Cooper 	}
107*57718be8SEnji Cooper 
108*57718be8SEnji Cooper 	return 0;
109*57718be8SEnji Cooper }
110