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