Bug 17498

Summary: killall(1) is a slow perl script that's dependant on procfs
Product: Base System Reporter: bugg <bugg>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.0-CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.shar none

Description bugg 2000-03-20 03:20:00 UTC
	The problem is that killall(1) currently uses procfs for abstraction
of process information from the kernel, which while it sounds like an excellent
idea in concept, does not provide a significant advantage over using a
sysctl. 
	In cases where the system is to be secure, procfs usually is not
mounted.  This is because procfs has had more than one vulnerability found
in it over the years, and, well, "if they really don't need it, don't
let them have it" security logic.
	Most jails that are setup using jail() do not have access to a
mounted procfs.  If one were to use the command killall inside such
a jail, they'd just get an error about procfs not being mounted.
	The current implementation of killall crawls procfs looking for
a matching process.  It is effective, but not too speedy as the data is 
abstracted via a filesystem.  Following is proof of the current killall's
lack of speed:

With the stock killall:

curly% time killall top
        0.04 real         0.03 user         0.00 sys

With the sysctl based killall:

curly% time ./killall top
        0.00 real         0.00 user         0.00 sys

	Now, the difference in speed may not seem like a big issue, but the fact
is these tests were performed on an Intel Celeron 400 under hardly any
load.  On a slower computer, or under significant load, the increased efficency
is something that the end user will definetly feel.

Fix: The following is an example C program that performs the same function
as the current implementation of killall(1), and is option-by-option 
compatible, bar two exceptions.  These exceptions are so-called
double verbosity (specifying the -v option twice to get a list of 
information obtained from procfs: this seems like a feature that
serves no practical purpose as ps(1) provides the same information)

The other feature which is not present in this version is the -m option.
This feature is dependant on its usage of perl, and may or may not be
worth reimplementing in C.

I've modified the existing manpage to reflect the changes made, and
in the event this program is accepted with out much changes to its
behavior, contact me and I will send you a copy of the manpage.

This program has only a dependency on being able to call sysctl(), not
procfs or /dev/kmem.

Please excuse in advance any whitespace, style, or coding errors in
this program.  I've tested it somewhat to make sure none exist,
but I'm sure some of you will be able to find things that could
be done better :)

Regards,
	Dan Papasian.
How-To-Repeat: 
Use killall when you can't wait .04 seconds, or on a box without a mounted
procfs.
Comment 1 peter 2000-03-20 12:38:26 UTC
Dan Papasian wrote:
[..]
> X	++argv;
> X	while (--argc > 0 && **argv == '-') {
> X
> X		/* Remove dashes */
> X		while (**argv == '-')
> X			++* argv;
> X
> X		/* If the argument ends here, it isn't the signal */
> X		/* If it is a digit, it is the signal.  Don't pass to switch */
> X		if (argv[0][1] == '\0' && !isdigit(**argv)) {
> X			switch (**argv) {
> X			case 'd':
> X			case 'v':

This doesn't use getopt(), it probably should.

> X	sysctl(mib, 3, NULL, &kplen, NULL, 0);
> X	procall = kp = malloc(kplen);
> X	sysctl(mib, 3, kp, &kplen, NULL, 0);

There is no error checking here..

Cheers,
-Peter
Comment 2 Johan Karlsson freebsd_committer freebsd_triage 2000-12-15 18:20:20 UTC
State Changed
From-To: open->closed

killall(1) is now a c program.