Subject: Re: new sysctl(KERN_PROC, ...) interface (was: sysinfo(2))
To: Eduardo Horvath <erh@nimenees.com>
From: Simon Burge <simonb@netbsd.org>
List: tech-kern
Date: 04/17/2000 10:40:17
Eduardo Horvath wrote:
> On Sat, 15 Apr 2000 erh@nimenees.com wrote:
>
> If I recall correctly, the original source for this discussion was my
> mentioning that sysctl() and kernel grovelling does not work well for
> binaries under 32-bit emulation.
I thought the original motivation (and has been my main motivation) was
fixing ps's "proc size mismatch" errors, but 32 bit emulation is another
canditate as well. Indeed, I don't think I'd seen a reference until
you sent one just after I sent my message about an implementation being
available. Crossed wires or whatever...
> The proposed interface(s) don't really address this issue.
>
> sysctl() is broken because it passes internal kernel structures
> directly out to userland. This means that any 32-bit emulation
> sysctl() system call must have knowledge of all sysctl variables to make
> appropriate translations.
More below on this...
> And this still does not solve the kmem grovelling issue that results if
> you want to extract the data from a dead kernel.
This is handled (or will be when it's coded up) by kvm_getproc2(). In
theory you shouldn't need to use the sysctl interface directly, although
of course nothing stops you from doing that.
> What you need to do is provide a formal interface which provides data in a
> specific format so the syscall wrappers can do required
> translations. Providing raw kernel data structures along with a size does
> not help. You could do the same thing with kernel grovelling by ignoring
> the structure size mismatch and presuming that no existing fields have
> changed size or location.
In generel there was no intent to pass raw kernel data structures back
to userland. kinfo_proc2 was defined in terms of a long of basic kernel
types (uid_t, pid_t, etc) and I had mentioned earlier that if the size
of these types changed then a backwards compatibilish type should be
provided for the kinfo_proc2 interface.
and from your last message:
> You should either get rid of all these pointers and convert them to a
> u_int64_t so the structure does not change, or provide some mechanism to
> repack te structure before the copyout() so this entire mess does not need
> to be reimplemented inside COMPAT_NETBSD32 code.
Ok, I've just about changed it so that _all_ fields are {u_,}intXX_t's,
except for the char[] fields. One remaining hassle is sigset_t which is
defined as a structure of 4 u_int32_t's. Instead of
sigset_t p_siglist;
I could have
u_int32_t p_siglist[SIGSET_LEN];
but that seems sorta ugly.
To deal with pointers, I've changed all pointers in kinfo_proc2 to
u_int64_t's, and got in fill_kproc2():
#define PTRTOINT64(foo) ((u_int64_t)(long)(foo))
ki->p_paddr = PTRTOINT64(p);
I need to double case to stop warnings on 32 bit platforms. Is this
the best way?
One more thing - I guess I have to worry about structure packing,
especially for the compat32 case, right? If so, I'll arrange for
everything to be aligned at 8 bytes then.
Will these changes address all of your compat32 concerns? I don't have
anything to test this against - I imagine sparc64 with sparc userland is
the only user of this at the moment?
Simon.