Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 May 2018 10:32:30 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Eitan Adler <eadler@freebsd.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org,  svn-src-head@freebsd.org
Subject:   Re: svn commit: r333945 - head/usr.bin/top
Message-ID:  <20180521094344.Q1053@besplex.bde.org>
In-Reply-To: <201805202319.w4KNJ9hj038452@repo.freebsd.org>
References:  <201805202319.w4KNJ9hj038452@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 20 May 2018, Eitan Adler wrote:

> Log:
>  top(1): set max username length based on system constant
>
>  This changes previous behavior of calculating it at startup based on
>  the current max username length.
>
>  This is done because:
>  - it is in theory possible for the max length to change at run-time
>    (e.g., a new user is added after top starts running)
>  - on machines with many users this delays startup significantly

This is sort of backwards.  MAXLOGNAME would be harmful if it were actually
used for the limit here, but it has never been used for the limit here.

First, MAXLOGNAME should never be used.  It is an old BSD name for the
POSIX limit {LOGIN_NAME_MAX}.  LOGIN_NAME_MAX should never be used either.
It might be undefined, or possibily -1, to indicate that it can vary.
sysconf() should be used to determine {LOGIN_NAME_MAX}.

After determining the correct value, you will find that it is always
unusable here because it is too large.  It might be LONG_MAX to indicate
no limit, or it might be 255 which is merely 3 times the terminal width.
It used to be 17 in FreeBSD, and is now 33.  17 is about 1/5 of the terminal
width, but that is too wide.  33 is grossly too wide.  17 was used for a
while, but this was mostly fixed in r146291 in 2005.  The log message for
r146291 claims to limit the length to 8, but the code is slightly better,
but obfuscated.  The lower limit is never 8, but is 13 for SMP and 15 for
UP.  8 is only the lower limit and is only imposed so that the format doesn't
change too often if all user names are short.

>  PR:		20799
>  PR:		89762
>  Reported by:	ob@e-Gitt.NET
>  Reported by:	wkwu@Kavalan.csie.NCTU.edu.tw
>  Reported on:	2000-08-23 and 2005-11-30

The first one of these is much older than the fix in r146291.

> Modified: head/usr.bin/top/machine.c
> ==============================================================================
> --- head/usr.bin/top/machine.c	Sun May 20 22:07:44 2018	(r333944)
> +++ head/usr.bin/top/machine.c	Sun May 20 23:19:09 2018	(r333945)
> @@ -340,12 +340,7 @@ machine_init(struct statics *statics, char do_unames)
> 	    NULL, 0) == 0 && carc_en == 1)
> 		carc_enabled = 1;
>
> -	if (do_unames) {
> -	    while ((pw = getpwent()) != NULL) {
> -		if (strlen(pw->pw_name) > namelength)
> -			namelength = strlen(pw->pw_name);
> -	    }
> -	}

namelength is now initially TOP_USERNAME_LEN if that is defined, else 8.
TOP_USERNAME_LEN is now never used as well as rarely configured.  The
hard-coded 8 is now never used instead of rarely used.

The above loop took the maximum of {(initial TOP_USERNAME_LEN or 8),
all names in system}.  On large systems there is usually at least one
use with a verbose name.  This makes any reasonably small initial limits
have no effect (since they minimums, not maximumns).  A minimum limit is
also needed for space for "USERNAME<spaces>" in the header.

> +	namelength = MAXLOGNAME;

This is now always 33 in FreeBSD.

> 	if (smpmode && namelength > SMPUNAMELEN)
> 		namelength = SMPUNAMELEN;
> 	else if (namelength > UPUNAMELEN)

But 33 is too large.  It is much larger than the hard-coded maximum limits,
so it is never used, but is reduced to SMPNAMELEN = 13 or UPUNAMELEN = 15.

So getting the correct value of about 8 is even harder than before, but
changing SMPNAMELEN to 4 works quite well -- "USERNAME" in the header is
then reduced to "USER" and space is made available for something useful
like the command name.

The old code did work for forcing a minimum user name length of
(TOP_USERNAME_LEN or 8) and a maximum user name length of (SMPUNAMELEN or
UPUNAMELEN).  The breakage in this commit is only seen on systems without
verbose names, e.g., mine, where the longest name is "operator" (length 8).
Then the dynamic maximum is the same as the static maximum (8), so the
final length is 8.  Now the minimum and maxium are hard-coded (modulo
MAXLOGNAME being unusuably large) as 15 or 13, so all systems now waste
space like only large systems used to do.

The correct method is something like defaulting to 8 but allow overriding
this using an environment variable or option.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20180521094344.Q1053>