Home | History | Annotate | Line # | Download | only in md
h_mdserv.c revision 1.3
      1 /*	$NetBSD: h_mdserv.c,v 1.3 2010/11/30 14:31:14 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 = malloc(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