NetBSD Problem Report #46111

From Wolfgang.Stukenbrock@nagler-company.com  Tue Feb 28 16:18:07 2012
Return-Path: <Wolfgang.Stukenbrock@nagler-company.com>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	by www.NetBSD.org (Postfix) with ESMTP id D5C5E63B952
	for <gnats-bugs@gnats.NetBSD.org>; Tue, 28 Feb 2012 16:18:06 +0000 (UTC)
Message-Id: <20120228161800.893041E80A5@test-s0.nagler-company.com>
Date: Tue, 28 Feb 2012 17:18:00 +0100 (CET)
From: Wolfgang.Stukenbrock@nagler-company.com
Reply-To: Wolfgang.Stukenbrock@nagler-company.com
To: gnats-bugs@gnats.NetBSD.org
Subject: yplib will hang forever if no server can be found
X-Send-Pr-Version: 3.95

>Number:         46111
>Category:       lib
>Synopsis:       yplib will hang forever if no server can be found
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Feb 28 16:20:01 +0000 2012
>Closed-Date:    Thu Jan 03 23:48:19 +0000 2013
>Last-Modified:  Mon Jan 07 12:35:02 +0000 2013
>Originator:     Wolfgang Stukenbrock
>Release:        NetBSD 5.1
>Organization:
Dr. Nagler & Company GmbH
>Environment:


System: NetBSD test-s0 4.0 NetBSD 4.0 (NSW-WS) #0: Tue Aug 17 17:28:09 CEST 2010 wgstuken@test-s0:/usr/src/sys/arch/amd64/compile/NSW-WS amd64
Architecture: x86_64
Machine: amd64
>Description:
	The original yplib.c from Sun has a bug that it will hang forever
	in some situations, if no yp-server can be found.
	In some other situation YPERR_YPBIND is returned.
	This is very ugly if an application may be instructed to get some
	information from a random domain, because this may lockup the
	application.
	The following patch will return after the "normal" retry processing,
	if no yp-server can be found to avoid this hangup.
	The patch will still block forever, if a yp-server has been found
	before but currently no yp-server can be reached for the desired
	domain anymore.
	This preserves the current behaviour for applications that need it if
	a server has been reached before, but allows to request data from
	not-reachable domains without blocking forever.
>How-To-Repeat:
	Setup yp and try "ypcat -d yomething passwd". It will hang forever.
>Fix:
	The following fix should be applied to /usr/src/lib/libc/yp/yplib.c
	to add this fix.
--- yplib.c     2011/12/27 12:04:10     1.1
+++ yplib.c     2011/12/27 12:05:32
@@ -220,6 +220,11 @@
                    "YP server for domain %s not responding, still trying\n",
                                    dom);
                        }
+                       else if (new == 1 && ++nerrs == _yplib_nerrs) {
+// first connect to domain on network fails - do not loop forever here ...
+                         free(ysd);
+                         return YPERR_YPBIND;
+                       }
                        clnt_destroy(client);
                        ysd->dom_vers = -1;
                        goto again;

>Release-Note:

>Audit-Trail:
From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@NetBSD.org, lib-bug-people@netbsd.org, 
	gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Cc: 
Subject: Re: lib/46111: yplib will hang forever if no server can be found
Date: Tue, 28 Feb 2012 13:40:45 -0500

 On Feb 28,  4:20pm, Wolfgang.Stukenbrock@nagler-company.com (Wolfgang.Stukenbrock@nagler-company.com) wrote:
 -- Subject: lib/46111: yplib will hang forever if no server can be found

 | 	The original yplib.c from Sun has a bug that it will hang forever
 | 	in some situations, if no yp-server can be found.

 Yes, I think that this was done by design. Back when I was at school,
 we had 1 yp server and many clients. When the server crashed, people
 tended to reboot their workstations which would then come back up before
 the server finished fsck, thus not finding any nis server. When ypbind
 tried to start, they would hang and wait saying:

     'yp server not responding; still trying'

 instead of letting it fail and proceeding. This behavior was useful,
 because most of the user and group database was not stored locally,
 so coming up multi-user without it would require a reboot anyway.

 All these have changed right now, but I would prefer to make such a change
 in a compatible way, letting the program choose its behavior with a flag
 or some configuration file.

 christos

From: Wolfgang Stukenbrock <Wolfgang.Stukenbrock@nagler-company.com>
To: gnats-bugs@NetBSD.org
Cc: lib-bug-people@NetBSD.org, gnats-admin@NetBSD.org, netbsd-bugs@NetBSD.org,
        Wolfgang.Stukenbrock@nagler-company.com
Subject: Re: lib/46111: yplib will hang forever if no server can be found
Date: Wed, 29 Feb 2012 08:59:03 +0100

 Hi,

 I've no problem with such a sollution.
 At least "my" application will have no problem with setting a global 
 variable in the library to an other value.

 Any suggestions about a name for this.
 I can prepare a patch to the libs and the manual pages then.

 best regards

 W. Stukenbrock

 Christos Zoulas wrote:

 > The following reply was made to PR lib/46111; it has been noted by GNATS.
 > 
 > From: christos@zoulas.com (Christos Zoulas)
 > To: gnats-bugs@NetBSD.org, lib-bug-people@netbsd.org, 
 > 	gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
 > Cc: 
 > Subject: Re: lib/46111: yplib will hang forever if no server can be found
 > Date: Tue, 28 Feb 2012 13:40:45 -0500
 > 
 >  On Feb 28,  4:20pm, Wolfgang.Stukenbrock@nagler-company.com (Wolfgang.Stukenbrock@nagler-company.com) wrote:
 >  -- Subject: lib/46111: yplib will hang forever if no server can be found
 >  
 >  | 	The original yplib.c from Sun has a bug that it will hang forever
 >  | 	in some situations, if no yp-server can be found.
 >  
 >  Yes, I think that this was done by design. Back when I was at school,
 >  we had 1 yp server and many clients. When the server crashed, people
 >  tended to reboot their workstations which would then come back up before
 >  the server finished fsck, thus not finding any nis server. When ypbind
 >  tried to start, they would hang and wait saying:
 >  
 >      'yp server not responding; still trying'
 >  
 >  instead of letting it fail and proceeding. This behavior was useful,
 >  because most of the user and group database was not stored locally,
 >  so coming up multi-user without it would require a reboot anyway.
 >  
 >  All these have changed right now, but I would prefer to make such a change
 >  in a compatible way, letting the program choose its behavior with a flag
 >  or some configuration file.
 >  
 >  christos
 >  
 > 


 -- 


 Dr. Nagler & Company GmbH
 Hauptstraße 9
 92253 Schnaittenbach

 Tel. +49 9622/71 97-42
 Fax +49 9622/71 97-50

 Wolfgang.Stukenbrock@nagler-company.com
 http://www.nagler-company.com


 Hauptsitz: Schnaittenbach
 Handelregister: Amberg HRB
 Gerichtsstand: Amberg
 Steuernummer: 201/118/51825
 USt.-ID-Nummer: DE 273143997
 Geschäftsführer: Dr. Martin Nagler, Dr. Dr. Karl-Kuno Kunze


