6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
24 #define NFSD_PORTS_FILE "/proc/fs/nfsd/portlist"
25 #define NFSD_VERS_FILE "/proc/fs/nfsd/versions"
26 #define NFSD_THREAD_FILE "/proc/fs/nfsd/threads"
29 nfssvc_setfds(int port, unsigned int ctlbits, char *haddr)
33 int udpfd = -1, tcpfd = -1;
34 struct sockaddr_in sin;
36 fd = open(NFSD_PORTS_FILE, O_RDONLY);
39 n = read(fd, buf, BUFSIZ);
43 /* there are no ports currently open, so it is safe to
44 * try to open some and pass them through.
45 * Note: If the user explicitly asked for 'udp', then
46 * we should probably check if that is open, and should
47 * open it if not. However we don't yet. All sockets
48 * have to be opened when the first daemon is started.
50 fd = open(NFSD_PORTS_FILE, O_WRONLY);
53 sin.sin_family = AF_INET;
54 sin.sin_port = htons(port);
55 sin.sin_addr.s_addr = inet_addr(haddr);
57 if (NFSCTL_UDPISSET(ctlbits)) {
58 udpfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
60 syslog(LOG_ERR, "nfssvc: unable to create UPD socket: "
61 "errno %d (%s)\n", errno, strerror(errno));
64 if (bind(udpfd, (struct sockaddr *)&sin, sizeof(sin)) < 0){
65 syslog(LOG_ERR, "nfssvc: unable to bind UPD socket: "
66 "errno %d (%s)\n", errno, strerror(errno));
71 if (NFSCTL_TCPISSET(ctlbits)) {
72 tcpfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
74 syslog(LOG_ERR, "nfssvc: unable to createt tcp socket: "
75 "errno %d (%s)\n", errno, strerror(errno));
78 if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
79 syslog(LOG_ERR, "nfssvc: unable to set SO_REUSEADDR: "
80 "errno %d (%s)\n", errno, strerror(errno));
83 if (bind(tcpfd, (struct sockaddr *)&sin, sizeof(sin)) < 0){
84 syslog(LOG_ERR, "nfssvc: unable to bind TCP socket: "
85 "errno %d (%s)\n", errno, strerror(errno));
88 if (listen(tcpfd, 64) < 0){
89 syslog(LOG_ERR, "nfssvc: unable to create listening socket: "
90 "errno %d (%s)\n", errno, strerror(errno));
95 snprintf(buf, BUFSIZ,"%d\n", udpfd);
96 if (write(fd, buf, strlen(buf)) != strlen(buf)) {
98 "nfssvc: writing fds to kernel failed: errno %d (%s)",
99 errno, strerror(errno));
106 fd = open(NFSD_PORTS_FILE, O_WRONLY);
107 snprintf(buf, BUFSIZ,"%d\n", tcpfd);
108 if (write(fd, buf, strlen(buf)) != strlen(buf)) {
110 "nfssvc: writing fds to kernel failed: errno %d (%s)",
111 errno, strerror(errno));
119 nfssvc_versbits(unsigned int ctlbits)
122 char buf[BUFSIZ], *ptr;
126 fd = open(NFSD_VERS_FILE, O_WRONLY);
130 for (n = NFSD_MINVERS; n <= NFSD_MAXVERS; n++) {
131 if (NFSCTL_VERISSET(ctlbits, n))
132 off += snprintf(ptr+off, BUFSIZ - off, "+%d ", n);
134 off += snprintf(ptr+off, BUFSIZ - off, "-%d ", n);
136 snprintf(ptr+off, BUFSIZ - off, "\n");
137 if (write(fd, buf, strlen(buf)) != strlen(buf)) {
138 syslog(LOG_ERR, "nfssvc: Setting version failed: errno %d (%s)",
139 errno, strerror(errno));
146 nfssvc(int port, int nrservs, unsigned int versbits, unsigned protobits,
149 struct nfsctl_arg arg;
152 /* Note: must set versions before fds so that
153 * the ports get registered with portmap against correct
156 nfssvc_versbits(versbits);
157 nfssvc_setfds(port, protobits, haddr);
159 fd = open(NFSD_THREAD_FILE, O_WRONLY);
161 fd = open("/proc/fs/nfs/threads", O_WRONLY);
163 /* 2.5+ kernel with nfsd filesystem mounted.
164 * Just write the number in.
165 * Cannot handle port number yet, but does anyone care?
169 snprintf(buf, 20,"%d\n", nrservs);
170 n = write(fd, buf, strlen(buf));
172 if (n != strlen(buf))
178 arg.ca_version = NFSCTL_VERSION;
179 arg.ca_svc.svc_nthreads = nrservs;
180 arg.ca_svc.svc_port = port;
181 return nfsctl(NFSCTL_SVC, &arg, NULL);