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:
(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.