bin/73422: portmap forks ad infinitum when the NIS domain name
is set, probably a bug in the RPC library
Trond Endrestøl
Trond.Endrestol at gtf.ol.no
Fri Nov 12 05:50:40 PST 2004
The following reply was made to PR bin/73422; it has been noted by GNATS.
From: =?ISO-8859-1?Q?Trond_Endrest=F8l?= <Trond.Endrestol at gtf.ol.no>
To: FreeBSD-gnats-submit at freebsd.org
Cc:
Subject: Re: bin/73422: portmap forks ad infinitum when the NIS domain name
is set, probably a bug in the RPC library
Date: Fri, 12 Nov 2004 14:42:45 +0100 (CET)
This is a followup to the original PR. I have done some further
investigations and believe to have isolated the problem.
>Submitter-Id: current-users
>Originator: Trond Endrestøl
>Organization: Private
>Confidential: no
>Synopsis: portmap forks ad infinitum if verbose logging is turned on and NIS domainname is set
>Severity: serious
>Priority: high
>Category: bin
>Class: sw-bug
>Release: FreeBSD 4.10-RELEASE i386
>Environment:
System: FreeBSD sovereign.bsd.net 4.10-RELEASE FreeBSD 4.10-RELEASE #0: Fri Oct 22 22:31:31 CEST 2004 root at sovereign.bsd.net:/usr/src/sys/compile/SOVEREIGN i386
Pentium 133 MHz running FreeBSD 4.10-RELEASE
>Description:
1. If portmap is running with verbose logging (-v) and the NIS
domain name is set, it will try to resolve RPC program numbers
into names using getrpcbynumber() in logit() in pmap_check.c
2. This results in a new request to portmap about the port number
for ypbind. ypbind may not have registered yet with portmap,
and due to the verbose logging, portmap attempts another call
to getrpcbynumber(). As portmap does the logging by forking
a child to do the work, this leads to hundreds, if not
thousands, of portmap processes getting nowhere.
3. End result is a utmost slow system, with a non-functioning
portmapper, and a system in desperate need of operator attention.
>How-To-Repeat:
Run portmap with verbose logging turned on (-v) and
with the NIS domain name set to a valid value
(e.g. nisdomainname="blah.blah.blah").
>Fix:
Simplest solution:
Advice users to run portmap without verbose logging if running NIS.
I.e., make a point of this in the FreeBSD Handbook if nothing
further is done to correct the issue.
A better solution:
Change ypbind to check the NIS domain name after processing
the command line. The domain name may have been set by using
-S domain,nisserver1,nisserver2,...
See patch below for ypbind.c.
Change portmap not to resolve RPC program numbers into names
when doing verbose logging. See patch below for pmap_check.c.
If possible to resolve RPC program numbers using something
other than NIS even if the NIS domain name is set, use that
approach.
Change /etc/rc.network to unset the NIS domain name early in
network_pass1(). This helps if the user recently went from
multiuser mode to single user mode, and wants to go back
to multiuser mode. Otherwise, programs such as named tries to
contact portmap and may suspend the booting process for
a minute or so. Let /etc/rc.network set the NIS domain name
just prior to launching ypserv and other NIS related servers.
See patch below for /etc/rc.network.
If nothing is done with pmap_check.c as described above,
still let /etc/rc.network unset the NIS domain name at
the beginning of execution, and set the NIS domain name after
ypbind is launched. Programs such as rpc.yppasswdd and ypbind
need to be told the NIS domain name using command line
options.
Patches follows:
*** ypbind.c.orig Fri Feb 15 01:46:59 2002
--- ypbind.c Tue Nov 2 15:54:05 2004
***************
*** 403,413 ****
if (flock(yplockfd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK)
errx(1, "another ypbind is already running. Aborting");
- /* XXX domainname will be overriden if we use restricted mode */
- yp_get_default_domain(&domain_name);
- if (domain_name[0] == '\0')
- errx(1, "domainname not set. Aborting");
-
for (i = 1; i<argc; i++) {
if (strcmp("-ypset", argv[i]) == 0)
ypsetmode = YPSET_ALL;
--- 403,408 ----
***************
*** 419,424 ****
--- 414,426 ----
yp_restricted_mode(argv[i+1]);
else if (strcmp("-m", argv[i]) == 0)
yp_manycast++;
+ }
+
+ if (domain_name == NULL || domain_name[0] == '\0') {
+ /* XXX domainname will be overriden if we use restricted mode */
+ yp_get_default_domain(&domain_name);
+ if (domain_name[0] == '\0')
+ errx(1, "domainname not set. Aborting");
}
/* blow away everything in BINDINGDIR (if it exists) */
*** pmap_check.c.orig Sun Jan 16 00:08:28 2000
--- pmap_check.c Fri Nov 12 12:32:35 2004
***************
*** 238,246 ****
if (prognum == 0) {
progname = "";
! } else if ((rpc = getrpcbynumber((int) prognum))) {
progname = rpc->r_name;
! } else {
sprintf(progbuf, "%lu", prognum);
progname = progbuf;
}
--- 238,246 ----
if (prognum == 0) {
progname = "";
! } /* else if ((rpc = getrpcbynumber((int) prognum))) {
progname = rpc->r_name;
! } */ else {
sprintf(progbuf, "%lu", prognum);
progname = progbuf;
}
*** rc.network.orig Tue May 25 23:28:42 2004
--- rc.network Fri Nov 12 13:38:42 2004
***************
*** 133,148 ****
;;
esac
! # Set the domainname if we're using NIS
#
! case ${nisdomainname} in
! [Nn][Oo] | '')
! ;;
! *)
! domainname ${nisdomainname}
! echo -n ' domain'
! ;;
! esac
echo '.'
--- 133,142 ----
;;
esac
! # Unset the domainname, it will be set later if requested
#
! domainname ''
! echo -n ' domain (unset)'
echo '.'
***************
*** 579,584 ****
--- 573,589 ----
case ${portmap_enable} in
[Yy][Ee][Ss])
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
+ ;;
+ esac
+
+ # Set the domainname if we're using NIS
+ #
+ case ${nisdomainname} in
+ [Nn][Oo] | '')
+ ;;
+ *)
+ domainname ${nisdomainname}
+ echo -n " domain (${nisdomainname})"
;;
esac
--
----------------------------------------------------------------------
Trond Endrestøl | trond at ramstind.gtf.ol.no
Patron of The Art of Computer Programming| FreeBSD 4.8-S & Pine 4.55
More information about the freebsd-bugs
mailing list