Assorted changes from Steve Dickson nfs-utils-1-0-7-post6
authorneilbrown <neilbrown>
Thu, 6 Oct 2005 05:20:19 +0000 (05:20 +0000)
committerneilbrown <neilbrown>
Thu, 6 Oct 2005 05:20:19 +0000 (05:20 +0000)
16 files changed:
ChangeLog
support/include/nfslib.h
support/nfs/Makefile
support/nfs/closeall.c [new file with mode: 0644]
support/nfs/exports.c
support/nfs/xlog.c
utils/idmapd/Makefile
utils/idmapd/idmapd.c
utils/mountd/mountd.c
utils/nfsd/nfsd.c
utils/statd/monitor.c
utils/statd/rmtcall.c
utils/statd/statd.c
utils/statd/statd.h
utils/statd/svc_run.c
utils/svcgssd/svcgssd.c

index ddb0082..df3ae49 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2005-10-06 Steve Dickson <SteveD@redhat.com> NeilBrown <neilb@suse.de>
+       * support/nfs/export.c: don't warn about sync/async for readonly
+       exports
+       * support/nfs/closeall.c: new file with function to close all 
+       file descriptors from a give minimum upwards.
+       * nfsd/mountd/statd/idmapd/gsssvcd: use closeall.
+       * utils/mountd/mountd.c: Eliminate 3 syslog message that are
+       logged for successful events. 
+       * utils/mountd/mountd.c: make sure the correct hostname is used in
+       the SM_NOTIFY message that is sent from a rebooted server which
+       has multiple network interfaces. (bz 139101)
+
+       Details can be found in:
+       https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=139101
+
+       *utils/idmapd/idmapd.c:Fixed subscripting problem in idmapd (bz
+       158188) This fixes the following problem: 
+         rpc.idmapd: nfsdreopen: Opening '' failed: errno 2 (No such file or directory)
+
+        Details can be found in:
+        https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=158188
+
+       *utils/statd/statd.c(drop_privs): clear st_gid as well as st_uid
+       of stat fails.
+       *utils/statd/svc_run.c(my_svc_run): remove usage of undocumented
+       %m format specifier.
+       *utils/statd/montor.c(sm_mon_1_svc): as above
+       *support/nfs/xlog.c(xlog): Changed xlog to use LOG_INFO instead of
+       LOG_DEBUG so debug messages will appear w/out any config changes
+       to syslog.conf. 
+
+       
 2005-09-02 Mike Frysinger <vapier@gentoo.org>
        * utils/rquotad/rquota_server.c(getquotainfo): use explicit
        struture-member copying rather than memcpy, as the element
index 2fbd0f5..a1932a5 100644 (file)
@@ -137,6 +137,8 @@ int qword_get_int(char **bpp, int *anint);
 void cache_flush(int force);
 int check_new_cache(void);
 
+void closeall(int min);
+
 /* lockd. */
 int                    lockdsvc();
 
index fb8f508..7740224 100644 (file)
@@ -6,7 +6,7 @@ LIBNAME = libnfs.a
 OBJS   = exports.o rmtab.o xio.o \
          rpcmisc.o rpcdispatch.o xlog.o xmalloc.o wildmat.o \
          nfssvc.o nfsclient.o nfsexport.o getfh.o nfsctl.o \
-         lockdsvc.o svc_socket.o cacheio.o
+         lockdsvc.o svc_socket.o cacheio.o closeall.o
 
 include $(TOP)rules.mk
 
diff --git a/support/nfs/closeall.c b/support/nfs/closeall.c
new file mode 100644 (file)
index 0000000..cc7fb3b
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * support/nfs/closeall.c
+ * Close all file descriptors greater than some limit,
+ * Use readdir "/proc/self/fd" to avoid excess close(2) calls.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <dirent.h>
+
+void
+closeall(int min)
+{
+       DIR *dir = opendir("/proc/self/fd");
+       if (dir != NULL) {
+               int dfd = dirfd(dir);
+               struct dirent *d;
+
+               while ((d = readdir(dir)) != NULL) {
+                       char *endp;
+                       long n = strtol(d->d_name, &endp, 10);
+                       if (*endp != '\0' && n >= min && n != dfd)
+                               (void) close(n);
+               }
+               closedir(dir);
+       } else {
+               int fd = sysconf(_SC_OPEN_MAX);
+               while (--fd >= min)
+                       (void) close(fd);
+       }
+}
index 43e68b1..1048c80 100644 (file)
@@ -448,7 +448,7 @@ bad_option:
        ep->e_nsqgids = nsqgids;
 
 out:
