From owner-freebsd-current Tue Apr 9 18:11:14 1996 Return-Path: owner-current Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id SAA07316 for current-outgoing; Tue, 9 Apr 1996 18:11:14 -0700 (PDT) Received: from ki.net (root@ki.net [205.150.102.1]) by freefall.freebsd.org (8.7.3/8.7.3) with ESMTP id SAA07308 for ; Tue, 9 Apr 1996 18:11:08 -0700 (PDT) Received: from localhost (scrappy@localhost) by ki.net (8.7.4/8.7.4) with SMTP id VAA02050 for ; Tue, 9 Apr 1996 21:10:59 -0400 (EDT) Date: Tue, 9 Apr 1996 21:10:58 -0400 (EDT) From: "Marc G. Fournier" Reply-To: "Marc G. Fournier" To: current@freebsd.org Subject: mount_nfs fails to mount from -stable to -current machine (extra) Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-current@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Hi... After doing some more poking around, I found out that mount_nfs was installed: freebsd# ls -lt `which mount_nfs` -r-xr-xr-x 1 bin bin 110592 Apr 7 17:05 /sbin/mount_nfs The system went down @ ~19:00 on the 9th, and was up for 2days, 18hours previous to that. So, I upgraded mount_nfs *since* the last reboot, and haven't used it since. The error message is coming from: /usr/src/sbin/mount_nfs/mount_nfs.c: while (retrycnt > 0) { saddr.sin_family = AF_INET; saddr.sin_port = htons(PMAPPORT); if ((tport = port_no ? port_no : pmap_getport(&saddr, RPCPROG_NFS, nfsvers, nfsproto)) == 0) { if ((opflags & ISBGRND) == 0) clnt_pcreateerror("NFS Portmap"); Or, at least, that's the only occurance of "NFS Portmap" that I can find. Now, looking through mount_nfs.c, retrycnt is set to 1000 as DEF_RETRY, so this loop is going to try 1000 times before it gives up (excessive, no? *grin*) Now, port_no is set to zero, so tport is to be set to the result of pmap_getport() (bear with me, I don't know sockets very well...yet) So, so far as I can see, tport isn't getting a port number set to it by pmap_getport(), since the only way that tport could evaluate to be zero is if port_no is zero, which forces tport to try pmap_getport()... correct? So, assuming that pmap_getport() isn't giving me a port number (and, if I'm totally off track here, please let me know where my analysis failed for next time) ... The only thing in pmap_getport() that I do not understand is this "call": if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms, xdr_u_short, &port, tottimeout) != RPC_SUCCESS){ which maps to, in /usr/include/rpc/clnt.h: #define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \ ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) How exactly do I interprete this call? :( Okay, my head is spinning now, I've tried to look even deeper and now its starting to go over my head (need to get a book on sockets). *pause*...I think I got it after going through it *again*... This is out of /usr/src/lib/libc/rpc/pmap_getport.c: client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); if (client != (CLIENT *)NULL) { parms.pm_prog = program; parms.pm_vers = version; parms.pm_prot = protocol; parms.pm_port = 0; /* not needed or used */ if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms, xdr_u_short, &port, tottimeout) != RPC_SUCCESS){ rpc_createerr.cf_stat = RPC_PMAPFAILURE; clnt_geterr(client, &rpc_createerr.cf_error); } else if (port == 0) { rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; } CLNT_DESTROY(client); } (void)close(socket); address->sin_port = 0; return (port); Essentially, it creates a socket to the remote server(?), and if it gets the connection, CLNT_CALL is what queries the other end requesting a port number..? So, *if* CLNT_CALL is successful, and port was zero, then I should get a different response then "NFS Portmap: RPC Success", no? I should get whatever message PROGNOTREGISTSERED would generate, so either clntudp_bufcreate() is failing and port is being returned as zero, or something between the call to CLNT_CALL coming back successfully and the "return (port)" line is resetting port to zero. Does this make sense? If this does happen to make sense (long shot?), why isn't the above written something like: client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); if (client != (CLIENT *)NULL) { parms.pm_prog = program; parms.pm_vers = version; parms.pm_prot = protocol; parms.pm_port = 0; /* not needed or used */ if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms, xdr_u_short, &port, tottimeout) != RPC_SUCCESS){ rpc_createerr.cf_stat = RPC_PMAPFAILURE; clnt_geterr(client, &rpc_createerr.cf_error); } else if (port == 0) { rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; } CLNT_DESTROY(client); (void)close(socket); } else rpc_createerr.cf_stat = RPC_SYSTEMERROR; address->sin_port = 0; return (port); This way, you'd at least get an error message from mount_nfs that made sense. I'm going to leave this here for tonight, since if I'm way out in left field on this, there isn't much point in adding more...and if I'm not, well, I'm not quite sure where to go from here, so I leave it to those that understand sockets better then I. I've just re-sup'd in the sources, and there weren't any changes to anything that seemed related (libraries or utilities)...I don't know if this is a kernel problem, mind you, and there have been alot of changes there, but I'm not sure how they would be related. Marc G. Fournier scrappy@ki.net Systems Administrator @ ki.net scrappy@freebsd.org