Subject: new sysctl(KERN_PROC, ...) interface (was: sysinfo(2))
To: None <tech-kern@netbsd.org>
From: Simon Burge <simonb@netbsd.org>
List: tech-kern
Date: 04/16/2000 02:28:19
Recently there was a little talk about limiting the rate of change of
the size of struct kinfo_proc, primarily motivated by ps(1) complaining
about 'proc size mismatches' whenever some kernel structures changed
size.

Recently there was a little talk about limiting the rate of change
and providing binary compatility with sysctl(KERN_PROC, ...) (and
kvm_getprocs()).

My current thinking is to handle this within sysctl() (and
kvm_getproc*()), by adding a new mib based on KERN_PROC with two
extra entries:

	mib[0] = CTL_KERN;
	mib[1] = KERN_PROC2;
	mib[2] = op;
	mib[3] = arg;
	mib[4] = elem_size;
	mib[5] = elem_count;

where op and arg are as they currently are.  elem_size is the size of
each requested process info structure and elem_count is the number of
structures requested.  sysctl()'s oldlen would still be the overall
size (usually elem_size * elem_count).

Given that the current interface is useless each time something in
struct proc (and some other structures) change, I was originally
thinking of renaming the current mib number to KERN_OPROC and have it
immediately fail.  However the current interface (in kvm_getprocs())
grabs a complete struct proc from a crash dump if not running on a live
system which is mighty useful for debugging.  I'm sure there'll also be
a couple of third party programs around that like kernel diving (lsof
and skill come to mind).

The new KERN_PROC2 handler would stuff a relatively fixed size struct
kinfo_proc2, with any new elements only ever being added to the end of
the structure.  kvm_getproc2() would also grovel a memory image and fill
it in so the programs using the new interface will still work on crash
dumps.

struct kinfo_proc2 would be a single level structure so there'd be no
references to any kernel structures that may change size later on.  I'd
not expect types like pid_t, gid_t, sigset_t and segsz_t to change size
to often - if they do then we'd add an o<type>_t or similar (perhaps
local to <sys/sysctl.h>) and fill in as much of the old type as we
could, and a new element of the new type at the end of kinfo_proc2.

For each process requested, the handler would memcpy (uiomove or
whatever) only the first elem_size bytes or each struct kinfo_proc2 to
the user buffer.  Thus we should be able to have an old ps(1) work on a
new kernel without complaining about proc size mismatches.

Any basic flaws in this line of reasoning so far?  Aidan - I know this
is not exactly what you had in mind; how much different is it?

Simon.