]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/netbsd-tests/dev/md/h_mdserv.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / netbsd-tests / dev / md / h_mdserv.c
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
24 static void *
25 prober(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
63 int
64 main(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 }