No, it really is tripping over the PERMANENT flag!
In kern/kern_sysctl.c line 736 the check for "init_done" is made by
looking at the flags of the system's default sysctl tree, regardless
of which root is being updated. So even though netbsd32_sysctl_init()
is adding its shadow nodes to a non-default tree, it fails because
of the init_done check.
I think the following patch is appropriate. It changes the init_done
check to examine the PERMANENT flag in the affected tree's root node,
rather than the default system tree's node. (Note I have not yet done
even a compile test of this patch yet!)
Index: kern/kern_sysctl.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.219
diff -u -p -r1.219 kern_sysctl.c
--- kern/kern_sysctl.c 12 Nov 2008 12:36:16 -0000 1.219
+++ kern/kern_sysctl.c 14 Dec 2008 02:18:17 -0000
@@ -733,7 +733,7 @@ sysctl_create(SYSCTLFN_ARGS)
* the tree itself is not writeable or
* the entire sysctl system is not writeable
*/
- if ((sysctl_root.sysctl_flags & CTLFLAG_PERMANENT) &&
+ if ((sysctl_rootof(rnode)->sysctl_flags & CTLFLAG_PERMANENT) &&
(!(sysctl_rootof(rnode)->sysctl_flags & CTLFLAG_READWRITE) ||
!(sysctl_root.sysctl_flags & CTLFLAG_READWRITE)))
return (EPERM);
OK, I have verified that the above patch compiles, builds, and even
addresses the problem. So that pretty much confirms that the problem
is caused by the CTLFLAG_PERMANENT check.
Does it really make sense for the state of one sysctl tree to control
whether or not another tree can be manipulated? I'm still questioning
the last condition in this check, which requires that the main/default
tree's root be writeable in order to add an entry to any tree.