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



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
--- 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);


Home | Main Index | Thread Index | Old Index