diff options
Diffstat (limited to 'support')
-rw-r--r-- | support/include/conn.h | 3 | ||||
-rw-r--r-- | support/include/nfs/nfs.h | 11 | ||||
-rw-r--r-- | support/include/nfslib.h | 2 | ||||
-rw-r--r-- | support/misc/mountpoint.c | 19 | ||||
-rw-r--r-- | support/nfs/cacheio.c | 6 | ||||
-rw-r--r-- | support/nfs/conn.c | 13 | ||||
-rw-r--r-- | support/nfs/nfssvc.c | 122 | ||||
-rw-r--r-- | support/nfs/svc_socket.c | 2 | ||||
-rw-r--r-- | support/nfs/xio.c | 12 |
9 files changed, 166 insertions, 24 deletions
diff --git a/support/include/conn.h b/support/include/conn.h index ae19a3e..1761dc4 100644 --- a/support/include/conn.h +++ b/support/include/conn.h @@ -31,7 +31,8 @@ typedef struct { static const struct timeval TIMEOUT = { 20, 0 }; static const struct timeval RETRY_TIMEOUT = { 3, 0 }; -int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int); +int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int, + struct sockaddr_in *); u_long nfsvers_to_mnt(const u_long); u_long mntvers_to_nfs(const u_long); int get_socket(struct sockaddr_in *, u_int, int); diff --git a/support/include/nfs/nfs.h b/support/include/nfs/nfs.h index c7fc42c..f0286b2 100644 --- a/support/include/nfs/nfs.h +++ b/support/include/nfs/nfs.h @@ -10,6 +10,9 @@ #define NFS3_FHSIZE 64 #define NFS_FHSIZE 32 +#define NFSD_MINVERS 2 +#define NFSD_MAXVERS 4 + struct nfs_fh_len { int fh_size; u_int8_t fh_handle[NFS3_FHSIZE]; @@ -40,7 +43,15 @@ struct nfs_fh_old { #define NFSCTL_LOCKD 0x10000 #define LOCKDCTL_SVC NFSCTL_LOCKD +#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1))) +#define NFSCTL_UDPUNSET(_cltbits) ((_cltbits) &= ~(1 << (17 - 1))) +#define NFSCTL_TCPUNSET(_cltbits) ((_cltbits) &= ~(1 << (18 - 1))) + +#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1))) +#define NFSCTL_UDPISSET(_cltbits) ((_cltbits) & (1 << (17 - 1))) +#define NFSCTL_TCPISSET(_cltbits) ((_cltbits) & (1 << (18 - 1))) +#define NFSCTL_ALLBITS (~0) /* SVC */ struct nfsctl_svc { diff --git a/support/include/nfslib.h b/support/include/nfslib.h index 8c83262..3e25761 100644 --- a/support/include/nfslib.h +++ b/support/include/nfslib.h @@ -120,7 +120,7 @@ int wildmat(char *text, char *pattern); * nfsd library functions. */ int nfsctl(int, struct nfsctl_arg *, union nfsctl_res *); -int nfssvc(int port, int nrservs); +int nfssvc(int port, int nrservs, unsigned int versbits, unsigned int portbits, char *haddr); int nfsaddclient(struct nfsctl_client *clp); int nfsdelclient(struct nfsctl_client *clp); int nfsexport(struct nfsctl_export *exp); diff --git a/support/misc/mountpoint.c b/support/misc/mountpoint.c index 6d0f34e..750b6e8 100644 --- a/support/misc/mountpoint.c +++ b/support/misc/mountpoint.c @@ -20,15 +20,20 @@ is_mountpoint(char *path) */ char *dotdot; struct stat stb, pstb; + int rv; + + dotdot = xmalloc(strlen(path)+4); - dotdot = malloc(strlen(path)+4); strcat(strcpy(dotdot, path), "/.."); if (lstat(path, &stb) != 0 || lstat(dotdot, &pstb) != 0) - return 0; - - if (stb.st_dev != pstb.st_dev - || stb.st_ino == pstb.st_ino) - return 1; - return 0; + rv = 0; + else + if (stb.st_dev != pstb.st_dev || + stb.st_ino == pstb.st_ino) + rv = 1; + else + rv = 0; + free(dotdot); + return rv; } diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c index d7ad429..3e868d8 100644 --- a/support/nfs/cacheio.c +++ b/support/nfs/cacheio.c @@ -259,9 +259,9 @@ cache_flush(int force) "nfsd.export", NULL }; - stb.st_mtime = time(0); - if (!force) - stat(_PATH_ETAB, &stb); + if (force || + stat(_PATH_ETAB, &stb) != 0) + stb.st_mtime = time(0); sprintf(stime, "%ld\n", stb.st_mtime); for (c=0; cachelist[c]; c++) { diff --git a/support/nfs/conn.c b/support/nfs/conn.c index bf2afad..733bf24 100644 --- a/support/nfs/conn.c +++ b/support/nfs/conn.c @@ -93,7 +93,7 @@ int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp) return RPC_ANYSOCK; } } - if (type == SOCK_STREAM) { + if (type == SOCK_STREAM || type == SOCK_DGRAM) { cc = connect(so, (struct sockaddr *)saddr, namelen); if (cc < 0) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; @@ -119,7 +119,7 @@ int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp) */ int clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers, - const u_int prot) + const u_int prot, struct sockaddr_in *caddr) { CLIENT *clnt=NULL; int sock, stat; @@ -161,8 +161,15 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers, rpc_createerr.cf_stat = stat; } clnt_destroy(clnt); - if (sock != -1) + if (sock != -1) { + if (caddr) { + /* Get the address of our end of this connection */ + int len = sizeof(*caddr); + if (getsockname(sock, caddr, &len) != 0) + caddr->sin_family = 0; + } close(sock); + } if (stat == RPC_SUCCESS) return 1; diff --git a/support/nfs/nfssvc.c b/support/nfs/nfssvc.c index 38240a0..a6ea410 100644 --- a/support/nfs/nfssvc.c +++ b/support/nfs/nfssvc.c @@ -10,18 +10,136 @@ #include <config.h> #endif +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include <unistd.h> #include <fcntl.h> +#include <errno.h> +#include <syslog.h> + #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) +{ + int fd, n, off; + char buf[BUFSIZ], *ptr; + + ptr = buf; + off = 0; + fd = open(NFSD_VERS_FILE, O_WRONLY); + if (fd < 0) + return; + + for (n = NFSD_MINVERS; n <= NFSD_MAXVERS; n++) { + if (NFSCTL_VERISSET(ctlbits, n)) + off += snprintf(ptr+off, BUFSIZ - off, "+%d ", n); + else + off += snprintf(ptr+off, BUFSIZ - off, "-%d ", n); + } + snprintf(ptr+off, BUFSIZ - off, "\n"); + if (write(fd, buf, strlen(buf)) != strlen(buf)) { + syslog(LOG_ERR, "nfssvc: Setting version failed: errno %d (%s)", + errno, strerror(errno)); + } + close(fd); + + return; +} int -nfssvc(int port, int nrservs) +nfssvc(int port, int nrservs, unsigned int versbits, unsigned protobits, + char *haddr) { struct nfsctl_arg arg; int fd; - fd = open("/proc/fs/nfsd/threads", O_WRONLY); + nfssvc_setfds(port, protobits, haddr); + + nfssvc_versbits(versbits); + + fd = open(NFSD_THREAD_FILE, O_WRONLY); if (fd < 0) fd = open("/proc/fs/nfs/threads", O_WRONLY); if (fd >= 0) { diff --git a/support/nfs/svc_socket.c b/support/nfs/svc_socket.c index 888c915..c41a1a3 100644 --- a/support/nfs/svc_socket.c +++ b/support/nfs/svc_socket.c @@ -42,7 +42,7 @@ svc_socket (u_long number, int type, int protocol, int reuse) socklen_t len = sizeof (struct sockaddr_in); char rpcdata [1024], servdata [1024]; struct rpcent rpcbuf, *rpcp; - struct servent servbuf, *servp; + struct servent servbuf, *servp = NULL; int sock, ret; const char *proto = protocol == IPPROTO_TCP ? "tcp" : "udp"; diff --git a/support/nfs/xio.c b/support/nfs/xio.c index 1ce5157..221cce6 100644 --- a/support/nfs/xio.c +++ b/support/nfs/xio.c @@ -95,11 +95,6 @@ xgettok(XFILE *xfp, char sepa, char *tok, int len) while (i < len && (c = xgetc(xfp)) != EOF && (quoted || (c != sepa && !isspace(c)))) { - if (!quoted && i == 0 && c == '#') { - c = xskipcomment(xfp); - xfp->x_line++; - break; - } if (c == '"') { quoted = !quoted; continue; @@ -164,7 +159,12 @@ xskip(XFILE *xfp, char *str) { int c; - while ((c = xgetc(xfp)) != EOF && strchr(str, c)); + while ((c = xgetc(xfp)) != EOF) { + if (c == '#') + c = xskipcomment(xfp); + if (strchr(str, c) == NULL) + break; + } xungetc(c, xfp); } |