1 1.5 andvar /* $NetBSD: h_mdserv.c,v 1.5 2021/09/16 22:19:11 andvar 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.5 andvar * successful. 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