From: per@erix.ericsson.se (Per Hedeland)
Subject: Re: Slave NIS Server Reboots -> Client Hangs?
Nntp-Posting-User: per
Organization: Ellemtel Telecom Systems Labs, Stockholm, Sweden
Date: Sun, 13 Dec 1992 19:37:06 GMT

In article <k231Hs&vab@atlantis.psu.edu> barr@pop.psu.edu (David Barr) writes:
>	Doncha just love NIS?  *sigh*.  There is a patch which
>"fixes" it, but at a significant performance penalty.  Here's part
>of the README for patch 100342-02:
[deleted]
>	Personally, I haven't applied this patch, but I'm tempted
>to.  I'm sick and tired of NIS just going out the window whenever
>an NIS client reboots.  Somehow I think Sun could have thought up
>a smarter fix to the problem than this.

They certainly could have, and fortunately for us Casper Dik did - I've
been running the patch below for 8 months now on SunOS 4.1.1 and 4.1.3,
works great - I recently added it to the static libc.a too, since emacs
(statically linked because of the need to do dump/undump) didn't benefit
otherwise. I've also found that some automounting that would previously
occasionally hang for a long time never does so anymore.

--Per Hedeland
per@erix.ericsson.se  or
per%erix.ericsson.se@sunic.sunet.se  or
...uunet!erix.ericsson.se!per


From: casper@fwi.uva.nl (Casper H.S. Dik)
Newsgroups: comp.sys.sun.misc,comp.sys.sun.admin
Subject: FIX for slow rebinding of NIS.
Summary: a small change in libc makes life with NIS a lot easier.
Date: 17 Jan 92 17:39:05 GMT
Organization: FWI, University of Amsterdam

Have you been plagued by long waits when your NIS server is rebooted?
READ ON!

Sun has a patch, but the README says:

********************* WARNING ******************************

  This is a new version of ypbind that never uses the NIS 
  binding file to cache the servers binding. This will have
  the effect of fixing the current symptom. However, it might
  degrade the overall performance of the system when the 
  server is available. This is most likely to happen on an
  overloaded server, which will cause the network to produce
  a broadcast storm. 

*************************************************************

Therefor, I have produced another fix.

o What goes wrong.

When the NIS server is rebooted, ypserv will obtain different ports
to listen for RPC requests. All clients will continue to use the old
binding they obtained earlier. The NIS server will send ICMP dst unreachable
messages for the RPC requests that arrive at the old port. These ICMPs
are dropped on the floor and the client code will continue sending the
requests until the timer has expired. The small fix at the end of this
message will pick up these ICMP messages and deliver them to the RPC layer.

o Before and after.

I've tested this on some machines and this is the result:

	(kill and restart ypserv on the server)

original% time ypmatch user passwd
user:....
0.040u 0.090s 2:35.64 0.0% 0+126k 0+0io 0pf+0w (155 seconds elapsed time)

fixedhost% time ypmatch user passwd
user:....
0.050u 0.050s 0:10.20 0.9% 0+136k 0+0io 0pf+0w (10 seconds elapsed time)

Rebinding is almost instantaneous.

o Other benefits.
	RPC calls that use UDP as transport will no longer time out but
	will abort much sooner. (E.g., the remote host is unreachable or
	111/udp is filtered by an intermediate router)


o How to apply the fix.

	- obtain clnt_udp.c from SUNRPC 4.0
	  SUNRPC 4.0 is available at numerous FTP sites, e.g.,
	  ftp.uu.net:/systems/sun/sextape/rpc4.0/rpc/clnt_udp.c.Z

	- apply the context diff at the end of this messages.
	  
	- compile:
		cc -O4 -c -pic clnt_udp.c
	  install the obtained clnt_udp.o in the shared library.

	  See /usr/lib/shlib.etc/README for details. If you run SunOS 4.1.2,
	  you must change the following in shlib.etc/Makefile (twice): 

	   ld -assert pure-text `${OBJSORT} lorder-sparc tmp`
	  to
	   ld -assert pure-text `${OBJSORT} lorder-sparc tmp` -ldl

	 - test the new shared library.
	   % setenv LD_LIBRARY_PATH <where the library is>
	   % ldd /usr/etc/rpcinfo 
		-lc.1 => <the new library>
		-ldl.1 => ...		(with SunOS 4.1.2)
	   % /usr/etc/rpcinfo -u <host> ypserv
	   if <host> is unreachable, or if host does not run the portmapper
	   the (immediate) response should be:

	   rpcinfo: RPC: Port mapper failure - RPC: Unable to receive
	   program 100004 is not available

	   

Casper

*** clnt_udp.c.orig	Thu Mar 14 12:52:12 1991
--- clnt_udp.c	Fri Jan 17 17:55:39 1992
***************
*** 27,32 ****
--- 27,37 ----
   * 2550 Garcia Avenue
   * Mountain View, California  94043
   */
+ /*
+  * Casper Dik (casper@fwi.uva.nl)
+  * changed sendto in clntudp_call to connect/send.
+  * This enables the caller to receive ICMP messages as Host or port unreachable
+  */
  #if !defined(lint) && defined(SCCSIDS)
  static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";
  #endif
***************
*** 256,265 ****
  		return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
  	outlen = (int)XDR_GETPOS(xdrs);
  
  send_again:
! 	if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
! 	    (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen)
! 	    != outlen) {
  		cu->cu_error.re_errno = errno;
  		return (cu->cu_error.re_status = RPC_CANTSEND);
  	}
--- 261,280 ----
  		return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
  	outlen = (int)XDR_GETPOS(xdrs);
  
+ 	/*
+ 	 * Give error (ECONNREFUSED/EHOSTUNREACH) instead of timeout.
+ 	 * Gives much faster NIS rebinding.
+ 	 * Errors are not detected here, but in the recvfrom()
+ 	 * following the select().
+ 	 */
+ 	if (connect(cu->cu_sock, (struct sockaddr *)(&cu->cu_raddr),
+ 	    cu->cu_rlen) != 0) {
+ 		cu->cu_error.re_errno = errno;
+ 		return (cu->cu_error.re_status = RPC_CANTSEND);
+ 	}
+ 
  send_again:
! 	if (send(cu->cu_sock, cu->cu_outbuf, outlen, 0) != outlen) {
  		cu->cu_error.re_errno = errno;
  		return (cu->cu_error.re_status = RPC_CANTSEND);
  	}
-- 
						|	Casper H.S. Dik
						|	casper@fwi.uva.nl


Newsgroups: comp.sys.sun.admin