4 * This is the user level part of nfsd. This is very primitive, because
5 * all the work is now done in the kernel module.
7 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
34 static void usage(const char *);
36 static struct option longopts[] =
38 { "host", 1, 0, 'H' },
39 { "help", 0, 0, 'h' },
40 { "no-nfs-version", 1, 0, 'N' },
41 { "no-tcp", 0, 0, 'T' },
42 { "no-udp", 0, 0, 'U' },
43 { "port", 1, 0, 'P' },
44 { "port", 1, 0, 'p' },
45 { "debug", 0, 0, 'd' },
46 { "syslog", 0, 0, 's' },
50 /* given a family and ctlbits, disable any that aren't listed in netconfig */
53 nfsd_enable_protos(unsigned int *proto4, unsigned int *proto6)
55 struct netconfig *nconf;
56 unsigned int *famproto;
59 xlog(D_GENERAL, "Checking netconfig for visible protocols.");
61 handle = setnetconfig();
62 while((nconf = getnetconfig(handle))) {
63 if (!(nconf->nc_flag & NC_VISIBLE))
66 if (!strcmp(nconf->nc_protofmly, NC_INET))
68 else if (!strcmp(nconf->nc_protofmly, NC_INET6))
73 if (!strcmp(nconf->nc_proto, NC_TCP))
74 NFSCTL_TCPSET(*famproto);
75 else if (!strcmp(nconf->nc_proto, NC_UDP))
76 NFSCTL_UDPSET(*famproto);
78 xlog(D_GENERAL, "Enabling %s %s.", nconf->nc_protofmly,
84 #else /* HAVE_LIBTIRPC */
86 nfsd_enable_protos(unsigned int *proto4, unsigned int *proto6)
88 /* Enable all IPv4 protocols if no TIRPC support */
89 *proto4 = NFSCTL_ALLBITS;
92 #endif /* HAVE_LIBTIRPC */
95 main(int argc, char **argv)
97 int count = NFSD_NPROC, c, error = 0, portnum = 0, fd, found_one;
98 char *p, *progname, *port;
101 int minorvers41 = 0; /* nfsv4 minor version */
102 unsigned int versbits = NFSCTL_ALLBITS;
103 unsigned int protobits = NFSCTL_ALLBITS;
104 unsigned int proto4 = 0;
105 unsigned int proto6 = 0;
107 progname = strdup(basename(argv[0]));
109 fprintf(stderr, "%s: unable to allocate memory.\n", argv[0]);
113 port = strdup("nfs");
115 fprintf(stderr, "%s: unable to allocate memory.\n", progname);
122 while ((c = getopt_long(argc, argv, "dH:hN:p:P:sTU", longopts, NULL)) != EOF) {
125 xlog_config(D_ALL, 1);
129 * for now, this only handles one -H option. Use the
130 * last one specified.
133 haddr = strdup(optarg);
135 fprintf(stderr, "%s: unable to allocate "
136 "memory.\n", progname);
140 case 'P': /* XXX for nfs-server compatibility */
142 /* only the last -p option has any effect */
143 portnum = atoi(optarg);
144 if (portnum <= 0 || portnum > 65535) {
145 fprintf(stderr, "%s: bad port number: %s\n",
150 port = strdup(optarg);
152 fprintf(stderr, "%s: unable to allocate "
153 "memory.\n", progname);
158 switch((c = strtol(optarg, &p, 0))) {
163 fprintf(stderr, "%s: unsupported minor version\n", optarg);
171 NFSCTL_VERUNSET(versbits, c);
174 fprintf(stderr, "%s: Unsupported version\n", optarg);
183 NFSCTL_TCPUNSET(protobits);
186 NFSCTL_UDPUNSET(protobits);
189 fprintf(stderr, "Invalid argument: '%c'\n", c);
196 if ((count = atoi(argv[optind])) < 0) {
197 /* insane # of servers */
199 "%s: invalid server count (%d), using 1\n",
202 } else if (count == 0) {
204 * don't bother setting anything else if the threads
205 * are coming down anyway.
214 nfsd_enable_protos(&proto4, &proto6);
216 if (!NFSCTL_TCPISSET(protobits)) {
217 NFSCTL_TCPUNSET(proto4);
218 NFSCTL_TCPUNSET(proto6);
221 if (!NFSCTL_UDPISSET(protobits)) {
222 NFSCTL_UDPUNSET(proto4);
223 NFSCTL_UDPUNSET(proto6);
226 /* make sure that at least one version is enabled */
228 for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) {
229 if (NFSCTL_VERISSET(versbits, c))
233 xlog(L_ERROR, "no version specified");
237 if (NFSCTL_VERISSET(versbits, 4) &&
238 !NFSCTL_TCPISSET(proto4) &&
239 !NFSCTL_TCPISSET(proto6)) {
240 xlog(L_ERROR, "version 4 requires the TCP protocol");
244 if (chdir(NFS_STATEDIR)) {
245 xlog(L_ERROR, "chdir(%s) failed: %m", NFS_STATEDIR);
249 /* make sure nfsdfs is mounted if it's available */
250 nfssvc_mount_nfsdfs(progname);
252 /* can only change number of threads if nfsd is already up */
253 if (nfssvc_inuse()) {
259 * must set versions before the fd's so that the right versions get
260 * registered with rpcbind. Note that on older kernels w/o the right
261 * interfaces, these are a no-op.
263 nfssvc_setvers(versbits, minorvers41);
265 error = nfssvc_set_sockets(AF_INET, proto4, haddr, port);
269 #ifdef IPV6_SUPPORTED
270 error = nfssvc_set_sockets(AF_INET6, proto6, haddr, port);
273 #endif /* IPV6_SUPPORTED */
276 /* don't start any threads if unable to hand off any sockets */
278 xlog(L_ERROR, "unable to set any sockets for nfsd");
285 * Some kernels let nfsd kernel threads inherit open files
286 * from the program that spawns them (i.e. us). So close
287 * everything before spawning kernel threads. --Chip
289 fd = open("/dev/null", O_RDWR);
291 xlog(L_ERROR, "Unable to open /dev/null: %m");
293 /* switch xlog output to syslog since stderr is being closed */
302 if ((error = nfssvc_threads(portnum, count)) < 0)
303 xlog(L_ERROR, "error starting threads: errno %d (%m)", errno);
312 usage(const char *prog)
314 fprintf(stderr, "Usage:\n"
315 "%s [-d|--debug] [-H hostname] [-p|-P|--port port] [-N|--no-nfs-version version ] [-s|--syslog] [-T|--no-tcp] [-U|--no-udp] nrservs\n",