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 } 110