Subject: Re: dynamic sysctl
To: None <tech-kern@NetBSD.org>
From: Andrew Brown <atatat@atatdot.net>
List: tech-kern
Date: 11/16/2003 21:02:39
>> > >> and then you have all the mappings for name<->number under net.  for
>> > >> the children of those nodes, you simply iterate.
>> > >
>> > >What happens if the name<->number mappings change in between the 
>> > >mapping call and the walking?  It's dynamic, so you're going to have to 
>> > >expect this.
>> > 
>> > good question.
>> > 
>> > the answer is that each node has a version number (an int -- i am
>> > studiously ignoring the case where the version number wraps around).
>> > 
>> > when a node is created the global version counter is incremented and
>> > the new version number is assigned to the new node and its parent,
>> > straight up to the root of the tree.
>> > 
>> > likewise, when a node is destroyed, the global version number is
>> > incremented, and the new version number is assigned to the parent of
>> > the node that is being destroyed all the way back up the tree.
>> > 
>> > sysctlnametomib() just checks that all the versions are the same at
>> > the top of the tree each time it's called, and for those that have
>> > changed, it purges that data from its cache.
>> 
>
>I do not even understand my own question. Let me try that again.

i think i didn't either.

>I am not sure I understand how sysctlnametomib works. Tell me if this is
>right: my program calls sysctlnametomib("/a/b/c"). sysctlnametomib uses
>sysctl to record the version number stored at the top of the tree. It
>resolves "/a/b" to 13.27 using two sysctl calls. In the mean time, the
>kernel deletes the path "/a/b/d", which increases the version number
>at 13.27, at 13, and at the root.  Now, sysctlnametomib resolves "c"
>at 13.27 to 4.  It compares the version number at the root with the
>version number it recorded. Finding that the versions are different,
>it sets errno to EAGAIN (say) and returns -1. My program has to try
>again to resolve /a/b/c to a number.
>
>Assuming that is the way it works, I will worry that my program will
>sometimes have to try again forever to resolve "/a/b/c" to a numeric path.

okay, i follow you.  here's how it works:

	you call sysctlnametomib("/a/b/c")

	sysctlnametomib() rechecks[*] that the root versions are all
 	consistent and prunes anything that has "expired"

	sysctlnametomib() finds that "a" maps to 13

	sysctlnametomib() has the children for "a" in its cache and it
	finds that "b" maps to 27

	sysctlnametomib() doesn't have the children for "b" in its
	cache, so it loads them[*] and finds that "c" maps to 2343453

	sysctlnametomib() returns 13.27.2343453, namelen 3,
	canonicalized name "/a/b/c", and your program presumably calls
	sysctl()[*]

the places where [*] occurs are calls to sysctl(3).  the version
number is not maniacally checked everywhere it might conceivably be
possible at all times.

that said, i think i have already written support in the kernel
portions of this to support such a fiendish plan, but i didn't see
much actual value in making sysctlnametomib() go nuts like that.

-- 
|-----< "CODE WARRIOR" >-----|
codewarrior@daemon.org             * "ah!  i see you have the internet
twofsonet@graffiti.com (Andrew Brown)                that goes *ping*!"
werdna@squooshy.com       * "information is power -- share the wealth."