-       if (warn && !had_sync_opt)
+       if (warn && !had_sync_opt && !(ep->e_flags & NFSEXP_READONLY))
                xlog(L_WARNING, "%s [%d]: No 'sync' or 'async' option specified for export \"%s:%s\".\n"
                                "  Assuming default behaviour ('sync').\n"
                                "  NOTE: this default has changed from previous versions\n",
index e1e4c3f..d59f27f 100644 (file)
@@ -161,7 +161,7 @@ xlog(int kind, const char *fmt, ...)
                        break;
                default:
                        if (!log_stderr)
-                               syslog(LOG_DEBUG, "%s", buff);
+                               syslog(LOG_INFO, "%s", buff);
                        break;
                }
        }
index 41314ef..4e432ad 100644 (file)
@@ -6,7 +6,7 @@ TOP     = ../../
 PROGRAM        = idmapd
 PREFIX = rpc.
 OBJS   = atomicio.o cfg.o idmapd.o setproctitle.o strlcat.o strlcpy.o
-LIBS   = -levent -lnfsidmap
+LIBS   = -levent -lnfsidmap -lnfs
 MAN8   = idmapd
 MAN5   = idmapd.conf
 
index 80819d4..3be8148 100644 (file)
@@ -91,8 +91,8 @@
                (w) = p;                        \
 } while (0)
 
