rumpnfsd.c revision 313498
1/*	$NetBSD: rumpnfsd.c,v 1.9 2015/11/08 02:45:16 christos Exp $	*/
2
3/*-
4 * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/types.h>
29
30#include <dlfcn.h>
31#include <err.h>
32#include <errno.h>
33#include <pthread.h>
34#include <semaphore.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <syslog.h>
39#include <unistd.h>
40#include <rpc/rpc.h>
41
42void *mountd_main(void *);
43void *rpcbind_main(void *);
44int nfsd_main(int, char **);
45
46sem_t gensem;
47
48#include "../../../net/config/netconfig.c"
49#include "../../common/h_fsmacros.h"
50#include "svc_fdset.h"
51
52#include <rump/rump.h>
53#include <rump/rump_syscalls.h>
54
55int
56main(int argc, char *argv[])
57{
58	const char *ethername, *ethername_ro;
59	const char *serveraddr, *serveraddr_ro;
60	const char *netmask;
61	const char *exportpath;
62	const char *imagename;
63	char ifname[IFNAMSIZ], ifname_ro[IFNAMSIZ];
64	void *fsarg;
65	pthread_t t;
66	int rv;
67
68	/* for netcfg */
69	noatf = 1;
70
71	/* use defaults? */
72	if (argc == 1) {
73		ethername = "etherbus";
74		ethername_ro = "etherbus_ro";
75		serveraddr = "10.3.2.1";
76		serveraddr_ro = "10.4.2.1";
77		netmask = "255.255.255.0";
78		exportpath = "/myexport";
79		imagename = "ffs.img";
80	} else {
81		ethername = argv[1];
82		ethername_ro = argv[2];
83		serveraddr = argv[3];
84		serveraddr_ro = argv[4];
85		netmask = argv[5];
86		exportpath = argv[6];
87		imagename = argv[7];
88	}
89
90	rump_init();
91	svc_fdset_init(SVC_FDSET_MT);
92
93	rv = rump_pub_etfs_register("/etc/exports", "./exports", RUMP_ETFS_REG);
94	if (rv) {
95		errx(1, "register /etc/exports: %s", strerror(rv));
96	}
97
98	/* mini-mtree for mountd */
99	static const char *const dirs[] = { "/var", "/var/run", "/var/db" };
100	for (size_t i = 0; i < __arraycount(dirs); i++)
101		if (rump_sys_mkdir(dirs[i], 0777) == -1)
102			err(1, "can't mkdir `%s'", dirs[i]);
103
104	if (ffs_fstest_newfs(NULL, &fsarg,
105	    imagename, FSTEST_IMGSIZE, NULL) != 0)
106		err(1, "newfs failed");
107	if (ffs_fstest_mount(NULL, fsarg, exportpath, 0) != 0)
108		err(1, "mount failed");
109
110#if 0
111	/*
112	 * Serve from host instead of dedicated mount?
113	 * THIS IS MORE EVIL THAN MURRAY THE DEMONIC TALKING SKULL!
114	 */
115
116	if (ukfs_modload("/usr/lib/librumpfs_syspuffs.so") < 1)
117		errx(1, "modload");
118
119	mount_syspuffs_parseargs(__arraycount(pnullarg), pnullarg,
120	    &args, &mntflags, canon_dev, canon_dir);
121	if ((ukfs = ukfs_mount(MOUNT_PUFFS, "/", UKFS_DEFAULTMP, MNT_RDONLY,
122	    &args, sizeof(args))) == NULL)
123		err(1, "mount");
124
125	if (ukfs_modload("/usr/lib/librumpfs_nfsserver.so") < 1)
126		errx(1, "modload");
127#endif
128
129	if (sem_init(&gensem, 1, 0) == -1)
130		err(1, "gensem init");
131
132	/* create interface */
133	netcfg_rump_makeshmif(ethername, ifname);
134	netcfg_rump_if(ifname, serveraddr, netmask);
135
136	netcfg_rump_makeshmif(ethername_ro, ifname_ro);
137	netcfg_rump_if(ifname_ro, serveraddr_ro, netmask);
138
139	/*
140	 * No syslogging, thanks.
141	 * XXX: "0" does not modify the mask, so pick something
142	 * which is unlikely to cause any logging
143	 */
144	setlogmask(0x10000000);
145
146	if (pthread_create(&t, NULL, rpcbind_main, NULL) == -1)
147		err(1, "rpcbind");
148	sem_wait(&gensem);
149
150	if (pthread_create(&t, NULL, mountd_main, NULL) == -1)
151		err(1, "mountd");
152	sem_wait(&gensem);
153
154	rv = 0;
155	/* signal the other process we're almost done */
156	if (write(3, &rv, 4) != 4)
157		errx(1, "magic write failed");
158
159	{
160	char *nfsargv[] = { __UNCONST("nfsd"), NULL };
161	nfsd_main(1, nfsargv);
162	}
163	/*NOTREACHED*/
164
165	return 0;
166}
167