* [PATCH] DefineSimpleCache macro problem
@ 2004-05-13 8:22 Olaf Kirch
2004-05-13 9:36 ` Neil Brown
0 siblings, 1 reply; 5+ messages in thread
From: Olaf Kirch @ 2004-05-13 8:22 UTC (permalink / raw)
To: nfs
[-- Attachment #1: Type: text/plain, Size: 1470 bytes --]
Hi,
the 2.6 code has this new cache stuff to create caches for various
things, which is used for the export table and ip client list.
I came across a strange problem where a host exported several directories
to a group of clients, but clients were unable to mount more than one.
It turned out that the problem was caused by svc_export_lookup, which
will create bogus entries even if called in lookup-only mode. This caused
bogus export entries to be created, which didn't have the VALID flag set.
Essentially, the macro-defined function in sunrpc/cache.h will always
create entries in the cache, even if "set == 0". The attached patch
fixes this, and changes the lookup functions to return NULL in this
case, rather than a bogus entry.
However, this change uncovered another problem. AIX clients will
do a NULL procedure call before attempting the mount (I think this
is a known issue). If the file system is exported to a wildcard
group, the kernel will not know about the client when this call
arrives.
Previously, this would always succeed, because the ip_map_lookup() call
from svcauth_unix_accept() would always return an entry, even if it was
a bogus one. With the change to cache.h, ip_map_lookup() will now return
NULL for unknown clients, causing the NULL call from the AIX client
to be dropped. The second patch attached below will fix this issue
as well.
Cheers
Olaf
--
Olaf Kirch | The Hardware Gods hate me.
okir@suse.de |
---------------+
[-- Attachment #2: sunrpc-bogus-export-entry --]
[-- Type: text/plain, Size: 489 bytes --]
--- linux-2.6.5/include/linux/sunrpc/cache.h.bug 2004-03-12 12:17:26.000000000 +0100
+++ linux-2.6.5/include/linux/sunrpc/cache.h 2004-05-10 13:19:58.000000000 +0200
@@ -223,7 +223,7 @@
else read_unlock(&(DETAIL)->hash_lock); \
if (new && set) \
cache_fresh(DETAIL, &new->MEMBER, item->MEMBER.expiry_time); \
- if (new) \
+ if (new || !set) \
return new; \
new = kmalloc(sizeof(*new), GFP_KERNEL); \
if (new) { \
[-- Attachment #3: sunrpc-null-noauth --]
[-- Type: text/plain, Size: 567 bytes --]
--- linux-2.6.5/net/sunrpc/svcauth_unix.c.aix 2004-05-12 21:40:41.000000000 +0200
+++ linux-2.6.5/net/sunrpc/svcauth_unix.c 2004-05-13 10:05:38.000000000 +0200
@@ -390,7 +390,13 @@
break;
default: BUG();
}
- else rv = SVC_DROP;
+ else if (rqstp->rq_proc == 0) {
+ /* We always accept calls to NULL. AIX clients try
+ a NULL call before mounting, so when we get here
+ we may not know about the export entry yet. */
+ rv = SVC_OK;
+ } else
+ rv = SVC_DROP;
if (rqstp->rq_client == NULL && rqstp->rq_proc != 0)
*authp = rpc_autherr_badcred;
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] DefineSimpleCache macro problem 2004-05-13 8:22 [PATCH] DefineSimpleCache macro problem Olaf Kirch @ 2004-05-13 9:36 ` Neil Brown 2004-05-13 10:45 ` Olaf Kirch 0 siblings, 1 reply; 5+ messages in thread From: Neil Brown @ 2004-05-13 9:36 UTC (permalink / raw) To: Olaf Kirch; +Cc: nfs On Thursday May 13, okir@suse.de wrote: > Hi, > > the 2.6 code has this new cache stuff to create caches for various > things, which is used for the export table and ip client list. > > I came across a strange problem where a host exported several directories > to a group of clients, but clients were unable to mount more than one. > > It turned out that the problem was caused by svc_export_lookup, which > will create bogus entries even if called in lookup-only mode. This caused > bogus export entries to be created, which didn't have the VALID flag set. > > Essentially, the macro-defined function in sunrpc/cache.h will always > create entries in the cache, even if "set == 0". The attached patch > fixes this, and changes the lookup functions to return NULL in this > case, rather than a bogus entry. That would be wrong. Always returning an entry (possibly non-VALID) - except on kmalloc failure - is a design feature. If a non-VALID entry is returned the caller typically initiates an upcall for the information in that entry (unless one is already pending), and then the request is deferred until the entry is filled in. When the cache item is marked VALID, all the deferred requests attached to it are queued for re-processing. So we definitely want to return the non-VALID entry. Can you help understand more about your particular problem? Why do you think that svc_export_lookup returning a non-VALID entry causes a problem. It is only called with "set" == 0 in exp_get_by_name, and exp_get_by_name will only return it to the caller it is VALID. So I cannot figure out what the real problem is yet. Also, are you running with the nfsd filesystem mounted on /proc/fs/nfsd (or /proc/fs/nfs) or with it unmounted? NeilBrown ------------------------------------------------------- This SF.Net email is sponsored by: SourceForge.net Broadband Sign-up now for SourceForge Broadband and get the fastest 6.0/768 connection for only $19.95/mo for the first 3 months! http://ads.osdn.com/?ad_id=2562&alloc_id=6184&op=click _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] DefineSimpleCache macro problem 2004-05-13 9:36 ` Neil Brown @ 2004-05-13 10:45 ` Olaf Kirch 2004-05-13 19:15 ` J. Bruce Fields 2004-05-14 1:20 ` Neil Brown 0 siblings, 2 replies; 5+ messages in thread From: Olaf Kirch @ 2004-05-13 10:45 UTC (permalink / raw) To: Neil Brown; +Cc: nfs On Thu, May 13, 2004 at 07:36:27PM +1000, Neil Brown wrote: > That would be wrong. Always returning an entry (possibly non-VALID) > - except on kmalloc failure - is a design feature. Does this mean I can eat all your memory by flooding your NFS server with NULL calls from bogus addresses? That would be bad. > Can you help understand more about your particular problem? > Why do you think that svc_export_lookup returning a non-VALID entry > causes a problem. > It is only called with "set" == 0 in exp_get_by_name, and > exp_get_by_name will only return it to the caller it is VALID. > So I cannot figure out what the real problem is yet. The problem is that somewhere somehow an invalid entry is created, which remains in the cache and the flags don't get updated. Here's a trace of mountd, after reboot with a fresh slate (i.e. /proc/net/rpc/nfsd.export/contents is empty). The mount attempts are pretty close together; this happens reproduceably if the client is the automounter using /net/<hostname> open("/proc/net/rpc/nfsd.export/channel", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6 write(6, "someclient.suse.de / 2147483647 32 65534 65534 2053 \n", 50) = 50 open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6 write(6, "someclient.suse.de 0 \\x0008000502000000 2147483647 / \n", 51) = 51 open("/proc/net/rpc/nfsd.export/channel", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6 write(6, "someclient.suse.de /boot 2147483647 32 65534 65534 2049 \n", 54) = 54 open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6 write(6, "someclient.suse.de 0 \\x0008000102000000 2147483647 /boot \n", 55) = -1 ENOENT (No such file or directory) open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY) = 6 open("/proc/net/rpc/nfsd.export/channel", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6 write(6, "someclient.suse.de /home 2147483647 32 65534 65534 2054 \n", 54) = 54 open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6 write(6, "someclient.suse.de 0 \\x0008000602000000 2147483647 /home \n", 55) = -1 ENOENT (No such file or directory) As you can see, the attempt to write to nfsd.fh fails with ENOENT. Here's a snippet from syslog: May 10 12:54:52 testnfs kernel: nfsd: exp_rootfh(/ [c7dd2280] appserv.suse.de:sda5/2) ... May 10 12:54:52 testnfs kernel: svc_expkey_lookup called May 10 12:54:52 testnfs kernel: cache_check:67: item=c54c09c0 May 10 12:54:52 testnfs kernel: cache_check:80: rv=0 ^^^ we repeatedly call svc_expkey_lookup, ^^^ I see 2 or 3 different item pointers ... May 10 12:54:52 testnfs kernel: svc_export_lookup called May 10 12:54:52 testnfs kernel: cache_init:40: item=c54c0900 May 10 12:54:52 testnfs kernel: exp_get_by_name:589: exp=c54c0900 flags=8 ^^^ here we get a fresh entry but don't init it ^^^ not sure who called exp_get_by_name here May 10 12:54:52 testnfs kernel: cache_check:67: item=c54c0900 May 10 12:54:52 testnfs kernel: cache_check:71: flags=0x8 expiry=1084186612 now=1084186492 May 10 12:54:52 testnfs kernel: cache_check:86: rv=-11 May 10 12:54:52 testnfs kernel: Want update, refage=120, age=0 May 10 12:54:52 testnfs kernel: cache_fresh:130: item=c54c0900, expiry=1084186612 ... May 10 12:54:52 testnfs kernel: svc_export_parse:402: an_int=32 May 10 12:54:52 testnfs kernel: svc_export_parse:425: err=0 May 10 12:54:52 testnfs kernel: svc_export_lookup called May 10 12:54:52 testnfs kernel: svc_export_update:494: new=c54c0900 flags=b ^^^ and by now the item has turned bad ^^^ (HASHED,VALID,NEGATIVE) May 10 12:54:52 testnfs kernel: cache_fresh:130: item=c54c0900, expiry=2147483647 May 10 12:54:52 testnfs kernel: svc_export_parse:428: expp=c54c0900 flags=b May 10 12:54:52 testnfs kernel: svc_export_parse:440: err=0 May 10 12:54:52 testnfs kernel: found domain someclient.suse.de May 10 12:54:52 testnfs kernel: found fsidtype 0 May 10 12:54:52 testnfs kernel: found fsid length 8 May 10 12:54:52 testnfs kernel: Path seems to be </boot> May 10 12:54:52 testnfs kernel: Found the path /boot ... I haven't yet figured out exactly what happens, but _something_ calls exp_get_by_name for /boot prior to mount's call. This leaves an invalid item in the cache, and svc_export_update doesn't fix the flags. These bad export entries are visible in /proc/net/rpc/nfsd.export/contents; they're shown as # someclient.suse.de .... > Also, are you running with the nfsd filesystem mounted on > /proc/fs/nfsd (or /proc/fs/nfs) or with it unmounted? The nfsd file system is not mounted, but I think this shouldn't make a difference. Olaf -- Olaf Kirch | The Hardware Gods hate me. okir@suse.de | ---------------+ ------------------------------------------------------- This SF.Net email is sponsored by: SourceForge.net Broadband Sign-up now for SourceForge Broadband and get the fastest 6.0/768 connection for only $19.95/mo for the first 3 months! http://ads.osdn.com/?ad_id=2562&alloc_id=6184&op=click _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] DefineSimpleCache macro problem 2004-05-13 10:45 ` Olaf Kirch @ 2004-05-13 19:15 ` J. Bruce Fields 2004-05-14 1:20 ` Neil Brown 1 sibling, 0 replies; 5+ messages in thread From: J. Bruce Fields @ 2004-05-13 19:15 UTC (permalink / raw) To: Olaf Kirch; +Cc: Neil Brown, nfs On Thu, May 13, 2004 at 12:45:52PM +0200, Olaf Kirch wrote: > On Thu, May 13, 2004 at 07:36:27PM +1000, Neil Brown wrote: > > That would be wrong. Always returning an entry (possibly non-VALID) > > - except on kmalloc failure - is a design feature. > > Does this mean I can eat all your memory by flooding your NFS server > with NULL calls from bogus addresses? That would be bad. There is an expiration time on those entries (2 minutes), but I don't see any bound on the number of them. I'm guessing one of those ip_map cache entries is about 80 bytes on i386? I'm not sure what a reasonable assumption is about packet rates, but it seems like it could be a problem, unless I'm missing some other constraint here. > The problem is that somewhere somehow an invalid entry is created, > which remains in the cache and the flags don't get updated. Ugh, and it's the failure to update the flags that's the bug, I suspect. Does this help? (Caveat: looks straightforward enough, but I haven't actually tested it!) --b. Normally the _lookup functions are only called with set = 1 on items with CACHE_NEGATIVE not set; however in the case of the export cache it can happen, and is especially likely if mountd isn't listening in on the proc/net/rpc/*/content files, since then any lookup (if followed by cache_check()) generates a CACHE_NEGATIVE entry. Make sure we clear the CACHE_NEGATIVE bit on update if necessary in DefineCacheLookup. include/linux/sunrpc/cache.h | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) diff -puN include/linux/sunrpc/cache.h~nfsd_cache_update_negative include/linux/sunrpc/cache.h --- linux-2.6.6-rc3/include/linux/sunrpc/cache.h~nfsd_cache_update_negative 2004-05-13 14:44:13.000000000 -0400 +++ linux-2.6.6-rc3-bfields/include/linux/sunrpc/cache.h 2004-05-13 14:45:47.000000000 -0400 @@ -195,7 +195,10 @@ RTN *FNAME ARGS \ } \ if (test_bit(CACHE_NEGATIVE, &item->MEMBER.flags)) \ set_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \ - else {UPDATE;} \ + else { \ + clear_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \ + UPDATE; \ + } \ } \ if (set||new) write_unlock(&(DETAIL)->hash_lock); \ else read_unlock(&(DETAIL)->hash_lock); \ _ ------------------------------------------------------- This SF.Net email is sponsored by: SourceForge.net Broadband Sign-up now for SourceForge Broadband and get the fastest 6.0/768 connection for only $19.95/mo for the first 3 months! http://ads.osdn.com/?ad_id=2562&alloc_id=6184&op=click _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] DefineSimpleCache macro problem 2004-05-13 10:45 ` Olaf Kirch 2004-05-13 19:15 ` J. Bruce Fields @ 2004-05-14 1:20 ` Neil Brown 1 sibling, 0 replies; 5+ messages in thread From: Neil Brown @ 2004-05-14 1:20 UTC (permalink / raw) To: Olaf Kirch, J. Bruce Fields; +Cc: nfs On Thursday May 13, okir@suse.de wrote: > > I haven't yet figured out exactly what happens, but _something_ calls > exp_get_by_name for /boot prior to mount's call. This leaves an invalid > item in the cache, and svc_export_update doesn't fix the flags. My only guess for what could be calling exp_get_by_name is exp_parent, which would be called when user-space asked for a file handle at-or-below the point in question. But I don't know if or why that is happening. Bruce's patch is the right thing to fix the problem, though I would clear the bit *after* the UPDATE has been completed, just to make sure no-one see an inconsistent structure. Thanks Bruce. > > Also, are you running with the nfsd filesystem mounted on > > /proc/fs/nfsd (or /proc/fs/nfs) or with it unmounted? > > The nfsd file system is not mounted, but I think this shouldn't > make a difference. It makes a big difference to how exportfs and mountd do their stuff. They are less pro-active about giving information to the kernel, and more reactive, only giving it when asked for. NeilBrown ------------------------------------------------------- This SF.Net email is sponsored by: SourceForge.net Broadband Sign-up now for SourceForge Broadband and get the fastest 6.0/768 connection for only $19.95/mo for the first 3 months! http://ads.osdn.com/?ad_id=2562&alloc_id=6184&op=click _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2004-05-14 1:20 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-05-13 8:22 [PATCH] DefineSimpleCache macro problem Olaf Kirch 2004-05-13 9:36 ` Neil Brown 2004-05-13 10:45 ` Olaf Kirch 2004-05-13 19:15 ` J. Bruce Fields 2004-05-14 1:20 ` Neil Brown
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.