nfs-utils: have mountd hold open etab file to force inode number to change
authorJeff Layton <jlayton@redhat.com>
Wed, 9 May 2007 14:19:33 +0000 (10:19 -0400)
committerNeil Brown <neilb@suse.de>
Fri, 11 May 2007 03:33:56 +0000 (13:33 +1000)
This patch changes mountd to hold the etab file open so that when it's
changed by exportfs, the inode number should change. We then change
auth_reload to reload the file based on whether st_ino is different
from the last time it was checked. It also changes auth_reload to
maintain a static counter value and return it instead of a timestamp
and fixes up get_exportlist accordingly. Finally, it adds some
comments to xtab_write to warn people about editing the etab in place.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
support/export/xtab.c
utils/mountd/auth.c
utils/mountd/mountd.c
utils/mountd/mountd.h

index 0ddb251..292087b 100644 (file)
@@ -80,6 +80,12 @@ xtab_export_read(void)
        return xtab_read(_PATH_ETAB, 1);
 }
 
+/*
+ * mountd now keeps an open fd for the etab at all times to make sure that the
+ * inode number changes when the xtab_export_write is done. If you change the
+ * routine below such that the files are edited in place, then you'll need to
+ * fix the auth_reload logic as well...
+ */
 static int
 xtab_write(char *xtab, char *xtabtmp, int is_export)
 {
index 183c9ea..f7fe23d 100644 (file)
@@ -14,6 +14,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <errno.h>
+#include <unistd.h>
 #include "misc.h"
 #include "nfslib.h"
 #include "exportfs.h"
@@ -46,24 +47,34 @@ auth_init(char *exports)
        xtab_mount_write();
 }
 
-time_t
+unsigned int
 auth_reload()
 {
        struct stat             stb;
-       static time_t           last_modified = 0;
-
-       if (stat(_PATH_ETAB, &stb) < 0)
+       static ino_t            last_inode;
+       static int              last_fd;
+       static unsigned int     counter;
+       int                     fd;
+
+       if ((fd = open(_PATH_ETAB, O_RDONLY)) < 0) {
+               xlog(L_FATAL, "couldn't open %s", _PATH_ETAB);
+       } else if (fstat(fd, &stb) < 0) {
                xlog(L_FATAL, "couldn't stat %s", _PATH_ETAB);
-       if (stb.st_mtime == last_modified)
-               return last_modified;
-       last_modified = stb.st_mtime;
+       } else if (stb.st_ino == last_inode) {
+               close(fd);
+               return counter;
+       } else {
+               close(last_fd);
+               last_fd = fd;
+               last_inode = stb.st_ino;
+       }
 
        export_freeall();
        memset(&my_client, 0, sizeof(my_client));
-       // export_read(export_file);
        xtab_export_read();
+       ++counter;
 
-       return last_modified;
+       return counter;
 }
 
 static nfs_export *
index 04141d1..999f035 100644 (file)
@@ -465,18 +465,18 @@ static exports
 get_exportlist(void)
 {
        static exports          elist = NULL;
-       static time_t           etime = 0;
-       time_t                  atime;
        struct exportnode       *e, *ne;
        struct groupnode        *g, *ng, *c, **cp;
        nfs_export              *exp;
        int                     i;
+       static unsigned int     ecounter;
+       unsigned int            acounter;
 
-       atime = auth_reload();
-       if (elist && atime == etime)
+       acounter = auth_reload();
+       if (elist && acounter == ecounter)
                return elist;
 
-       etime = atime;
+       ecounter = acounter;
 
        for (e = elist; e != NULL; e = ne) {
                ne = e->ex_next;
index b539278..31bacb5 100644 (file)
@@ -40,7 +40,7 @@ bool_t                mount_mnt_3_svc(struct svc_req *, dirpath *, mountres3 *);
 
 void           mount_dispatch(struct svc_req *, SVCXPRT *);
 void           auth_init(char *export_file);
-time_t         auth_reload(void);
+unsigned int   auth_reload(void);
 nfs_export *   auth_authenticate(char *what, struct sockaddr_in *sin,
                                        char *path);
 void           auth_export(nfs_export *exp);