X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=support%2Fnfs%2Fnfssvc.c;h=a6ea410226f193d5f22def299ff9d9a57914682a;hp=c51ace18ea078c223aa597afb4637b9fbd1663a1;hb=49b164d978ee6266df7ba0bd335cb34337e7c381;hpb=fde2ae7794047a698feeaf17963d690a1e660a80 diff --git a/support/nfs/nfssvc.c b/support/nfs/nfssvc.c index c51ace1..a6ea410 100644 --- a/support/nfs/nfssvc.c +++ b/support/nfs/nfssvc.c @@ -10,13 +10,97 @@ #include #endif +#include +#include +#include #include #include #include #include + #include "nfslib.h" +#define NFSD_PORTS_FILE "/proc/fs/nfsd/portlist" +#define NFSD_VERS_FILE "/proc/fs/nfsd/versions" +#define NFSD_THREAD_FILE "/proc/fs/nfsd/threads" + +static void +nfssvc_setfds(int port, unsigned int ctlbits, char *haddr) +{ + int fd, on=1; + char buf[BUFSIZ]; + int udpfd = -1, tcpfd = -1; + struct sockaddr_in sin; + + fd = open(NFSD_PORTS_FILE, O_WRONLY); + if (fd < 0) + return; + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr.s_addr = inet_addr(haddr); + + if (NFSCTL_UDPISSET(ctlbits)) { + udpfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (udpfd < 0) { + syslog(LOG_ERR, "nfssvc: unable to create UPD socket: " + "errno %d (%s)\n", errno, strerror(errno)); + exit(1); + } + if (bind(udpfd, (struct sockaddr *)&sin, sizeof(sin)) < 0){ + syslog(LOG_ERR, "nfssvc: unable to bind UPD socket: " + "errno %d (%s)\n", errno, strerror(errno)); + exit(1); + } + } + + if (NFSCTL_TCPISSET(ctlbits)) { + tcpfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (tcpfd < 0) { + syslog(LOG_ERR, "nfssvc: unable to createt tcp socket: " + "errno %d (%s)\n", errno, strerror(errno)); + exit(1); + } + if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { + syslog(LOG_ERR, "nfssvc: unable to set SO_REUSEADDR: " + "errno %d (%s)\n", errno, strerror(errno)); + exit(1); + } + if (bind(tcpfd, (struct sockaddr *)&sin, sizeof(sin)) < 0){ + syslog(LOG_ERR, "nfssvc: unable to bind TCP socket: " + "errno %d (%s)\n", errno, strerror(errno)); + exit(1); + } + if (listen(tcpfd, 64) < 0){ + syslog(LOG_ERR, "nfssvc: unable to create listening socket: " + "errno %d (%s)\n", errno, strerror(errno)); + exit(1); + } + } + if (udpfd >= 0) { + snprintf(buf, BUFSIZ,"%d\n", udpfd); + if (write(fd, buf, strlen(buf)) != strlen(buf)) { + syslog(LOG_ERR, + "nfssvc: writting fds to kernel failed: errno %d (%s)", + errno, strerror(errno)); + } + close(fd); + fd = -1; + } + if (tcpfd >= 0) { + if (fd < 0) + fd = open(NFSD_PORTS_FILE, O_WRONLY); + snprintf(buf, BUFSIZ,"%d\n", tcpfd); + if (write(fd, buf, strlen(buf)) != strlen(buf)) { + syslog(LOG_ERR, + "nfssvc: writting fds to kernel failed: errno %d (%s)", + errno, strerror(errno)); + } + } + close(fd); + + return; +} static void nfssvc_versbits(unsigned int ctlbits) { @@ -25,7 +109,7 @@ nfssvc_versbits(unsigned int ctlbits) ptr = buf; off = 0; - fd = open("/proc/fs/nfsd/versions", O_WRONLY); + fd = open(NFSD_VERS_FILE, O_WRONLY); if (fd < 0) return; @@ -45,14 +129,17 @@ nfssvc_versbits(unsigned int ctlbits) return; } int -nfssvc(int port, int nrservs, unsigned int versbits) +nfssvc(int port, int nrservs, unsigned int versbits, unsigned protobits, + char *haddr) { struct nfsctl_arg arg; int fd; + nfssvc_setfds(port, protobits, haddr); + nfssvc_versbits(versbits); - fd = open("/proc/fs/nfsd/threads", O_WRONLY); + fd = open(NFSD_THREAD_FILE, O_WRONLY); if (fd < 0) fd = open("/proc/fs/nfs/threads", O_WRONLY); if (fd >= 0) {