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' },
46 /* given a family and ctlbits, disable any that aren't listed in netconfig */
49 nfsd_enable_protos(unsigned int *proto4, unsigned int *proto6)
51 struct netconfig *nconf;
52 unsigned int *famproto;
55 xlog(D_GENERAL, "Checking netconfig for visible protocols.");
57 handle = setnetconfig();
58 while((nconf = getnetconfig(handle))) {
59 if (!(nconf->nc_flag & NC_VISIBLE))
62 if (!strcmp(nconf->nc_protofmly, NC_INET))
64 else if (!strcmp(nconf->nc_protofmly, NC_INET6))
69 if (!strcmp(nconf->nc_proto, NC_TCP))
70 NFSCTL_TCPSET(*famproto);
71 else if (!strcmp(nconf->nc_proto, NC_UDP))
72 NFSCTL_UDPSET(*famproto);
74 xlog(D_GENERAL, "Enabling %s %s.", nconf->nc_protofmly,
80 #else /* HAVE_LIBTIRPC */
82 nfsd_enable_protos(unsigned int *proto4, unsigned int *proto6)
84 /* Enable all IPv4 protocols if no TIRPC support */
85 *proto4 = NFSCTL_ALLBITS;
88 #endif /* HAVE_LIBTIRPC */
91 main(int argc, char **argv)
93 int count = 1, c, error = 0, portnum = 0, fd, found_one;
94 char *p, *progname, *port;
97 int minorvers41 = 0; /* nfsv4 minor version */
98 unsigned int versbits = NFSCTL_ALLBITS;
99 unsigned int protobits = NFSCTL_ALLBITS;
100 unsigned int proto4 = 0;
101 unsigned int proto6 = 0;
103 progname = strdup(basename(argv[0]));
105 fprintf(stderr, "%s: unable to allocate memory.\n", argv[0]);
109 port = strdup("nfs");
111 fprintf(stderr, "%s: unable to allocate memory.\n", progname);
118 while ((c = getopt_long(argc, argv, "dH:hN:p:P:sTU", longopts, NULL)) != EOF) {
121 xlog_config(D_ALL, 1);
125 * for now, this only handles one -H option. Use the
126 * last one specified.
129 haddr = strdup(optarg);
131 fprintf(stderr, "%s: unable to allocate "
132 "memory.\n", progname);
136 case 'P': /* XXX for nfs-server compatibility */
138 /* only the last -p option has any effect */
139 portnum = atoi(optarg);
140 if (portnum <= 0 || portnum > 65535) {
141 fprintf(stderr, "%s: bad port number: %s\n",
146 port = strdup(optarg);
148 fprintf(stderr, "%s: unable to allocate "
149 "memory.\n", progname);
154 switch((c = strtol(optarg, &p, 0))) {
159 fprintf(stderr, "%s: unsupported minor version\n", optarg);
167 NFSCTL_VERUNSET(versbits, c);
170 fprintf(stderr, "%s: Unsupported version\n", optarg);
179 NFSCTL_TCPUNSET(protobits);
182 NFSCTL_UDPUNSET(protobits);
185 fprintf(stderr, "Invalid argument: '%c'\n", c);
192 if ((count = atoi(argv[optind])) < 0) {
193 /* insane # of servers */
195 "%s: invalid server count (%d), using 1\n",
198 } else if (count == 0) {
200 * don't bother setting anything else if the threads
201 * are coming down anyway.
210 nfsd_enable_protos(&proto4, &proto6);
212 if (!NFSCTL_TCPISSET(protobits)) {
213 NFSCTL_TCPUNSET(proto4);
214 NFSCTL_TCPUNSET(proto6);
217 if (!NFSCTL_UDPISSET(protobits)) {
218 NFSCTL_UDPUNSET(proto4);
219 NFSCTL_UDPUNSET(proto6);
222 /* make sure that at least one version is enabled */
224 for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) {
225 if (NFSCTL_VERISSET(versbits, c))
229 xlog(L_ERROR, "no version specified");
233 if (NFSCTL_VERISSET(versbits, 4) &&
234 !NFSCTL_TCPISSET(proto4) &&
235 !NFSCTL_TCPISSET(proto6)) {
236 xlog(L_ERROR, "version 4 requires the TCP protocol");
240 if (chdir(NFS_STATEDIR)) {
241 xlog(L_ERROR, "chdir(%s) failed: %m", NFS_STATEDIR);
245 /* make sure nfsdfs is mounted if it's available */
246 nfssvc_mount_nfsdfs(progname);
248 /* can only change number of threads if nfsd is already up */
249 if (nfssvc_inuse()) {
255 * must set versions before the fd's so that the right versions get
256 * registered with rpcbind. Note that on older kernels w/o the right
257 * interfaces, these are a no-op.
259 nfssvc_setvers(versbits, minorvers41);
261 error = nfssvc_set_sockets(AF_INET, proto4, haddr, port);
265 #ifdef IPV6_SUPPORTED
266 error = nfssvc_set_sockets(AF_INET6, proto6, haddr, port);
269 #endif /* IPV6_SUPPORTED */
272 /* don't start any threads if unable to hand off any sockets */
274 xlog(L_ERROR, "unable to set any sockets for nfsd");
281 * Some kernels let nfsd kernel threads inherit open files
282 * from the program that spawns them (i.e. us). So close
283 * everything before spawning kernel threads. --Chip
285 fd = open("/dev/null", O_RDWR);
287 xlog(L_ERROR, "Unable to open /dev/null: %m");
289 /* switch xlog output to syslog since stderr is being closed */
298 if ((error = nfssvc_threads(portnum, count)) < 0)
299 xlog(L_ERROR, "error starting threads: errno %d (%m)", errno);
308 usage(const char *prog)
310 fprintf(stderr, "Usage:\n"
311 "%s [-d|--debug] [-H hostname] [-p|-P|--port port] [-N|--no-nfs-version version ] [-s|--syslog] [-T|--no-tcp] [-U|--no-udp] nrservs\n",