From: christos@zoulas.com (Christos Zoulas)
To: Wolfgang Stukenbrock <Wolfgang.Stukenbrock@nagler-company.com>, 
	gnats-bugs@NetBSD.org
Cc: lib-bug-people@NetBSD.org, gnats-admin@NetBSD.org, 
	netbsd-bugs@NetBSD.org
Subject: Re: lib/46111: yplib will hang forever if no server can be found
Date: Wed, 29 Feb 2012 08:58:53 -0500

 On Feb 29,  8:59am, Wolfgang.Stukenbrock@nagler-company.com (Wolfgang Stukenbrock) wrote:
 -- Subject: Re: lib/46111: yplib will hang forever if no server can be found

 | Hi,
 | 
 | I've no problem with such a sollution.
 | At least "my" application will have no problem with setting a global 
 | variable in the library to an other value.
 | 
 | Any suggestions about a name for this.
 | I can prepare a patch to the libs and the manual pages then.
 | 
 | best regards
 | 
 | W. Stukenbrock

 How about 'void yp_setbindtries(int ntries)', where 0 means infinity?

 christos

From: Manuel Bouyer <bouyer@antioche.eu.org>
To: Christos Zoulas <christos@zoulas.com>
Cc: gnats-bugs@NetBSD.org, lib-bug-people@NetBSD.org, gnats-admin@NetBSD.org,
        netbsd-bugs@NetBSD.org
