All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] nfs-utils: make auth_reload respect sub-second timestamps on etab
@ 2007-04-25 17:39 Jeff Layton
  2007-04-25 18:09 ` Jeff Layton
  2007-04-26  4:50 ` Neil Brown
  0 siblings, 2 replies; 18+ messages in thread
From: Jeff Layton @ 2007-04-25 17:39 UTC (permalink / raw)
  To: nfs

Currently, when auth_reload is called, it only looks at the tv_sec field
of the mtime when deciding whether to invalidate the exports cache. It's
fairly simple to fool this by doing something like:

# exportfs -rv && rpc.mountd && exportfs -uva && exportfs -iv -o no_root_squash,rw 127.0.0.1:/foo

With this, exportfs will show the export for /foo, but mountd will still have
whatever contents were in /etc/exports. The issue is that the etab is being
updated twice during the same second, and mountd is reading in the file in
between updates. When it goes to look at the file again, its timestamp matches
the timestamp of the cache, and it ends up keeping the cached contents even
though the file has changed.

While not all local filesystems provide sub-second timestamps, we might as
well fix this problem on those that do. The following patch changes
auth_reload to consider the tv_nsec field of the mtime when deciding whether
to invalidate the export cache. It also fixes up the callers to pass it a
pointer to a struct timespec for it to fill out.

I've not yet tested this on a filesystem that provides sub-second timestamps,
so I'm not clear on how well this works yet, but it seems to not break
anything on ext3 in some cursory testing.

diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c
index 183c9ea..54e7516 100644
--- a/utils/mountd/auth.c
+++ b/utils/mountd/auth.c
@@ -42,28 +42,34 @@ auth_init(char *exports)
 {
 
 	export_file = exports;
-	auth_reload();
+	auth_reload(NULL);
 	xtab_mount_write();
 }
 
-time_t
-auth_reload()
+void
+auth_reload(struct timespec *ts)
 {
 	struct stat		stb;
-	static time_t		last_modified = 0;
+	static struct timespec	last_modified;
 
 	if (stat(_PATH_ETAB, &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;
+	if (stb.st_mtim.tv_sec == last_modified.tv_sec &&
+	    stb.st_mtim.tv_nsec == last_modified.tv_nsec)
+		goto out;
 
+	last_modified.tv_sec = stb.st_mtim.tv_sec;
+	last_modified.tv_nsec = stb.st_mtim.tv_nsec;
 	export_freeall();
 	memset(&my_client, 0, sizeof(my_client));
 	// export_read(export_file);
 	xtab_export_read();
-
-	return last_modified;
+out:
+	if (ts) {
+		ts->tv_sec = stb.st_mtim.tv_sec;
+		ts->tv_nsec = stb.st_mtim.tv_nsec;
+	}
+	return;
 }
 
 static nfs_export *
diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index d068843..77c559f 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -90,7 +90,7 @@ void auth_unix_ip(FILE *f)
 	if (inet_aton(ipaddr, &addr)==0)
 		return;
 
-	auth_reload();
+	auth_reload(NULL);
 
 	/* addr is a valid, interesting address, find the domain name... */
 	client = client_compose(addr);
@@ -354,7 +354,7 @@ void nfsd_fh(FILE *f)
 		break;
 	}
 
-	auth_reload();
+	auth_reload(NULL);
 
 	/* Now determine export point for this fsid/domain */
 	for (i=0 ; i < MCL_MAXTYPES; i++) {
@@ -575,7 +575,7 @@ void nfsd_export(FILE *f)
 	if (qword_get(&cp, path, strlen(lbuf)) <= 0)
 		goto out;
 
-	auth_reload();
+	auth_reload(NULL);
 
 	/* now find flags for this export point in this domain */
 	for (i=0 ; i < MCL_MAXTYPES; i++) {
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index 04141d1..96d25a1 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -241,7 +241,7 @@ bool_t
 mount_umntall_1_svc(struct svc_req *rqstp, void *argp, void *resp)
 {
 	/* Reload /etc/xtab if necessary */
-	auth_reload();
+	auth_reload(NULL);
 
 	mountlist_del_all((struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt));
 	return 1;
@@ -299,7 +299,7 @@ mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res)
 		p = "/";
 
 	/* Reload /etc/xtab if necessary */
-	auth_reload();
+	auth_reload(NULL);
 
 	/* Resolve symlinks */
 	if (realpath(p, rpath) != NULL) {
@@ -373,7 +373,7 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, mountstat3 *error, int v3)
 		p = "/";
 
 	/* Reload /var/lib/nfs/etab if necessary */
-	auth_reload();
+	auth_reload(NULL);
 
 	/* Resolve symlinks */
 	if (realpath(p, rpath) != NULL) {
@@ -465,18 +465,20 @@ static exports
 get_exportlist(void)
 {
 	static exports		elist = NULL;
-	static time_t		etime = 0;
-	time_t			atime;
+	static struct timespec	etime;
+	struct timespec		atime;
 	struct exportnode	*e, *ne;
 	struct groupnode	*g, *ng, *c, **cp;
 	nfs_export		*exp;
 	int			i;
 
-	atime = auth_reload();
-	if (elist && atime == etime)
+	auth_reload(&atime);
+	if (elist && atime.tv_sec == etime.tv_sec &&
+	    atime.tv_nsec == etime.tv_nsec)
 		return elist;
 
-	etime = atime;
+	etime.tv_sec = atime.tv_sec;
+	etime.tv_nsec = atime.tv_nsec;
 
 	for (e = elist; e != NULL; e = ne) {
 		ne = e->ex_next;
diff --git a/utils/mountd/mountd.h b/utils/mountd/mountd.h
index b539278..58694d9 100644
--- a/utils/mountd/mountd.h
+++ b/utils/mountd/mountd.h
@@ -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);
+void 		auth_reload(struct timespec *ts);
 nfs_export *	auth_authenticate(char *what, struct sockaddr_in *sin,
 					char *path);
 void		auth_export(nfs_export *exp);


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2007-05-03 12:11 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-25 17:39 [PATCH] nfs-utils: make auth_reload respect sub-second timestamps on etab Jeff Layton
2007-04-25 18:09 ` Jeff Layton
2007-04-25 20:13   ` Jeff Layton
2007-04-25 21:29     ` Chuck Lever
2007-04-26  4:56       ` Neil Brown
2007-04-26 12:05         ` Jeff Layton
2007-04-26 16:23           ` Jeff Layton
2007-04-26 16:58             ` J. Bruce Fields
2007-04-26 17:00               ` Jeff Layton
2007-04-26 17:24                 ` J. Bruce Fields
2007-04-26 18:29                   ` Jeff Layton
2007-05-03  0:55                     ` Neil Brown
2007-05-03 11:58                       ` Jeff Layton
2007-05-03 12:11                         ` Jeff Layton
2007-04-26 17:33                 ` Jeff Layton
2007-04-26 12:35         ` J. Bruce Fields
2007-04-26  4:50 ` Neil Brown
2007-04-26 11:50   ` Jeff Layton

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.