Subject: sysctl handler to return arrays
To: None <tech-kern@netbsd.org>
From: Simon Burge <simonb@wasabisystems.com>
List: tech-kern
Date: 11/20/2000 18:00:05
As part of my plan to sysctlise the kmem grovellers, I'm going to add
some sysctls to read back info that is currently stored in various lists
and arrays - disk info, evcnt structres, pool stats, and kmem stats and
buckets.  To handle this in a forward binary compatible way means that
we need elem_size type info as is currently done with the kern_proc2
sysctl handler.

The guts of one such list handler (that doesn't handle fixed size
structures in an binary compatibile way) might look like

	for (evp = TAILQ_FIRST(&allevents); evp != NULL;
	    evp = TAILQ_NEXT(evp, ev_list)) {
		if (left < sizeof(struct evcnt_sysctl))
			break;

		... fill in the sevcnt structure ...

		error = copyout(&sevcnt, where, sizeof(sevcnt));
		if (error)
			break;
		where += sizeof(sevcnt);
		*sizep += sizeof(sevcnt);
		left -= sizeof(sevcnt);
	}

but I'm thinking something like

	buf = where;
	buflen = *sizep;
	for (evp = TAILQ_FIRST(&allevents); evp != NULL;
	    evp = TAILQ_NEXT(evp, ev_list)) {
		if (elem_count < 0 || left < elem_size)
			break;

		... fill in the sevcnt structure ...

		error = sysctl_rdstructnext(&sevcnt, &where, &buflen,
		    elem_size, &elem_count);
		if (error)
			break;
	}

where sysctl_rdstructnext() handles the copyout and pointer/buffer
length manipulation rather than duplicating similar code all over
the place.  Does this sound reasonable?

There's also the calling conventions from userland.  For the above example,
this would be:

	mib[0] = CTL_KERN;
	mib[1] = KERN_EVCNT;
	mib[2] = elem_size;
	mib[3] = elem_count;	/* unnecessary?  we already have oldlen */
	sysctl(mib, 4, ...);

I'm not sure that overloading the last mib position(s) is the cleanest
way of passing elem_{size,count} but can't think of any better way of
doing it.  Adding an extra parameter (or two) to sysctl() or even a
separate syscall sounds like way too much overkill though.  Is using
the last mib position(s) the best way of doing this?

Also, the kern_proc2 handler (the only existing elem_* style handler)
uses an elem_count.  I'm thinking of dropping this for future sysctl
handlers as we already have oldlen as well - there's no need for the
extra info.  Again, does this sound reasonable.

Simon.
--
Simon Burge                            <simonb@wasabisystems.com>
NetBSD Sales, Support and Service:  http://www.wasabisystems.com/