Subject: Re: Generic Properties
To: None <eeh@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-kern
Date: 10/05/2001 16:30:42
[ I'm re-adding tech-kern to the CC, because I really want to keep this
  discussion there... ]

On Fri, Oct 05, 2001 at 09:47:47PM -0000, eeh@netbsd.org wrote:

 > If you want to use a property database to store the sysctl tree, you could
 > also store the different sysctl nodes as objects in a single database and 
 > thread them together using "parent" and "children" properties rather than
 > allocate an entire database for each node.

Well, if you do this, you also need "sibling" linkage for each property.
The propdb already provides this (all props in a propdb are logical
siblings).  Another reason for a separate propdb for each level in the
tree is that allows each level in the tree to use the opaque ID as it
sees fit.  For example, it might want to use this as an index into a
table for some reason.  You'll note I did this in my TCP example, giving
each "property" a unique opaque ID within that propdb.

 > | 	- If "store" is NULL, the backing store for the object is
 > | 	  allocated when the prop is first set with prop_set().
 > | 	  Otherwise, the provided backing store is used for the
 > | 	  object.  This can be used for things like variables that
 > | 	  only need to be noticed when they're used, like some of
 > | 	  the TCP tunables (e.g. "tcp_cwm").
 > 
 > May as well set the value with the same semantics as prop_set() and save
 > an extra prop_set() call and all the overhead that can entail.

If you want a prop_set() implied with each prop_create(), that creates
an interesting problem.  Note in my definition of prop_create(), I said
that if backing store was provided by prop_create(), then this backing
store will always be used for the property value.  Note that this may not
be what you want for an "implied prop_set()".  For the vast majority (all?)
of sysctl-like properties, the prop_create() call will be providing backing
store, and thus will be implicitly set.  For others, I don't think the two
calls is that big of a deal.

 > I presume the semantics of PROP_CONST would have to change then?  Otherwise
 > a prop_set() with PROP_CONST set will replace the storage location.

Aha... my brain is still thinking "CONST" means "cannot be changed", i.e.
prop_set() is not allowed on this property -- it is read-only.  I would
really prefer this be the case.  Yes, we would need an additional flag,
such as "PROP_EXTSTORE", for internal use only, that would indicate that
the property backing store is maintained outside the database (such as
would be the case with virtually all sysctl-like properties).

 > | I think this is all doable, and I think it will pretty much address
 > | everyone's concerns, and can be done with out too much hackery to
 > | the current subr_prop.c.
 > 
 > We still don't have a specification for:

Ok, ignoring the pieces that are still missing, do you find my suggestions
reasonable?

 > 	* A syscall interface

I'm hand-waving over this right now... we can deploy the infrastructure
in the kernel and provide backward-compatible sysctl interface (which
we have to do ANYWAY), and doing this wouldn't even be that hard.

 > 	* Access protection for individual properties

See my comment about PROP_CONST.

 > 	* A name/MIB space

Err, I'm not sure what you mean, here.  As for a "name space", the
name space would not be all that different than what we currently
have for sysctl ... and you can "privatize" parts of it using the
extension to propdb_create() that I suggested.

 > 	* Methods to traverse the sysctl tree

Yah, I have thought about this .. it would be done a lot like how fts(3)
is done ... "get a list of the nodes here, then descend into each node".
If a node disappears before you get to it, so what... just return an error
or skip it or whatever.  This can be implemented almost entirely in userland
(need a way to query "which nodes are here?", and that's it).

 > 	* Atomic query/update (so the object is not replaced while
 > 	  you are trying to update it).

Give me an example of what you want to do, here.  There are obvious
locking issues here... although, we could add a "property" file descriptor
on which one can do flock-style locking.

 > 	* Handling databases with completely dynamic object space,
 > 	  such as "kern.proc.*"

See the "get" method that's passed in to prop_create().

 > The last issue is probably the nastiest.  If you want to query "kern.proc.pid.512",
 > you either need to intercept the request at "pid" and finish it off, or you need to
 > create (and destroy) a property for every single process on the machine on fork()
 > (and exit()).  Same for querying vnodes, mbufs, etc.

There's no reason you couldn't do this (intercept the request at...),
actually.  The node lookup could be implemented like pathname lookup,
consuming as much of the path as it wants each time.

 > Rather than look around to see what you can use to replace sysctl(), I would 
 > recommend sitting down and specifying a set of requirements for the new 
 > super-sysctl() so you don't end up with another square peg trying to cover
 > a round hole.
 > 
 > Eduardo

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>