[Toybox] How toybox PS works.
Ed Maste
emaste at freebsd.org
Thu Jan 31 06:06:35 PST 2019
On Wed, 30 Jan 2019 at 18:58, Rob Landley <rob at landley.net> wrote:
>
> The bigger problem for BSD/macos is ps.c parses /proc/$PID/stat to get its
> process information, and I don't think BSD even has that concept?
We do have a procfs, but its use is discouraged and is not compatible
with the Linux procfs. We do have a linprocfs for the Linux emulation
layer, but it's not mounted in a FreeBSD tree.
> No idea where
> BSD or MacOS versions of ps get this sort of data. (Bell Labs unix read /dev/mem
> and parsed the in-kernel process table structures. No really!
Yep, there are vestiges of this history in FreeBSD still, and I
believe the FreeBSD lsof port still works this way.
On FreeBSD ps links against libkvm and uses kvm_getprocs, from the man page:
struct kinfo_proc *
kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt);
The kvm_getprocs() function returns a (sub-)set of active processes in
the kernel indicated by kd. The op and arg arguments constitute a
predicate which limits the set of processes returned. The value of op
describes the filtering predicate as follows:
KERN_PROC_ALL all processes and kernel visible threads
KERN_PROC_PROC all processes, without threads
KERN_PROC_PID processes with process ID arg
KERN_PROC_PGRP processes with process group arg
KERN_PROC_SESSION processes with session arg
KERN_PROC_TTY processes with TTY arg
KERN_PROC_UID processes with effective user ID arg
KERN_PROC_RUID processes with real user ID arg
KERN_PROC_INC_THREAD modifier to return all kernel visible threads
when filtering by process ID, process group,
TTY, user ID, and real user ID
The man page also includes a BUGS section that states "These routines
do not belong in the kvm interface" but they presumably will never
move.
Under the hood kvm_getprocs uses the sysctl interface,
kern.proc.<op>.<pid>. Source is here:
https://reviews.freebsd.org/source/src/browse/head/lib/libkvm/kvm_proc.c$491
I haven't looked at Darwin, but I suspect it uses the same interface.
Linking against libkvm on *BSD seems reasonable.
> In practice, the dirtree infrastructure that finds the processes (lib/dirtree.c)
> is recursive directory descent plumbing populating a tree of struct dirtree *
> structures for each entry and calling a callback function to filter and/or act
> upon them. Which means A) it assumes it's reading a filesystem to populate, B)
> our get_ps() is a callback function that knows about the /proc layout. There's
> also a get_threads() shim that descends an extra level for Linux's weird thread
> layout (and then calls get_ps() to do the reading once it's identified the next
> directory with something interesting).
For us including or excluding threads is just a flag to kvm_getprocs.
If it simplifies things leaving get_ps as a callback seems fine,
although replacing the dirtree search means there's probably a fair
bit that needs to be done differently. In any case for me the more
system-specific utilities are the lowest priority; the pure
text-processing and basic filesystem utilities are more interesting
initially.
More information about the Toybox
mailing list