Subject: Re: lib/46111: yplib will hang forever if no server can be found
Date: Wed, 29 Feb 2012 16:07:26 +0100

 On Tue, Feb 28, 2012 at 01:40:45PM -0500, Christos Zoulas wrote:
 > On Feb 28,  4:20pm, Wolfgang.Stukenbrock@nagler-company.com (Wolfgang.Stukenbrock@nagler-company.com) wrote:
 > -- Subject: lib/46111: yplib will hang forever if no server can be found
 > 
 > | 	The original yplib.c from Sun has a bug that it will hang forever
 > | 	in some situations, if no yp-server can be found.
 > 
 > Yes, I think that this was done by design. Back when I was at school,
 > we had 1 yp server and many clients. When the server crashed, people
 > tended to reboot their workstations which would then come back up before
 > the server finished fsck, thus not finding any nis server. When ypbind
 > tried to start, they would hang and wait saying:
 > 
 >     'yp server not responding; still trying'
 > 
 > instead of letting it fail and proceeding. This behavior was useful,
 > because most of the user and group database was not stored locally,
 > so coming up multi-user without it would require a reboot anyway.

 I second this. Linux clients bail out after a while; after a power outage
 clients usually are at ypbind stage before the network is back up (especially
 when the server's UPS exhausted its batteries). This leaves the clients 
 multiusers but unusable, while the NetBSD clients just waits for a server
 to be there, and recover without manual intervention.

 -- 
 Manuel Bouyer <bouyer@antioche.eu.org>
      NetBSD: 26 ans d'experience feront toujours la difference
 --

From: Wolfgang Stukenbrock <Wolfgang.Stukenbrock@nagler-company.com>
To: gnats-bugs@NetBSD.org
Cc: lib-bug-people@NetBSD.org, gnats-admin@NetBSD.org, netbsd-bugs@NetBSD.org,
        Wolfgang.Stukenbrock@nagler-company.com
Subject: Re: lib/46111: yplib will hang forever if no server can be found
Date: Wed, 29 Feb 2012 16:35:16 +0100

 Hi,

 I'm not shure if a function is a good idea, because there is already a 
 global variable _yplib_nerrs that is set to 5 as default.
 As far as I've figured out _yplib_nerrs is used in some files in 
 src/lib/libc/yp and is not documented in any headerfiles and/or the 
 manual. It seems to be a global libc-internal variable.
 A disadvantage of a function is the missing ability to query the current 
 state.
 So I would prefer a variable, but I can implement a function too, if you 
 prefer this.

 Currently after _yplib_nerrs number of retries the message "YP server 
 for ... still trying" is printed, but only if the domain is already 
 found in the _ypbindlist. No printing is done for the first contact with 
 ypbind - or I've overlooked something.
 This looks like someone has changed the original Sun behaviour in the 
 past that is printing this message as far as I remember even for the 
 first connection attemp.
 remark: an entry is added to the _ypbindlist after successfull 
 contacting ypbind or if a binding file is present and valid.

 If there is a binding file present for the domain, and the file locking 
 fails, YPERR_YPBIND is returned without contacting ypbind.
 When contacting ypbind, YPERR_YPBIND is returned too if clnttcp_create() 
 fails.
 Theese both should be very rare situations, but will already currently 
 not wait until a server is available.

 In e.g. yp_first and yp_next the variable _yplib_nerrs is used to print 
 a message too if the binding has succeeded but the clnt_call() has 
 failed the configured number of times. This will be done in an endless 
 loop too, if the binding succeded every time.
 Should this behaviour be changed too? If the binding fails, YPERR_DOMAIN 
 is returned.

 I aggree not to change de default behaviour of the lib, but allow to 
 change it unter program control. At least I need currently need the 
 possibility to catch the problem with ypbind to faile my request and 
 continue to work.


 My "current" patch will return YPERR_YPBIND only if there is no 
 previously setup entry in the _ypbindlist.
 Should I also terminate the processing after <n> retries, if there is an 
 entry in _ypbindlist present? I think yes.
 Should in such case the "still trying" message be written to stderr or 
 should the lib be silent. I think no printing should be done.

 What about the following sollution:
 I reuse _yplib_nerrs for the new functionality.
    _yplib_nerrs > 0 - current behaviour - wait endless and print a 
 message every _yplib_nerrs retries. The default value will be 5 as before.
    _yplib_nerrs == 0 - wait endless without printing to stderr
    (this is something that would already happen now when _yplib_nerrs 
 gets set to 0, because the print-check check starts with 1 and the first 
 printout will happen on the integer-wrap ...)
    _yplib_nerrs < 0 - number of retries (as negative count) with ypbind 
 after that YPERR_YPBIND is returned. And the lib will return regardless 
 if the domainname has been queried before or not.
 I will add it to the rpcsvc/ypclnt.h headerfile as extern declaration 
 and add it the to ypclnt(3) manual.

 This implies disabling the printing in the other routines (yp_first etc. 
 ) too on none-positive retry numbers.

 Is this OK?

 Best reguards

 W. Stukenbrock


 Christos Zoulas wrote:

 > The following reply was made to PR lib/46111; it has been noted by GNATS.
 > 
 > From: christos@zoulas.com (Christos Zoulas)
 > To: Wolfgang Stukenbrock <Wolfgang.Stukenbrock@nagler-company.com>, 
 > 	gnats-bugs@NetBSD.org
 > Cc: lib-bug-people@NetBSD.org, gnats-admin@NetBSD.org, 
 > 	netbsd-bugs@NetBSD.org
 > Subject: Re: lib/46111: yplib will hang forever if no server can be found
 > Date: Wed, 29 Feb 2012 08:58:53 -0500
 > 
 >  On Feb 29,  8:59am, Wolfgang.Stukenbrock@nagler-company.com (Wolfgang Stukenbrock) wrote:
 >  -- Subject: Re: lib/46111: yplib will hang forever if no server can be found
 >  
 >  | Hi,
 >  | 
 >  | I've no problem with such a sollution.
 >  | At least "my" application will have no problem with setting a global 
 >  | variable in the library to an other value.
 >  | 
 >  | Any suggestions about a name for this.
 >  | I can prepare a patch to the libs and the manual pages then.
 >  | 
 >  | best regards
 >  | 
 >  | W. Stukenbrock
 >  
 >  How about 'void yp_setbindtries(int ntries)', where 0 means infinity?
 >  
 >  christos
 >  
 > 


From: christos@zoulas.com (Christos Zoulas)
To: Wolfgang Stukenbrock <Wolfgang.Stukenbrock@nagler-company.com>, 
	gnats-bugs@NetBSD.org
Cc: lib-bug-people@NetBSD.org, gnats-admin@NetBSD.org, 
	netbsd-bugs@NetBSD.org
Subject: Re: lib/46111: yplib will hang forever if no server can be found
Date: Wed, 29 Feb 2012 11:14:56 -0500

 On Feb 29,  4:35pm, Wolfgang.Stukenbrock@nagler-company.com (Wolfgang Stukenbrock) wrote:
 -- Subject: Re: lib/46111: yplib will hang forever if no server can be found

 | Hi,
 | 
 | I'm not shure if a function is a good idea, because there is already a 
 | global variable _yplib_nerrs that is set to 5 as default.
 | As far as I've figured out _yplib_nerrs is used in some files in 
 | src/lib/libc/yp and is not documented in any headerfiles and/or the 
 | manual. It seems to be a global libc-internal variable.
 | A disadvantage of a function is the missing ability to query the current 
 | state.
 | So I would prefer a variable, but I can implement a function too, if you 
 | prefer this.

 make it return the current state then, and ignore the setting if the setting
 is negative.

 | Currently after _yplib_nerrs number of retries the message "YP server 
 | for ... still trying" is printed, but only if the domain is already 
 | found in the _ypbindlist. No printing is done for the first contact with 
 | ypbind - or I've overlooked something.
 | This looks like someone has changed the original Sun behaviour in the 
 | past that is printing this message as far as I remember even for the 
 | first connection attemp.
 | remark: an entry is added to the _ypbindlist after successfull 
 | contacting ypbind or if a binding file is present and valid.
 | 
 | If there is a binding file present for the domain, and the file locking 
 | fails, YPERR_YPBIND is returned without contacting ypbind.
 | When contacting ypbind, YPERR_YPBIND is returned too if clnttcp_create() 
 | fails.
 | Theese both should be very rare situations, but will already currently 
 | not wait until a server is available.
 | 
 | In e.g. yp_first and yp_next the variable _yplib_nerrs is used to print 
 | a message too if the binding has succeeded but the clnt_call() has 
 | failed the configured number of times. This will be done in an endless 
 | loop too, if the binding succeded every time.
 | Should this behaviour be changed too? If the binding fails, YPERR_DOMAIN 
 | is returned.
 | 
 | I aggree not to change de default behaviour of the lib, but allow to 
 | change it unter program control. At least I need currently need the 
 | possibility to catch the problem with ypbind to faile my request and 
 | continue to work.
 | 
 | 
 | My "current" patch will return YPERR_YPBIND only if there is no 
 | previously setup entry in the _ypbindlist.
 | Should I also terminate the processing after <n> retries, if there is an 
 | entry in _ypbindlist present? I think yes.
 | Should in such case the "still trying" message be written to stderr or 
 | should the lib be silent. I think no printing should be done.
 | 
 | What about the following sollution:
 | I reuse _yplib_nerrs for the new functionality.
 |    _yplib_nerrs > 0 - current behaviour - wait endless and print a 
 | message every _yplib_nerrs retries. The default value will be 5 as before.
 |    _yplib_nerrs == 0 - wait endless without printing to stderr
 |    (this is something that would already happen now when _yplib_nerrs 
 | gets set to 0, because the print-check check starts with 1 and the first 
 | printout will happen on the integer-wrap ...)
 |    _yplib_nerrs < 0 - number of retries (as negative count) with ypbind 
 | after that YPERR_YPBIND is returned. And the lib will return regardless 
 | if the domainname has been queried before or not.
 | I will add it to the rpcsvc/ypclnt.h headerfile as extern declaration 
 | and add it the to ypclnt(3) manual.
 | 
 | This implies disabling the printing in the other routines (yp_first etc. 
 | ) too on none-positive retry numbers.
 | 
 | Is this OK?

 I think it is cleaner not to oveload the variable this way and use a new one.
 Alterning the behavior of internal variables that are present in most reference
 implementations is not a good idea, because if you take the code from NetBSD
 to another OS it will not behave as expected. With the new function at least
 you get a link error that tells you that you need to do something else.

 christos

From: Wolfgang Stukenbrock <Wolfgang.Stukenbrock@nagler-company.com>
To: Christos Zoulas <christos@zoulas.com>
Cc: Wolfgang Stukenbrock <Wolfgang.Stukenbrock@nagler-company.com>,
        gnats-bugs@NetBSD.org, lib-bug-people@NetBSD.org,
        gnats-admin@NetBSD.org, netbsd-bugs@NetBSD.org
Subject: Re: lib/46111: yplib will hang forever if no server can be found
Date: Fri, 02 Mar 2012 13:07:29 +0100

 This is a multi-part message in MIME format.
 --------------070607020409060700060200
 Content-Type: text/plain; charset=us-ascii; format=flowed
 Content-Transfer-Encoding: 7bit

 Hi again,

 it takes some time to test (I hope) all aspects of the following patches 
   to the yp-subsystem.

 (I hope that attaching the output of "diff -u" as a file is good for 
 this tracing system. If not please contact me and I will place in the 
 normal text flow ...)

 I've added a new funtion "int yp_setbindtries(int)" that will set a 
 max-retry parameter in the libc. The default is 0 - infinit. If the new 
 function is not called, everything behaves as before.
 If called with a negative number only the current value is returned 
 without changeing it.
 At least on my test-system each retry takes aprox. 10 seconds. So 
 setting the retry count to 3 will return after 30 seconds with an error.
 The value of 10 seconds is NOT stated in the manual, because I'm not 
 shure if this will be valid if someone changes network parameters.

 The manual ypclnt(3) has been expanded and a manual link from 
 yp_setbindtries(3) to it gets installed. (Tested on an amd64-machine, 
 that has been setup from cratch for testing.)

 The user commands ypcat and ypmatch now have a new options "-b <num>" 
 that will use this new call.
 The effect is, that ypcat/ypmatch can now return an error and do not 
 hang forever if called with "-d <domain>" when no ypserver for that 
 domain exists. (Will of cause work with the default domain too.)
 The new options is added to the  manuals for this commands.

 Feel free to adjust the text in the manuals if desired.

 Best regards

 W. Stukenbrock

 --------------070607020409060700060200
 Content-Type: text/plain;
  name="yp-patch-diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="yp-patch-diff"

 --- src/include/rpcsvc/ypclnt.h	2012/03/01 08:20:00	1.1
 +++ src/include/rpcsvc/ypclnt.h	2012/03/01 08:20:53
 @@ -80,6 +80,7 @@
  int	yp_all		(const char *, const char *, struct ypall_callback *);
  char *	yperr_string	(int);
  int	ypprot_err	(unsigned int);
 +int	yp_setbindtries	(int);
  __END_DECLS

  #endif /* _RPCSVC_YPCLNT_H_ */
 --- src/distrib/sets/lists/comp/mi	2012/03/01 11:04:24	1.1
 +++ src/distrib/sets/lists/comp/mi	2012/03/01 11:06:56
 @@ -7858,6 +7858,7 @@
  ./usr/share/man/cat3/ypclnt.0			comp-c-catman		yp,.cat
  ./usr/share/man/cat3/yperr_string.0		comp-c-catman		yp,.cat
  ./usr/share/man/cat3/ypprot_err.0		comp-c-catman		yp,.cat
 +./usr/share/man/cat3/yp_setbindtries.0		comp-c-catman		yp,.cat
  ./usr/share/man/cat3/zlib.0			comp-c-catman		.cat
  ./usr/share/man/cat5/config.0			comp-util-catman	.cat
  ./usr/share/man/cat5/config.samples.0		comp-util-catman	.cat
 @@ -13115,6 +13116,7 @@
  ./usr/share/man/html3/ypclnt.html		comp-c-htmlman		yp,html
  ./usr/share/man/html3/yperr_string.html		comp-c-htmlman		yp,html
  ./usr/share/man/html3/ypprot_err.html		comp-c-htmlman		yp,html
 +./usr/share/man/html3/yp_setbindtries.html	comp-c-htmlman		yp,html
  ./usr/share/man/html3/zlib.html			comp-c-htmlman		html
  ./usr/share/man/html5/config.html		comp-util-htmlman	html
  ./usr/share/man/html5/config.samples.html	comp-util-htmlman	html
 @@ -18451,6 +18453,7 @@
  ./usr/share/man/man3/ypclnt.3			comp-c-man		yp,.man
  ./usr/share/man/man3/yperr_string.3		comp-c-man		yp,.man
  ./usr/share/man/man3/ypprot_err.3		comp-c-man		yp,.man
 +./usr/share/man/man3/yp_setbindtries.3		comp-c-man		yp,.man
  ./usr/share/man/man3/zlib.3			comp-c-man		.man
  ./usr/share/man/man5/config.5			comp-util-man		.man
  ./usr/share/man/man5/config.samples.5		comp-util-man		.man
 --- src/distrib/utils/libhack/yplib.c	2012/03/01 08:15:52	1.1
 +++ src/distrib/utils/libhack/yplib.c	2012/03/01 10:51:04
 @@ -51,6 +51,7 @@
  #define yp_unbind		_yp_unbind
  #define yperr_string		_yperr_string
  #define ypprot_err		_ypprot_err
 +#define yp_setbindtries		_yp_setbindtries
  #endif

  #include <sys/types.h>
 @@ -76,7 +77,7 @@
  struct timeval _yplib_rpc_timeout = { YPLIB_TIMEOUT / YPLIB_RPC_RETRIES,
  	1000000 * (YPLIB_TIMEOUT % YPLIB_RPC_RETRIES) / YPLIB_RPC_RETRIES };
  int _yplib_nerrs = 5;
 -
 +int _yplib_bindtries = 0;

  #ifdef __weak_alias
  __weak_alias(yp_all,_yp_all);
 @@ -91,12 +92,22 @@
  __weak_alias(yp_unbind, _yp_unbind);
  __weak_alias(yperr_string,_yperr_string);
  __weak_alias(ypprot_err,_ypprot_err);
 +__weak_alias(yp_setbindtries, _yp_setbindtries)
  #endif

  void __yp_unbind __P((struct dom_binding *));
  int _yp_invalid_domain __P((const char *));

  int
 +yp_setbindtries(int ntries)
 +{
 +  int old_val = _yplib_bindtries;
 +
 +  if (ntries >= 0) _yplib_bindtries = ntries;
 +  return old_val;
 +}
 +
 +int
  _yp_dobind(dom, ypdb)
  	const char *dom;
  	struct dom_binding **ypdb;
 --- src/lib/libc/yp/yp_first.c	2012/03/01 08:05:48	1.1
 +++ src/lib/libc/yp/yp_first.c	2012/03/01 08:33:05
 @@ -41,6 +41,7 @@

  extern struct timeval _yplib_timeout;
  extern int _yplib_nerrs;
 +extern int _yplib_bindtries;

  #ifdef __weak_alias
  __weak_alias(yp_first,_yp_first)
 @@ -84,10 +85,13 @@
  	    (xdrproc_t)xdr_ypreq_nokey,
  	    &yprnk, (xdrproc_t)xdr_ypresp_key_val, &yprkv, _yplib_timeout);
  	if (r != RPC_SUCCESS) {
 -		if (++nerrs == _yplib_nerrs) {
 +		if (_yplib_bindtries <= 0 && ++nerrs == _yplib_nerrs) {
  			clnt_perror(ysd->dom_client, "yp_first: clnt_call");
  			nerrs = 0;
  		}
 +		else if (_yplib_bindtries > 0 && ++nerrs == _yplib_bindtries) {
 +			return YPERR_YPSERV;
 +		}
  		ysd->dom_vers = -1;
  		goto again;
  	}
 @@ -167,10 +171,13 @@
  	    (xdrproc_t)xdr_ypreq_key,
  	    &yprk, (xdrproc_t)xdr_ypresp_key_val, &yprkv, _yplib_timeout);
  	if (r != RPC_SUCCESS) {
 -		if (++nerrs == _yplib_nerrs) {
 +		if (_yplib_bindtries <= 0 && ++nerrs == _yplib_nerrs) {
  			clnt_perror(ysd->dom_client, "yp_next: clnt_call");
  			nerrs = 0;
  		}
 +		else if (_yplib_bindtries > 0 && ++nerrs == _yplib_bindtries) {
 +			return YPERR_YPSERV;
 +		}
  		ysd->dom_vers = -1;
  		goto again;
  	}
 --- src/lib/libc/yp/yp_maplist.c	2012/03/01 08:05:48	1.1
 +++ src/lib/libc/yp/yp_maplist.c	2012/03/01 08:35:13
 @@ -40,6 +40,7 @@

  extern struct timeval _yplib_timeout;
  extern int _yplib_nerrs;
 +extern int _yplib_bindtries;

  #ifdef __weak_alias
  __weak_alias(yp_maplist,_yp_maplist)
 @@ -68,10 +69,13 @@
  		   (xdrproc_t)xdr_ypdomain_wrap_string, &indomain,
  		   (xdrproc_t)xdr_ypresp_maplist, &ypml, _yplib_timeout);
  	if (r != RPC_SUCCESS) {
 -		if (++nerrs == _yplib_nerrs) {
 +		if (_yplib_bindtries <= 0 && ++nerrs == _yplib_nerrs) {
  			clnt_perror(ysd->dom_client, "yp_maplist: clnt_call");
  			nerrs = 0;
  		}
 +		else if (_yplib_bindtries > 0 && ++nerrs == _yplib_bindtries) {
 +			return YPERR_YPSERV;
 +		}
  		ysd->dom_vers = -1;
  		goto again;
  	}
 --- src/lib/libc/yp/yp_master.c	2012/03/01 08:05:48	1.1
 +++ src/lib/libc/yp/yp_master.c	2012/03/01 08:35:15
 @@ -41,6 +41,7 @@

  extern struct timeval _yplib_timeout;
  extern int _yplib_nerrs;
 +extern int _yplib_bindtries;

  #ifdef __weak_alias
  __weak_alias(yp_master,_yp_master)
 @@ -80,10 +81,13 @@
  		      (xdrproc_t)xdr_ypreq_nokey, &yprnk,
  		      (xdrproc_t)xdr_ypresp_master, &yprm, _yplib_timeout);
  	if (r != RPC_SUCCESS) {
 -		if (++nerrs == _yplib_nerrs) {
 +		if (_yplib_bindtries <= 0 && ++nerrs == _yplib_nerrs) {
  			clnt_perror(ysd->dom_client, "yp_master: clnt_call");
  			nerrs = 0;
  		}
 +		else if (_yplib_bindtries > 0 && ++nerrs == _yplib_bindtries) {
 +			return YPERR_YPSERV;
 +		}
  		ysd->dom_vers = -1;
  		goto again;
  	}
 --- src/lib/libc/yp/yp_match.c	2012/03/01 08:05:48	1.1
 +++ src/lib/libc/yp/yp_match.c	2012/03/01 08:35:20
 @@ -47,6 +47,7 @@

  extern struct timeval _yplib_timeout;
  extern int _yplib_nerrs;
 +extern int _yplib_bindtries;
  extern char _yp_domain[];

  #ifdef __weak_alias
 @@ -229,10 +230,13 @@
  		      (xdrproc_t)xdr_ypresp_val, &yprv, 
  		      _yplib_timeout);
  	if (r != RPC_SUCCESS) {
 -		if (++nerrs == _yplib_nerrs) {
 +		if (_yplib_bindtries <= 0 && ++nerrs == _yplib_nerrs) {
  			clnt_perror(ysd->dom_client, "yp_match: clnt_call");
  			nerrs = 0;
  		}
 +		else if (_yplib_bindtries > 0 && ++nerrs == _yplib_bindtries) {
 +			return YPERR_YPSERV;
 +		}
  		ysd->dom_vers = -1;
  		goto again;
  	}
 --- src/lib/libc/yp/yp_order.c	2012/03/01 08:05:48	1.1
 +++ src/lib/libc/yp/yp_order.c	2012/03/01 08:35:23
 @@ -40,6 +40,7 @@

  extern struct timeval _yplib_timeout;
  extern int _yplib_nerrs;
 +extern int _yplib_bindtries;

  #ifdef __weak_alias
  __weak_alias(yp_order,_yp_order)
 @@ -78,10 +79,13 @@
  		      (xdrproc_t)xdr_ypresp_order, &ypro, 
  		      _yplib_timeout);
  	if (r != RPC_SUCCESS) {
 -		if (++nerrs == _yplib_nerrs) {
 +		if (_yplib_bindtries <= 0 && ++nerrs == _yplib_nerrs) {
  			clnt_perror(ysd->dom_client, "yp_order: clnt_call");
  			nerrs = 0;
  		}
 +		else if (_yplib_bindtries > 0 && ++nerrs == _yplib_bindtries) {
 +			return YPERR_YPSERV;
 +		}
  	        if (r == RPC_PROCUNAVAIL) {
  			/* Case of NIS+ server in NIS compat mode */
  			r = YPERR_YPERR;
 --- src/lib/libc/yp/ypclnt.3	2012/03/01 08:36:33	1.1
 +++ src/lib/libc/yp/ypclnt.3	2012/03/01 08:52:02
 @@ -42,6 +42,7 @@
  .Nm yp_unbind ,
  .Nm yperr_string ,
  .Nm ypprot_err
 +.Nm yp_setbindtries
  .Nd Interface to the YP subsystem
  .Sh LIBRARY
  .Lb libc
 @@ -72,6 +73,8 @@
  .Fn yperr_string "int incode"
  .Ft int
  .Fn ypprot_err "unsigned int incode"
 +.Ft int
 +.Fn yp_setbindtries "int ntries"
  .Sh DESCRIPTION
  The
  .Nm ypclnt
 @@ -348,6 +351,16 @@
  .Nm ypclnt
  error code suitable for
  .Fn yperr_string .
 +.It Fn yp_setbindtries
 +Modifies blocking behaviour of the functions above and return previous state.
 +Default value is 0 which means wait forever if no ypserver can be found
 +or RPC-communication with ypserver fails.
 +If set to a value larger 0, the function called returns an error after
 +the specified number of failure.
 +If called with a value less 0, only the current setting is returned.
 +.Pp
 +This function is an extention to the client library that allows application
 +to catch communication problems with the ypserver without blocking forever.
  .El
  .Sh RETURN VALUES
  All functions in the
 --- src/lib/libc/yp/yplib.c	2011/12/27 12:04:10	1.1
 +++ src/lib/libc/yp/yplib.c	2012/03/01 08:34:51
 @@ -67,11 +67,13 @@
  struct timeval _yplib_rpc_timeout = { YPLIB_TIMEOUT / YPLIB_RPC_RETRIES,
  	1000000 * (YPLIB_TIMEOUT % YPLIB_RPC_RETRIES) / YPLIB_RPC_RETRIES };
  int _yplib_nerrs = 5;
 +int _yplib_bindtries = 0;

  #ifdef __weak_alias
  __weak_alias(yp_bind, _yp_bind)
  __weak_alias(yp_unbind, _yp_unbind)
  __weak_alias(yp_get_default_domain, _yp_get_default_domain)
 +__weak_alias(yp_setbindtries, _yp_setbindtries)
  #endif

  #ifdef _REENTRANT
 @@ -83,6 +85,14 @@
  #define YPUNLOCK()
  #endif

 +int yp_setbindtries(int ntries)
 +{
 +  int old_val = _yplib_bindtries;
 +
 +  if (ntries >= 0) _yplib_bindtries = ntries;
 +  return old_val;
 +}
 +
  int
  _yp_dobind(dom, ypdb)
  	const char     *dom;
 @@ -214,12 +224,18 @@
  		    (xdrproc_t)xdr_ypdomain_wrap_string, &dom,
  		    (xdrproc_t)xdr_ypbind_resp, &ypbr, _yplib_timeout);
  		if (r != RPC_SUCCESS) {
 -			if (new == 0 && ++nerrs == _yplib_nerrs) {
 +			if (_yplib_bindtries <= 0 && new == 0 &&
 +			    ++nerrs == _yplib_nerrs) {
  				nerrs = 0;
  				fprintf(stderr,
  		    "YP server for domain %s not responding, still trying\n",
  				    dom);
  			}
 +			else if (_yplib_bindtries > 0 &&
 +			         ++nerrs == _yplib_bindtries) {
 +				free(ysd);
 +				return YPERR_YPBIND;
 +			}
  			clnt_destroy(client);
  			ysd->dom_vers = -1;
  			goto again;
 --- src/lib/libc/include/namespace.h	2012/03/01 11:02:19	1.1
 +++ src/lib/libc/include/namespace.h	2012/03/01 11:03:13
 @@ -757,6 +757,7 @@
  #define yp_unbind		_yp_unbind
  #define yperr_string		_yperr_string
  #define ypprot_err		_ypprot_err
 +#define yp_setbindtries		_yp_setbindtries
  #define dlopen			__dlopen
  #define dlclose			__dlclose
  #define dlsym			__dlsym
 --- src/lib/libc/yp/Makefile.inc	2012/03/01 10:47:46	1.1
 +++ src/lib/libc/yp/Makefile.inc	2012/03/01 10:48:51
 @@ -10,4 +10,5 @@
  MLINKS+=ypclnt.3 yp_all.3 ypclnt.3 yp_bind.3 ypclnt.3 yp_first.3 \
  	ypclnt.3 yp_get_default_domain.3 ypclnt.3 yp_master.3 \
  	ypclnt.3 yp_match.3 ypclnt.3 yp_next.3 ypclnt.3 yp_order.3 \
 -	ypclnt.3 yp_unbind.3 ypclnt.3 yperr_string.3 ypclnt.3 ypprot_err.3
 +	ypclnt.3 yp_unbind.3 ypclnt.3 yperr_string.3 ypclnt.3 ypprot_err.3 \
 +	ypclnt.3 yp_setbindtries.3
 --- src/usr.bin/ypcat/ypcat.1	2012/03/01 11:35:22	1.1
 +++ src/usr.bin/ypcat/ypcat.1	2012/03/01 12:08:04
 @@ -37,6 +37,7 @@
  .Sh SYNOPSIS
  .Nm
  .Op Fl kt
 +.Op Fl b Ar num_retry
  .Op Fl d Ar domainname
  .Ar mapname
  .Nm
 @@ -51,6 +52,10 @@
  .Pp
  The options are as follows:
  .Bl -tag -width indent
 +.It Fl b Ar num_retry
 +Do not wait infinite time for ypserver to come up.
 +Retry only the specified number times. See 
 +.Xr yp_setbindtries 3 for explanation. Valid range is limited from 0 to 65535 by this program. 
  .It Fl d Ar domainname
  Specify a domain other than the default domain.
  .It Fl k
 @@ -67,6 +72,7 @@
  .Xr domainname 1 ,
  .Xr ypmatch 1 ,
  .Xr ypwhich 1 ,
 +.Xr yp_setbindtries 3 ,
  .Xr nis 8 ,
  .Xr ypbind 8 ,
  .Xr yppoll 8 ,
 --- src/usr.bin/ypcat/ypcat.c	2012/03/01 11:35:22	1.1
 +++ src/usr.bin/ypcat/ypcat.c	2012/03/01 12:11:32
 @@ -70,15 +70,15 @@
  	int argc;
  	char *argv[];
  {
 -	char *domainname;
 +	char *domainname, *b_retry_cnt;
  	struct ypall_callback ypcb;
  	char *inmap;
  	int notrans;
  	int c, r, i;

 -	domainname = NULL;
 +	domainname = b_retry_cnt = NULL;
  	notrans = key = 0;
 -	while((c = getopt(argc, argv, "xd:kt")) != -1) {
 +	while((c = getopt(argc, argv, "xb:d:kt")) != -1) {
  		switch (c) {
  		case 'x':
  			for (i = 0;
 @@ -88,6 +88,10 @@
  					ypaliases[i].name);
  			exit(0);

 +		case 'b':
 +			b_retry_cnt = optarg;
 +			break;
 +
  		case 'd':
  			domainname = optarg;
  			break;
 @@ -111,6 +115,15 @@
  	if (argc != 1)
  		usage();

 +	if (b_retry_cnt != NULL) {
 +		char *s;
 +		unsigned long l;
 +
 +		l = strtoul(b_retry_cnt, &s, 10);
 +		if (*s != '\0' || l > 0xffff) usage();
 +		yp_setbindtries((int)l);
 +	}
 +
  	if (domainname == NULL)
  		yp_get_default_domain(&domainname);

 @@ -162,7 +175,7 @@
  usage()
  {

 -	fprintf(stderr, "usage: %s [-k] [-d domainname] [-t] mapname\n",
 +	fprintf(stderr, "usage: %s [-b <num-retry>] [-k] [-d domainname] [-t] mapname\n",
  	    getprogname());
  	fprintf(stderr, "       %s -x\n", getprogname());
  	exit(1);
 --- src/usr.bin/ypmatch/ypmatch.1	2012/03/01 11:36:13	1.1
 +++ src/usr.bin/ypmatch/ypmatch.1	2012/03/01 12:08:10
 @@ -37,6 +37,7 @@
  .Sh SYNOPSIS
  .Nm
  .Op Fl ktz
 +.Op Fl b Ar num_retry
  .Op Fl d Ar domainname
  .Ar key ...
  .Ar mapname
 @@ -52,6 +53,10 @@
  .Pp
  The options are as follows:
  .Bl -tag -width indent
 +.It Fl b Ar num_retry
 +Do not wait infinite time for ypserver to come up.
 +Retry only the specified number times. See
 +.Xr yp_setbindtries 3 for explanation. Valid range is limited from 0 to 65535 by this program.
  .It Fl d Ar domainname
  Specify a domain other than the default domain.
  .It Fl k
 @@ -72,6 +77,7 @@
  .Xr domainname 1 ,
  .Xr ypcat 1 ,
  .Xr ypwhich 1 ,
 +.Xr yp_setbindtries 3 ,
  .Xr nis 8 ,
  .Xr ypbind 8 ,
  .Xr yppoll 8 ,
 --- src/usr.bin/ypmatch/ypmatch.c	2012/03/01 11:36:13	1.1
 +++ src/usr.bin/ypmatch/ypmatch.c	2012/03/01 12:11:27
 @@ -67,15 +67,15 @@
  	int argc;
  	char *argv[];
  {
 -	char *domainname;
 +	char *domainname, *b_retry_cnt;
  	char *inkey, *inmap, *outbuf;
  	int outbuflen, key, null, notrans;
  	int c, r, i, len;
  	int rval;

 -	domainname = NULL;
 +	domainname = b_retry_cnt = NULL;
  	notrans = key = null = 0;
 -	while ((c = getopt(argc, argv, "xd:ktz")) != -1) {
 +	while ((c = getopt(argc, argv, "xb:d:ktz")) != -1) {
  		switch (c) {
  		case 'x':
  			for(i = 0;
 @@ -85,6 +85,10 @@
  					ypaliases[i].name);
  			exit(0);

 +		case 'b':
 +			b_retry_cnt = optarg;
 +			break;
 +
  		case 'd':
  			domainname = optarg;
  			break;
 @@ -112,6 +116,15 @@
  	if (argc < 2)
  		usage();

 +	if (b_retry_cnt != NULL) {
 +		char *s;
 +		unsigned long l;
 +
 +		l = strtoul(b_retry_cnt, &s, 10);
 +		if (*s != '\0' || l > 0xffff) usage();
 +		yp_setbindtries((int)l);
 +	}
 +
  	if (domainname == NULL)
  		yp_get_default_domain(&domainname);

 @@ -157,7 +170,7 @@
  usage()
  {

 -	fprintf(stderr, "usage: %s [-d domain] [-tkz] key [key ...] "
 +	fprintf(stderr, "usage: %s [-b <num-retry>] [-d domain] [-tkz] key [key ...] "
  	    "mapname\n", getprogname());
  	fprintf(stderr, "       %s -x\n", getprogname());
  	exit(1);

 --------------070607020409060700060200--

From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/46111 CVS commit: src
Date: Fri, 2 Mar 2012 12:27:50 -0500

 Module Name:	src
 Committed By:	christos
 Date:		Fri Mar  2 17:27:49 UTC 2012

 Modified Files:
 	src/distrib/sets/lists/comp: mi
 	src/include/rpcsvc: ypclnt.h
 	src/lib/libc/include: namespace.h
 	src/lib/libc/yp: Makefile.inc yp_first.c yp_maplist.c yp_master.c
 	    yp_match.c yp_order.c ypclnt.3 yplib.c
 	src/usr.bin/ypcat: ypcat.1 ypcat.c
 	src/usr.bin/ypmatch: ypmatch.1 ypmatch.c

 Log Message:
 PR/46111: Wolfgang Stukenbrock: Add yp_setbindtries(3) so that yp operations
 don't hang forever if requested.


 To generate a diff of this commit:
 cvs rdiff -u -r1.1743 -r1.1744 src/distrib/sets/lists/comp/mi
 cvs rdiff -u -r1.13 -r1.14 src/include/rpcsvc/ypclnt.h
 cvs rdiff -u -r1.150 -r1.151 src/lib/libc/include/namespace.h
 cvs rdiff -u -r1.14 -r1.15 src/lib/libc/yp/Makefile.inc \
     src/lib/libc/yp/yp_first.c
 cvs rdiff -u -r1.11 -r1.12 src/lib/libc/yp/yp_maplist.c
 cvs rdiff -u -r1.13 -r1.14 src/lib/libc/yp/yp_master.c
 cvs rdiff -u -r1.17 -r1.18 src/lib/libc/yp/yp_match.c
 cvs rdiff -u -r1.12 -r1.13 src/lib/libc/yp/yp_order.c
 cvs rdiff -u -r1.24 -r1.25 src/lib/libc/yp/ypclnt.3
 cvs rdiff -u -r1.43 -r1.44 src/lib/libc/yp/yplib.c
 cvs rdiff -u -r1.19 -r1.20 src/usr.bin/ypcat/ypcat.1
 cvs rdiff -u -r1.16 -r1.17 src/usr.bin/ypcat/ypcat.c
 cvs rdiff -u -r1.16 -r1.17 src/usr.bin/ypmatch/ypmatch.1
 cvs rdiff -u -r1.19 -r1.20 src/usr.bin/ypmatch/ypmatch.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Thu, 03 Jan 2013 23:48:19 +0000
State-Changed-Why:
Committed by Christos back in March. Unless there's an explicit
need to, I think we won't bring this into netbsd-6. Let us know
if you need it.


From: Wolfgang Stukenbrock <wolfgang.stukenbrock@nagler-company.com>
To: gnats-bugs@NetBSD.org
Cc: lib-bug-people@NetBSD.org, netbsd-bugs@NetBSD.org, gnats-admin@NetBSD.org,
        dholland@NetBSD.org
Subject: Re: lib/46111 (yplib will hang forever if no server can be found)
Date: Mon, 07 Jan 2013 13:30:44 +0100

 Hi,

 if you have multiple NIS-domains (and servers) blocking forever in the 
 lib when a domain cannot be reached will hang up any application that 
 tries to get some information.

 We have a NIS-cache-Module integrated into apache, radius, .. for 
 authentification and/or authorisation and such a situation will lock up 
 the application, even if only one domain does not work.

 So I think this change should be integrated into all future releases.
 It is compartible with "previous" bahaviour if you do not explicitly 
 activate the do-not-hangup-mode.
 And we need it here.
 But I can add it in "our" version all the time in the future again, if 
 you decide not to keep it in future releases.

 best regards

 W. Stukenbrock


 dholland@NetBSD.org wrote:

 > Synopsis: yplib will hang forever if no server can be found
 > 
 > State-Changed-From-To: open->closed
 > State-Changed-By: dholland@NetBSD.org
 > State-Changed-When: Thu, 03 Jan 2013 23:48:19 +0000
 > State-Changed-Why:
 > Committed by Christos back in March. Unless there's an explicit
 > need to, I think we won't bring this into netbsd-6. Let us know
 > if you need it.
 > 
 > 
 > 
 > 
 > 


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.