Subject: Re: Replacing the sysctl() interface.
To: Darren Reed <darrenr@reed.wattle.id.au>
From: Eduardo Horvath <eeh@turbolinux.com>
List: tech-kern
Date: 06/06/2000 09:16:48
On Tue, 6 Jun 2000, Darren Reed wrote:

> In some email I received from Eduardo Horvath, sie wrote:
> > On Mon, 5 Jun 100, Darren Reed wrote:
> > 
> > > I'm musing over working on replacing the current sysctl with something
> > > that's much more flexible and supports (at the very least) it being
> > > dynamic in nature.
> > > 
> > > Some of changes I think are worthwhile making:
> > 
> > Something that is lacking in the current sysctl setup is some way to
> > determine the type of a sysctl variable so it can be converted if needed
> > (for 32-bit emulation).
> 
> Currently, there is a sysctl function to deal with int's, quad's,
> strings and struct's.  "int" is presumed to be 32bit, quad is...
> potentially vague.  Should we even be using {u_,}quad_t (use int64_t
> in its place) in the kernel ?

The `int', strings and `quad's are fairly straight forward.  Structs,
however, may require conversion.  For example `kern.boottime' returns a
`struct timeval' which is:

struct timeval {
	long	tv_sec;		/* seconds */
	long	tv_usec;	/* and microseconds */
};

And `long' is 32-bits in ILP32 but 64-bits in LP64.  This structure needs
to be converted properly before being copied out.  The current interface
just does:

#define SYSCTL_SCALAR_CORE_LEN(oldp, oldlenp, valp, len) 		\
	if (oldlenp) {							\
		if (!oldp)						\
			*oldlenp = len;					\
		else {							\
			if (*oldlenp < len)				\
				return(ENOMEM);				\
			*oldlenp = len;					\
			error = copyout((caddr_t)valp, oldp, len);	\
		}							\
	}


> To me, it is a problem for the in-kernel sysctl code.  There, the code
> knows the size of the userland object into which the value is being
> stored, as well as the size of the object in the kernel to be copied back.
> >From that information, it should be relatively easy to determine if it
> is a 64bit object into a 32bit container.

True, but the code does not know the layout of the kernel or userland
object being copied out so it cannot make the appropriate
conversions.  Appropriate converters need to be called for each different
object.  In the default case (kernel and userland are the same) these
converters simply do the copyin()/copyout().  Otherwise marshalling must
be done.

Eduardo Horvath