From c2db41e8abb6ddc9d03a0c91c6db043fa0f85a8f Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Fri, 23 Jun 2006 13:37:08 +1000 Subject: Try to make sure that clientid used for NFSv4 is reliable. We need to give an IP address to identify this client to the server. The current code does a gethostbyname of the hostname. One some systems this returns 127.0.0.1 or similar, which is not useful. Instead, use getsockname of the sock used to connect to the server to confirm that the server is working. This gives the address on the interface that was chosen to talk to that server, which is the best address we can find (if there is a NAT in the way, it might still not work, but in that case there is nothing we can do). --- support/include/conn.h | 3 ++- support/nfs/conn.c | 13 ++++++++++--- utils/mount/nfs4mount.c | 18 +++++++++++++++--- utils/mount/nfsmount.c | 2 +- 4 files changed, 28 insertions(+), 8 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/nfs/conn.c b/support/nfs/conn.c index a020394..5160c8b 100644 --- a/support/nfs/conn.c +++ b/support/nfs/conn.c @@ -92,7 +92,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; @@ -118,7 +118,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; @@ -160,8 +160,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/utils/mount/nfs4mount.c b/utils/mount/nfs4mount.c index b59c27c..717ad56 100644 --- a/utils/mount/nfs4mount.c +++ b/utils/mount/nfs4mount.c @@ -189,9 +189,10 @@ int nfs4mount(const char *spec, const char *node, int *flags, static struct nfs4_mount_data data; static char hostdir[1024]; static char ip_addr[16] = "127.0.0.1"; - static struct sockaddr_in server_addr; + static struct sockaddr_in server_addr, client_addr; static int pseudoflavour[MAX_USER_FLAVOUR]; int num_flavour = 0; + int ip_addr_in_opts = 0; char *hostname, *dirname, *old_opts; char new_opts[1024]; @@ -302,6 +303,7 @@ int nfs4mount(const char *spec, const char *node, int *flags, opteq+1); strncpy(ip_addr,opteq+1, sizeof(ip_addr)); ip_addr[sizeof(ip_addr)-1] = '\0'; + ip_addr_in_opts = 1; } else if (!strcmp(opt, "sec")) { num_flavour = parse_sec(opteq+1, pseudoflavour); if (!num_flavour) @@ -412,9 +414,19 @@ int nfs4mount(const char *spec, const char *node, int *flags, NFS_PROGRAM, 4, data.proto == IPPROTO_UDP ? "udp" : "tcp", ntohs(server_addr.sin_port)); } - clnt_ping(&server_addr, NFS_PROGRAM, 4, data.proto); - if (rpc_createerr.cf_stat == RPC_SUCCESS) + client_addr.sin_family = 0; + client_addr.sin_addr.s_addr = 0; + clnt_ping(&server_addr, NFS_PROGRAM, 4, data.proto, &client_addr); + if (rpc_createerr.cf_stat == RPC_SUCCESS) { + if (!ip_addr_in_opts && + client_addr.sin_family != 0 && + client_addr.sin_addr.s_addr != 0) { + snprintf(ip_addr, sizeof(ip_addr), "%s", + inet_ntoa(client_addr.sin_addr)); + data.client_addr.len = strlen(ip_addr); + } break; + } switch(rpc_createerr.cf_stat){ case RPC_TIMEDOUT: diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c index 1266660..2b1eb8c 100644 --- a/utils/mount/nfsmount.c +++ b/utils/mount/nfsmount.c @@ -376,7 +376,7 @@ probe_port(clnt_addr_t *server, inet_ntoa(saddr->sin_addr), prog, *p_vers, *p_prot == IPPROTO_UDP ? "udp" : "tcp", p_port); } - if (clnt_ping(saddr, prog, *p_vers, *p_prot)) + if (clnt_ping(saddr, prog, *p_vers, *p_prot, NULL)) goto out_ok; if (rpc_createerr.cf_stat == RPC_TIMEDOUT) goto out_bad; -- cgit From ceeffc1f76485b4084b2c61f4ff3c40e4f51c3b8 Mon Sep 17 00:00:00 2001 From: Amit Gud Date: Thu, 22 Jun 2006 12:49:24 -0400 Subject: Merge nfsmount.x and mount.x into mount.x Merge utils/mount/nfsmount.x and support/export/mount.x into support/export/mount.x. Signed-off-by: Amit Gud Signed-off-by: Steve Dickson --- utils/mount/Makefile.am | 38 +----- utils/mount/mount.c | 2 +- utils/mount/nfsmount.c | 10 +- utils/mount/nfsmount.x | 336 ------------------------------------------------ utils/mount/nfsumount.c | 2 +- utils/mount/nfsumount.h | 2 +- 6 files changed, 11 insertions(+), 379 deletions(-) delete mode 100644 utils/mount/nfsmount.x diff --git a/utils/mount/Makefile.am b/utils/mount/Makefile.am index 3ed0ace..4a2f437 100644 --- a/utils/mount/Makefile.am +++ b/utils/mount/Makefile.am @@ -2,48 +2,16 @@ man8_MANS = mount.nfs.man umount.nfs.man -RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen - -GENFILES_CLNT = nfsmount_clnt.c -GENFILES_XDR = nfsmount_xdr.c -GENFILES_H = nfsmount.h - -GENFILES = $(GENFILES_CLNT) $(GENFILES_XDR) $(GENFILES_H) - sbin_PROGRAMS = mount.nfs EXTRA_DIST = nfsmount.x $(man8_MANS) mount_nfs_SOURCES = mount.c nfsmount.c nfs4mount.c nfsumount.c \ - nfsmount_xdr.c mount_constants.h nfs4_mount.h nfsmount.h \ - nfs_mount4.h - -BUILT_SOURCES = $(GENFILES) -mount_nfs_LDADD = ../../support/nfs/libnfs.a - - -$(RPCGEN): - make -C ../../tools/rpcgen all - -$(GENFILES_CLNT): %_clnt.c: %.x $(RPCGEN) - test -f $@ && rm -rf $@ || true - $(RPCGEN) -l -o $@ $< - -$(GENFILES_SVC): %_svc.c: %.x $(RPCGEN) - test -f $@ && rm -rf $@ || true - $(RPCGEN) -m -o $@ $< - -$(GENFILES_XDR): %_xdr.c: %.x $(RPCGEN) - test -f $@ && rm -rf $@ || true - $(RPCGEN) -c -o $@ $< - -$(GENFILES_H): %.h: %.x $(RPCGEN) - test -f $@ && rm -rf $@ || true - $(RPCGEN) -h -o $@ $< + mount_constants.h nfs4_mount.h nfs_mount4.h +mount_nfs_LDADD = ../../support/nfs/libnfs.a \ + ../../support/export/libexport.a MAINTAINERCLEANFILES = Makefile.in -CLEANFILES = $(GENFILES) - install-exec-hook: (cd $(DESTDIR)$(sbindir) && \ ln -sf $(sbin_PROGRAMS) mount.nfs4 && \ diff --git a/utils/mount/mount.c b/utils/mount/mount.c index 270a179..ca87e3d 100644 --- a/utils/mount/mount.c +++ b/utils/mount/mount.c @@ -37,7 +37,7 @@ #include "nfs_mount.h" #include "nfs4_mount.h" #include "nfsumount.h" -#include "nfsmount.h" +#include "mount.h" char *progname; int nomtab; diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c index 2b1eb8c..507ccdb 100644 --- a/utils/mount/nfsmount.c +++ b/utils/mount/nfsmount.c @@ -59,7 +59,7 @@ #include "conn.h" #include "xcommon.h" -#include "nfsmount.h" +#include "mount.h" #include "nfsumount.h" #include "nfs_mount.h" #include "mount_constants.h" @@ -1084,11 +1084,11 @@ nfsmount(const char *spec, const char *node, int *flags, } #if NFS_MOUNT_VERSION >= 5 mountres = &mntres.nfsv3.mountres3_u.mountinfo; - i = mountres->auth_flavours.auth_flavours_len; + i = mountres->auth_flavors.auth_flavors_len; if (i <= 0) - goto noauth_flavours; + goto noauth_flavors; - flavor = mountres->auth_flavours.auth_flavours_val; + flavor = mountres->auth_flavors.auth_flavors_val; while (--i >= 0) { if (flavor[i] == data.pseudoflavor) yum = 1; @@ -1106,7 +1106,7 @@ nfsmount(const char *spec, const char *node, int *flags, nfs_call_umount(&mnt_server, &dirname); goto fail; } -noauth_flavours: +noauth_flavors: #endif fhandle = &mntres.nfsv3.mountres3_u.mountinfo.fhandle; memset(data.old_root.data, 0, NFS_FHSIZE); diff --git a/utils/mount/nfsmount.x b/utils/mount/nfsmount.x deleted file mode 100644 index ad4bf99..0000000 --- a/utils/mount/nfsmount.x +++ /dev/null @@ -1,336 +0,0 @@ -%/* -% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for -% * unrestricted use provided that this legend is included on all tape -% * media and as a part of the software program in whole or part. Users -% * may copy or modify Sun RPC without charge, but are not authorized -% * to license or distribute it to anyone else except as part of a product or -% * program developed by the user or with the express written consent of -% * Sun Microsystems, Inc. -% * -% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE -% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR -% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. -% * -% * Sun RPC is provided with no support and without any obligation on the -% * part of Sun Microsystems, Inc. to assist in its use, correction, -% * modification or enhancement. -% * -% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE -% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC -% * OR ANY PART THEREOF. -% * -% * In no event will Sun Microsystems, Inc. be liable for any lost revenue -% * or profits or other special, indirect and consequential damages, even if -% * Sun has been advised of the possibility of such damages. -% * -% * Sun Microsystems, Inc. -% * 2550 Garcia Avenue -% * Mountain View, California 94043 -% */ - -%/* -% * Copyright (c) 1985, 1990 by Sun Microsystems, Inc. -% */ -% -%/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */ - -/* - * Protocol description for the mount program - */ - -#ifdef RPC_HDR -%#ifndef _rpcsvc_mount_h -%#define _rpcsvc_mount_h -#endif - -#ifdef RPC_CLNT -%#include /* for memset() */ -#endif -%#include - -const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */ -const MNTNAMLEN = 255; /* maximum bytes in a name argument */ -const FHSIZE = 32; /* size in bytes of a file handle */ -const FHSIZE3 = 64; /* size in bytes of a file handle */ - -/* - * The fhandle is the file handle that the server passes to the client. - * All file operations are done using the file handles to refer to a file - * or a directory. The file handle can contain whatever information the - * server needs to distinguish an individual file. - */ -typedef opaque fhandle[FHSIZE]; -typedef opaque fhandle3; - -enum mountstat3 { - MNT_OK = 0, /* no error */ - MNT3ERR_PERM = 1, /* not owner */ - MNT3ERR_NOENT = 2, /* No such file or directory */ - MNT3ERR_IO = 5, /* I/O error */ - MNT3ERR_ACCES = 13, /* Permission denied */ - MNT3ERR_NOTDIR = 20, /* Not a directory */ - MNT3ERR_INVAL = 22, /* Invalid argument */ - MNT3ERR_NAMETOOLONG = 63, /* File name too long */ - MNT3ERR_NOTSUPP = 10004, /* Operation not supported */ - MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */ -}; - -/* - * If a status of zero is returned, the call completed successfully, and - * a file handle for the directory follows. A non-zero status indicates - * some sort of error. The status corresponds with UNIX error numbers. - */ -union fhstatus switch (unsigned fhs_status) { -case 0: - fhandle fhs_fhandle; -default: - void; -}; - -struct mountres3_ok { - fhandle3 fhandle; - int auth_flavours<>; -}; - -union mountres3 switch (mountstat3 fhs_status) { -case MNT_OK: - mountres3_ok mountinfo; -default: - void; -}; - -/* - * The type dirpath is the pathname of a directory - */ -typedef string dirpath; - -/* - * The type name is used for arbitrary names (hostnames, groupnames) - */ -typedef string name; - -/* - * A list of who has what mounted - */ -typedef struct mountbody *mountlist; -struct mountbody { - name ml_hostname; - dirpath ml_directory; - mountlist ml_next; -}; - -/* - * A list of netgroups - */ -typedef struct groupnode *groups; -struct groupnode { - name gr_name; - groups gr_next; -}; - -/* - * A list of what is exported and to whom - */ -typedef struct exportnode *exports; -struct exportnode { - dirpath ex_dir; - groups ex_groups; - exports ex_next; -}; - -/* - * POSIX pathconf information - */ -struct ppathcnf { - int pc_link_max; /* max links allowed */ - short pc_max_canon; /* max line len for a tty */ - short pc_max_input; /* input a tty can eat all at once */ - short pc_name_max; /* max file name length (dir entry) */ - short pc_path_max; /* max path name length (/x/y/x/.. ) */ - short pc_pipe_buf; /* size of a pipe (bytes) */ - u_char pc_vdisable; /* safe char to turn off c_cc[i] */ - char pc_xxx; /* alignment padding; cc_t == char */ - short pc_mask[2]; /* validity and boolean bits */ -}; - -program MOUNTPROG { - /* - * Version one of the mount protocol communicates with version two - * of the NFS protocol. The only connecting point is the fhandle - * structure, which is the same for both protocols. - */ - version MOUNTVERS { - /* - * Does no work. It is made available in all RPC services - * to allow server reponse testing and timing - */ - void - MOUNTPROC_NULL(void) = 0; - - /* - * If fhs_status is 0, then fhs_fhandle contains the - * file handle for the directory. This file handle may - * be used in the NFS protocol. This procedure also adds - * a new entry to the mount list for this client mounting - * the directory. - * Unix authentication required. - */ - fhstatus - MOUNTPROC_MNT(dirpath) = 1; - - /* - * Returns the list of remotely mounted filesystems. The - * mountlist contains one entry for each hostname and - * directory pair. - */ - mountlist - MOUNTPROC_DUMP(void) = 2; - - /* - * Removes the mount list entry for the directory - * Unix authentication required. - */ - void - MOUNTPROC_UMNT(dirpath) = 3; - - /* - * Removes all of the mount list entries for this client - * Unix authentication required. - */ - void - MOUNTPROC_UMNTALL(void) = 4; - - /* - * Returns a list of all the exported filesystems, and which - * machines are allowed to import it. - */ - exports - MOUNTPROC_EXPORT(void) = 5; - - /* - * Identical to MOUNTPROC_EXPORT above - */ - exports - MOUNTPROC_EXPORTALL(void) = 6; - } = 1; - - /* - * Version two of the mount protocol communicates with version two - * of the NFS protocol. - * The only difference from version one is the addition of a POSIX - * pathconf call. - */ - version MOUNTVERS_POSIX { - /* - * Does no work. It is made available in all RPC services - * to allow server reponse testing and timing - */ - void - MOUNTPROC_NULL(void) = 0; - - /* - * If fhs_status is 0, then fhs_fhandle contains the - * file handle for the directory. This file handle may - * be used in the NFS protocol. This procedure also adds - * a new entry to the mount list for this client mounting - * the directory. - * Unix authentication required. - */ - fhstatus - MOUNTPROC_MNT(dirpath) = 1; - - /* - * Returns the list of remotely mounted filesystems. The - * mountlist contains one entry for each hostname and - * directory pair. - */ - mountlist - MOUNTPROC_DUMP(void) = 2; - - /* - * Removes the mount list entry for the directory - * Unix authentication required. - */ - void - MOUNTPROC_UMNT(dirpath) = 3; - - /* - * Removes all of the mount list entries for this client - * Unix authentication required. - */ - void - MOUNTPROC_UMNTALL(void) = 4; - - /* - * Returns a list of all the exported filesystems, and which - * machines are allowed to import it. - */ - exports - MOUNTPROC_EXPORT(void) = 5; - - /* - * Identical to MOUNTPROC_EXPORT above - */ - exports - MOUNTPROC_EXPORTALL(void) = 6; - - /* - * POSIX pathconf info (Sun hack) - */ - ppathcnf - MOUNTPROC_PATHCONF(dirpath) = 7; - } = 2; - version MOUNT_V3 { - /* - * Does no work. It is made available in all RPC services - * to allow server reponse testing and timing - */ - void - MOUNTPROC3_NULL(void) = 0; - - /* - * If fhs_status is 0, then fhs_fhandle contains the - * file handle for the directory. This file handle may - * be used in the NFS protocol. This procedure also adds - * a new entry to the mount list for this client mounting - * the directory. - * Unix authentication required. - */ - mountres3 - MOUNTPROC3_MNT(dirpath) = 1; - - /* - * Returns the list of remotely mounted filesystems. The - * mountlist contains one entry for each hostname and - * directory pair. - */ - mountlist - MOUNTPROC3_DUMP(void) = 2; - - /* - * Removes the mount list entry for the directory - * Unix authentication required. - */ - void - MOUNTPROC3_UMNT(dirpath) = 3; - - /* - * Removes all of the mount list entries for this client - * Unix authentication required. - */ - void - MOUNTPROC3_UMNTALL(void) = 4; - - /* - * Returns a list of all the exported filesystems, and which - * machines are allowed to import it. - */ - exports - MOUNTPROC3_EXPORT(void) = 5; - - } = 3; -} = 100005; - -#ifdef RPC_HDR -%#endif /*!_rpcsvc_mount_h*/ -#endif diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c index d1d476a..28f4244 100644 --- a/utils/mount/nfsumount.c +++ b/utils/mount/nfsumount.c @@ -30,7 +30,7 @@ #include "conn.h" #include "mount_constants.h" -#include "nfsmount.h" +#include "mount.h" #include "nfsumount.h" #if !defined(MNT_FORCE) diff --git a/utils/mount/nfsumount.h b/utils/mount/nfsumount.h index c089275..e37eaff 100644 --- a/utils/mount/nfsumount.h +++ b/utils/mount/nfsumount.h @@ -2,7 +2,7 @@ #define _NFS_UMOUNT_H #include "conn.h" -#include "nfsmount.h" +#include "mount.h" int nfsumount(int, char **); int nfs_call_umount(clnt_addr_t *, dirpath *); -- cgit From bec968578d97eabc63ae4a12bdeb2b33f40baec4 Mon Sep 17 00:00:00 2001 From: Amit Gud Date: Thu, 22 Jun 2006 12:51:04 -0400 Subject: Change mount configure option to --enable-mount Change the configure option from --with-mount to --enable-mount. Signed-off-by: Amit Gud Signed-off-by: Steve Dickson --- configure.in | 12 ++++++------ utils/Makefile.am | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/configure.in b/configure.in index 5eb1d79..a136fd7 100644 --- a/configure.in +++ b/configure.in @@ -107,12 +107,12 @@ AC_ARG_ENABLE(rquotad, fi AM_CONDITIONAL(CONFIG_RQUOTAD, [test "$enable_rquotad" = "yes"]) -AC_ARG_WITH(mount, - [AC_HELP_STRING([--without-mount], - [Create mount.nfs and do not use the util-linux mount(8) functionality. By default it doesn't.])], - use_mount=$withval, - use_mount=yes) - AM_CONDITIONAL(CONFIG_NOMOUNT, [test "$use_mount" = "no"]) +AC_ARG_ENABLE(mount, + [AC_HELP_STRING([--enable-mount], + [Create mount.nfs and don't use the util-linux mount(8) functionality. @<:@default=yes@:>@])], + enable_mount=$enableval, + enable_mount=yes) + AM_CONDITIONAL(CONFIG_MOUNT, [test "$enable_mount" = "yes"]) # Check whether user wants TCP wrappers support AC_TCP_WRAPPERS diff --git a/utils/Makefile.am b/utils/Makefile.am index 259bec3..9cdb4ea 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -14,7 +14,7 @@ if CONFIG_GSS OPTDIRS += gssd endif -if CONFIG_NOMOUNT +if CONFIG_MOUNT OPTDIRS += mount endif -- cgit From ff42180930a444cea7f19e55e2cd2bfe6d3f108b Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Fri, 23 Jun 2006 14:06:00 +1000 Subject: Fix comment parsing (again) Bruce Fields noticed that I broke comment parsing... as xskip() is always called before xgettok(), that is the best place to put xskipcomment and still maintain proper semantics of xskip and xgettok. --- support/nfs/xio.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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); } -- cgit From 2e075a16da4963f54cd556403ca9e15a68de27fd Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Fri, 23 Jun 2006 14:38:33 +1000 Subject: Fix various issues discovered by Coverity Thanks to Michael Halcrow for finding them. --- support/misc/mountpoint.c | 18 ++++++++++++------ support/nfs/cacheio.c | 6 +++--- support/nfs/svc_socket.c | 2 +- tools/rpcgen/rpc_parse.c | 11 +---------- tools/rpcgen/rpc_scan.c | 1 + utils/idmapd/cfg.c | 10 +++++++--- utils/idmapd/idmapd.c | 8 +++++--- utils/rquotad/rquota_server.c | 3 ++- utils/statd/notlist.c | 6 +++++- 9 files changed, 37 insertions(+), 28 deletions(-) diff --git a/support/misc/mountpoint.c b/support/misc/mountpoint.c index 6d0f34e..2cf1324 100644 --- a/support/misc/mountpoint.c +++ b/support/misc/mountpoint.c @@ -20,15 +20,21 @@ is_mountpoint(char *path) */ char *dotdot; struct stat stb, pstb; + int rv; dotdot = malloc(strlen(path)+4); + if (!dotdot) + return 0; 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/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/tools/rpcgen/rpc_parse.c b/tools/rpcgen/rpc_parse.c index 577312e..70d1260 100644 --- a/tools/rpcgen/rpc_parse.c +++ b/tools/rpcgen/rpc_parse.c @@ -94,6 +94,7 @@ get_definition(void) def_const(defp); break; case TOK_EOF: + free(defp); return (NULL); default: error("definition keyword expected"); @@ -290,7 +291,6 @@ def_union(definition *defp) declaration dec; case_list *cases; case_list **tailp; - int flag; defp->def_kind = DEF_UNION; scan(TOK_IDENT, &tok); @@ -309,7 +309,6 @@ def_union(definition *defp) cases->case_name = tok.str; scan(TOK_COLON, &tok); /* now peek at next token */ - flag=0; if(peekscan(TOK_CASE,&tok)) { @@ -325,14 +324,6 @@ def_union(definition *defp) }while(peekscan(TOK_CASE,&tok)); } - else - if(flag) - { - - *tailp = cases; - tailp = &cases->next; - cases = ALLOC(case_list); - }; get_declaration(&dec, DEF_UNION); cases->case_decl = dec; diff --git a/tools/rpcgen/rpc_scan.c b/tools/rpcgen/rpc_scan.c index 62d906d..51eecfe 100644 --- a/tools/rpcgen/rpc_scan.c +++ b/tools/rpcgen/rpc_scan.c @@ -468,6 +468,7 @@ docppline(char *line, int *lineno, char **fname) *p = 0; if (*file == 0) { *fname = NULL; + free(file); } else { *fname = file; } diff --git a/utils/idmapd/cfg.c b/utils/idmapd/cfg.c index b22a7c9..16d392a 100644 --- a/utils/idmapd/cfg.c +++ b/utils/idmapd/cfg.c @@ -487,8 +487,10 @@ conf_get_list (char *section, char *tag) if (!node) goto cleanup; node->field = strdup (field); - if (!node->field) + if (!node->field) { + free(node); goto cleanup; + } TAILQ_INSERT_TAIL (&list->fields, node, link); } free (liststr); @@ -523,8 +525,10 @@ conf_get_tag_list (char *section) if (!node) goto cleanup; node->field = strdup (cb->tag); - if (!node->field) + if (!node->field) { + free(node); goto cleanup; + } TAILQ_INSERT_TAIL (&list->fields, node, link); } return list; @@ -708,7 +712,7 @@ conf_remove (int transaction, char *section, char *tag) return 0; fail: - if (node->section) + if (node && node->section) free (node->section); if (node) free (node); diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c index 158feaf..1231db4 100644 --- a/utils/idmapd/idmapd.c +++ b/utils/idmapd/idmapd.c @@ -1003,9 +1003,11 @@ mydaemon(int nochdir, int noclose) if (noclose == 0) { tempfd = open("/dev/null", O_RDWR); - dup2(tempfd, 0); - dup2(tempfd, 1); - dup2(tempfd, 2); + if (tempfd >= 0) { + dup2(tempfd, 0); + dup2(tempfd, 1); + dup2(tempfd, 2); + } closeall(3); } diff --git a/utils/rquotad/rquota_server.c b/utils/rquotad/rquota_server.c index 109c94e..e3715bd 100644 --- a/utils/rquotad/rquota_server.c +++ b/utils/rquotad/rquota_server.c @@ -201,7 +201,6 @@ getquota_rslt *getquotainfo(int flags, caddr_t *argp, struct svc_req *rqstp) free(qfpathname); continue; } - free(qfpathname); lseek(fd, (long) dqoff(id), L_SET); switch (read(fd, &dq_dqb, sizeof(struct dqblk))) { case 0:/* EOF */ @@ -215,6 +214,7 @@ getquota_rslt *getquotainfo(int flags, caddr_t *argp, struct svc_req *rqstp) break; default: /* ERROR */ close(fd); + free(qfpathname); continue; } close(fd); @@ -228,6 +228,7 @@ getquota_rslt *getquotainfo(int flags, caddr_t *argp, struct svc_req *rqstp) dqb.dqb_btime = dq_dqb.dqb_btime; dqb.dqb_itime = dq_dqb.dqb_itime; } + free(qfpathname); endmntent(fp); if (err && (flags & ACTIVE)) { diff --git a/utils/statd/notlist.c b/utils/statd/notlist.c index 4f52b1d..98aa6e2 100644 --- a/utils/statd/notlist.c +++ b/utils/statd/notlist.c @@ -61,8 +61,12 @@ nlist_new(char *my_name, char *mon_name, int state) NL_TIMES(new) = MAX_TRIES; NL_STATE(new) = state; if (!(NL_MY_NAME(new) = xstrdup(my_name)) - || !(NL_MON_NAME(new) = xstrdup(mon_name))) + || !(NL_MON_NAME(new) = xstrdup(mon_name))) { + if (NL_MY_NAME(new)) + free(NL_MY_NAME(new)); + free(new); return NULL; + } return new; } -- cgit From 0523fd513c6baa8dbf45d1a7afea2044262aeb3d Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Fri, 23 Jun 2006 17:10:56 +1000 Subject: Further coverity related cleanups. Greg Banks suggested some variations, particularly improved use of xmalloc/xstrdup functions. Thanks. --- support/misc/mountpoint.c | 5 ++--- utils/idmapd/idmapd.c | 7 +++++-- utils/statd/notlist.c | 12 +++--------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/support/misc/mountpoint.c b/support/misc/mountpoint.c index 2cf1324..750b6e8 100644 --- a/support/misc/mountpoint.c +++ b/support/misc/mountpoint.c @@ -22,9 +22,8 @@ is_mountpoint(char *path) struct stat stb, pstb; int rv; - dotdot = malloc(strlen(path)+4); - if (!dotdot) - return 0; + dotdot = xmalloc(strlen(path)+4); + strcat(strcpy(dotdot, path), "/.."); if (lstat(path, &stb) != 0 || lstat(dotdot, &pstb) != 0) diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c index 1231db4..5fc7811 100644 --- a/utils/idmapd/idmapd.c +++ b/utils/idmapd/idmapd.c @@ -1003,12 +1003,15 @@ mydaemon(int nochdir, int noclose) if (noclose == 0) { tempfd = open("/dev/null", O_RDWR); + if (tempfd < 0) + tempfd = open("/", O_RDONLY); if (tempfd >= 0) { dup2(tempfd, 0); dup2(tempfd, 1); dup2(tempfd, 2); - } - closeall(3); + closeall(3); + } else + closeall(0); } return; diff --git a/utils/statd/notlist.c b/utils/statd/notlist.c index 98aa6e2..b74d9df 100644 --- a/utils/statd/notlist.c +++ b/utils/statd/notlist.c @@ -54,19 +54,13 @@ nlist_new(char *my_name, char *mon_name, int state) { notify_list *new; - if (!(new = (notify_list *) xmalloc(sizeof(notify_list)))) - return NULL; + new = (notify_list *) xmalloc(sizeof(notify_list)); memset(new, 0, sizeof(*new)); NL_TIMES(new) = MAX_TRIES; NL_STATE(new) = state; - if (!(NL_MY_NAME(new) = xstrdup(my_name)) - || !(NL_MON_NAME(new) = xstrdup(mon_name))) { - if (NL_MY_NAME(new)) - free(NL_MY_NAME(new)); - free(new); - return NULL; - } + NL_MY_NAME(new) = xstrdup(my_name); + NL_MON_NAME(new) = xstrdup(mon_name); return new; } -- cgit From fde2ae7794047a698feeaf17963d690a1e660a80 Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Mon, 26 Jun 2006 15:23:19 +1000 Subject: Add support for suppressing different NFS versions. e.g. -N 2 means that NFSv2 won't be supported, just v3 and v4 (if the kernel supports them). --- support/include/nfs/nfs.h | 7 +++++++ support/include/nfslib.h | 2 +- support/nfs/nfssvc.c | 33 +++++++++++++++++++++++++++++++- utils/nfsd/nfsd.c | 48 +++++++++++++++++++++++++++++++++++++++-------- utils/nfsd/nfsd.man | 11 +++++++++-- 5 files changed, 89 insertions(+), 12 deletions(-) diff --git a/support/include/nfs/nfs.h b/support/include/nfs/nfs.h index c7fc42c..2cf6857 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,11 @@ struct nfs_fh_old { #define NFSCTL_LOCKD 0x10000 #define LOCKDCTL_SVC NFSCTL_LOCKD +#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1))) + +#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1))) +#define NFSCTL_ALLBITS (~0) /* SVC */ struct nfsctl_svc { diff --git a/support/include/nfslib.h b/support/include/nfslib.h index 8c83262..50892e2 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); int nfsaddclient(struct nfsctl_client *clp); int nfsdelclient(struct nfsctl_client *clp); int nfsexport(struct nfsctl_export *exp); diff --git a/support/nfs/nfssvc.c b/support/nfs/nfssvc.c index 38240a0..c51ace1 100644 --- a/support/nfs/nfssvc.c +++ b/support/nfs/nfssvc.c @@ -12,15 +12,46 @@ #include #include +#include +#include #include "nfslib.h" +static void +nfssvc_versbits(unsigned int ctlbits) +{ + int fd, n, off; + char buf[BUFSIZ], *ptr; + + ptr = buf; + off = 0; + fd = open("/proc/fs/nfsd/versions", 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) { struct nfsctl_arg arg; int fd; + nfssvc_versbits(versbits); + fd = open("/proc/fs/nfsd/threads", O_WRONLY); if (fd < 0) fd = open("/proc/fs/nfs/threads", O_WRONLY); diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c index 05506ee..fa6ee71 100644 --- a/utils/nfsd/nfsd.c +++ b/utils/nfsd/nfsd.c @@ -24,10 +24,18 @@ static void usage(const char *); +static struct option longopts[] = +{ + { "help", 0, 0, 'h' }, + { "no-nfs-version", 1, 0, 'N' }, + { NULL, 0, 0, 0 } +}; +unsigned int versbits = NFSCTL_ALLBITS; + int main(int argc, char **argv) { - int count = 1, c, error, port, fd; + int count = 1, c, error, port, fd, found_one; struct servent *ent; ent = getservbyname ("nfs", "udp"); @@ -36,7 +44,7 @@ main(int argc, char **argv) else port = 2049; - while ((c = getopt(argc, argv, "hp:P:")) != EOF) { + while ((c = getopt_long(argc, argv, "hN:p:P:", longopts, NULL)) != EOF) { switch(c) { case 'P': /* XXX for nfs-server compatibility */ case 'p': @@ -47,12 +55,36 @@ main(int argc, char **argv) usage(argv [0]); } break; + case 'N': + switch((c = atoi(optarg))) { + case 2: + case 3: + case 4: + NFSCTL_VERUNSET(versbits, c); + break; + default: + fprintf(stderr, "%c: Unsupported version\n", c); + exit(1); + } break; - case 'h': default: + fprintf(stderr, "Invalid argument: '%c'\n", c); + case 'h': usage(argv[0]); } } + /* + * Do some sanity checking, if the ctlbits are set + */ + found_one = 0; + for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) { + if (NFSCTL_VERISSET(versbits, c)) + found_one = 1; + } + if (!found_one) { + fprintf(stderr, "no version specified\n"); + exit(1); + } if (chdir(NFS_STATEDIR)) { fprintf(stderr, "%s: chdir(%s) failed: %s\n", @@ -69,7 +101,6 @@ main(int argc, char **argv) count = 1; } } - /* KLUDGE ALERT: Some kernels let nfsd kernel threads inherit open files from the program that spawns them (i.e. us). So close @@ -84,9 +115,9 @@ main(int argc, char **argv) } closeall(3); - if ((error = nfssvc(port, count)) < 0) { + openlog("nfsd", LOG_PID, LOG_DAEMON); + if ((error = nfssvc(port, count, versbits)) < 0) { int e = errno; - openlog("nfsd", LOG_PID, LOG_DAEMON); syslog(LOG_ERR, "nfssvc: %s", strerror(e)); closelog(); } @@ -97,7 +128,8 @@ main(int argc, char **argv) static void usage(const char *prog) { - fprintf(stderr, "usage:\n" - "%s nrservs\n", prog); + fprintf(stderr, "Usage:\n" + "%s [-p|-P|--port port] [-N|--no-nfs-version version ] nrservs\n", + prog); exit(2); } diff --git a/utils/nfsd/nfsd.man b/utils/nfsd/nfsd.man index a890ea6..d175d11 100644 --- a/utils/nfsd/nfsd.man +++ b/utils/nfsd/nfsd.man @@ -6,7 +6,7 @@ .SH NAME rpc.nfsd \- NFS server process .SH SYNOPSIS -.BI "/usr/sbin/rpc.nfsd [-p " port "] " nproc +.BI "/usr/sbin/rpc.nfsd [" options "]" " "nproc .SH DESCRIPTION The .B rpc.nfsd @@ -22,11 +22,18 @@ server provides an ancillary service needed to satisfy mount requests by NFS clients. .SH OPTIONS .TP -.BI \-p " port" +.B \-p " or " \-\-port port specify a diferent port to listen on for NFS requests. By default, .B rpc.nfsd will listen on port 2049. .TP +.B \-N " or " \-\-no-nfs-version vers +This option can be used to request that +.B rpc.nfsd +does not offer certain versions of NFS. The current version of +.B rpc.nfsd +can support both NFS version 2,3 and the newer version 4. +.TP .I nproc specify the number of NFS server threads. By default, just one thread is started. However, for optimum performance several threads -- cgit From 49b164d978ee6266df7ba0bd335cb34337e7c381 Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Mon, 3 Jul 2006 09:52:00 +1000 Subject: Allow rpc.nfsd to suppress tcp or udp, and listen on a specific address. -T - will suppressing listening for TCP connection. -U - will suppress UDP -H host - will only listen on that local address -p port - will listen on that port. This requires kernel patches which will hopefully be in 2.6.19 and possibly some earlier test and vendor kernels. --- support/include/nfs/nfs.h | 4 ++ support/include/nfslib.h | 2 +- support/nfs/nfssvc.c | 93 +++++++++++++++++++++++++++++++++++++++++++++-- utils/nfsd/nfsd.c | 47 ++++++++++++++++++++++-- utils/nfsd/nfsd.man | 21 +++++++++++ 5 files changed, 160 insertions(+), 7 deletions(-) diff --git a/support/include/nfs/nfs.h b/support/include/nfs/nfs.h index 2cf6857..f0286b2 100644 --- a/support/include/nfs/nfs.h +++ b/support/include/nfs/nfs.h @@ -44,8 +44,12 @@ struct nfs_fh_old { #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) diff --git a/support/include/nfslib.h b/support/include/nfslib.h index 50892e2..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, unsigned int versbits); +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/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) { diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c index fa6ee71..d0bbfb3 100644 --- a/utils/nfsd/nfsd.c +++ b/utils/nfsd/nfsd.c @@ -20,23 +20,35 @@ #include #include #include +#include +#include +#include + #include "nfslib.h" static void usage(const char *); static struct option longopts[] = { + { "host", 1, 0, 'H' }, { "help", 0, 0, 'h' }, { "no-nfs-version", 1, 0, 'N' }, + { "no-tcp", 0, 0, 'T' }, + { "no-udp", 0, 0, 'U' }, + { "port", 1, 0, 'P' }, + { "port", 1, 0, 'p' }, { NULL, 0, 0, 0 } }; +unsigned int protobits = NFSCTL_ALLBITS; unsigned int versbits = NFSCTL_ALLBITS; +char *haddr = NULL; int main(int argc, char **argv) { int count = 1, c, error, port, fd, found_one; struct servent *ent; + struct hostent *hp; ent = getservbyname ("nfs", "udp"); if (ent != NULL) @@ -44,8 +56,19 @@ main(int argc, char **argv) else port = 2049; - while ((c = getopt_long(argc, argv, "hN:p:P:", longopts, NULL)) != EOF) { + while ((c = getopt_long(argc, argv, "H:hN:p:P:TU", longopts, NULL)) != EOF) { switch(c) { + case 'H': + if (inet_addr(optarg) != INADDR_NONE) { + haddr = strdup(optarg); + } else if ((hp = gethostbyname(optarg)) != NULL) { + haddr = inet_ntoa((*(struct in_addr*)(hp->h_addr_list[0]))); + } else { + fprintf(stderr, "%s: Unknown hostname: %s\n", + argv[0], optarg); + usage(argv [0]); + } + break; case 'P': /* XXX for nfs-server compatibility */ case 'p': port = atoi(optarg); @@ -67,6 +90,12 @@ main(int argc, char **argv) exit(1); } break; + case 'T': + NFSCTL_TCPUNSET(protobits); + break; + case 'U': + NFSCTL_UDPUNSET(protobits); + break; default: fprintf(stderr, "Invalid argument: '%c'\n", c); case 'h': @@ -76,6 +105,10 @@ main(int argc, char **argv) /* * Do some sanity checking, if the ctlbits are set */ + if (!NFSCTL_UDPISSET(protobits) && !NFSCTL_TCPISSET(protobits)) { + fprintf(stderr, "invalid protocol specified\n"); + exit(1); + } found_one = 0; for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) { if (NFSCTL_VERISSET(versbits, c)) @@ -85,6 +118,14 @@ main(int argc, char **argv) fprintf(stderr, "no version specified\n"); exit(1); } + if (NFSCTL_VERISSET(versbits, 4) && !NFSCTL_TCPISSET(versbits)) { + fprintf(stderr, "version 4 requires the TCP protocol\n"); + exit(1); + } + if (haddr == NULL) { + struct in_addr in = {INADDR_ANY}; + haddr = strdup(inet_ntoa(in)); + } if (chdir(NFS_STATEDIR)) { fprintf(stderr, "%s: chdir(%s) failed: %s\n", @@ -116,7 +157,7 @@ main(int argc, char **argv) closeall(3); openlog("nfsd", LOG_PID, LOG_DAEMON); - if ((error = nfssvc(port, count, versbits)) < 0) { + if ((error = nfssvc(port, count, versbits, protobits, haddr)) < 0) { int e = errno; syslog(LOG_ERR, "nfssvc: %s", strerror(e)); closelog(); @@ -129,7 +170,7 @@ static void usage(const char *prog) { fprintf(stderr, "Usage:\n" - "%s [-p|-P|--port port] [-N|--no-nfs-version version ] nrservs\n", + "%s [-H hostname] [-p|-P|--port port] [-N|--no-nfs-version version ] [-T|--no-tcp] [-U|--no-udp] nrservs\n", prog); exit(2); } diff --git a/utils/nfsd/nfsd.man b/utils/nfsd/nfsd.man index d175d11..4ac709c 100644 --- a/utils/nfsd/nfsd.man +++ b/utils/nfsd/nfsd.man @@ -22,6 +22,17 @@ server provides an ancillary service needed to satisfy mount requests by NFS clients. .SH OPTIONS .TP +.B \-H " or " \-\-host hostname +specify a particular hostname (or address) that NFS requests will +be accepted on. By default, +.B rpc.nfsd +will accept NFS requests on all known network addresses. +Note that +.B lockd +(which performs file locking services for NFS) may still accept +request on all known network addresses. This may change in future +releases of the Linux Kernel. +.TP .B \-p " or " \-\-port port specify a diferent port to listen on for NFS requests. By default, .B rpc.nfsd @@ -34,6 +45,16 @@ does not offer certain versions of NFS. The current version of .B rpc.nfsd can support both NFS version 2,3 and the newer version 4. .TP +.B \-T " or " \-\-no-tcp +Disable +.B rpc.nfsd +from accepting TCP connections from clients. +.TP +.B \-U " or " \-\-no-udp +Disable +.B rpc.nfsd +from accepting UDP connections from clients. +.TP .I nproc specify the number of NFS server threads. By default, just one thread is started. However, for optimum performance several threads -- cgit From a503848d423fe1681879936da7b526b15f7eca23 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 3 Jul 2006 10:02:03 +1000 Subject: nfs-utils 1.0.9-pre1 Update change log and change version number --- ChangeLog | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.in | 2 +- 2 files changed, 185 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 35de983..aec3014 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,187 @@ +commit 49b164d978ee6266df7ba0bd335cb34337e7c381 +Author: Steve Dickson +Date: Mon Jul 3 09:52:00 2006 +1000 + + Allow rpc.nfsd to suppress tcp or udp, and listen on a specific address. + + -T - will suppressing listening for TCP connection. + -U - will suppress UDP + -H host - will only listen on that local address + -p port - will listen on that port. + + This requires kernel patches which will hopefully be in 2.6.19 and possibly some + earlier test and vendor kernels. + +commit fde2ae7794047a698feeaf17963d690a1e660a80 +Author: Steve Dickson +Date: Mon Jun 26 15:23:19 2006 +1000 + + Add support for suppressing different NFS versions. + + e.g. -N 2 + means that NFSv2 won't be supported, just v3 and v4 (if the kernel + supports them). + +commit 0523fd513c6baa8dbf45d1a7afea2044262aeb3d +Author: Neil Brown +Date: Fri Jun 23 17:10:56 2006 +1000 + + Further coverity related cleanups. + + Greg Banks suggested some variations, particularly improved + use of xmalloc/xstrdup functions. Thanks. + +commit 2e075a16da4963f54cd556403ca9e15a68de27fd +Author: Neil Brown +Date: Fri Jun 23 14:38:33 2006 +1000 + + Fix various issues discovered by Coverity + + Thanks to Michael Halcrow for finding them. + +commit ff42180930a444cea7f19e55e2cd2bfe6d3f108b +Author: Neil Brown +Date: Fri Jun 23 14:06:00 2006 +1000 + + Fix comment parsing (again) + + Bruce Fields noticed that I broke comment parsing... + + as xskip() is always called before xgettok(), that is the + best place to put xskipcomment and still maintain proper + semantics of xskip and xgettok. + +commit bec968578d97eabc63ae4a12bdeb2b33f40baec4 +Author: Amit Gud +Date: Thu Jun 22 12:51:04 2006 -0400 + + Change mount configure option to --enable-mount + + Change the configure option from --with-mount to --enable-mount. + + Signed-off-by: Amit Gud + Signed-off-by: Steve Dickson + +commit ceeffc1f76485b4084b2c61f4ff3c40e4f51c3b8 +Author: Amit Gud +Date: Thu Jun 22 12:49:24 2006 -0400 + + Merge nfsmount.x and mount.x into mount.x + + + Merge utils/mount/nfsmount.x and support/export/mount.x into support/export/mount.x. + + Signed-off-by: Amit Gud + Signed-off-by: Steve Dickson + +commit c2db41e8abb6ddc9d03a0c91c6db043fa0f85a8f +Author: Neil Brown +Date: Fri Jun 23 13:37:08 2006 +1000 + + Try to make sure that clientid used for NFSv4 is reliable. + + We need to give an IP address to identify this client to the + server. + The current code does a gethostbyname of the hostname. One + some systems this returns 127.0.0.1 or similar, which is not useful. + + Instead, use getsockname of the sock used to connect to the server + to confirm that the server is working. This gives the address on the + interface that was chosen to talk to that server, which is the + best address we can find (if there is a NAT in the way, it might + still not work, but in that case there is nothing we can do). + +commit 11d34d11153df198103a57291937ea9ff8b7356e +Author: Greg Banks +Date: Wed Jun 14 22:48:10 2006 +1000 + + multiple threads for mountd + + + How about the attached patch against nfs-utils tot? It + adds a -t option to set the number of forked workers. + Default is 1 thread, i.e. the old behaviour. + + I've verified that showmount -e, the Ogata mount client, + and a real mount from Linux and IRIX boxes work with and + without the new option. + + I've verified that you can manually kill any of the workers + without the portmap registration going away, that killing + all the workers causes the manager process to wake up and + unregister, and killing the manager process causes the + workers to be killed and portmap unregistered. + + I've verified that all the workers have file descriptors + for the udp socket and the tcp rendezvous socket, that + connections are balanced across all the workers if service + times are sufficiently long, and that performance is + improved by that parallelism, at least for small numbers + of threads. For example, with 60 parallel MOUNT calls + and a testing patch to make DNS lookups take 100 milliseconds + time to perform all mounts (averaged over 5 runs) is: + + num elapsed + threads time (sec) + ------ ---------- + 1 13.125 + 2 6.859 + 3 4.836 + 4 3.841 + 5 3.303 + 6 3.100 + 7 3.078 + 8 3.018 + + Greg. + -- + Greg Banks, R&D Software Engineer, SGI Australian Software Group. + I don't speak for SGI. + +commit db96d056578338dd1bb0371dc84638973c187ec6 +Author: Neil Brown +Date: Fri Jun 16 13:16:09 2006 +1000 + + Remove some temporary files that shouldn't be in 'git'. + + deleted: compile + deleted: config.guess + deleted: config.sub + deleted: depcomp + deleted: install-sh + deleted: ltmain.sh + deleted: missing + +commit 82b53188aaffad0e237461f8f1274794166feb3a +Author: Neil Brown +Date: Fri Jun 16 13:09:26 2006 +1000 + + Add support to auto-generate nfsmount* files for new nfs.mount program + +commit 4e2bae795e5eaf9922f0b966ab5df64994c836a2 +Author: Amit Gud +Date: Mon Jun 12 19:08:27 2006 -0400 + + Move NFS mount code from util-linux to nfs-utils - part 2 + + Adds the support functions needed for mount and umount. This + functionality will someday be available in the form of shared mount + library. + + Signed-off-by: Amit Gud + Signed-off-by: Steve Dickson + +commit a0520fa1a41bd33815b331b660b4545f2723495c +Author: Amit Gud +Date: Mon Jun 12 19:06:36 2006 -0400 + + Move NFS mount code from util-linux to nfs-utils - part 1 + + Adds the mount directory and the code to mount and umount the NFS file system. + + Signed-off-by: Amit Gud + Signed-off-by: Steve Dickson + 2006-06-05 NeilBrown - Remove debian/ at request of Debian maintainer "Steinar H. Gunderson" - fix_exportfs_with_multiple_matches.diff: Fixes a problem with exportfs -o diff --git a/configure.in b/configure.in index a136fd7..ded529f 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. dnl -AC_INIT([linux nfs-utils],[1.0.8],[nfs@lists.sf.net],[nfs-utils]) +AC_INIT([linux nfs-utils],[1.0.9-pre1],[nfs@lists.sf.net],[nfs-utils]) AC_CANONICAL_BUILD([]) AC_CANONICAL_HOST([]) AC_CONFIG_SRCDIR(tools/getiversion/getiversion.c) -- cgit