-#define IC_IDNAME 1
-#define IC_NAMEID 2
+#define IC_IDNAME 0
+#define IC_NAMEID 1
 struct idmap_client {
        int                        ic_fd;
        int                        ic_dirfd;
@@ -622,8 +622,8 @@ nfsdreopen()
 static int
 nfsdopen(char *path)
 {
-       return ((nfsdopenone(&nfsd_ic[0], IC_NAMEID, path) == 0 &&
-                   nfsdopenone(&nfsd_ic[1], IC_IDNAME, path) == 0) ? 0 : -1);
+       return ((nfsdopenone(&nfsd_ic[IC_NAMEID], IC_NAMEID, path) == 0 &&
+                   nfsdopenone(&nfsd_ic[IC_IDNAME], IC_IDNAME, path) == 0) ? 0 : -1);
 }
 
 static int
@@ -846,7 +846,7 @@ int pipefds[2] = { -1, -1};
 void
 mydaemon(int nochdir, int noclose)
 {
-       int pid, status, tempfd, fdmax, filedes;
+       int pid, status, tempfd;
 
        if (pipe(pipefds) < 0)
                err(1, "mydaemon: pipe() failed: errno %d (%s)\n", errno, strerror(errno));
@@ -879,13 +879,10 @@ mydaemon(int nochdir, int noclose)
 
        if (noclose == 0) {
                tempfd = open("/dev/null", O_RDWR);
-               close(0); dup2(tempfd, 0);
-               close(1); dup2(tempfd, 1);
-               close(2); dup2(tempfd, 2);
-               fdmax = sysconf (_SC_OPEN_MAX);
-               for (filedes = 3; filedes < fdmax; filedes++)
-                       if (filedes != pipefds[1])
-                               close (filedes);
+               dup2(tempfd, 0);
+               dup2(tempfd, 1);
+               dup2(tempfd, 2);
+               closeall(3);
        }
 
        return;
index 7325b25..a9ec1c7 100644 (file)
@@ -104,10 +104,11 @@ mount_dump_1_svc(struct svc_req *rqstp, void *argp, mountlist *res)
 {
        struct sockaddr_in *addr =
                (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt);
-       xlog(L_NOTICE, "dump request from %s",
-               inet_ntoa(addr->sin_addr));
 
-       *res = mountlist_list();
+       if ((*res = mountlist_list()) == NULL)
+               xlog(L_WARNING, "dump request from %s failed.",
+                       inet_ntoa(addr->sin_addr));
+
        return 1;
 }
 
@@ -157,9 +158,11 @@ mount_export_1_svc(struct svc_req *rqstp, void *argp, exports *resp)
 {
        struct sockaddr_in *addr =
                (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt);
-       xlog(L_NOTICE, "export request from %s",
-               inet_ntoa(addr->sin_addr));
-       *resp = get_exportlist();
+
+       if ((*resp = get_exportlist()) == NULL)
+               xlog(L_WARNING, "export request from %s failed.",
+                       inet_ntoa(addr->sin_addr));
+               
        return 1;
 }
 
@@ -168,9 +171,10 @@ mount_exportall_1_svc(struct svc_req *rqstp, void *argp, exports *resp)
 {
        struct sockaddr_in *addr =
                (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt);
-       xlog(L_NOTICE, "exportall request from %s",
-               inet_ntoa(addr->sin_addr));
-       *resp = get_exportlist();
+
+       if ((*resp = get_exportlist()) == NULL)
+               xlog(L_WARNING, "exportall request from %s failed.",
+                       inet_ntoa(addr->sin_addr));
        return 1;
 }
 
@@ -557,11 +561,8 @@ main(int argc, char **argv)
        sigaction(SIGCHLD, &sa, NULL);
 
        /* Daemons should close all extra filehandles ... *before* RPC init. */
-       if (!foreground) {
-               int fd = sysconf (_SC_OPEN_MAX);
-               while (--fd > 2)
-                       (void) close(fd);
-       }
+       if (!foreground)
+               closeall(3);
 
        new_cache = check_new_cache();
        if (new_cache)
index 86e8094..78143ed 100644 (file)
@@ -80,9 +80,7 @@ main(int argc, char **argv)
                (void) dup2(fd, 1);
                (void) dup2(fd, 2);
        }
-       fd = sysconf(_SC_OPEN_MAX);
-       while (--fd > 2)
-               (void) close(fd);
+       closeall(3);
 
        if ((error = nfssvc(port, count)) < 0) {
                int e = errno;
index 88b33db..40e8f49 100644 (file)
@@ -15,6 +15,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <errno.h>
 #include <arpa/inet.h>
 #include "misc.h"
 #include "statd.h"
@@ -172,7 +173,7 @@ sm_mon_1_svc(struct mon *argp, struct svc_req *rqstp)
        sprintf(path, "%s/%s", SM_DIR, mon_name);
        if ((fd = open(path, O_WRONLY|O_SYNC|O_CREAT, S_IRUSR|S_IWUSR)) < 0) {
                /* Didn't fly.  We won't monitor. */
-               note(N_ERROR, "creat(%s) failed: %m", path);
+               note(N_ERROR, "creat(%s) failed: %s", path, strerror (errno));
                nlist_free(NULL, clnt);
                free(path);
                goto failure;
index 474bbb4..a45705b 100644 (file)
@@ -26,6 +26,7 @@
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <netinet/in.h>
+#include <net/if.h>
 #include <arpa/inet.h>
 #include <rpc/rpc.h>
 #include <rpc/pmap_prot.h>
@@ -34,6 +35,7 @@
 #include <netdb.h>
 #include <string.h>
 #include <unistd.h>
+#include <ifaddrs.h>
 #include "sm_inter.h"
 #include "statd.h"
 #include "notlist.h"
@@ -90,7 +92,50 @@ statd_get_socket(int port)
 out_success:
        return sockfd;
 }
-
+/*
+ * Using the NL_ADDR(lp), reset (if needed) the hostname
+ * that will be put in the SM_NOTIFY to the hostname
+ * that is associated with the network interface 
+ * that was monitored
+ */
+static void
+reset_my_name(notify_list *lp)
+{
+       struct ifaddrs *ifa = NULL, *ifap;
+       struct in_addr netaddr, tmp;
+       struct sockaddr_in *sin, *nsin;
+       struct hostent *hp;
+
+       netaddr.s_addr = inet_netof(NL_ADDR(lp));
+       if (getifaddrs(&ifa) >= 0) {
+               for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) {
+                       if (!(ifap->ifa_flags & IFF_UP))
+                               continue;
+
+                       note(N_DEBUG, "ifa_name %s\n", ifap->ifa_name);
+                       if (ifap->ifa_addr == NULL)
+                               continue;
+                       if (ifap->ifa_addr->sa_family != AF_INET)
+                               continue;
+
+                       sin = (struct sockaddr_in *)ifap->ifa_addr;
+                       nsin = (struct sockaddr_in *)ifap->ifa_netmask;
+                       tmp.s_addr = sin->sin_addr.s_addr & nsin->sin_addr.s_addr;
+                       if (memcmp(&tmp.s_addr, &netaddr.s_addr, sizeof(netaddr.s_addr)))
+                               continue;
+                       hp = gethostbyaddr((char *)&sin->sin_addr, 
+                               sizeof(sin->sin_addr), AF_INET);
+                       if (hp == NULL)
+                               continue;
+                       if (strcmp(NL_MY_NAME(lp), hp->h_name)) {
+                               free(NL_MY_NAME(lp));
+                               NL_MY_NAME(lp)= strdup(hp->h_name);
+                               note(N_DEBUG, "NL_MY_NAME %s\n", NL_MY_NAME(lp));
+                       }
+               }
+       }
+       return;
+}
 /*
  * Try to resolve host name for notify/callback request
  *
@@ -300,6 +345,7 @@ process_entry(int sockfd, notify_list *lp)
 {
        struct sockaddr_in      sin;
        struct status           new_status;
+       stat_chge               new_stat;
        xdrproc_t               func;
        void                    *objp;
        u_int32_t               proc, vers, prog;
@@ -326,9 +372,19 @@ process_entry(int sockfd, notify_list *lp)
 
                /* Use source address for notify replies */
                sin.sin_addr   = lp->addr;
+               /* 
+                * Unless a static hostname has been defined
+                * set the NL_MY_NAME(lp) hostname to the 
+                * one associated with the network interface
+                */
+               if (!(run_mode & STATIC_HOSTNAME))
+                       reset_my_name(lp);
 
                func = (xdrproc_t) xdr_stat_chge;
-               objp = &SM_stat_chge;
+               new_stat.state = MY_STATE;
+               new_stat.mon_name = NL_MY_NAME(lp);
+
+               objp = &new_stat;
                break;
        case NOTIFY_CALLBACK:
                prog = NL_MY_PROG(lp);
index 48362c0..f61914d 100644 (file)
@@ -22,6 +22,7 @@
 #include <grp.h>
 #include "statd.h"
 #include "version.h"
+#include "nfslib.h"
 
 /* Socket operations */
 #include <sys/types.h>
@@ -194,8 +195,10 @@ static void drop_privs(void)
        struct stat st;
 
        if (stat(SM_DIR, &st) == -1 &&
-           stat(DIR_BASE, &st) == -1)
+           stat(DIR_BASE, &st) == -1) {
                st.st_uid = 0;
+               st.st_gid = 0;
+       }
 
        if (st.st_uid == 0) {
                note(N_WARNING, "statd running as root. chown %s to choose different user\n",
@@ -285,6 +288,7 @@ int main (int argc, char **argv)
                        }
                        break;
                case 'n':       /* Specify local hostname */
+                       run_mode |= STATIC_HOSTNAME;
                        MY_NAME = xstrdup(optarg);
                        break;
                case 'P':
@@ -400,14 +404,12 @@ int main (int argc, char **argv)
                        }
                }
                tempfd = open("/dev/null", O_RDWR);
