NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: lib/46111: yplib will hang forever if no server can be found
The following reply was made to PR lib/46111; it has been noted by GNATS.
From: Wolfgang Stukenbrock <Wolfgang.Stukenbrock%nagler-company.com@localhost>
To: Christos Zoulas <christos%zoulas.com@localhost>
Cc: Wolfgang Stukenbrock <Wolfgang.Stukenbrock%nagler-company.com@localhost>,
gnats-bugs%NetBSD.org@localhost, lib-bug-people%NetBSD.org@localhost,
gnats-admin%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
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--
Home |
Main Index |
Thread Index |
Old Index