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>
30 static void usage(const char *);
32 static struct option longopts[] =
34 { "host", 1, 0, 'H' },
35 { "help", 0, 0, 'h' },
36 { "no-nfs-version", 1, 0, 'N' },
37 { "no-tcp", 0, 0, 'T' },
38 { "no-udp", 0, 0, 'U' },
39 { "port", 1, 0, 'P' },
40 { "port", 1, 0, 'p' },
41 { "debug", 0, 0, 'd' },
42 { "syslog", 0, 0, 's' },
45 unsigned int protobits = NFSCTL_ALLBITS;
46 unsigned int versbits = NFSCTL_ALLBITS;
47 int minorvers4 = NFSD_MAXMINORVERS4; /* nfsv4 minor version */
50 main(int argc, char **argv)
52 int count = 1, c, error, portnum = 0, fd, found_one;
53 char *p, *progname, *port;
57 progname = strdup(basename(argv[0]));
59 fprintf(stderr, "%s: unable to allocate memory.\n", argv[0]);
65 fprintf(stderr, "%s: unable to allocate memory.\n", progname);
72 while ((c = getopt_long(argc, argv, "dH:hN:p:P:sTU", longopts, NULL)) != EOF) {
75 xlog_config(D_ALL, 1);
79 * for now, this only handles one -H option. Use the
83 haddr = strdup(optarg);
85 fprintf(stderr, "%s: unable to allocate "
86 "memory.\n", progname);
90 case 'P': /* XXX for nfs-server compatibility */
92 /* only the last -p option has any effect */
93 portnum = atoi(optarg);
94 if (portnum <= 0 || portnum > 65535) {
95 fprintf(stderr, "%s: bad port number: %s\n",
100 port = strdup(optarg);
102 fprintf(stderr, "%s: unable to allocate "
103 "memory.\n", progname);
108 switch((c = strtol(optarg, &p, 0))) {
111 minorvers4 = -atoi(p + 1);
116 NFSCTL_VERUNSET(versbits, c);
119 fprintf(stderr, "%s: Unsupported version\n", optarg);
128 NFSCTL_TCPUNSET(protobits);
131 NFSCTL_UDPUNSET(protobits);
134 fprintf(stderr, "Invalid argument: '%c'\n", c);
143 * Do some sanity checking, if the ctlbits are set
145 if (!NFSCTL_UDPISSET(protobits) && !NFSCTL_TCPISSET(protobits)) {
146 xlog(L_ERROR, "invalid protocol specified");
150 for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) {
151 if (NFSCTL_VERISSET(versbits, c))
155 xlog(L_ERROR, "no version specified");
159 if (NFSCTL_VERISSET(versbits, 4) && !NFSCTL_TCPISSET(protobits)) {
160 xlog(L_ERROR, "version 4 requires the TCP protocol");
164 struct in_addr in = {INADDR_ANY};
165 haddr = strdup(inet_ntoa(in));
168 if (chdir(NFS_STATEDIR)) {
169 xlog(L_ERROR, "chdir(%s) failed: %m", NFS_STATEDIR);
174 if ((count = atoi(argv[optind])) < 0) {
175 /* insane # of servers */
176 xlog(L_ERROR, "invalid server count (%d), using 1",
182 /* can only change number of threads if nfsd is already up */
183 if (nfssvc_inuse()) {
189 * must set versions before the fd's so that the right versions get
190 * registered with rpcbind. Note that on older kernels w/o the right
191 * interfaces, these are a no-op.
193 nfssvc_setvers(versbits, minorvers4);
195 error = nfssvc_set_sockets(AF_INET, protobits, haddr, port);
200 /* don't start any threads if unable to hand off any sockets */
202 xlog(L_ERROR, "unable to set any sockets for nfsd");
209 * Some kernels let nfsd kernel threads inherit open files
210 * from the program that spawns them (i.e. us). So close
211 * everything before spawning kernel threads. --Chip
213 fd = open("/dev/null", O_RDWR);
215 xlog(L_ERROR, "Unable to open /dev/null: %m");
217 /* switch xlog output to syslog since stderr is being closed */
226 if ((error = nfssvc_threads(portnum, count)) < 0)
227 xlog(L_ERROR, "error starting threads: errno %d (%m)", errno);
236 usage(const char *prog)
238 fprintf(stderr, "Usage:\n"
239 "%s [-d|--debug] [-H hostname] [-p|-P|--port port] [-N|--no-nfs-version version ] [-s|--syslog] [-T|--no-tcp] [-U|--no-udp] nrservs\n",