| Summary: | killall(1) is a slow perl script that's dependant on procfs | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | bugg <bugg> | ||||
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 4.0-CURRENT | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
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 State Changed From-To: open->closed killall(1) is now a c program. |
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.