misc/89762: top startup is very slow on system with many users

Oliver Brandmueller ob at e-gitt.net
Wed Nov 30 15:40:06 GMT 2005


>Number:         89762
>Category:       misc
>Synopsis:       top startup is very slow on system with many users
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Nov 30 15:40:05 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Oliver Brandmueller
>Release:        RELENG_6
>Organization:
>Environment:
FreeBSD waikiki.visp.de 6.0-STABLE FreeBSD 6.0-STABLE #0: Tue Nov 29 18:12:02 CET 2005     root at waikiki.visp.de:/usr/obj/usr/src/sys/APP-32-FBSD6  i386
>Description:
My servers have >80k accounts via nss_ldap. Startup of top is very slow, because top read the whole list of system users to find out which is the longest username. This takes several seconds for starting up top on an idle machine of decent speed.

My current patch replaces the username advance code if a variable is defined at compile time. I suggest dropping the current behaviour completely, because the routine is for cosmetic changes to top output only while really being a pain in the ass if you have lots of users.
>How-To-Repeat:
put 80k users on your system (probably use a slow user database like LDAP or NIS) and start top.
>Fix:
diff -c usr.bin/top.orig/Makefile usr.bin/top/Makefile
*** usr.bin/top.orig/Makefile   Sat Feb  9 00:07:35 2002
--- usr.bin/top/Makefile        Wed Nov 30 00:21:29 2005
***************
*** 7,12 ****
--- 7,21 ----
  CFLAGS+= -DHAVE_GETOPT -DHAVE_STRERROR -I${.CURDIR} -I${TOPDIR} -I. -DORDER
  
  #
+ # In large setups advancing through the complete usertable to find the
+ # maximum length of a username means a long startup time. If you define
+ # TOP_NO_NAMELEN in /etc/make.conf the maximum length is considered to
+ # be a good value
+ .if defined(TOP_NO_NAMELEN)
+ CFLAGS+= -DTOP_NO_NAMELEN
+ .endif
+ 
+ #
  # The table size should be a prime number approximately twice as
  # large as the number of lines in /etc/passwd.  The default number
  # is 20011, use /etc/make.conf to override this.
diff -c usr.bin/top.orig/machine.c usr.bin/top/machine.c
*** usr.bin/top.orig/machine.c  Wed May 18 15:42:51 2005
--- usr.bin/top/machine.c       Wed Nov 30 16:34:02 2005
***************
*** 235,240 ****
--- 235,246 ----
            modelen != sizeof(smpmode))
                smpmode = 0;
  
+ #ifdef TOP_NO_NAMELEN
+       if(smpmode)
+               namelength = SMPUNAMELEN;
+       else
+               namelength = UPUNAMELEN;
+ #else
        while ((pw = getpwent()) != NULL) {
                if (strlen(pw->pw_name) > namelength)
                        namelength = strlen(pw->pw_name);
***************
*** 243,248 ****
--- 249,255 ----
                namelength = SMPUNAMELEN;
        else if (namelength > UPUNAMELEN)
                namelength = UPUNAMELEN;
+ #endif
  
        kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open");
        if (kd == NULL)

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list