-               close(0); dup2(tempfd, 0);
-               close(1); dup2(tempfd, 1);
-               close(2); dup2(tempfd, 2);
-               fdmax = sysconf (_SC_OPEN_MAX);
-               for (filedes = 3; filedes < fdmax; filedes++) 
-                       if (filedes != pipefds[1])
-                               close (filedes);
-
+               dup2(tempfd, 0);
+               dup2(tempfd, 1);
+               dup2(tempfd, 2);
+               dup2(pipefds[1], 3);
+               pipefds[1] = 3;
+               closeall(4);
        }
 
        /* Child. */
index e782972..d9d5d3d 100644 (file)
@@ -78,6 +78,7 @@ extern int run_mode;
 /* LH - notify_only mode would be for notifying hosts on an IP alias
  * that just came back up, for ex, when failing over a HA service to
  * another host.... */
+#define STATIC_HOSTNAME 8      /* Always use the hostname set by -n */
 
 /*
  * Program name and version pointers -- See statd.c for the reasoning
index f6bcbb9..597b68d 100644 (file)
@@ -123,7 +123,8 @@ my_svc_run(void)
                        if (errno == EINTR || errno == ECONNREFUSED
                         || errno == ENETUNREACH || errno == EHOSTUNREACH)
                                continue;
-                       note(N_ERROR, "my_svc_run() - select: %m");
+                       note(N_ERROR, "my_svc_run() - select: %s",
+                               strerror (errno));
                        return;
 
                case 0:
index 3b5a981..3059253 100644 (file)
@@ -113,13 +113,10 @@ mydaemon(int nochdir, int noclose)
 
        if (noclose == 0) {
                tempfd = open("/dev/null", O_RDWR);
-               close(0); dup2(tempfd, 0);
-               close(1); dup2(tempfd, 1);
-               close(2); dup2(tempfd, 2);
-               fdmax = sysconf (_SC_OPEN_MAX);
-               for (filedes = 3; filedes < fdmax; filedes++)
-                       if (filedes != pipefds[1])
-                               close (filedes);
+               dup2(tempfd, 0);
+               dup2(tempfd, 1);
+               dup2(tempfd, 2);
+               closeall(3);
        }
 
        return;