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