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